aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKarsten Heimrich <karsten.heimrich@qt.io>2022-03-11 15:41:34 +0100
committerKarsten Heimrich <karsten.heimrich@qt.io>2022-04-05 11:18:57 +0000
commit724ed366ec292f875e17d8e0f1e994461e099c6d (patch)
treeaf0418d93750e93dddad4be31f50ddf3425416ef
parentb11f42de79c296b4c56d971929c2b25a57f5a267 (diff)
Rework help link chooser and translation page search
* Introduce new classes to use VS provided search facility and update implementations using these new classes. * Minor using statement cleanup Change-Id: Idc299665c3712cd0b7a1b1b7e5e1bc270831b9df Reviewed-by: Miguel Costa <miguel.costa@qt.io>
-rw-r--r--QtVsTools.Core/QtVsTools.Core.csproj2
-rw-r--r--QtVsTools.Core/VisualStudio/VsSearch.cs146
-rw-r--r--QtVsTools.Package/Package/QtHelp.cs6
-rw-r--r--QtVsTools.Package/Package/QtHelpLinkChooser.xaml18
-rw-r--r--QtVsTools.Package/Package/QtHelpLinkChooser.xaml.cs23
-rw-r--r--QtVsTools.Wizards/ItemWizard/Translation/TranslationPage.xaml28
-rw-r--r--QtVsTools.Wizards/ItemWizard/Translation/TranslationPage.xaml.cs18
7 files changed, 191 insertions, 50 deletions
diff --git a/QtVsTools.Core/QtVsTools.Core.csproj b/QtVsTools.Core/QtVsTools.Core.csproj
index fbc2cc9c..b6d7aa75 100644
--- a/QtVsTools.Core/QtVsTools.Core.csproj
+++ b/QtVsTools.Core/QtVsTools.Core.csproj
@@ -69,6 +69,7 @@
// -->
<ItemGroup>
<Service Include="{508349B6-6B84-4DF5-91F0-309BEEBAD82D}" />
+ <Reference Include="PresentationFramework" />
<Reference Include="System" />
<Reference Include="System.Drawing" />
<Reference Include="System.Xml" />
@@ -182,6 +183,7 @@
<Compile Include="SR.cs" />
<Compile Include="VersionInformation.cs" />
<Compile Include="VisualStudio\IProjectTracker.cs" />
+ <Compile Include="VisualStudio\VsSearch.cs" />
<Compile Include="VisualStudio\VsServiceProvider.cs" />
<Compile Include="WaitDialog.cs" />
<EmbeddedResource Include="ExportProjectDialog.resx">
diff --git a/QtVsTools.Core/VisualStudio/VsSearch.cs b/QtVsTools.Core/VisualStudio/VsSearch.cs
new file mode 100644
index 00000000..5951b0b7
--- /dev/null
+++ b/QtVsTools.Core/VisualStudio/VsSearch.cs
@@ -0,0 +1,146 @@
+/****************************************************************************
+**
+** Copyright (C) 2022 The Qt Company Ltd.
+** Contact: https://www.qt.io/licensing/
+**
+** This file is part of the Qt VS Tools.
+**
+** $QT_BEGIN_LICENSE:GPL-EXCEPT$
+** Commercial License Usage
+** Licensees holding valid commercial Qt licenses may use this file in
+** accordance with the commercial license agreement provided with the
+** Software or, alternatively, in accordance with the terms contained in
+** a written agreement between you and The Qt Company. For licensing terms
+** and conditions see https://www.qt.io/terms-conditions. For further
+** information use the contact form at https://www.qt.io/contact-us.
+**
+** GNU General Public License Usage
+** Alternatively, this file may be used under the terms of the GNU
+** General Public License version 3 as published by the Free Software
+** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
+** included in the packaging of this file. Please review the following
+** information to ensure the GNU General Public License requirements will
+** be met: https://www.gnu.org/licenses/gpl-3.0.html.
+**
+** $QT_END_LICENSE$
+**
+****************************************************************************/
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Windows.Controls;
+using System.Windows.Data;
+using Microsoft.Internal.VisualStudio.PlatformUI;
+using Microsoft.VisualStudio;
+using Microsoft.VisualStudio.PlatformUI;
+using Microsoft.VisualStudio.Shell;
+using Microsoft.VisualStudio.Shell.Interop;
+
+namespace QtVsTools.VisualStudio
+{
+ public class SearchTask : VsSearchTask
+ {
+ private readonly Action _clearCallback = null;
+ private readonly Func<IEnumerable<string>, uint> _searchCallBack = null;
+
+ public SearchTask(uint cookie, IVsSearchQuery query, IVsSearchCallback callback,
+ Action clearCallback, Func<IEnumerable<string>, uint> searchCallBack)
+ : base(cookie, query, callback)
+ {
+ _clearCallback = clearCallback;
+ _searchCallBack = searchCallBack;
+ }
+
+ protected override void OnStartSearch()
+ {
+ ErrorCode = VSConstants.S_OK;
+ try {
+ _ = ThreadHelper.JoinableTaskFactory.RunAsync(async () =>
+ {
+ await ThreadHelper.JoinableTaskFactory.SwitchToMainThreadAsync();
+ if (TaskStatus != VSConstants.VsSearchTaskStatus.Stopped) {
+ SearchResults = _searchCallBack(
+ SearchUtilities.ExtractSearchTokens(SearchQuery).Select(token =>
+ {
+ ThreadHelper.ThrowIfNotOnUIThread();
+ return token.ParsedTokenText;
+ })
+ );
+ } else if (TaskStatus == VSConstants.VsSearchTaskStatus.Stopped) {
+ _clearCallback();
+ }
+ });
+ } catch {
+ ErrorCode = VSConstants.E_FAIL;
+ }
+ base.OnStartSearch();
+ }
+
+ protected override void OnStopSearch()
+ {
+ SearchResults = 0;
+ }
+ }
+
+ public abstract class VsWindowSearch : IVsWindowSearch
+ {
+ public abstract IVsSearchTask CreateSearch(uint cookie, IVsSearchQuery query,
+ IVsSearchCallback callback);
+
+ public virtual void ClearSearch()
+ {}
+
+ public virtual void ProvideSearchSettings(IVsUIDataSource settings)
+ {
+ Utilities.SetValue(settings, SearchSettingsDataSource.PropertyNames.ControlMaxWidth,
+ (uint)10000);
+ Utilities.SetValue(settings, SearchSettingsDataSource.PropertyNames.SearchStartType,
+ (uint)VSSEARCHSTARTTYPE.SST_INSTANT);
+ }
+
+ public virtual bool OnNavigationKeyDown(uint dwNavigationKey, uint dwModifiers) => false;
+
+ public virtual bool SearchEnabled => true;
+
+ public virtual Guid Category => Guid.Empty;
+
+ public virtual IVsEnumWindowSearchFilters SearchFiltersEnum => null;
+
+ public virtual IVsEnumWindowSearchOptions SearchOptionsEnum => null;
+ }
+
+ public class ListBoxSearch : VsWindowSearch
+ {
+ private readonly ListBox _listBox = null;
+ private Action<string> _setSearchText = null;
+
+ public ListBoxSearch(ListBox listBox, Action<string> action)
+ {
+ _listBox = listBox;
+ _setSearchText = action;
+ }
+
+ public override IVsSearchTask CreateSearch(uint cookie, IVsSearchQuery query,
+ IVsSearchCallback callback)
+ {
+ return new SearchTask(cookie, query, callback, ClearSearch,
+ searchCallBack: (IEnumerable<string> tokens) =>
+ {
+ _setSearchText(string.Join(" ", tokens));
+ var view = CollectionViewSource.GetDefaultView(_listBox.ItemsSource);
+
+ view.Refresh();
+ if (_listBox.Items.Count == 1 || _listBox.SelectedItem == null)
+ _listBox.SelectedIndex = 0;
+ return (uint)view.Cast<object>().Count();
+ });
+ }
+
+ public override void ClearSearch()
+ {
+ _setSearchText(string.Empty);
+ CollectionViewSource.GetDefaultView(_listBox.ItemsSource).Refresh();
+ }
+ }
+}
diff --git a/QtVsTools.Package/Package/QtHelp.cs b/QtVsTools.Package/Package/QtHelp.cs
index e3e86b30..84b121d1 100644
--- a/QtVsTools.Package/Package/QtHelp.cs
+++ b/QtVsTools.Package/Package/QtHelp.cs
@@ -1,6 +1,6 @@
/****************************************************************************
**
-** Copyright (C) 2016 The Qt Company Ltd.
+** Copyright (C) 2022 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt VS Tools.
@@ -33,11 +33,9 @@ using System.Data.Common;
using System.Data.SQLite;
using System.IO;
using System.Linq;
+using EnvDTE;
using Microsoft.VisualStudio.Shell;
using Microsoft.VisualStudio.Shell.Interop;
-using EnvDTE;
-
-using Task = System.Threading.Tasks.Task;
namespace QtVsTools
{
diff --git a/QtVsTools.Package/Package/QtHelpLinkChooser.xaml b/QtVsTools.Package/Package/QtHelpLinkChooser.xaml
index d9d6a1d6..0494ddef 100644
--- a/QtVsTools.Package/Package/QtHelpLinkChooser.xaml
+++ b/QtVsTools.Package/Package/QtHelpLinkChooser.xaml
@@ -46,15 +46,13 @@
ResizeMode="CanResizeWithGrip"
WindowStartupLocation="CenterOwner">
<vsui:DialogWindow.Resources>
- <BooleanToVisibilityConverter x:Key="b2v" />
<Style x:Key="ListBoxDoubleClickStyle"
TargetType="ListBoxItem">
<EventSetter Event="MouseDoubleClick"
Handler="OnListBoxItem_DoubleClick" />
</Style>
</vsui:DialogWindow.Resources>
- <Grid Margin="10"
- FocusManager.FocusedElement="{Binding ElementName=searchBox}">
+ <Grid Margin="10">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
@@ -68,18 +66,8 @@
Text="{Binding Path=Keyword}" />
<Run Text=":" />
</TextBlock>
- <Grid Grid.Row="1"
- MinHeight="22"
- Background="White">
- <TextBlock Text=" Filter..."
- Foreground="LightSteelBlue"
- VerticalAlignment="Center"
- Visibility="{Binding ElementName=searchBox,
- Path=Text.IsEmpty, Converter={StaticResource b2v}}" />
- <TextBox Name="searchBox"
- Background="Transparent"
- TextChanged="OnSearchBox_TextChanged"
- VerticalContentAlignment="Center" />
+ <Grid Grid.Row="1">
+ <Grid Name="searchControlHost" />
</Grid>
<ListBox Grid.Row="2"
Margin="0,10,0,0"
diff --git a/QtVsTools.Package/Package/QtHelpLinkChooser.xaml.cs b/QtVsTools.Package/Package/QtHelpLinkChooser.xaml.cs
index 32b46387..655954ad 100644
--- a/QtVsTools.Package/Package/QtHelpLinkChooser.xaml.cs
+++ b/QtVsTools.Package/Package/QtHelpLinkChooser.xaml.cs
@@ -33,6 +33,9 @@ using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Input;
using Microsoft.VisualStudio.PlatformUI;
+using Microsoft.VisualStudio.Shell;
+using Microsoft.VisualStudio.Shell.Interop;
+using QtVsTools.VisualStudio;
namespace QtVsTools
{
@@ -47,28 +50,32 @@ namespace QtVsTools
}
public string Link { get; set; }
+ public string SearchText { get; set; }
+
public string Keyword { private get; set; }
public Dictionary<string, string> Links { private get; set; }
private void OnLoaded(object sender, RoutedEventArgs e)
{
+ ThreadHelper.ThrowIfNotOnUIThread();
+
var view = CollectionViewSource.GetDefaultView(linkListBox.ItemsSource);
view.Filter = obj =>
{
- if (string.IsNullOrEmpty(searchBox.Text))
+ if (string.IsNullOrEmpty(SearchText))
return true;
var item = (KeyValuePair<string, string>)obj;
- return item.Key.IndexOf(searchBox.Text, StringComparison.OrdinalIgnoreCase) >= 0;
+ return item.Key.IndexOf(SearchText, StringComparison.OrdinalIgnoreCase) >= 0;
};
linkListBox.SelectedIndex = 0;
- }
- private void OnSearchBox_TextChanged(object sender, TextChangedEventArgs e)
- {
- CollectionViewSource.GetDefaultView(linkListBox.ItemsSource).Refresh();
- if (linkListBox.Items.Count == 1 || linkListBox.SelectedItem == null)
- linkListBox.SelectedIndex = 0;
+ var factory = VsServiceProvider
+ .GetService<SVsWindowSearchHostFactory, IVsWindowSearchHostFactory>();
+ var host = factory.CreateWindowSearchHost(searchControlHost);
+
+ host.SetupSearch(new ListBoxSearch(linkListBox, value => SearchText = value));
+ host.Activate(); // set focus
}
private void OnListBoxItem_DoubleClick(object sender, MouseButtonEventArgs e)
diff --git a/QtVsTools.Wizards/ItemWizard/Translation/TranslationPage.xaml b/QtVsTools.Wizards/ItemWizard/Translation/TranslationPage.xaml
index b87402d9..f025643c 100644
--- a/QtVsTools.Wizards/ItemWizard/Translation/TranslationPage.xaml
+++ b/QtVsTools.Wizards/ItemWizard/Translation/TranslationPage.xaml
@@ -30,7 +30,6 @@
<common:WizardPage x:Class="QtVsTools.Wizards.ItemWizard.TranslationPage"
xmlns:common="clr-namespace:QtVsTools.Wizards.Common"
- xmlns:util="clr-namespace:QtVsTools.Wizards.Util"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
@@ -38,12 +37,8 @@
KeepAlive="True"
mc:Ignorable="d"
d:DesignHeight="445"
- d:DesignWidth="585"
- FocusManager.FocusedElement="{Binding ElementName=LanguageListBox}">
- <common:WizardPage.Resources>
- <BooleanToVisibilityConverter x:Key="b2v" />
- </common:WizardPage.Resources>
- <Grid>
+ d:DesignWidth="585" >
+ <Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="100" />
<ColumnDefinition Width="*" />
@@ -92,19 +87,8 @@
<TextBlock Grid.Row="0"
Margin="0,0,0,5"
Text="Select a Language:" />
- <Grid Grid.Row="1"
- MinHeight="22"
- Background="White">
- <TextBlock Text=" Filter..."
- Foreground="LightSteelBlue"
- VerticalAlignment="Center"
- Visibility="{Binding ElementName=searchBox,
- Path=Text.IsEmpty,
- Converter={StaticResource b2v}}" />
- <TextBox Name="searchBox"
- Background="Transparent"
- TextChanged="OnSearchBoxTextChanged"
- VerticalContentAlignment="Center" />
+ <Grid Grid.Row="1">
+ <Grid Name="searchControlHost" />
</Grid>
<ListBox Grid.Row="2"
Margin="0,10,0,8"
@@ -115,6 +99,7 @@
SelectedValue="{Binding Path=Data.CultureInfoName}"
SelectionChanged="OnLanguageBoxSelectionChanged" />
<TextBlock Grid.Row="3"
+ Margin="0,0,0,5"
Text="Save as:"/>
<Grid Grid.Row="4">
<Grid.ColumnDefinitions>
@@ -123,7 +108,8 @@
</Grid.ColumnDefinitions>
<TextBox Text="{Binding Path=Data.TsFile}"/>
<TextBlock Grid.Column="1"
- Margin="5,0,0,0">
+ Margin="5,0,0,0"
+ VerticalAlignment="Center">
<Run FontWeight="Bold"
Text="{Binding Path=Data.CultureInfoName}" />
<Run Text=".ts" />
diff --git a/QtVsTools.Wizards/ItemWizard/Translation/TranslationPage.xaml.cs b/QtVsTools.Wizards/ItemWizard/Translation/TranslationPage.xaml.cs
index 59dbb5b7..7a25c517 100644
--- a/QtVsTools.Wizards/ItemWizard/Translation/TranslationPage.xaml.cs
+++ b/QtVsTools.Wizards/ItemWizard/Translation/TranslationPage.xaml.cs
@@ -31,13 +31,18 @@ using System.Collections.Generic;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
+using Microsoft.VisualStudio.Shell;
+using Microsoft.VisualStudio.Shell.Interop;
namespace QtVsTools.Wizards.ItemWizard
{
+ using QtVsTools.VisualStudio;
using Wizards.Common;
public partial class TranslationPage : WizardPage
{
+ private string SearchText { get; set; }
+
public TranslationPage()
{
InitializeComponent();
@@ -47,16 +52,25 @@ namespace QtVsTools.Wizards.ItemWizard
private void OnTranslationPageLoaded(object sender, RoutedEventArgs e)
{
+ ThreadHelper.ThrowIfNotOnUIThread();
+
var view = CollectionViewSource.GetDefaultView(LanguageListBox.ItemsSource);
view.Filter = obj =>
{
- if (string.IsNullOrEmpty(searchBox.Text))
+ if (string.IsNullOrEmpty(SearchText))
return true;
var item = (KeyValuePair<string, string>)obj;
- return item.Value.IndexOf(searchBox.Text, StringComparison.OrdinalIgnoreCase) >= 0;
+ return item.Value.IndexOf(SearchText, StringComparison.OrdinalIgnoreCase) >= 0;
};
LanguageListBox.SelectedIndex = 0;
+
+ var factory = VsServiceProvider
+ .GetService<SVsWindowSearchHostFactory, IVsWindowSearchHostFactory>();
+ var host = factory.CreateWindowSearchHost(searchControlHost);
+
+ host.SetupSearch(new ListBoxSearch(LanguageListBox, value => SearchText = value));
+ host.Activate(); // set focus
}
private void OnSearchBoxTextChanged(object sender, TextChangedEventArgs e)