From 9d94507e1618dfa78e989819d7ceb8b15ca9be4c Mon Sep 17 00:00:00 2001 From: Garulf <535299+Garulf@users.noreply.github.com> Date: Wed, 1 Dec 2021 05:02:11 -0500 Subject: [PATCH 01/11] Initial support --- Flow.Launcher/MainWindow.xaml | 4 ++++ Flow.Launcher/ViewModel/MainViewModel.cs | 27 ++++++++++++++++++++++++ 2 files changed, 31 insertions(+) diff --git a/Flow.Launcher/MainWindow.xaml b/Flow.Launcher/MainWindow.xaml index dd897965075..d04b4a165c4 100644 --- a/Flow.Launcher/MainWindow.xaml +++ b/Flow.Launcher/MainWindow.xaml @@ -46,6 +46,10 @@ Key="Tab" Command="{Binding SelectPrevItemCommand}" Modifiers="Shift" /> + SelectedResults.SelectFirstResult()); + CopyToClipboard = new RelayCommand(index => + { + var results = SelectedResults; + + if (index != null) + { + results.SelectedIndex = int.Parse(index.ToString()); + } + + var result = results.SelectedItem?.Result; + if (result != null) // SelectedItem returns null if selection is empty. + { + bool hideWindow = result.Action != null && result.Action(new ActionContext + { + SpecialKeyState = GlobalHotkey.Instance.CheckModifiers() + }); + Clipboard.SetText(result.Title.ToString()); + if (hideWindow) + { + Hide(); + } + + + } + }); + StartHelpCommand = new RelayCommand(_ => { SearchWeb.NewTabInBrowser("https://github.com/Flow-Launcher/Flow.Launcher/wiki/Flow-Launcher/"); @@ -383,6 +409,7 @@ private ResultsViewModel SelectedResults public ICommand OpenSettingCommand { get; set; } public ICommand ReloadPluginDataCommand { get; set; } public ICommand ClearQueryCommand { get; private set; } + public ICommand CopyToClipboard { get; set; } public string OpenResultCommandModifiers { get; private set; } From 6f556a47b575a4347a080251359efc917a7ea226 Mon Sep 17 00:00:00 2001 From: Garulf <535299+Garulf@users.noreply.github.com> Date: Thu, 2 Dec 2021 03:55:47 -0500 Subject: [PATCH 02/11] Hook copy command --- Flow.Launcher/MainWindow.xaml | 3 +++ Flow.Launcher/MainWindow.xaml.cs | 10 +++++++++ Flow.Launcher/ViewModel/MainViewModel.cs | 26 ------------------------ 3 files changed, 13 insertions(+), 26 deletions(-) diff --git a/Flow.Launcher/MainWindow.xaml b/Flow.Launcher/MainWindow.xaml index d04b4a165c4..daa3810bab0 100644 --- a/Flow.Launcher/MainWindow.xaml +++ b/Flow.Launcher/MainWindow.xaml @@ -178,6 +178,9 @@ Style="{DynamicResource QueryBoxStyle}" Text="{Binding QueryText, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Visibility="Visible"> + + + diff --git a/Flow.Launcher/MainWindow.xaml.cs b/Flow.Launcher/MainWindow.xaml.cs index ba0b63a5211..29f2391e361 100644 --- a/Flow.Launcher/MainWindow.xaml.cs +++ b/Flow.Launcher/MainWindow.xaml.cs @@ -47,7 +47,17 @@ public MainWindow() { InitializeComponent(); } + private void OnCopy(object sender, ExecutedRoutedEventArgs e) + { + var results = _viewModel.Results; + var result = results.SelectedItem?.Result; + if (result != null) // SelectedItem returns null if selection is empty. + { + System.Windows.Clipboard.SetDataObject(result.Title.ToString()); + } + e.Handled = true; + } private async void OnClosing(object sender, CancelEventArgs e) { _settings.WindowTop = Top; diff --git a/Flow.Launcher/ViewModel/MainViewModel.cs b/Flow.Launcher/ViewModel/MainViewModel.cs index 83ef29b190b..9a4268854e4 100644 --- a/Flow.Launcher/ViewModel/MainViewModel.cs +++ b/Flow.Launcher/ViewModel/MainViewModel.cs @@ -189,32 +189,6 @@ private void InitializeKeyCommands() SelectFirstResultCommand = new RelayCommand(_ => SelectedResults.SelectFirstResult()); - CopyToClipboard = new RelayCommand(index => - { - var results = SelectedResults; - - if (index != null) - { - results.SelectedIndex = int.Parse(index.ToString()); - } - - var result = results.SelectedItem?.Result; - if (result != null) // SelectedItem returns null if selection is empty. - { - bool hideWindow = result.Action != null && result.Action(new ActionContext - { - SpecialKeyState = GlobalHotkey.Instance.CheckModifiers() - }); - Clipboard.SetText(result.Title.ToString()); - if (hideWindow) - { - Hide(); - } - - - } - }); - StartHelpCommand = new RelayCommand(_ => { SearchWeb.NewTabInBrowser("https://github.com/Flow-Launcher/Flow.Launcher/wiki/Flow-Launcher/"); From 621d48725a1d7d4e98aeb7beb8ed059d01067514 Mon Sep 17 00:00:00 2001 From: Garulf <535299+Garulf@users.noreply.github.com> Date: Thu, 2 Dec 2021 04:15:17 -0500 Subject: [PATCH 03/11] Only copy result title if query text is unselected --- Flow.Launcher/MainWindow.xaml.cs | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/Flow.Launcher/MainWindow.xaml.cs b/Flow.Launcher/MainWindow.xaml.cs index 29f2391e361..9c233278f48 100644 --- a/Flow.Launcher/MainWindow.xaml.cs +++ b/Flow.Launcher/MainWindow.xaml.cs @@ -49,13 +49,18 @@ public MainWindow() } private void OnCopy(object sender, ExecutedRoutedEventArgs e) { - var results = _viewModel.Results; - var result = results.SelectedItem?.Result; - if (result != null) // SelectedItem returns null if selection is empty. + var _NewClipboard = QueryTextBox.SelectedText; + if (QueryTextBox.SelectionLength == 0) { - - System.Windows.Clipboard.SetDataObject(result.Title.ToString()); + var results = _viewModel.Results; + var result = results.SelectedItem?.Result; + if (result != null) // SelectedItem returns null if selection is empty. + { + _NewClipboard = result.Title.ToString(); + } + } + System.Windows.Clipboard.SetDataObject(_NewClipboard); e.Handled = true; } private async void OnClosing(object sender, CancelEventArgs e) From 705d7645555b94d2a2585ac7cb796d91b69da27d Mon Sep 17 00:00:00 2001 From: Garulf <535299+Garulf@users.noreply.github.com> Date: Thu, 2 Dec 2021 04:36:06 -0500 Subject: [PATCH 04/11] Remove unused KeyBinding --- Flow.Launcher/MainWindow.xaml | 4 ---- 1 file changed, 4 deletions(-) diff --git a/Flow.Launcher/MainWindow.xaml b/Flow.Launcher/MainWindow.xaml index daa3810bab0..eee38ad2a64 100644 --- a/Flow.Launcher/MainWindow.xaml +++ b/Flow.Launcher/MainWindow.xaml @@ -46,10 +46,6 @@ Key="Tab" Command="{Binding SelectPrevItemCommand}" Modifiers="Shift" /> - Date: Thu, 2 Dec 2021 04:39:54 -0500 Subject: [PATCH 05/11] Update clipboard only if needed We don't want to clear the clipboard if nothing is selected --- Flow.Launcher/MainWindow.xaml.cs | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/Flow.Launcher/MainWindow.xaml.cs b/Flow.Launcher/MainWindow.xaml.cs index 9c233278f48..ebc3dc874ed 100644 --- a/Flow.Launcher/MainWindow.xaml.cs +++ b/Flow.Launcher/MainWindow.xaml.cs @@ -49,18 +49,21 @@ public MainWindow() } private void OnCopy(object sender, ExecutedRoutedEventArgs e) { - var _NewClipboard = QueryTextBox.SelectedText; + if (QueryTextBox.SelectionLength == 0) { var results = _viewModel.Results; var result = results.SelectedItem?.Result; if (result != null) // SelectedItem returns null if selection is empty. { - _NewClipboard = result.Title.ToString(); + System.Windows.Clipboard.SetDataObject(result.Title.ToString()); } - + + } + else + { + System.Windows.Clipboard.SetDataObject(QueryTextBox.SelectedText;); } - System.Windows.Clipboard.SetDataObject(_NewClipboard); e.Handled = true; } private async void OnClosing(object sender, CancelEventArgs e) From bf317b8caa1b837dd54ffb2b13095c7bdda30992 Mon Sep 17 00:00:00 2001 From: Garulf <535299+Garulf@users.noreply.github.com> Date: Thu, 2 Dec 2021 04:46:26 -0500 Subject: [PATCH 06/11] Don't copy query if blank --- Flow.Launcher/MainWindow.xaml.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Flow.Launcher/MainWindow.xaml.cs b/Flow.Launcher/MainWindow.xaml.cs index ebc3dc874ed..1afb2848f0a 100644 --- a/Flow.Launcher/MainWindow.xaml.cs +++ b/Flow.Launcher/MainWindow.xaml.cs @@ -60,9 +60,9 @@ private void OnCopy(object sender, ExecutedRoutedEventArgs e) } } - else + else if (!String.IsNullOrEmpty(QueryTextBox.Text)) { - System.Windows.Clipboard.SetDataObject(QueryTextBox.SelectedText;); + System.Windows.Clipboard.SetDataObject(QueryTextBox.SelectedText); } e.Handled = true; } From 20d80283a4533398d1a8ee810f4b6877a85c5cc6 Mon Sep 17 00:00:00 2001 From: Garulf <535299+Garulf@users.noreply.github.com> Date: Sat, 4 Dec 2021 00:48:18 -0500 Subject: [PATCH 07/11] Add CopyText field for plugin support --- Flow.Launcher.Plugin/Result.cs | 2 ++ Flow.Launcher/MainWindow.xaml.cs | 14 ++++++++------ 2 files changed, 10 insertions(+), 6 deletions(-) diff --git a/Flow.Launcher.Plugin/Result.cs b/Flow.Launcher.Plugin/Result.cs index 833ada9cda1..adf185557c3 100644 --- a/Flow.Launcher.Plugin/Result.cs +++ b/Flow.Launcher.Plugin/Result.cs @@ -29,6 +29,8 @@ public class Result /// public string ActionKeywordAssigned { get; set; } + public string CopyText { get; set; } = String.Empty; + public string IcoPath { get { return _icoPath; } diff --git a/Flow.Launcher/MainWindow.xaml.cs b/Flow.Launcher/MainWindow.xaml.cs index 1afb2848f0a..79be50a4b0d 100644 --- a/Flow.Launcher/MainWindow.xaml.cs +++ b/Flow.Launcher/MainWindow.xaml.cs @@ -56,15 +56,17 @@ private void OnCopy(object sender, ExecutedRoutedEventArgs e) var result = results.SelectedItem?.Result; if (result != null) // SelectedItem returns null if selection is empty. { - System.Windows.Clipboard.SetDataObject(result.Title.ToString()); + string _copyText = String.IsNullOrEmpty(result.CopyText) ? result.Title : result.CopyText; + System.Windows.Clipboard.SetDataObject(_copyText.ToString()); + e.Handled = true; } } - else if (!String.IsNullOrEmpty(QueryTextBox.Text)) - { - System.Windows.Clipboard.SetDataObject(QueryTextBox.SelectedText); - } - e.Handled = true; + //else if (!String.IsNullOrEmpty(QueryTextBox.Text)) + //{ + // System.Windows.Clipboard.SetDataObject(QueryTextBox.SelectedText); + //} + e.Handled = false; } private async void OnClosing(object sender, CancelEventArgs e) { From 25f64beb3301ade5230d246b0c7303248e62fa1f Mon Sep 17 00:00:00 2001 From: Garulf <535299+Garulf@users.noreply.github.com> Date: Sat, 4 Dec 2021 01:14:08 -0500 Subject: [PATCH 08/11] Add FileCopy field --- Flow.Launcher.Plugin/Result.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/Flow.Launcher.Plugin/Result.cs b/Flow.Launcher.Plugin/Result.cs index adf185557c3..324d4881eaa 100644 --- a/Flow.Launcher.Plugin/Result.cs +++ b/Flow.Launcher.Plugin/Result.cs @@ -30,6 +30,7 @@ public class Result public string ActionKeywordAssigned { get; set; } public string CopyText { get; set; } = String.Empty; + public string FileCopy { get; set; } = String.Empty; public string IcoPath { From 48dbfc240b9abbc2fca81607a00a2ca654bc698e Mon Sep 17 00:00:00 2001 From: Garulf <535299+Garulf@users.noreply.github.com> Date: Tue, 25 Jan 2022 19:45:08 -0500 Subject: [PATCH 09/11] Add file path to clipboard as file if valid --- Flow.Launcher/MainWindow.xaml.cs | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/Flow.Launcher/MainWindow.xaml.cs b/Flow.Launcher/MainWindow.xaml.cs index eaaac452ccb..6625a6d899f 100644 --- a/Flow.Launcher/MainWindow.xaml.cs +++ b/Flow.Launcher/MainWindow.xaml.cs @@ -20,6 +20,7 @@ using System.Windows.Media; using Flow.Launcher.Infrastructure.Hotkey; using Flow.Launcher.Plugin.SharedCommands; +using System.IO; namespace Flow.Launcher { @@ -59,18 +60,31 @@ private void OnCopy(object sender, ExecutedRoutedEventArgs e) { var results = _viewModel.Results; var result = results.SelectedItem?.Result; - if (result != null) // SelectedItem returns null if selection is empty. + if (result != null) { - string _copyText = String.IsNullOrEmpty(result.CopyText) ? result.Title : result.CopyText; - System.Windows.Clipboard.SetDataObject(_copyText.ToString()); + string copyText = String.IsNullOrEmpty(result.CopyText) ? result.SubTitle : result.CopyText; + if (File.Exists(copyText) || Directory.Exists(copyText)) + { + + System.Collections.Specialized.StringCollection paths = new System.Collections.Specialized.StringCollection(); + paths.Add(copyText); + + System.Windows.Clipboard.SetFileDropList(paths); + + } + else + { + System.Windows.Clipboard.SetDataObject(copyText.ToString()); + } + e.Handled = true; } } - //else if (!String.IsNullOrEmpty(QueryTextBox.Text)) - //{ - // System.Windows.Clipboard.SetDataObject(QueryTextBox.SelectedText); - //} + else if (!String.IsNullOrEmpty(QueryTextBox.Text)) + { + System.Windows.Clipboard.SetDataObject(QueryTextBox.SelectedText); + } e.Handled = false; } private async void OnClosing(object sender, CancelEventArgs e) From c5be5b89cb6ba675b23c5c0d61c0c7b05c7450fa Mon Sep 17 00:00:00 2001 From: Jeremy Date: Thu, 27 Jan 2022 16:35:45 +1100 Subject: [PATCH 10/11] move logic to view model --- Flow.Launcher.Plugin/Result.cs | 8 +++-- Flow.Launcher/MainWindow.xaml.cs | 29 ++---------------- Flow.Launcher/ViewModel/MainViewModel.cs | 38 ++++++++++++++++++++++++ 3 files changed, 47 insertions(+), 28 deletions(-) diff --git a/Flow.Launcher.Plugin/Result.cs b/Flow.Launcher.Plugin/Result.cs index c97146fce93..4a5eb39afc0 100644 --- a/Flow.Launcher.Plugin/Result.cs +++ b/Flow.Launcher.Plugin/Result.cs @@ -29,8 +29,12 @@ public class Result /// public string ActionKeywordAssigned { get; set; } - public string CopyText { get; set; } = String.Empty; - public string FileCopy { get; set; } = String.Empty; + /// + /// This holds the text which can be provided by plugin to be copied to the + /// user's clipboard when Ctrl + C is pressed on a result. If the text is a file/directory path + /// flow will copy the actual file/folder instead of just the path text. + /// + public string CopyText { get; set; } = string.Empty; /// /// This holds the text which can be provided by plugin to help Flow autocomplete text diff --git a/Flow.Launcher/MainWindow.xaml.cs b/Flow.Launcher/MainWindow.xaml.cs index 6625a6d899f..366407182e0 100644 --- a/Flow.Launcher/MainWindow.xaml.cs +++ b/Flow.Launcher/MainWindow.xaml.cs @@ -20,7 +20,6 @@ using System.Windows.Media; using Flow.Launcher.Infrastructure.Hotkey; using Flow.Launcher.Plugin.SharedCommands; -using System.IO; namespace Flow.Launcher { @@ -55,37 +54,15 @@ public MainWindow() } private void OnCopy(object sender, ExecutedRoutedEventArgs e) { - if (QueryTextBox.SelectionLength == 0) { - var results = _viewModel.Results; - var result = results.SelectedItem?.Result; - if (result != null) - { - string copyText = String.IsNullOrEmpty(result.CopyText) ? result.SubTitle : result.CopyText; - if (File.Exists(copyText) || Directory.Exists(copyText)) - { - - System.Collections.Specialized.StringCollection paths = new System.Collections.Specialized.StringCollection(); - paths.Add(copyText); - - System.Windows.Clipboard.SetFileDropList(paths); - - } - else - { - System.Windows.Clipboard.SetDataObject(copyText.ToString()); - } - - e.Handled = true; - } + _viewModel.ResultCopy(string.Empty); } - else if (!String.IsNullOrEmpty(QueryTextBox.Text)) + else if (!string.IsNullOrEmpty(QueryTextBox.Text)) { - System.Windows.Clipboard.SetDataObject(QueryTextBox.SelectedText); + _viewModel.ResultCopy(QueryTextBox.SelectedText); } - e.Handled = false; } private async void OnClosing(object sender, CancelEventArgs e) { diff --git a/Flow.Launcher/ViewModel/MainViewModel.cs b/Flow.Launcher/ViewModel/MainViewModel.cs index 47b2cba9e99..e4353bbcbe3 100644 --- a/Flow.Launcher/ViewModel/MainViewModel.cs +++ b/Flow.Launcher/ViewModel/MainViewModel.cs @@ -19,6 +19,8 @@ using Microsoft.VisualStudio.Threading; using System.Threading.Channels; using ISavable = Flow.Launcher.Plugin.ISavable; +using System.IO; +using System.Collections.Specialized; namespace Flow.Launcher.ViewModel { @@ -873,6 +875,42 @@ public void UpdateResultView(IEnumerable resultsForUpdates) Results.AddResults(resultsForUpdates, token); } + /// + /// This is the global copy method for an individual result. If no text is passed, + /// the method will work out what is to be copied based on the result, so plugin can offer the text + /// to be copied via the result model. If the text is a directory/file path, + /// then actual file/folder will be copied instead. + /// The result's subtitle text is the default text to be copied + /// + public void ResultCopy(string stringToCopy) + { + if (string.IsNullOrEmpty(stringToCopy)) + { + var result = Results.SelectedItem?.Result; + if (result != null) + { + string copyText = string.IsNullOrEmpty(result.CopyText) ? result.SubTitle : result.CopyText; + if (File.Exists(copyText) || Directory.Exists(copyText)) + { + + var paths = new StringCollection(); + paths.Add(copyText); + + Clipboard.SetFileDropList(paths); + + } + else + { + Clipboard.SetDataObject(copyText.ToString()); + } + } + + return; + } + + Clipboard.SetDataObject(stringToCopy); + } + #endregion } } \ No newline at end of file From 8839f1bf6e3b49723059322f5deed496cff587d2 Mon Sep 17 00:00:00 2001 From: Jeremy Date: Thu, 27 Jan 2022 17:13:06 +1100 Subject: [PATCH 11/11] add copy notification --- Flow.Launcher/Languages/en.xaml | 3 +++ Flow.Launcher/ViewModel/MainViewModel.cs | 16 +++++++++++++--- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/Flow.Launcher/Languages/en.xaml b/Flow.Launcher/Languages/en.xaml index ec355a0ac11..25de530bc45 100644 --- a/Flow.Launcher/Languages/en.xaml +++ b/Flow.Launcher/Languages/en.xaml @@ -18,6 +18,9 @@ Copy Cut Paste + File + Folder + Text Game Mode Suspend the use of Hotkeys. diff --git a/Flow.Launcher/ViewModel/MainViewModel.cs b/Flow.Launcher/ViewModel/MainViewModel.cs index e4353bbcbe3..0fe3bdf8052 100644 --- a/Flow.Launcher/ViewModel/MainViewModel.cs +++ b/Flow.Launcher/ViewModel/MainViewModel.cs @@ -890,18 +890,28 @@ public void ResultCopy(string stringToCopy) if (result != null) { string copyText = string.IsNullOrEmpty(result.CopyText) ? result.SubTitle : result.CopyText; - if (File.Exists(copyText) || Directory.Exists(copyText)) + var isFile = File.Exists(copyText); + var isFolder = Directory.Exists(copyText); + if (isFile || isFolder) { - var paths = new StringCollection(); paths.Add(copyText); Clipboard.SetFileDropList(paths); - + App.API.ShowMsg( + App.API.GetTranslation("copy") + +" " + + (isFile? App.API.GetTranslation("fileTitle") : App.API.GetTranslation("folderTitle")), + App.API.GetTranslation("completedSuccessfully")); } else { Clipboard.SetDataObject(copyText.ToString()); + App.API.ShowMsg( + App.API.GetTranslation("copy") + + " " + + App.API.GetTranslation("textTitle"), + App.API.GetTranslation("completedSuccessfully")); } }