feat: add workspace-specific default clone directory functionality (#1183)

* refactor: improve diff handling for EOL changes and enhance text diff display

- Updated `Diff.cs` to streamline whitespace handling in diff arguments.
- Enhanced `DiffContext.cs` to check for EOL changes when old and new hashes differ, creating a text diff if necessary.
- Added support for showing end-of-line symbols in `TextDiffView.axaml.cs` options.

* localization: update translations to include EOF handling in ignore whitespace messages

- Modified the ignore whitespace text in multiple language files to specify that EOF changes are also ignored.
- Ensured consistency across all localization files for the patch application feature.

* revert: Typo in DiffResult comment

* revert: update diff arguments to ignore CR at EOL in whitespace handling (like before changes)

* revert: update translations to remove EOF references in Text.Apply.IgnoreWS and fixed typo in Text.Diff.IgnoreWhitespace (EOF => EOL)

* feat: add workspace-specific default clone directory functionality

- Implemented logic in Clone.cs to set ParentFolder based on the active workspace's DefaultCloneDir if available, falling back to the global GitDefaultCloneDir.
- Added DefaultCloneDir property to Workspace.cs to store the default clone directory for each workspace.
- Updated ConfigureWorkspace.axaml to include a TextBox and Button for setting the DefaultCloneDir in the UI.
- Implemented folder selection functionality in ConfigureWorkspace.axaml.cs to allow users to choose a directory for cloning.
- This closes issue #1145

---------

Co-authored-by: mpagani <massimo.pagani@unitec-group.com>
This commit is contained in:
Massimo 2025-04-14 10:41:34 +02:00 committed by GitHub
parent e89dbd8f43
commit f14a666091
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 55 additions and 4 deletions

View file

@ -64,6 +64,17 @@ namespace SourceGit.ViewModels
_pageId = pageId; _pageId = pageId;
View = new Views.Clone() { DataContext = this }; View = new Views.Clone() { DataContext = this };
// Use workspace-specific DefaultCloneDir if available
var activeWorkspace = Preferences.Instance.GetActiveWorkspace();
if (activeWorkspace != null && !string.IsNullOrEmpty(activeWorkspace.DefaultCloneDir))
{
ParentFolder = activeWorkspace.DefaultCloneDir;
}
else
{
ParentFolder = Preferences.Instance.GitDefaultCloneDir;
}
Task.Run(async () => Task.Run(async () =>
{ {
try try
@ -170,7 +181,7 @@ namespace SourceGit.ViewModels
private string _remote = string.Empty; private string _remote = string.Empty;
private bool _useSSH = false; private bool _useSSH = false;
private string _sshKey = string.Empty; private string _sshKey = string.Empty;
private string _parentFolder = Preferences.Instance.GitDefaultCloneDir; private string _parentFolder = string.Empty;
private string _local = string.Empty; private string _local = string.Empty;
private string _extraArgs = string.Empty; private string _extraArgs = string.Empty;
} }

View file

@ -46,6 +46,12 @@ namespace SourceGit.ViewModels
set => SetProperty(ref _restoreOnStartup, value); set => SetProperty(ref _restoreOnStartup, value);
} }
public string DefaultCloneDir
{
get => _defaultCloneDir;
set => SetProperty(ref _defaultCloneDir, value);
}
public IBrush Brush public IBrush Brush
{ {
get => new SolidColorBrush(_color); get => new SolidColorBrush(_color);
@ -55,5 +61,6 @@ namespace SourceGit.ViewModels
private uint _color = 4278221015; private uint _color = 4278221015;
private bool _isActive = false; private bool _isActive = false;
private bool _restoreOnStartup = true; private bool _restoreOnStartup = true;
private string _defaultCloneDir = string.Empty;
} }
} }

View file

@ -98,13 +98,20 @@
<ContentControl Grid.Column="2" Content="{Binding Selected}"> <ContentControl Grid.Column="2" Content="{Binding Selected}">
<ContentControl.DataTemplates> <ContentControl.DataTemplates>
<DataTemplate DataType="vm:Workspace"> <DataTemplate DataType="vm:Workspace">
<Grid RowDefinitions="32,32,Auto,Auto"> <Grid RowDefinitions="32,32,32,32,Auto,Auto">
<TextBox Grid.Row="0" CornerRadius="3" Height="28" Text="{Binding Name, Mode=TwoWay}"/> <TextBox Grid.Row="0" CornerRadius="3" Height="28" Text="{Binding Name, Mode=TwoWay}"/>
<CheckBox Grid.Row="1" <CheckBox Grid.Row="1"
Content="{DynamicResource Text.ConfigureWorkspace.Restore}" Content="{DynamicResource Text.ConfigureWorkspace.Restore}"
IsChecked="{Binding RestoreOnStartup, Mode=TwoWay}"/> IsChecked="{Binding RestoreOnStartup, Mode=TwoWay}"/>
<TextBlock Grid.Row="2" Margin="0,16,0,4" Text="{DynamicResource Text.ConfigureWorkspace.Color}"/> <TextBlock Grid.Row="2" Margin="0,16,0,4" Text="{DynamicResource Text.Preferences.Git.DefaultCloneDir}"/>
<v:ColorPicker Grid.Row="3" HorizontalAlignment="Left" Value="{Binding Color, Mode=TwoWay}"/> <Grid Grid.Row="3" ColumnDefinitions="*,Auto">
<TextBox Grid.Column="0" CornerRadius="3" Height="28" Text="{Binding DefaultCloneDir, Mode=TwoWay}"/>
<Button Grid.Column="1" Classes="icon_button" Width="30" Height="30" Click="SelectDefaultCloneDir">
<Path Data="{StaticResource Icons.Folder.Open}" Fill="{DynamicResource Brush.FG1}"/>
</Button>
</Grid>
<TextBlock Grid.Row="4" Margin="0,16,0,4" Text="{DynamicResource Text.ConfigureWorkspace.Color}"/>
<v:ColorPicker Grid.Row="5" HorizontalAlignment="Left" Value="{Binding Color, Mode=TwoWay}"/>
</Grid> </Grid>
</DataTemplate> </DataTemplate>
</ContentControl.DataTemplates> </ContentControl.DataTemplates>

View file

@ -1,4 +1,7 @@
using Avalonia.Controls; using Avalonia.Controls;
using Avalonia.Interactivity;
using Avalonia.Platform.Storage;
using System;
namespace SourceGit.Views namespace SourceGit.Views
{ {
@ -16,5 +19,28 @@ namespace SourceGit.Views
if (!Design.IsDesignMode) if (!Design.IsDesignMode)
ViewModels.Preferences.Instance.Save(); ViewModels.Preferences.Instance.Save();
} }
private async void SelectDefaultCloneDir(object _, RoutedEventArgs e)
{
var workspace = DataContext as ViewModels.ConfigureWorkspace;
if (workspace?.Selected == null)
return;
var options = new FolderPickerOpenOptions() { AllowMultiple = false };
try
{
var selected = await StorageProvider.OpenFolderPickerAsync(options);
if (selected.Count == 1)
{
workspace.Selected.DefaultCloneDir = selected[0].Path.LocalPath;
}
}
catch (Exception ex)
{
App.RaiseException(string.Empty, $"Failed to select default clone directory: {ex.Message}");
}
e.Handled = true;
}
} }
} }