Skip to content
Merged
7 changes: 7 additions & 0 deletions Flow.Launcher.Plugin/Result.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,13 @@ public class Result
/// </summary>
public string ActionKeywordAssigned { get; set; }

/// <summary>
/// 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.
/// </summary>
public string CopyText { get; set; } = string.Empty;

/// <summary>
/// This holds the text which can be provided by plugin to help Flow autocomplete text
/// for user on the plugin result. If autocomplete action for example is tab, pressing tab will have
Expand Down
3 changes: 3 additions & 0 deletions Flow.Launcher/Languages/en.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@
<system:String x:Key="copy">Copy</system:String>
<system:String x:Key="cut">Cut</system:String>
<system:String x:Key="paste">Paste</system:String>
<system:String x:Key="fileTitle">File</system:String>
<system:String x:Key="folderTitle">Folder</system:String>
<system:String x:Key="textTitle">Text</system:String>
<system:String x:Key="GameMode">Game Mode</system:String>
<system:String x:Key="GameModeToolTip">Suspend the use of Hotkeys.</system:String>

Expand Down
3 changes: 3 additions & 0 deletions Flow.Launcher/MainWindow.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,9 @@
Style="{DynamicResource QueryBoxStyle}"
Text="{Binding QueryText, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
Visibility="Visible">
<TextBox.CommandBindings>
<CommandBinding Command="ApplicationCommands.Copy" Executed="OnCopy" />
</TextBox.CommandBindings>
<TextBox.ContextMenu>
<ContextMenu>
<MenuItem Command="ApplicationCommands.Cut" Header="{DynamicResource cut}" />
Expand Down
11 changes: 11 additions & 0 deletions Flow.Launcher/MainWindow.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,18 @@ public MainWindow()
{
InitializeComponent();
}
private void OnCopy(object sender, ExecutedRoutedEventArgs e)
{
if (QueryTextBox.SelectionLength == 0)
{
_viewModel.ResultCopy(string.Empty);

}
else if (!string.IsNullOrEmpty(QueryTextBox.Text))
{
_viewModel.ResultCopy(QueryTextBox.SelectedText);
}
}
private async void OnClosing(object sender, CancelEventArgs e)
{
_settings.WindowTop = Top;
Expand Down
51 changes: 51 additions & 0 deletions Flow.Launcher/ViewModel/MainViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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
{
Expand Down Expand Up @@ -423,6 +425,9 @@ 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 ICommand AutocompleteQueryCommand { get; set; }

public string OpenResultCommandModifiers { get; private set; }
Expand Down Expand Up @@ -870,6 +875,52 @@ public void UpdateResultView(IEnumerable<ResultsForUpdate> resultsForUpdates)
Results.AddResults(resultsForUpdates, token);
}

/// <summary>
/// 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
/// </summary>
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;
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"));
}
}

return;
}

Clipboard.SetDataObject(stringToCopy);
}

#endregion
}
}