Skip to content

Commit abfc43c

Browse files
committed
Add Phase 4 TUI enhancements and refactor ResourceEditorWindow
Features added: - Undo/Redo system with operation history (Ctrl+Z/Ctrl+Y) - Code scanning integration (F7) with usage filters - Context menus on right-click - Clipboard support (Ctrl+C/Ctrl+V) - Enhanced search with clear button, match counter, F3/Shift+F3 - Progress bars for translation and scanning operations - Visual status indicators with color-coded icons - StatusBar upgrade with code scan statistics Refactoring: - Split ResourceEditorWindow.cs (4,225 lines) into 7 partial classes (4,471 lines) - Organized by concern: Main, Layout, Data, Events, Dialogs, Operations, Filters - Improves maintainability and makes future enhancements easier Testing: - Added OperationHistoryTests.cs with 15 comprehensive unit tests - All 488 tests passing
1 parent 8c3d2ea commit abfc43c

15 files changed

Lines changed: 4042 additions & 1489 deletions

Commands/EditCommand.cs

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
2020
// SOFTWARE.
2121

22+
using System.ComponentModel;
2223
using LocalizationManager.Core;
2324
using LocalizationManager.Core.Models;
2425
using LocalizationManager.UI;
@@ -31,16 +32,37 @@ namespace LocalizationManager.Commands;
3132
/// <summary>
3233
/// Command to launch the interactive TUI editor.
3334
/// </summary>
34-
public class EditCommand : Command<BaseCommandSettings>
35+
public class EditCommand : Command<EditCommand.Settings>
3536
{
36-
public override int Execute(CommandContext context, BaseCommandSettings settings, CancellationToken cancellationToken = default)
37+
public class Settings : BaseCommandSettings
38+
{
39+
[CommandOption("--source-path <PATH>")]
40+
[Description("Path to source code directory for code scanning. Defaults to parent directory of resource path.")]
41+
public string? SourcePath { get; set; }
42+
}
43+
44+
public override int Execute(CommandContext context, Settings settings, CancellationToken cancellationToken = default)
3745
{
3846
// Load configuration if available
3947
settings.LoadConfiguration();
4048

4149
var resourcePath = settings.GetResourcePath();
4250
var defaultCode = settings.LoadedConfiguration?.DefaultLanguageCode ?? "default";
4351

52+
// Determine source path for code scanning (same logic as ScanCommand)
53+
// Convert to absolute path first to handle relative paths correctly
54+
var absoluteResourcePath = Path.GetFullPath(resourcePath).TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar);
55+
string sourcePath;
56+
if (settings.SourcePath != null)
57+
{
58+
sourcePath = Path.GetFullPath(settings.SourcePath).TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar);
59+
}
60+
else
61+
{
62+
var parent = Directory.GetParent(absoluteResourcePath);
63+
sourcePath = parent?.FullName ?? absoluteResourcePath;
64+
}
65+
4466
try
4567
{
4668
// Discover languages
@@ -73,7 +95,7 @@ public override int Execute(CommandContext context, BaseCommandSettings settings
7395

7496
// Launch TUI
7597
Application.Init();
76-
Application.Run(new ResourceEditorWindow(resourceFiles, parser, defaultCode, settings.LoadedConfiguration));
98+
Application.Run(new ResourceEditorWindow(resourceFiles, parser, defaultCode, sourcePath, settings.LoadedConfiguration));
7799
Application.Shutdown();
78100

79101
return 0;

Commands/ScanCommand.cs

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,8 +62,19 @@ public override int Execute(CommandContext context, Settings settings, Cancellat
6262
var format = settings.GetOutputFormat();
6363
var isTableFormat = format == OutputFormat.Table;
6464

65-
// Determine source path
66-
var sourcePath = settings.SourcePath ?? Directory.GetParent(resourcePath)?.FullName ?? resourcePath;
65+
// Determine source path - convert to absolute path first to handle relative paths correctly
66+
// Trim trailing slashes to ensure Directory.GetParent works correctly
67+
var absoluteResourcePath = Path.GetFullPath(resourcePath).TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar);
68+
string sourcePath;
69+
if (settings.SourcePath != null)
70+
{
71+
sourcePath = Path.GetFullPath(settings.SourcePath).TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar);
72+
}
73+
else
74+
{
75+
var parent = Directory.GetParent(absoluteResourcePath);
76+
sourcePath = parent?.FullName ?? absoluteResourcePath;
77+
}
6778

6879
if (!Directory.Exists(sourcePath))
6980
{

Commands/ValidateCommand.cs

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -660,12 +660,19 @@ private void ScanCodeForDuplicates(
660660
if (!allDuplicateKeys.Any())
661661
return;
662662

663-
// Determine source path
664-
var sourcePath = settings.SourcePath;
665-
if (string.IsNullOrEmpty(sourcePath))
663+
// Determine source path - convert to absolute path first to handle relative paths correctly
664+
// Trim trailing slashes to ensure Directory.GetParent works correctly
665+
var absoluteResourcePath = Path.GetFullPath(resourcePath).TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar);
666+
string sourcePath;
667+
if (!string.IsNullOrEmpty(settings.SourcePath))
668+
{
669+
sourcePath = Path.GetFullPath(settings.SourcePath).TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar);
670+
}
671+
else
666672
{
667673
// Default to parent directory of resource path
668-
sourcePath = Directory.GetParent(resourcePath)?.FullName ?? resourcePath;
674+
var parent = Directory.GetParent(absoluteResourcePath);
675+
sourcePath = parent?.FullName ?? absoluteResourcePath;
669676
}
670677

671678
if (!Directory.Exists(sourcePath))

0 commit comments

Comments
 (0)