diff --git a/TRANSLATION.md b/TRANSLATION.md index c7b37e8c..aee0e2a0 100644 --- a/TRANSLATION.md +++ b/TRANSLATION.md @@ -13,10 +13,10 @@ This document shows the translation status of each locale file in the repository - Text.GitFlow.FinishWithPush - Text.GitFlow.FinishWithSquash -- Text.Hotkeys.Global.OpenWorkspaces -- Text.Hotkeys.Global.OpenWorkspaceAtIndex +- Text.Hotkeys.Global.SwitchWorkspace - Text.Hotkeys.TextEditor.OpenExternalMergeTool - Text.Repository.ShowSubmodulesAsTree +- Text.Repository.WorkspaceSwitcher - Text.Submodule.Status - Text.Submodule.Status.Modified - Text.Submodule.Status.NotInited @@ -31,8 +31,8 @@ This document shows the translation status of each locale file in the repository
Missing keys in es_ES.axaml -- Text.Hotkeys.Global.OpenWorkspaces -- Text.Hotkeys.Global.OpenWorkspaceAtIndex +- Text.Hotkeys.Global.SwitchWorkspace +- Text.Repository.WorkspaceSwitcher
@@ -60,8 +60,7 @@ This document shows the translation status of each locale file in the repository - Text.ConfirmEmptyCommit.WithLocalChanges - Text.GitFlow.FinishWithPush - Text.GitFlow.FinishWithSquash -- Text.Hotkeys.Global.OpenWorkspaces -- Text.Hotkeys.Global.OpenWorkspaceAtIndex +- Text.Hotkeys.Global.SwitchWorkspace - Text.Hotkeys.TextEditor.OpenExternalMergeTool - Text.Preferences.Git.IgnoreCRAtEOLInDiff - Text.Repository.BranchSort @@ -71,6 +70,7 @@ This document shows the translation status of each locale file in the repository - Text.Repository.ShowSubmodulesAsTree - Text.Repository.ViewLogs - Text.Repository.Visit +- Text.Repository.WorkspaceSwitcher - Text.Submodule.Status - Text.Submodule.Status.Modified - Text.Submodule.Status.NotInited @@ -94,8 +94,8 @@ This document shows the translation status of each locale file in the repository
Missing keys in it_IT.axaml -- Text.Hotkeys.Global.OpenWorkspaces -- Text.Hotkeys.Global.OpenWorkspaceAtIndex +- Text.Hotkeys.Global.SwitchWorkspace +- Text.Repository.WorkspaceSwitcher
@@ -123,8 +123,7 @@ This document shows the translation status of each locale file in the repository - Text.ConfirmEmptyCommit.WithLocalChanges - Text.GitFlow.FinishWithPush - Text.GitFlow.FinishWithSquash -- Text.Hotkeys.Global.OpenWorkspaces -- Text.Hotkeys.Global.OpenWorkspaceAtIndex +- Text.Hotkeys.Global.SwitchWorkspace - Text.Hotkeys.TextEditor.OpenExternalMergeTool - Text.Preferences.Git.IgnoreCRAtEOLInDiff - Text.Repository.BranchSort @@ -136,6 +135,7 @@ This document shows the translation status of each locale file in the repository - Text.Repository.Tags.OrderByNameDes - Text.Repository.ViewLogs - Text.Repository.Visit +- Text.Repository.WorkspaceSwitcher - Text.Submodule.Status - Text.Submodule.Status.Modified - Text.Submodule.Status.NotInited @@ -207,8 +207,7 @@ This document shows the translation status of each locale file in the repository - Text.GitFlow.FinishWithPush - Text.GitFlow.FinishWithSquash - Text.Hotkeys.Global.Clone -- Text.Hotkeys.Global.OpenWorkspaces -- Text.Hotkeys.Global.OpenWorkspaceAtIndex +- Text.Hotkeys.Global.SwitchWorkspace - Text.Hotkeys.TextEditor.OpenExternalMergeTool - Text.InProgress.CherryPick.Head - Text.InProgress.Merge.Operating @@ -246,6 +245,7 @@ This document shows the translation status of each locale file in the repository - Text.Repository.UseRelativeTimeInHistories - Text.Repository.ViewLogs - Text.Repository.Visit +- Text.Repository.WorkspaceSwitcher - Text.SetUpstream - Text.SetUpstream.Local - Text.SetUpstream.Unset @@ -279,9 +279,9 @@ This document shows the translation status of each locale file in the repository
Missing keys in ru_RU.axaml -- Text.Hotkeys.Global.OpenWorkspaces -- Text.Hotkeys.Global.OpenWorkspaceAtIndex +- Text.Hotkeys.Global.SwitchWorkspace - Text.Repository.ShowSubmodulesAsTree +- Text.Repository.WorkspaceSwitcher
@@ -309,8 +309,7 @@ This document shows the translation status of each locale file in the repository - Text.ConfirmEmptyCommit.WithLocalChanges - Text.GitFlow.FinishWithPush - Text.GitFlow.FinishWithSquash -- Text.Hotkeys.Global.OpenWorkspaces -- Text.Hotkeys.Global.OpenWorkspaceAtIndex +- Text.Hotkeys.Global.SwitchWorkspace - Text.Hotkeys.TextEditor.OpenExternalMergeTool - Text.Preferences.Git.IgnoreCRAtEOLInDiff - Text.Repository.BranchSort @@ -320,6 +319,7 @@ This document shows the translation status of each locale file in the repository - Text.Repository.ShowSubmodulesAsTree - Text.Repository.ViewLogs - Text.Repository.Visit +- Text.Repository.WorkspaceSwitcher - Text.Submodule.Status - Text.Submodule.Status.Modified - Text.Submodule.Status.NotInited @@ -358,8 +358,7 @@ This document shows the translation status of each locale file in the repository - Text.ConfigureWorkspace.Name - Text.GitFlow.FinishWithPush - Text.GitFlow.FinishWithSquash -- Text.Hotkeys.Global.OpenWorkspaces -- Text.Hotkeys.Global.OpenWorkspaceAtIndex +- Text.Hotkeys.Global.SwitchWorkspace - Text.Hotkeys.TextEditor.OpenExternalMergeTool - Text.Preferences.Git.IgnoreCRAtEOLInDiff - Text.Repository.BranchSort @@ -369,6 +368,7 @@ This document shows the translation status of each locale file in the repository - Text.Repository.ShowSubmodulesAsTree - Text.Repository.ViewLogs - Text.Repository.Visit +- Text.Repository.WorkspaceSwitcher - Text.Submodule.Status - Text.Submodule.Status.Modified - Text.Submodule.Status.NotInited @@ -382,22 +382,6 @@ This document shows the translation status of each locale file in the repository -### ![zh__CN](https://img.shields.io/badge/zh__CN-99.75%25-yellow) +### ![zh__CN](https://img.shields.io/badge/zh__CN-%E2%88%9A-brightgreen) -
-Missing keys in zh_CN.axaml - -- Text.Hotkeys.Global.OpenWorkspaces -- Text.Hotkeys.Global.OpenWorkspaceAtIndex - -
- -### ![zh__TW](https://img.shields.io/badge/zh__TW-99.75%25-yellow) - -
-Missing keys in zh_TW.axaml - -- Text.Hotkeys.Global.OpenWorkspaces -- Text.Hotkeys.Global.OpenWorkspaceAtIndex - -
\ No newline at end of file +### ![zh__TW](https://img.shields.io/badge/zh__TW-%E2%88%9A-brightgreen) \ No newline at end of file diff --git a/src/Resources/Locales/en_US.axaml b/src/Resources/Locales/en_US.axaml index 63c9815d..4ce0a1ad 100644 --- a/src/Resources/Locales/en_US.axaml +++ b/src/Resources/Locales/en_US.axaml @@ -386,8 +386,7 @@ Go to previous page Create new page Open Preferences dialog - Open Workspaces dialog - Switch to corresponding workspace + Switch active workspace REPOSITORY Commit staged changes Commit and push staged changes @@ -636,6 +635,7 @@ Use relative time in histories View Logs Visit '{0}' in Browser + Switch Workspace WORKTREES Add Worktree Prune diff --git a/src/Resources/Locales/zh_CN.axaml b/src/Resources/Locales/zh_CN.axaml index 56227607..1fd1a610 100644 --- a/src/Resources/Locales/zh_CN.axaml +++ b/src/Resources/Locales/zh_CN.axaml @@ -390,6 +390,7 @@ 切换到上一个页面 新建页面 打开偏好设置面板 + 切换工作区 仓库页面快捷键 提交暂存区更改 提交暂存区更改并推送 @@ -638,6 +639,7 @@ 在提交列表中使用相对时间 查看命令日志 访问远程仓库 '{0}' + 切换工作区 工作树列表 新增工作树 清理 diff --git a/src/Resources/Locales/zh_TW.axaml b/src/Resources/Locales/zh_TW.axaml index 204e1cf7..eca8214c 100644 --- a/src/Resources/Locales/zh_TW.axaml +++ b/src/Resources/Locales/zh_TW.axaml @@ -390,6 +390,7 @@ 切換到上一個頁面 新增頁面 開啟偏好設定面板 + 切換工作區 存放庫頁面快速鍵 提交暫存區變更 提交暫存區變更並推送 @@ -638,6 +639,7 @@ 在提交列表中使用相對時間 檢視 Git 指令記錄 檢視遠端存放庫 '{0}' + 切換工作區 工作區列表 新增工作區 清理 diff --git a/src/ViewModels/Launcher.cs b/src/ViewModels/Launcher.cs index 5eaca763..9a54bb32 100644 --- a/src/ViewModels/Launcher.cs +++ b/src/ViewModels/Launcher.cs @@ -23,6 +23,12 @@ namespace SourceGit.ViewModels private set; } + public WorkspaceSwitcher WorkspaceSwitcher + { + get => _workspaceSwitcher; + set => SetProperty(ref _workspaceSwitcher, value); + } + public Workspace ActiveWorkspace { get => _activeWorkspace; @@ -130,6 +136,79 @@ namespace SourceGit.ViewModels _ignoreIndexChange = false; } + public void OpenWorkspaceSwitcher() + { + WorkspaceSwitcher = new WorkspaceSwitcher(this); + } + + public void CancelWorkspaceSwitcher() + { + WorkspaceSwitcher = null; + } + + public void SwitchWorkspace(Workspace to) + { + if (to.IsActive) + return; + + foreach (var one in Pages) + { + if (!one.CanCreatePopup() || one.Data is Repository { IsAutoFetching: true }) + { + App.RaiseException(null, "You have unfinished task(s) in opened pages. Please wait!!!"); + return; + } + } + + _ignoreIndexChange = true; + + var pref = Preferences.Instance; + foreach (var w in pref.Workspaces) + w.IsActive = false; + + ActiveWorkspace = to; + to.IsActive = true; + + foreach (var one in Pages) + CloseRepositoryInTab(one, false); + + Pages.Clear(); + AddNewTab(); + + var repos = to.Repositories.ToArray(); + foreach (var repo in repos) + { + var node = pref.FindNode(repo); + if (node == null) + { + node = new RepositoryNode() + { + Id = repo, + Name = Path.GetFileName(repo), + Bookmark = 0, + IsRepository = true, + }; + } + + OpenRepositoryInTab(node, null); + } + + var activeIdx = to.ActiveIdx; + if (activeIdx >= 0 && activeIdx < Pages.Count) + { + ActivePage = Pages[activeIdx]; + } + else + { + ActivePage = Pages[0]; + to.ActiveIdx = 0; + } + + _ignoreIndexChange = false; + Preferences.Instance.Save(); + GC.Collect(); + } + public void AddNewTab() { var page = new LauncherPage(); @@ -463,14 +542,6 @@ namespace SourceGit.ViewModels return menu; } - public void SwitchWorkspace(int idx) - { - var pref = Preferences.Instance; - if (idx >= pref.Workspaces.Count || pref.Workspaces[idx].IsActive) return; - - SwitchWorkspace(pref.Workspaces[idx]); - } - private string GetRepositoryGitDir(string repo) { var fullpath = Path.Combine(repo, ".git"); @@ -501,66 +572,6 @@ namespace SourceGit.ViewModels return new Commands.QueryGitDir(repo).Result(); } - - private void SwitchWorkspace(Workspace to) - { - foreach (var one in Pages) - { - if (!one.CanCreatePopup() || one.Data is Repository { IsAutoFetching: true }) - { - App.RaiseException(null, "You have unfinished task(s) in opened pages. Please wait!!!"); - return; - } - } - - _ignoreIndexChange = true; - - var pref = Preferences.Instance; - foreach (var w in pref.Workspaces) - w.IsActive = false; - - ActiveWorkspace = to; - to.IsActive = true; - - foreach (var one in Pages) - CloseRepositoryInTab(one, false); - - Pages.Clear(); - AddNewTab(); - - var repos = to.Repositories.ToArray(); - foreach (var repo in repos) - { - var node = pref.FindNode(repo); - if (node == null) - { - node = new RepositoryNode() - { - Id = repo, - Name = Path.GetFileName(repo), - Bookmark = 0, - IsRepository = true, - }; - } - - OpenRepositoryInTab(node, null); - } - - var activeIdx = to.ActiveIdx; - if (activeIdx >= 0 && activeIdx < Pages.Count) - { - ActivePage = Pages[activeIdx]; - } - else - { - ActivePage = Pages[0]; - to.ActiveIdx = 0; - } - - _ignoreIndexChange = false; - Preferences.Instance.Save(); - GC.Collect(); - } private void CloseRepositoryInTab(LauncherPage page, bool removeFromWorkspace = true) { @@ -581,7 +592,7 @@ namespace SourceGit.ViewModels return; var workspace = _activeWorkspace.Name; - if (_activePage is { Data: Repository repo }) + if (_activePage is { Data: Repository }) { var node = _activePage.Node; var name = node.Name; @@ -607,5 +618,6 @@ namespace SourceGit.ViewModels private LauncherPage _activePage = null; private bool _ignoreIndexChange = false; private string _title = string.Empty; + private WorkspaceSwitcher _workspaceSwitcher = null; } } diff --git a/src/ViewModels/WorkspaceSwitcher.cs b/src/ViewModels/WorkspaceSwitcher.cs new file mode 100644 index 00000000..01d62744 --- /dev/null +++ b/src/ViewModels/WorkspaceSwitcher.cs @@ -0,0 +1,75 @@ +using System; +using System.Collections.Generic; +using CommunityToolkit.Mvvm.ComponentModel; + +namespace SourceGit.ViewModels +{ + public class WorkspaceSwitcher : ObservableObject + { + public List VisibleWorkspaces + { + get => _visibleWorkspaces; + private set => SetProperty(ref _visibleWorkspaces, value); + } + + public string SearchFilter + { + get => _searchFilter; + set + { + if (SetProperty(ref _searchFilter, value)) + UpdateVisibleWorkspaces(); + } + } + + public Workspace SelectedWorkspace + { + get => _selectedWorkspace; + set => SetProperty(ref _selectedWorkspace, value); + } + + public WorkspaceSwitcher(Launcher launcher) + { + _launcher = launcher; + UpdateVisibleWorkspaces(); + } + + public void ClearFilter() + { + SearchFilter = string.Empty; + } + + public void Switch() + { + if (_selectedWorkspace is { }) + _launcher.SwitchWorkspace(_selectedWorkspace); + + _launcher.CancelWorkspaceSwitcher(); + } + + private void UpdateVisibleWorkspaces() + { + var visible = new List(); + if (string.IsNullOrEmpty(_searchFilter)) + { + visible.AddRange(Preferences.Instance.Workspaces); + } + else + { + foreach (var workspace in Preferences.Instance.Workspaces) + { + if (workspace.Name.Contains(_searchFilter, StringComparison.OrdinalIgnoreCase)) + visible.Add(workspace); + } + } + + VisibleWorkspaces = visible; + SelectedWorkspace = visible.Count == 0 ? null : visible[0]; + } + + private Launcher _launcher = null; + private List _visibleWorkspaces = null; + private string _searchFilter = string.Empty; + private Workspace _selectedWorkspace = null; + } +} diff --git a/src/Views/Avatar.cs b/src/Views/Avatar.cs index 87bc7ce3..5dacac69 100644 --- a/src/Views/Avatar.cs +++ b/src/Views/Avatar.cs @@ -78,10 +78,10 @@ namespace SourceGit.Views if (switches[idx]) context.FillRectangle(brush, new Rect(x, y, stepX, stepY)); - if (switches[idx+1]) + if (switches[idx + 1]) context.FillRectangle(brush, new Rect(x + stepX, y, stepX, stepY)); - if (switches[idx+2]) + if (switches[idx + 2]) context.FillRectangle(brush, new Rect(x + stepX * 2, y, stepX, stepY)); } @@ -94,7 +94,7 @@ namespace SourceGit.Views if (switches[idx]) context.FillRectangle(brush, new Rect(x, y, stepX, stepY)); - if (switches[idx-1]) + if (switches[idx - 1]) context.FillRectangle(brush, new Rect(x + stepX, y, stepX, stepY)); } } diff --git a/src/Views/Hotkeys.axaml b/src/Views/Hotkeys.axaml index b1d436a4..5d9a6f9f 100644 --- a/src/Views/Hotkeys.axaml +++ b/src/Views/Hotkeys.axaml @@ -45,7 +45,7 @@ FontSize="{Binding Source={x:Static vm:Preferences.Instance}, Path=DefaultFontSize, Converter={x:Static c:DoubleConverters.Increase}}" Margin="0,0,0,8"/> - + @@ -70,11 +70,8 @@ - - - - - + + - - - + - + @@ -102,5 +102,22 @@ + + + + + + + + + + + + + + + diff --git a/src/Views/Launcher.axaml.cs b/src/Views/Launcher.axaml.cs index f558ff99..02cc4f08 100644 --- a/src/Views/Launcher.axaml.cs +++ b/src/Views/Launcher.axaml.cs @@ -100,7 +100,7 @@ namespace SourceGit.Views if (change.Property == WindowStateProperty) { - _lastWindowState = (WindowState)change.OldValue; + _lastWindowState = (WindowState)change.OldValue!; var state = (WindowState)change.NewValue!; if (!OperatingSystem.IsMacOS() && !UseSystemWindowFrame) @@ -157,6 +157,12 @@ namespace SourceGit.Views if (e.KeyModifiers.HasFlag(OperatingSystem.IsMacOS() ? KeyModifiers.Meta : KeyModifiers.Control)) { + if (e.Key == Key.P) + { + vm.OpenWorkspaceSwitcher(); + e.Handled = true; + } + if (e.Key == Key.W) { vm.CloseTab(null); @@ -248,30 +254,10 @@ namespace SourceGit.Views } } } - else if (e.KeyModifiers.HasFlag(KeyModifiers.Alt)) - { - if (e.Key == Key.Space && DataContext is ViewModels.Launcher launcher) - { - var menu = launcher.CreateContextForWorkspace(); - var workspacesButton = this.FindControl + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/Views/WorkspaceSwitcher.axaml.cs b/src/Views/WorkspaceSwitcher.axaml.cs new file mode 100644 index 00000000..04bdae1a --- /dev/null +++ b/src/Views/WorkspaceSwitcher.axaml.cs @@ -0,0 +1,49 @@ +using Avalonia.Controls; +using Avalonia.Input; + +namespace SourceGit.Views +{ + public partial class WorkspaceSwitcher : UserControl + { + public WorkspaceSwitcher() + { + InitializeComponent(); + } + + protected override void OnKeyDown(KeyEventArgs e) + { + base.OnKeyDown(e); + + if (e.Key == Key.Enter && DataContext is ViewModels.WorkspaceSwitcher switcher) + { + switcher.Switch(); + e.Handled = true; + } + } + + private void OnItemDoubleTapped(object sender, TappedEventArgs e) + { + if (DataContext is ViewModels.WorkspaceSwitcher switcher) + { + switcher.Switch(); + e.Handled = true; + } + } + + private void OnSearchBoxKeyDown(object sender, KeyEventArgs e) + { + if (e.Key == Key.Down && WorkspaceListBox.ItemCount > 0) + { + WorkspaceListBox.Focus(NavigationMethod.Directional); + + if (WorkspaceListBox.SelectedIndex < 0) + WorkspaceListBox.SelectedIndex = 0; + else if (WorkspaceListBox.SelectedIndex < WorkspaceListBox.ItemCount) + WorkspaceListBox.SelectedIndex++; + + e.Handled = true; + } + } + } +} +