mirror of
https://github.com/Flow-Launcher/Flow.Launcher.git
synced 2026-03-11 08:54:32 +00:00
Merge branch 'dev' into AddTimeFormat
This commit is contained in:
commit
b124cc3c8d
3 changed files with 161 additions and 167 deletions
|
|
@ -78,7 +78,6 @@ namespace Flow.Launcher.ViewModel
|
||||||
_userSelectedRecord = _userSelectedRecordStorage.Load();
|
_userSelectedRecord = _userSelectedRecordStorage.Load();
|
||||||
_topMostRecord = _topMostRecordStorage.Load();
|
_topMostRecord = _topMostRecordStorage.Load();
|
||||||
|
|
||||||
InitializeKeyCommands();
|
|
||||||
|
|
||||||
ContextMenu = new ResultsViewModel(Settings)
|
ContextMenu = new ResultsViewModel(Settings)
|
||||||
{
|
{
|
||||||
|
|
@ -168,160 +167,164 @@ namespace Flow.Launcher.ViewModel
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[RelayCommand]
|
||||||
|
private async Task ReloadPluginDataAsync()
|
||||||
private void InitializeKeyCommands()
|
|
||||||
{
|
{
|
||||||
EscCommand = new RelayCommand(_ =>
|
Hide();
|
||||||
|
|
||||||
|
await PluginManager.ReloadDataAsync().ConfigureAwait(false);
|
||||||
|
Notification.Show(InternationalizationManager.Instance.GetTranslation("success"), InternationalizationManager.Instance.GetTranslation("completedSuccessfully"));
|
||||||
|
}
|
||||||
|
[RelayCommand]
|
||||||
|
private void LoadHistory()
|
||||||
|
{
|
||||||
|
if (SelectedIsFromQueryResults())
|
||||||
{
|
{
|
||||||
if (!SelectedIsFromQueryResults())
|
SelectedResults = History;
|
||||||
{
|
History.SelectedIndex = _history.Items.Count - 1;
|
||||||
SelectedResults = Results;
|
}
|
||||||
}
|
else
|
||||||
else
|
|
||||||
{
|
|
||||||
Hide();
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
ClearQueryCommand = new RelayCommand(_ =>
|
|
||||||
{
|
{
|
||||||
if (!string.IsNullOrEmpty(QueryText))
|
SelectedResults = Results;
|
||||||
{
|
}
|
||||||
ChangeQueryText(string.Empty);
|
}
|
||||||
|
[RelayCommand]
|
||||||
// Push Event to UI SystemQuery has changed
|
private void LoadContextMenu()
|
||||||
//OnPropertyChanged(nameof(SystemQueryText));
|
{
|
||||||
}
|
if (SelectedIsFromQueryResults())
|
||||||
});
|
|
||||||
|
|
||||||
SelectNextItemCommand = new RelayCommand(_ => { SelectedResults.SelectNextResult(); });
|
|
||||||
|
|
||||||
SelectPrevItemCommand = new RelayCommand(_ => { SelectedResults.SelectPrevResult(); });
|
|
||||||
|
|
||||||
SelectNextPageCommand = new RelayCommand(_ => { SelectedResults.SelectNextPage(); });
|
|
||||||
|
|
||||||
SelectPrevPageCommand = new RelayCommand(_ => { SelectedResults.SelectPrevPage(); });
|
|
||||||
|
|
||||||
SelectFirstResultCommand = new RelayCommand(_ => SelectedResults.SelectFirstResult());
|
|
||||||
|
|
||||||
StartHelpCommand = new RelayCommand(_ =>
|
|
||||||
{
|
{
|
||||||
PluginManager.API.OpenUrl("https://github.com/Flow-Launcher/Flow.Launcher/wiki/Flow-Launcher/");
|
// When switch to ContextMenu from QueryResults, but no item being chosen, should do nothing
|
||||||
});
|
// i.e. Shift+Enter/Ctrl+O right after Alt + Space should do nothing
|
||||||
OpenSettingCommand = new RelayCommand(_ => { App.API.OpenSettingDialog(); });
|
if (SelectedResults.SelectedItem != null)
|
||||||
OpenResultCommand = new AsyncRelayCommand(async _ =>
|
SelectedResults = ContextMenu;
|
||||||
|
}
|
||||||
|
else
|
||||||
{
|
{
|
||||||
var results = SelectedResults;
|
SelectedResults = Results;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
[RelayCommand]
|
||||||
|
private void Backspace(object index)
|
||||||
|
{
|
||||||
|
var query = QueryBuilder.Build(QueryText.Trim(), PluginManager.NonGlobalPlugins);
|
||||||
|
|
||||||
var result = results.SelectedItem?.Result;
|
// GetPreviousExistingDirectory does not require trailing '\', otherwise will return empty string
|
||||||
if (result == null)
|
var path = FilesFolders.GetPreviousExistingDirectory((_) => true, query.Search.TrimEnd('\\'));
|
||||||
|
|
||||||
|
var actionKeyword = string.IsNullOrEmpty(query.ActionKeyword) ? string.Empty : $"{query.ActionKeyword} ";
|
||||||
|
|
||||||
|
ChangeQueryText($"{actionKeyword}{path}");
|
||||||
|
}
|
||||||
|
[RelayCommand]
|
||||||
|
private void AutocompleteQuery()
|
||||||
|
{
|
||||||
|
var result = SelectedResults.SelectedItem?.Result;
|
||||||
|
if (result != null && SelectedIsFromQueryResults()) // SelectedItem returns null if selection is empty.
|
||||||
|
{
|
||||||
|
var autoCompleteText = result.Title;
|
||||||
|
|
||||||
|
if (!string.IsNullOrEmpty(result.AutoCompleteText))
|
||||||
{
|
{
|
||||||
return;
|
autoCompleteText = result.AutoCompleteText;
|
||||||
}
|
}
|
||||||
var hideWindow = await result.ExecuteAsync(new ActionContext
|
else if (!string.IsNullOrEmpty(SelectedResults.SelectedItem?.QuerySuggestionText))
|
||||||
|
{
|
||||||
|
autoCompleteText = SelectedResults.SelectedItem.QuerySuggestionText;
|
||||||
|
}
|
||||||
|
|
||||||
|
var specialKeyState = GlobalHotkey.CheckModifiers();
|
||||||
|
if (specialKeyState.ShiftPressed)
|
||||||
|
{
|
||||||
|
autoCompleteText = result.SubTitle;
|
||||||
|
}
|
||||||
|
|
||||||
|
ChangeQueryText(autoCompleteText);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
[RelayCommand]
|
||||||
|
private async Task OpenResultAsync(string index)
|
||||||
|
{
|
||||||
|
var results = SelectedResults;
|
||||||
|
if (index is not null)
|
||||||
|
{
|
||||||
|
results.SelectedIndex = int.Parse(index);
|
||||||
|
}
|
||||||
|
var result = results.SelectedItem?.Result;
|
||||||
|
if (result == null)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var hideWindow = await result.ExecuteAsync(new ActionContext
|
||||||
{
|
{
|
||||||
SpecialKeyState = GlobalHotkey.CheckModifiers()
|
SpecialKeyState = GlobalHotkey.CheckModifiers()
|
||||||
}).ConfigureAwait(false);
|
})
|
||||||
|
.ConfigureAwait(false);
|
||||||
|
|
||||||
if (hideWindow)
|
if (hideWindow)
|
||||||
{
|
|
||||||
Hide();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (SelectedIsFromQueryResults())
|
|
||||||
{
|
|
||||||
_userSelectedRecord.Add(result);
|
|
||||||
_history.Add(result.OriginQuery.RawQuery);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
SelectedResults = Results;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
AutocompleteQueryCommand = new RelayCommand(_ =>
|
|
||||||
{
|
|
||||||
var result = SelectedResults.SelectedItem?.Result;
|
|
||||||
if (result != null && SelectedIsFromQueryResults()) // SelectedItem returns null if selection is empty.
|
|
||||||
{
|
|
||||||
var autoCompleteText = result.Title;
|
|
||||||
|
|
||||||
if (!string.IsNullOrEmpty(result.AutoCompleteText))
|
|
||||||
{
|
|
||||||
autoCompleteText = result.AutoCompleteText;
|
|
||||||
}
|
|
||||||
else if (!string.IsNullOrEmpty(SelectedResults.SelectedItem?.QuerySuggestionText))
|
|
||||||
{
|
|
||||||
autoCompleteText = SelectedResults.SelectedItem.QuerySuggestionText;
|
|
||||||
}
|
|
||||||
|
|
||||||
var specialKeyState = GlobalHotkey.CheckModifiers();
|
|
||||||
if (specialKeyState.ShiftPressed)
|
|
||||||
{
|
|
||||||
autoCompleteText = result.SubTitle;
|
|
||||||
}
|
|
||||||
|
|
||||||
ChangeQueryText(autoCompleteText);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
BackspaceCommand = new RelayCommand(index =>
|
|
||||||
{
|
|
||||||
var query = QueryBuilder.Build(QueryText.Trim(), PluginManager.NonGlobalPlugins);
|
|
||||||
|
|
||||||
// GetPreviousExistingDirectory does not require trailing '\', otherwise will return empty string
|
|
||||||
var path = FilesFolders.GetPreviousExistingDirectory((_) => true, query.Search.TrimEnd('\\'));
|
|
||||||
|
|
||||||
var actionKeyword = string.IsNullOrEmpty(query.ActionKeyword) ? string.Empty : $"{query.ActionKeyword} ";
|
|
||||||
|
|
||||||
ChangeQueryText($"{actionKeyword}{path}");
|
|
||||||
});
|
|
||||||
|
|
||||||
LoadContextMenuCommand = new RelayCommand(_ =>
|
|
||||||
{
|
|
||||||
if (SelectedIsFromQueryResults())
|
|
||||||
{
|
|
||||||
// When switch to ContextMenu from QueryResults, but no item being chosen, should do nothing
|
|
||||||
// i.e. Shift+Enter/Ctrl+O right after Alt + Space should do nothing
|
|
||||||
if (SelectedResults.SelectedItem != null)
|
|
||||||
SelectedResults = ContextMenu;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
SelectedResults = Results;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
LoadHistoryCommand = new RelayCommand(_ =>
|
|
||||||
{
|
|
||||||
if (SelectedIsFromQueryResults())
|
|
||||||
{
|
|
||||||
SelectedResults = History;
|
|
||||||
History.SelectedIndex = _history.Items.Count - 1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
SelectedResults = Results;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
ReloadPluginDataCommand = new RelayCommand(_ =>
|
|
||||||
{
|
{
|
||||||
Hide();
|
Hide();
|
||||||
|
}
|
||||||
|
|
||||||
_ = PluginManager
|
if (SelectedIsFromQueryResults())
|
||||||
.ReloadDataAsync()
|
{
|
||||||
.ContinueWith(_ =>
|
_userSelectedRecord.Add(result);
|
||||||
Application.Current.Dispatcher.Invoke(() =>
|
_history.Add(result.OriginQuery.RawQuery);
|
||||||
{
|
}
|
||||||
Notification.Show(
|
else
|
||||||
InternationalizationManager.Instance.GetTranslation("success"),
|
{
|
||||||
InternationalizationManager.Instance.GetTranslation("completedSuccessfully")
|
SelectedResults = Results;
|
||||||
);
|
}
|
||||||
}), TaskScheduler.Default)
|
}
|
||||||
.ConfigureAwait(false);
|
[RelayCommand]
|
||||||
});
|
private void OpenSetting()
|
||||||
|
{
|
||||||
|
App.API.OpenSettingDialog();
|
||||||
|
}
|
||||||
|
|
||||||
|
[RelayCommand]
|
||||||
|
private void SelectHelp()
|
||||||
|
{
|
||||||
|
PluginManager.API.OpenUrl("https://www.flowlauncher.com/docs/#/usage-tips");
|
||||||
|
}
|
||||||
|
|
||||||
|
[RelayCommand]
|
||||||
|
private void SelectFirstResult()
|
||||||
|
{
|
||||||
|
SelectedResults.SelectFirstResult();
|
||||||
|
}
|
||||||
|
[RelayCommand]
|
||||||
|
private void SelectPrevPage()
|
||||||
|
{
|
||||||
|
SelectedResults.SelectPrevPage();
|
||||||
|
}
|
||||||
|
|
||||||
|
[RelayCommand]
|
||||||
|
private void SelectNextPage()
|
||||||
|
{
|
||||||
|
SelectedResults.SelectNextPage();
|
||||||
|
}
|
||||||
|
[RelayCommand]
|
||||||
|
private void SelectPrevItem()
|
||||||
|
{
|
||||||
|
SelectedResults.SelectPrevResult();
|
||||||
|
}
|
||||||
|
[RelayCommand]
|
||||||
|
private void SelectNextItem()
|
||||||
|
{
|
||||||
|
SelectedResults.SelectNextResult();
|
||||||
|
}
|
||||||
|
|
||||||
|
[RelayCommand]
|
||||||
|
private void Esc()
|
||||||
|
{
|
||||||
|
if (!SelectedIsFromQueryResults())
|
||||||
|
{
|
||||||
|
SelectedResults = Results;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Hide();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
@ -418,6 +421,7 @@ namespace Flow.Launcher.ViewModel
|
||||||
/// but we don't want to move cursor to end when query is updated from TextBox
|
/// but we don't want to move cursor to end when query is updated from TextBox
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="queryText"></param>
|
/// <param name="queryText"></param>
|
||||||
|
/// <param name="reQuery">Force query even when Query Text doesn't change</param>
|
||||||
public void ChangeQueryText(string queryText, bool reQuery = false)
|
public void ChangeQueryText(string queryText, bool reQuery = false)
|
||||||
{
|
{
|
||||||
if (QueryText != queryText)
|
if (QueryText != queryText)
|
||||||
|
|
@ -496,25 +500,6 @@ namespace Flow.Launcher.ViewModel
|
||||||
|
|
||||||
public string PluginIconPath { get; set; } = null;
|
public string PluginIconPath { get; set; } = null;
|
||||||
|
|
||||||
public ICommand EscCommand { get; set; }
|
|
||||||
public ICommand BackspaceCommand { get; set; }
|
|
||||||
public ICommand SelectNextItemCommand { get; set; }
|
|
||||||
public ICommand SelectPrevItemCommand { get; set; }
|
|
||||||
public ICommand SelectNextPageCommand { get; set; }
|
|
||||||
public ICommand SelectPrevPageCommand { get; set; }
|
|
||||||
public ICommand SelectFirstResultCommand { get; set; }
|
|
||||||
public ICommand StartHelpCommand { get; set; }
|
|
||||||
public ICommand LoadContextMenuCommand { get; set; }
|
|
||||||
public ICommand LoadHistoryCommand { get; set; }
|
|
||||||
public ICommand OpenResultCommand { get; set; }
|
|
||||||
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; }
|
public string OpenResultCommandModifiers { get; private set; }
|
||||||
|
|
||||||
public string Image => Constant.QueryTextBoxIconImagePath;
|
public string Image => Constant.QueryTextBoxIconImagePath;
|
||||||
|
|
|
||||||
|
|
@ -97,8 +97,8 @@ namespace Flow.Launcher.Plugin.Program.Programs
|
||||||
}
|
}
|
||||||
|
|
||||||
// To initialize the app description
|
// To initialize the app description
|
||||||
public String description = String.Empty;
|
public string description = string.Empty;
|
||||||
|
public string arguments = string.Empty;
|
||||||
|
|
||||||
// Retrieve the target path using Shell Link
|
// Retrieve the target path using Shell Link
|
||||||
public string retrieveTargetPath(string path)
|
public string retrieveTargetPath(string path)
|
||||||
|
|
@ -122,13 +122,16 @@ namespace Flow.Launcher.Plugin.Program.Programs
|
||||||
buffer = new StringBuilder(MAX_PATH);
|
buffer = new StringBuilder(MAX_PATH);
|
||||||
((IShellLinkW)link).GetDescription(buffer, MAX_PATH);
|
((IShellLinkW)link).GetDescription(buffer, MAX_PATH);
|
||||||
description = buffer.ToString();
|
description = buffer.ToString();
|
||||||
|
|
||||||
|
buffer.Clear();
|
||||||
|
((IShellLinkW)link).GetArguments(buffer, MAX_PATH);
|
||||||
|
arguments = buffer.ToString();
|
||||||
}
|
}
|
||||||
|
|
||||||
// To release unmanaged memory
|
// To release unmanaged memory
|
||||||
Marshal.ReleaseComObject(link);
|
Marshal.ReleaseComObject(link);
|
||||||
|
|
||||||
return target;
|
return target;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -26,11 +26,11 @@ namespace Flow.Launcher.Plugin.Program.Programs
|
||||||
public string UniqueIdentifier { get => _uid; set => _uid = value == null ? string.Empty : value.ToLowerInvariant(); } // For path comparison
|
public string UniqueIdentifier { get => _uid; set => _uid = value == null ? string.Empty : value.ToLowerInvariant(); } // For path comparison
|
||||||
public string IcoPath { get; set; }
|
public string IcoPath { get; set; }
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Path of the file. It's the path of .lnk or .url for .lnk and .url.
|
/// Path of the file. It's the path of .lnk and .url for .lnk and .url files.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string FullPath { get; set; }
|
public string FullPath { get; set; }
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Path of the excutable for .lnk, or the URL for .url.
|
/// Path of the excutable for .lnk, or the URL for .url. Arguments are included if any.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public string LnkResolvedPath { get; set; }
|
public string LnkResolvedPath { get; set; }
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
|
@ -185,7 +185,7 @@ namespace Flow.Launcher.Plugin.Program.Programs
|
||||||
{
|
{
|
||||||
var info = new ProcessStartInfo
|
var info = new ProcessStartInfo
|
||||||
{
|
{
|
||||||
FileName = ExecutablePath,
|
FileName = FullPath,
|
||||||
WorkingDirectory = ParentDirectory,
|
WorkingDirectory = ParentDirectory,
|
||||||
Verb = "runas",
|
Verb = "runas",
|
||||||
UseShellExecute = true
|
UseShellExecute = true
|
||||||
|
|
@ -275,6 +275,12 @@ namespace Flow.Launcher.Plugin.Program.Programs
|
||||||
program.LnkResolvedPath = Path.GetFullPath(target);
|
program.LnkResolvedPath = Path.GetFullPath(target);
|
||||||
program.ExecutableName = Path.GetFileName(target);
|
program.ExecutableName = Path.GetFileName(target);
|
||||||
|
|
||||||
|
var args = _helper.arguments;
|
||||||
|
if(!string.IsNullOrEmpty(args))
|
||||||
|
{
|
||||||
|
program.LnkResolvedPath += " " + args;
|
||||||
|
}
|
||||||
|
|
||||||
var description = _helper.description;
|
var description = _helper.description;
|
||||||
if (!string.IsNullOrEmpty(description))
|
if (!string.IsNullOrEmpty(description))
|
||||||
{
|
{
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue