Add project files.
This commit is contained in:
parent
0e8e1640c3
commit
7284f9b00e
|
@ -0,0 +1,9 @@
|
|||
<Application x:Class="CodeMergerNG.App"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:local="clr-namespace:CodeMergerNG"
|
||||
StartupUri="MainWindow.xaml">
|
||||
<Application.Resources>
|
||||
|
||||
</Application.Resources>
|
||||
</Application>
|
|
@ -0,0 +1,13 @@
|
|||
using System.Configuration;
|
||||
using System.Data;
|
||||
using System.Windows;
|
||||
|
||||
namespace CodeMergerNG;
|
||||
|
||||
/// <summary>
|
||||
/// Interaction logic for App.xaml
|
||||
/// </summary>
|
||||
public partial class App : Application
|
||||
{
|
||||
}
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
using System.Windows;
|
||||
|
||||
[assembly:ThemeInfo(
|
||||
ResourceDictionaryLocation.None, //where theme specific resource dictionaries are located
|
||||
//(used if a resource is not found in the page,
|
||||
// or application resource dictionaries)
|
||||
ResourceDictionaryLocation.SourceAssembly //where the generic resource dictionary is located
|
||||
//(used if a resource is not found in the page,
|
||||
// app, or any theme specific resource dictionaries)
|
||||
)]
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,18 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<TargetFramework>net8.0-windows</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<UseWPF>true</UseWPF>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="AvalonEdit" Version="6.3.0.90" />
|
||||
<PackageReference Include="CommunityToolkit.Mvvm" Version="8.4.0" />
|
||||
<PackageReference Include="DocumentFormat.OpenXml" Version="3.2.0" />
|
||||
<PackageReference Include="Microsoft.CodeAnalysis.CSharp" Version="4.13.0" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
|
@ -0,0 +1,25 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio Version 17
|
||||
VisualStudioVersion = 17.13.35806.99 d17.13
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CodeMergerNG", "CodeMergerNG.csproj", "{E34F5B22-68C1-454A-A5FB-6FE89352C3C9}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{E34F5B22-68C1-454A-A5FB-6FE89352C3C9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{E34F5B22-68C1-454A-A5FB-6FE89352C3C9}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{E34F5B22-68C1-454A-A5FB-6FE89352C3C9}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{E34F5B22-68C1-454A-A5FB-6FE89352C3C9}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {4FB3A6C1-5305-4483-A6A9-2322D8361527}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
|
@ -0,0 +1,15 @@
|
|||
<Window x:Class="CodeMerger.Controls.CodeStructureTreeView"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="Code Structure" Height="600" Width="400"
|
||||
WindowStyle="ToolWindow" ShowInTaskbar="False">
|
||||
<Grid Margin="10">
|
||||
<DockPanel>
|
||||
<StackPanel DockPanel.Dock="Top" Orientation="Horizontal" Margin="5">
|
||||
<Button x:Name="btnExport" Content="Export Structure" Click="BtnExport_Click" Padding="5,2"
|
||||
Margin="0,0,5,0" />
|
||||
<Button x:Name="btnCopy" Content="Copy to Clipboard" Click="BtnCopy_Click" Padding="5,2" />
|
||||
</StackPanel>
|
||||
<TreeView x:Name="tvCodeStructure" />
|
||||
</DockPanel>
|
||||
</Grid>
|
||||
</Window>
|
|
@ -0,0 +1,28 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Documents;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
using System.Windows.Navigation;
|
||||
using System.Windows.Shapes;
|
||||
|
||||
namespace CodeMergerNG.Controls
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for CodeStructureTreeView.xaml
|
||||
/// </summary>
|
||||
public partial class CodeStructureTreeView : UserControl
|
||||
{
|
||||
public CodeStructureTreeView()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,24 @@
|
|||
<UserControl x:Class="CodeMerger.Controls.SimpleMergeLogControl"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" mc:Ignorable="d" d:DesignHeight="200"
|
||||
d:DesignWidth="800">
|
||||
<Grid>
|
||||
<DockPanel LastChildFill="True">
|
||||
<StackPanel DockPanel.Dock="Top" Orientation="Horizontal" Margin="0,0,0,5">
|
||||
<Button Content="Clear Log" Width="100" Height="25" Margin="0,0,10,0" Click="ClearLog_Click" />
|
||||
<Button Content="Copy Log" Width="100" Height="25" Margin="0,0,10,0" Click="CopyLog_Click" />
|
||||
<Button Content="Save Log" Width="100" Height="25" Margin="0,0,10,0" Click="SaveLog_Click" />
|
||||
</StackPanel>
|
||||
<RichTextBox x:Name="rtbLog" IsReadOnly="True" VerticalScrollBarVisibility="Auto"
|
||||
HorizontalScrollBarVisibility="Auto">
|
||||
<RichTextBox.Resources>
|
||||
<Style TargetType="{x:Type Paragraph}">
|
||||
<Setter Property="Margin" Value="0" />
|
||||
</Style>
|
||||
</RichTextBox.Resources>
|
||||
</RichTextBox>
|
||||
</DockPanel>
|
||||
</Grid>
|
||||
</UserControl>
|
|
@ -0,0 +1,114 @@
|
|||
using System;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Documents;
|
||||
using System.Windows.Media;
|
||||
using DocumentFormat.OpenXml.VariantTypes;
|
||||
using Microsoft.Win32;
|
||||
|
||||
namespace CodeMerger.Controls
|
||||
{
|
||||
public partial class SimpleMergeLogControl : UserControl
|
||||
{
|
||||
private static readonly SolidColorBrush InfoBrush = Brushes.Black;
|
||||
private static readonly SolidColorBrush WarningBrush = Brushes.Orange;
|
||||
private static readonly SolidColorBrush ErrorBrush = Brushes.Red;
|
||||
private static readonly SolidColorBrush AddedBrush = Brushes.Green;
|
||||
private static readonly SolidColorBrush ReplacedBrush = Brushes.Blue;
|
||||
|
||||
public SimpleMergeLogControl()
|
||||
{
|
||||
InitializeComponent();
|
||||
}
|
||||
|
||||
public void LogInfo(string message)
|
||||
{
|
||||
AppendText($"[INFO] {message}", InfoBrush);
|
||||
}
|
||||
|
||||
public void LogWarning(string message)
|
||||
{
|
||||
AppendText($"[WARNING] {message}", WarningBrush);
|
||||
}
|
||||
|
||||
public void LogError(string message)
|
||||
{
|
||||
AppendText($"[ERROR] {message}", ErrorBrush);
|
||||
}
|
||||
|
||||
public void LogMergeDetails(string mergeLog)
|
||||
{
|
||||
AppendText("--- MERGE DETAILS ---", InfoBrush);
|
||||
|
||||
// Procesar log de merge y colorear según el tipo
|
||||
foreach (var line in mergeLog.Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries))
|
||||
{
|
||||
if (line.StartsWith("ADDED:"))
|
||||
{
|
||||
AppendText(line, AddedBrush);
|
||||
}
|
||||
else if (line.StartsWith("REPLACED:"))
|
||||
{
|
||||
AppendText(line, ReplacedBrush);
|
||||
}
|
||||
else if (line.StartsWith("ERROR:"))
|
||||
{
|
||||
AppendText(line, ErrorBrush);
|
||||
}
|
||||
else
|
||||
{
|
||||
AppendText(line, InfoBrush);
|
||||
}
|
||||
}
|
||||
|
||||
AppendText("---------------------", InfoBrush);
|
||||
}
|
||||
|
||||
private void AppendText(string text, Brush color)
|
||||
{
|
||||
Application.Current.Dispatcher.Invoke(() =>
|
||||
{
|
||||
var paragraph = new Paragraph();
|
||||
paragraph.Inlines.Add(new Run(text) { Foreground = color });
|
||||
rtbLog.Document.Blocks.Add(paragraph);
|
||||
|
||||
// Auto-scroll al final
|
||||
rtbLog.ScrollToEnd();
|
||||
});
|
||||
}
|
||||
|
||||
private void ClearLog_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
rtbLog.Document.Blocks.Clear();
|
||||
}
|
||||
|
||||
private void CopyLog_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
Clipboard.SetText(new TextRange(rtbLog.Document.ContentStart, rtbLog.Document.ContentEnd).Text);
|
||||
LogInfo("Log copiado al portapapeles");
|
||||
}
|
||||
|
||||
private void SaveLog_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
SaveFileDialog saveFileDialog = new SaveFileDialog
|
||||
{
|
||||
Filter = "Archivos de texto (*.txt)|*.txt|Todos los archivos (*.*)|*.*",
|
||||
FileName = "CodeMerger_Log.txt"
|
||||
};
|
||||
|
||||
if (saveFileDialog.ShowDialog() == true)
|
||||
{
|
||||
try
|
||||
{
|
||||
string text = new TextRange(rtbLog.Document.ContentStart, rtbLog.Document.ContentEnd).Text;
|
||||
System.IO.File.WriteAllText(saveFileDialog.FileName, text);
|
||||
LogInfo($"Log guardado en: {saveFileDialog.FileName}");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogError($"Error al guardar el log: {ex.Message}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,23 @@
|
|||
<UserControl x:Class="CodeMerger.Controls.TestExamplesControl"
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" mc:Ignorable="d" d:DesignHeight="300"
|
||||
d:DesignWidth="800">
|
||||
<Grid Margin="5">
|
||||
<StackPanel>
|
||||
<TextBlock Text="Seleccione un ejemplo para cargar:" FontWeight="Bold" Margin="0,0,0,10" />
|
||||
<ListView x:Name="lvExamples" Height="200" SelectionChanged="LvExamples_SelectionChanged">
|
||||
<ListView.View>
|
||||
<GridView>
|
||||
<GridViewColumn Header="Descripción" Width="200" DisplayMemberBinding="{Binding Description}" />
|
||||
<GridViewColumn Header="Detalles" Width="500" DisplayMemberBinding="{Binding Details}" />
|
||||
</GridView>
|
||||
</ListView.View>
|
||||
</ListView>
|
||||
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right" Margin="0,10,0,0">
|
||||
<Button Content="Cargar Ejemplo" Width="120" Height="30" Click="LoadExample_Click" />
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</UserControl>
|
|
@ -0,0 +1,120 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using CodeMerger.TestExamples;
|
||||
|
||||
namespace CodeMerger.Controls
|
||||
{
|
||||
public partial class TestExamplesControl : UserControl
|
||||
{
|
||||
public class TestExample
|
||||
{
|
||||
public string Description { get; set; }
|
||||
public string Details { get; set; }
|
||||
public string MasterCode { get; set; }
|
||||
public string SnippetCode { get; set; }
|
||||
}
|
||||
|
||||
private List<TestExample> _examples = new List<TestExample>();
|
||||
|
||||
public TestExamplesControl()
|
||||
{
|
||||
InitializeComponent();
|
||||
LoadExamplesList();
|
||||
}
|
||||
|
||||
private void LoadExamplesList()
|
||||
{
|
||||
_examples = new List<TestExample>
|
||||
{
|
||||
new TestExample
|
||||
{
|
||||
Description = "Merge Simple",
|
||||
Details = "Añade un método a una clase simple",
|
||||
MasterCode = TestExampleCode.SimpleMaster,
|
||||
SnippetCode = TestExampleCode.SimpleSnippet
|
||||
},
|
||||
new TestExample
|
||||
{
|
||||
Description = "Manejo de Namespace",
|
||||
Details = "Merge de código con diferentes namespaces",
|
||||
MasterCode = TestExampleCode.NamespaceHandlingMaster,
|
||||
SnippetCode = TestExampleCode.NamespaceHandlingSnippet
|
||||
},
|
||||
new TestExample
|
||||
{
|
||||
Description = "Elementos Virtuales",
|
||||
Details = "Merge de código sin namespace ni clase",
|
||||
MasterCode = TestExampleCode.VirtualElementsMaster,
|
||||
SnippetCode = TestExampleCode.VirtualElementsSnippet
|
||||
},
|
||||
new TestExample
|
||||
{
|
||||
Description = "Reemplazo de Métodos",
|
||||
Details = "Reemplaza un método existente con una implementación mejorada",
|
||||
MasterCode = TestExampleCode.MethodReplacementMaster,
|
||||
SnippetCode = TestExampleCode.MethodReplacementSnippet
|
||||
},
|
||||
new TestExample
|
||||
{
|
||||
Description = "Merge Complejo",
|
||||
Details = "Merge de una clase genérica con múltiples métodos y propiedades",
|
||||
MasterCode = TestExampleCode.ComplexMergeMaster,
|
||||
SnippetCode = TestExampleCode.ComplexMergeSnippet
|
||||
},
|
||||
new TestExample
|
||||
{
|
||||
Description = "Clases Múltiples",
|
||||
Details = "Merge de código con múltiples clases y herencia",
|
||||
MasterCode = TestExampleCode.MultipleClassesMaster,
|
||||
SnippetCode = TestExampleCode.MultipleClassesSnippet
|
||||
},
|
||||
new TestExample
|
||||
{
|
||||
Description = "Clases Anidadas",
|
||||
Details = "Merge con clases anidadas y estructuras complejas",
|
||||
MasterCode = TestExampleCode.NestedClassesMaster,
|
||||
SnippetCode = TestExampleCode.NestedClassesSnippet
|
||||
},
|
||||
new TestExample
|
||||
{
|
||||
Description = "Comentarios y Formato",
|
||||
Details = "Merge preservando comentarios XML y formato",
|
||||
MasterCode = TestExampleCode.CommentsFormatMaster,
|
||||
SnippetCode = TestExampleCode.CommentsFormatSnippet
|
||||
}
|
||||
};
|
||||
|
||||
lvExamples.ItemsSource = _examples;
|
||||
}
|
||||
|
||||
private void LvExamples_SelectionChanged(object sender, SelectionChangedEventArgs e)
|
||||
{
|
||||
// No hacer nada, solo permitir selección
|
||||
}
|
||||
|
||||
private void LoadExample_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
var selectedExample = lvExamples.SelectedItem as TestExample;
|
||||
if (selectedExample == null)
|
||||
{
|
||||
MessageBox.Show("Por favor, seleccione un ejemplo primero", "Selección Requerida",
|
||||
MessageBoxButton.OK, MessageBoxImage.Information);
|
||||
return;
|
||||
}
|
||||
|
||||
var mainWindow = Window.GetWindow(this) as MainWindow;
|
||||
if (mainWindow != null)
|
||||
{
|
||||
// Cargar el ejemplo en los editores
|
||||
mainWindow.txtOriginalCode.Text = selectedExample.MasterCode;
|
||||
mainWindow.txtLLMCode.Text = selectedExample.SnippetCode;
|
||||
|
||||
// Notificar
|
||||
var logControl = mainWindow.logControl;
|
||||
logControl?.LogInfo($"Ejemplo cargado: {selectedExample.Description}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,136 @@
|
|||
<Window x:Class="CodeMerger.MainWindow" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:avalon="http://icsharpcode.net/sharpdevelop/avalonedit" xmlns:controls="clr-namespace:CodeMerger.Controls"
|
||||
Title="Code Merger" Height="{Binding Settings.WindowHeight, Mode=TwoWay}"
|
||||
Width="{Binding Settings.WindowWidth, Mode=TwoWay}" Left="{Binding Settings.WindowLeft, Mode=TwoWay}"
|
||||
Top="{Binding Settings.WindowTop, Mode=TwoWay}" WindowState="{Binding Settings.WindowState, Mode=TwoWay}"
|
||||
Closing="Window_Closing">
|
||||
<Grid Margin="10">
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="*" />
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="200" />
|
||||
</Grid.RowDefinitions>
|
||||
|
||||
<!-- Panel de Ejemplos de Test -->
|
||||
<Expander Grid.Row="0" Header="Test Examples" IsExpanded="False">
|
||||
<controls:TestExamplesControl x:Name="testExamplesControl" />
|
||||
</Expander>
|
||||
|
||||
<!-- Panel de Controles -->
|
||||
<StackPanel Grid.Row="1" Orientation="Horizontal" Margin="0,10,0,10">
|
||||
<GroupBox Header="Original Code" Margin="0,0,10,0">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<Button Content="Paste" Width="80" Margin="5" Command="{Binding PasteOriginalCommand}" />
|
||||
<Button Content="Copy" Width="80" Margin="5" Command="{Binding CopyOriginalCommand}" />
|
||||
</StackPanel>
|
||||
</GroupBox>
|
||||
|
||||
<GroupBox Header="LLM Code" Margin="0,0,10,0">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<Button Content="Paste" Width="80" Margin="5" Command="{Binding PasteLLMCommand}" />
|
||||
<Button Content="Copy" Width="80" Margin="5" Command="{Binding CopyLLMCommand}" />
|
||||
</StackPanel>
|
||||
</GroupBox>
|
||||
|
||||
<GroupBox Header="Merged Code" Margin="0,0,10,0">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<Button Content="Copy" Width="80" Margin="5" Command="{Binding CopyMergedCommand}" />
|
||||
</StackPanel>
|
||||
</GroupBox>
|
||||
|
||||
<Separator Margin="10,0" Width="2" Background="LightGray" />
|
||||
|
||||
<TextBox x:Name="txtSearch" Width="200" Height="30" Margin="0,0,5,0" VerticalContentAlignment="Center"
|
||||
Text="{Binding SearchText, UpdateSourceTrigger=PropertyChanged}">
|
||||
<TextBox.InputBindings>
|
||||
<KeyBinding Key="Return" Command="{Binding SearchCommand}" />
|
||||
</TextBox.InputBindings>
|
||||
</TextBox>
|
||||
<Button Content="Find" Width="80" Height="30" Margin="0,0,20,0" Command="{Binding SearchCommand}" />
|
||||
|
||||
<Button Content="Clear All" Width="120" Height="30" Margin="0,0,20,0" Command="{Binding ClearAllCommand}" />
|
||||
<Button Content="Analyze" Width="120" Height="30" Margin="0,0,10,0" Command="{Binding AnalyzeCodeCommand}" />
|
||||
<Button Content="Merge Code" Width="120" Height="30" Margin="0,0,0,0" Command="{Binding MergeCodeCommand}" />
|
||||
</StackPanel>
|
||||
|
||||
<!-- Editores de Código -->
|
||||
<Grid Grid.Row="2" Name="EditorsGrid">
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="{Binding FirstColumnWidth, Mode=TwoWay}" MinWidth="100" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="{Binding SecondColumnWidth, Mode=TwoWay}" MinWidth="100" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="{Binding ThirdColumnWidth, Mode=TwoWay}" MinWidth="100" />
|
||||
</Grid.ColumnDefinitions>
|
||||
|
||||
<!-- Editor de código original -->
|
||||
<GroupBox Header="Original Code" Grid.Column="1">
|
||||
<DockPanel LastChildFill="True">
|
||||
<Button DockPanel.Dock="Top" Content="Show Structure" Height="30" Margin="0,0,0,5"
|
||||
Command="{Binding ShowOriginalStructureCommand}" />
|
||||
<Button DockPanel.Dock="Bottom" Content="Analyze" Height="30" Margin="0,5,0,0"
|
||||
Command="{Binding AnalyzeCodeCommand}" />
|
||||
<avalon:TextEditor x:Name="txtOriginalCode" ShowLineNumbers="True" FontFamily="Consolas"
|
||||
SyntaxHighlighting="C#" Document="{Binding OriginalDocument}" WordWrap="True"
|
||||
Loaded="txtOriginalCode_Loaded" MouseDoubleClick="TextEditor_MouseDoubleClick" />
|
||||
</DockPanel>
|
||||
</GroupBox>
|
||||
|
||||
<!-- Separador -->
|
||||
<GridSplitter Grid.Column="2" Width="5" HorizontalAlignment="Center" Background="LightGray"
|
||||
ShowsPreview="True" DragCompleted="GridSplitter_DragCompleted" />
|
||||
|
||||
<!-- Editor de código LLM -->
|
||||
<GroupBox Header="LLM Code" Grid.Column="3">
|
||||
<DockPanel LastChildFill="True">
|
||||
<Button DockPanel.Dock="Top" Content="Show Structure" Height="30" Margin="0,0,0,5"
|
||||
Command="{Binding ShowLLMStructureCommand}" />
|
||||
<StackPanel DockPanel.Dock="Top" Orientation="Horizontal" Margin="0,0,0,5">
|
||||
<TextBlock Text="Default Namespace:" VerticalAlignment="Center" Margin="0,0,5,0" />
|
||||
<ComboBox x:Name="cbLLMNamespace" Width="180"
|
||||
ItemsSource="{Binding OriginalNamespaces, Mode=OneWay}"
|
||||
SelectedItem="{Binding SelectedLLMNamespace}" Margin="0,0,10,0" />
|
||||
<TextBlock Text="Default Class:" VerticalAlignment="Center" Margin="0,0,5,0" />
|
||||
<ComboBox x:Name="cbLLMClass" Width="180" ItemsSource="{Binding OriginalClasses, Mode=OneWay}"
|
||||
SelectedItem="{Binding SelectedLLMClass}" />
|
||||
</StackPanel>
|
||||
<Button DockPanel.Dock="Bottom" Content="Analyze" Height="30" Margin="0,5,0,0"
|
||||
Command="{Binding AnalyzeCodeCommand}" />
|
||||
<avalon:TextEditor x:Name="txtLLMCode" ShowLineNumbers="True" FontFamily="Consolas"
|
||||
SyntaxHighlighting="C#" Document="{Binding LLMDocument}" WordWrap="True"
|
||||
Loaded="txtLLMCode_Loaded" MouseDoubleClick="TextEditor_MouseDoubleClick" />
|
||||
</DockPanel>
|
||||
</GroupBox>
|
||||
|
||||
<!-- Separador -->
|
||||
<GridSplitter Grid.Column="4" Width="5" HorizontalAlignment="Center" Background="LightGray"
|
||||
ShowsPreview="True" DragCompleted="GridSplitter_DragCompleted" />
|
||||
|
||||
<!-- Editor de código fusionado -->
|
||||
<GroupBox Header="Merged Code" Grid.Column="5">
|
||||
<DockPanel LastChildFill="True">
|
||||
<Button DockPanel.Dock="Top" Content="Show Structure" Height="30" Margin="0,0,0,5"
|
||||
Command="{Binding ShowMergedStructureCommand}" />
|
||||
<Button DockPanel.Dock="Bottom" Content="Analyze" Height="30" Margin="0,5,0,0"
|
||||
Command="{Binding AnalyzeCodeCommand}" />
|
||||
<avalon:TextEditor x:Name="txtMergedCode" ShowLineNumbers="True" FontFamily="Consolas"
|
||||
SyntaxHighlighting="C#" Document="{Binding MergedDocument}" WordWrap="True"
|
||||
Loaded="txtMergedCode_Loaded" IsReadOnly="True"
|
||||
MouseDoubleClick="TextEditor_MouseDoubleClick" />
|
||||
</DockPanel>
|
||||
</GroupBox>
|
||||
</Grid>
|
||||
|
||||
<!-- Separador -->
|
||||
<GridSplitter Grid.Row="3" Height="5" HorizontalAlignment="Stretch" Background="LightGray" ShowsPreview="True" />
|
||||
|
||||
<!-- Panel de Log -->
|
||||
<Expander Grid.Row="4" Header="Log" IsExpanded="True">
|
||||
<controls:SimpleMergeLogControl x:Name="logControl" />
|
||||
</Expander>
|
||||
</Grid>
|
||||
</Window>
|
|
@ -0,0 +1,110 @@
|
|||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Input;
|
||||
using CodeMerger.ViewModels;
|
||||
using ICSharpCode.AvalonEdit;
|
||||
using ICSharpCode.AvalonEdit.Highlighting;
|
||||
|
||||
namespace CodeMerger
|
||||
{
|
||||
public partial class MainWindow : Window
|
||||
{
|
||||
private MainWindowViewModel _viewModel;
|
||||
|
||||
public MainWindow()
|
||||
{
|
||||
InitializeComponent();
|
||||
|
||||
_viewModel = new MainWindowViewModel();
|
||||
DataContext = _viewModel;
|
||||
}
|
||||
|
||||
private void txtOriginalCode_Loaded(object sender, RoutedEventArgs e)
|
||||
{
|
||||
ConfigureTextEditor(txtOriginalCode);
|
||||
}
|
||||
|
||||
private void txtLLMCode_Loaded(object sender, RoutedEventArgs e)
|
||||
{
|
||||
ConfigureTextEditor(txtLLMCode);
|
||||
}
|
||||
|
||||
private void txtMergedCode_Loaded(object sender, RoutedEventArgs e)
|
||||
{
|
||||
ConfigureTextEditor(txtMergedCode);
|
||||
}
|
||||
|
||||
private void ConfigureTextEditor(TextEditor editor)
|
||||
{
|
||||
editor.Options.EnableHyperlinks = false;
|
||||
editor.Options.EnableEmailHyperlinks = false;
|
||||
editor.Options.EnableVirtualSpace = false;
|
||||
editor.Options.ShowSpaces = false;
|
||||
editor.Options.ShowTabs = false;
|
||||
editor.Options.ShowEndOfLine = false;
|
||||
editor.Options.ShowColumnRuler = false;
|
||||
editor.Options.EnableRectangularSelection = true;
|
||||
editor.Options.EnableTextDragDrop = true;
|
||||
editor.WordWrap = true;
|
||||
|
||||
// Configurar syntax highlighting para C#
|
||||
editor.SyntaxHighlighting = HighlightingManager.Instance.GetDefinition("C#");
|
||||
|
||||
// Configurar indentación con tabulaciones
|
||||
editor.Options.ConvertTabsToSpaces = false;
|
||||
editor.Options.IndentationSize = 4;
|
||||
}
|
||||
|
||||
private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
|
||||
{
|
||||
// Guardar configuración antes de cerrar
|
||||
_viewModel.Settings.Save();
|
||||
}
|
||||
|
||||
private void GridSplitter_DragCompleted(object sender, System.Windows.Controls.Primitives.DragCompletedEventArgs e)
|
||||
{
|
||||
// Actualizar anchos de columnas en el ViewModel
|
||||
var columnDefinitions = EditorsGrid.ColumnDefinitions;
|
||||
_viewModel.FirstColumnWidth = columnDefinitions[1].ActualWidth;
|
||||
_viewModel.SecondColumnWidth = columnDefinitions[3].ActualWidth;
|
||||
_viewModel.ThirdColumnWidth = columnDefinitions[5].ActualWidth;
|
||||
}
|
||||
|
||||
private void TextEditor_MouseDoubleClick(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
// Seleccionar palabra completa al hacer doble clic
|
||||
var editor = sender as TextEditor;
|
||||
if (editor != null)
|
||||
{
|
||||
var position = editor.TextArea.Caret.Position;
|
||||
var document = editor.Document;
|
||||
var line = document.GetLineByOffset(position.Offset);
|
||||
var lineText = document.GetText(line);
|
||||
|
||||
// Obtener palabra bajo el cursor
|
||||
var offsetInLine = position.Offset - line.Offset;
|
||||
int wordStart = offsetInLine;
|
||||
int wordEnd = offsetInLine;
|
||||
|
||||
// Encontrar inicio de palabra
|
||||
while (wordStart > 0 && IsWordPart(lineText[wordStart - 1]))
|
||||
wordStart--;
|
||||
|
||||
// Encontrar fin de palabra
|
||||
while (wordEnd < lineText.Length && IsWordPart(lineText[wordEnd]))
|
||||
wordEnd++;
|
||||
|
||||
// Seleccionar palabra
|
||||
if (wordEnd > wordStart)
|
||||
{
|
||||
editor.Select(line.Offset + wordStart, wordEnd - wordStart);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private bool IsWordPart(char c)
|
||||
{
|
||||
return char.IsLetterOrDigit(c) || c == '_';
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,205 @@
|
|||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.IO;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Windows;
|
||||
using System.Xml.Serialization;
|
||||
|
||||
namespace CodeMerger
|
||||
{
|
||||
public class Settings : INotifyPropertyChanged
|
||||
{
|
||||
private static readonly string SettingsFilePath = Path.Combine(
|
||||
Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData),
|
||||
"CodeMerger",
|
||||
"settings.xml");
|
||||
|
||||
#region Propiedades de Ventana
|
||||
|
||||
private double _windowWidth = 1200;
|
||||
private double _windowHeight = 800;
|
||||
private double _windowLeft = 100;
|
||||
private double _windowTop = 100;
|
||||
private WindowState _windowState = WindowState.Normal;
|
||||
|
||||
public double WindowWidth
|
||||
{
|
||||
get => _windowWidth;
|
||||
set
|
||||
{
|
||||
if (_windowWidth != value)
|
||||
{
|
||||
_windowWidth = value;
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public double WindowHeight
|
||||
{
|
||||
get => _windowHeight;
|
||||
set
|
||||
{
|
||||
if (_windowHeight != value)
|
||||
{
|
||||
_windowHeight = value;
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public double WindowLeft
|
||||
{
|
||||
get => _windowLeft;
|
||||
set
|
||||
{
|
||||
if (_windowLeft != value)
|
||||
{
|
||||
_windowLeft = value;
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public double WindowTop
|
||||
{
|
||||
get => _windowTop;
|
||||
set
|
||||
{
|
||||
if (_windowTop != value)
|
||||
{
|
||||
_windowTop = value;
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public WindowState WindowState
|
||||
{
|
||||
get => _windowState;
|
||||
set
|
||||
{
|
||||
if (_windowState != value)
|
||||
{
|
||||
_windowState = value;
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Tamaños de Columnas
|
||||
|
||||
private double _firstColumnWidth = 400;
|
||||
private double _secondColumnWidth = 400;
|
||||
private double _thirdColumnWidth = 400;
|
||||
|
||||
public double FirstColumnWidth
|
||||
{
|
||||
get => _firstColumnWidth;
|
||||
set
|
||||
{
|
||||
if (_firstColumnWidth != value)
|
||||
{
|
||||
_firstColumnWidth = value;
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public double SecondColumnWidth
|
||||
{
|
||||
get => _secondColumnWidth;
|
||||
set
|
||||
{
|
||||
if (_secondColumnWidth != value)
|
||||
{
|
||||
_secondColumnWidth = value;
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public double ThirdColumnWidth
|
||||
{
|
||||
get => _thirdColumnWidth;
|
||||
set
|
||||
{
|
||||
if (_thirdColumnWidth != value)
|
||||
{
|
||||
_thirdColumnWidth = value;
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Carga y Guardado
|
||||
|
||||
public static Settings Load()
|
||||
{
|
||||
try
|
||||
{
|
||||
// Asegurarse de que el directorio existe
|
||||
string directory = Path.GetDirectoryName(SettingsFilePath);
|
||||
if (!Directory.Exists(directory))
|
||||
{
|
||||
Directory.CreateDirectory(directory);
|
||||
}
|
||||
|
||||
// Cargar configuración si existe
|
||||
if (File.Exists(SettingsFilePath))
|
||||
{
|
||||
using (var stream = File.OpenRead(SettingsFilePath))
|
||||
{
|
||||
var serializer = new XmlSerializer(typeof(Settings));
|
||||
return (Settings)serializer.Deserialize(stream);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
// En caso de error, devolver configuración por defecto
|
||||
}
|
||||
|
||||
return new Settings();
|
||||
}
|
||||
|
||||
public void Save()
|
||||
{
|
||||
try
|
||||
{
|
||||
string directory = Path.GetDirectoryName(SettingsFilePath);
|
||||
if (!Directory.Exists(directory))
|
||||
{
|
||||
Directory.CreateDirectory(directory);
|
||||
}
|
||||
|
||||
using (var stream = File.Create(SettingsFilePath))
|
||||
{
|
||||
var serializer = new XmlSerializer(typeof(Settings));
|
||||
serializer.Serialize(stream, this);
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
// Manejar error de guardado
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region INotifyPropertyChanged
|
||||
|
||||
public event PropertyChangedEventHandler PropertyChanged;
|
||||
|
||||
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
|
||||
{
|
||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
|
@ -0,0 +1,396 @@
|
|||
namespace CodeMerger.TestExamples
|
||||
{
|
||||
public static class TestExampleCode
|
||||
{
|
||||
// Ejemplo Simple
|
||||
public static string SimpleMaster = @"
|
||||
public class SimpleClass
|
||||
{
|
||||
private int _counter;
|
||||
|
||||
public int Counter
|
||||
{
|
||||
get { return _counter; }
|
||||
set { _counter = value; }
|
||||
}
|
||||
|
||||
public void Increment()
|
||||
{
|
||||
_counter++;
|
||||
}
|
||||
}";
|
||||
|
||||
public static string SimpleSnippet = @"
|
||||
public void Decrement()
|
||||
{
|
||||
_counter--;
|
||||
}";
|
||||
|
||||
// Manejo de Namespace
|
||||
public static string NamespaceHandlingMaster = @"
|
||||
namespace TestNamespace
|
||||
{
|
||||
public class MasterClass
|
||||
{
|
||||
public void ExistingMethod()
|
||||
{
|
||||
Console.WriteLine(""Original implementation"");
|
||||
}
|
||||
}
|
||||
}";
|
||||
|
||||
public static string NamespaceHandlingSnippet = @"
|
||||
namespace TestNamespace
|
||||
{
|
||||
public class MasterClass
|
||||
{
|
||||
public void NewMethod()
|
||||
{
|
||||
Console.WriteLine(""New method"");
|
||||
}
|
||||
}
|
||||
}";
|
||||
|
||||
// Elementos Virtuales
|
||||
public static string VirtualElementsMaster = @"
|
||||
// Sin namespace ni clase
|
||||
public int Calculate(int x, int y)
|
||||
{
|
||||
return x + y;
|
||||
}";
|
||||
|
||||
public static string VirtualElementsSnippet = @"
|
||||
// Sin namespace ni clase
|
||||
public int Multiply(int x, int y)
|
||||
{
|
||||
return x * y;
|
||||
}";
|
||||
|
||||
// Reemplazo de Métodos
|
||||
public static string MethodReplacementMaster = @"
|
||||
namespace Calculator
|
||||
{
|
||||
public class MathUtils
|
||||
{
|
||||
// Método original
|
||||
public double CalculateAverage(int[] numbers)
|
||||
{
|
||||
int sum = 0;
|
||||
foreach (var n in numbers)
|
||||
sum += n;
|
||||
return (double)sum / numbers.Length;
|
||||
}
|
||||
}
|
||||
}";
|
||||
|
||||
public static string MethodReplacementSnippet = @"
|
||||
// Mismo método con implementación mejorada
|
||||
public double CalculateAverage(int[] numbers)
|
||||
{
|
||||
return numbers.Length > 0 ? numbers.Average() : 0;
|
||||
}";
|
||||
|
||||
// Merge Complejo
|
||||
public static string ComplexMergeMaster = @"
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace DataAccess
|
||||
{
|
||||
public class Repository<T> where T : class
|
||||
{
|
||||
private List<T> _items = new List<T>();
|
||||
|
||||
public void Add(T item)
|
||||
{
|
||||
_items.Add(item);
|
||||
}
|
||||
|
||||
public T GetById(int id)
|
||||
{
|
||||
// Implementación básica
|
||||
return _items[id];
|
||||
}
|
||||
|
||||
public IEnumerable<T> GetAll()
|
||||
{
|
||||
return _items;
|
||||
}
|
||||
}
|
||||
}";
|
||||
|
||||
public static string ComplexMergeSnippet = @"
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace DataAccess
|
||||
{
|
||||
public class Repository<T> where T : class
|
||||
{
|
||||
// Método mejorado
|
||||
public T GetById(int id)
|
||||
{
|
||||
// Implementación mejorada con validación
|
||||
if (id < 0 || id >= _items.Count)
|
||||
throw new ArgumentOutOfRangeException(nameof(id));
|
||||
|
||||
return _items[id];
|
||||
}
|
||||
|
||||
// Método nuevo
|
||||
public void Remove(T item)
|
||||
{
|
||||
_items.Remove(item);
|
||||
}
|
||||
|
||||
// Método nuevo con sobrecarga
|
||||
public void Remove(int id)
|
||||
{
|
||||
if (id < 0 || id >= _items.Count)
|
||||
throw new ArgumentOutOfRangeException(nameof(id));
|
||||
|
||||
_items.RemoveAt(id);
|
||||
}
|
||||
}
|
||||
}";
|
||||
|
||||
// Múltiples Clases
|
||||
public static string MultipleClassesMaster = @"
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Demo
|
||||
{
|
||||
public class Person
|
||||
{
|
||||
public string Name { get; set; }
|
||||
public int Age { get; set; }
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return $""{Name}, {Age} years old"";
|
||||
}
|
||||
}
|
||||
|
||||
public class Employee : Person
|
||||
{
|
||||
public string Department { get; set; }
|
||||
public decimal Salary { get; set; }
|
||||
|
||||
public decimal CalculateBonus()
|
||||
{
|
||||
return Salary * 0.1m;
|
||||
}
|
||||
}
|
||||
}";
|
||||
|
||||
public static string MultipleClassesSnippet = @"
|
||||
using System;
|
||||
using System.Linq;
|
||||
|
||||
namespace Demo
|
||||
{
|
||||
// Modificar clase existente
|
||||
public class Person
|
||||
{
|
||||
// Nuevo campo
|
||||
private DateTime _birthDate;
|
||||
|
||||
// Nueva propiedad
|
||||
public DateTime BirthDate
|
||||
{
|
||||
get { return _birthDate; }
|
||||
set { _birthDate = value; Age = CalculateAge(value); }
|
||||
}
|
||||
|
||||
// Nuevo método
|
||||
private int CalculateAge(DateTime birthDate)
|
||||
{
|
||||
var today = DateTime.Today;
|
||||
var age = today.Year - birthDate.Year;
|
||||
if (birthDate > today.AddYears(-age)) age--;
|
||||
return age;
|
||||
}
|
||||
}
|
||||
|
||||
// Nueva clase
|
||||
public class Manager : Employee
|
||||
{
|
||||
public List<Employee> Team { get; set; } = new List<Employee>();
|
||||
|
||||
public decimal CalculateDepartmentSalary()
|
||||
{
|
||||
return Team.Sum(e => e.Salary) + Salary;
|
||||
}
|
||||
|
||||
// Sobreescribir método
|
||||
public new decimal CalculateBonus()
|
||||
{
|
||||
return Salary * 0.2m;
|
||||
}
|
||||
}
|
||||
}";
|
||||
|
||||
// Clases Anidadas
|
||||
public static string NestedClassesMaster = @"
|
||||
using System;
|
||||
|
||||
namespace Configuration
|
||||
{
|
||||
public class ConfigManager
|
||||
{
|
||||
private static ConfigManager _instance;
|
||||
|
||||
public static ConfigManager Instance
|
||||
{
|
||||
get
|
||||
{
|
||||
if (_instance == null)
|
||||
_instance = new ConfigManager();
|
||||
return _instance;
|
||||
}
|
||||
}
|
||||
|
||||
public class ConfigSection
|
||||
{
|
||||
public string Name { get; set; }
|
||||
public Dictionary<string, string> Settings { get; set; } = new Dictionary<string, string>();
|
||||
|
||||
public string GetSetting(string key)
|
||||
{
|
||||
return Settings.TryGetValue(key, out var value) ? value : null;
|
||||
}
|
||||
}
|
||||
|
||||
private Dictionary<string, ConfigSection> _sections = new Dictionary<string, ConfigSection>();
|
||||
|
||||
public ConfigSection GetSection(string name)
|
||||
{
|
||||
return _sections.TryGetValue(name, out var section) ? section : null;
|
||||
}
|
||||
}
|
||||
}";
|
||||
|
||||
public static string NestedClassesSnippet = @"
|
||||
namespace Configuration
|
||||
{
|
||||
public class ConfigManager
|
||||
{
|
||||
// Clase anidada modificada
|
||||
public class ConfigSection
|
||||
{
|
||||
// Nuevo método
|
||||
public void SetSetting(string key, string value)
|
||||
{
|
||||
Settings[key] = value;
|
||||
}
|
||||
|
||||
// Clase anidada dentro de otra clase anidada
|
||||
public class EncryptedSetting
|
||||
{
|
||||
public string EncryptedValue { get; set; }
|
||||
public string Decrypt()
|
||||
{
|
||||
// Simulación de desencriptación
|
||||
return System.Text.Encoding.UTF8.GetString(
|
||||
Convert.FromBase64String(EncryptedValue));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Nuevo método
|
||||
public void AddSection(string name)
|
||||
{
|
||||
if (!_sections.ContainsKey(name))
|
||||
_sections[name] = new ConfigSection { Name = name };
|
||||
}
|
||||
}
|
||||
}";
|
||||
|
||||
// Comentarios y Formato
|
||||
public static string CommentsFormatMaster = @"
|
||||
using System;
|
||||
|
||||
namespace Documentation
|
||||
{
|
||||
/// <summary>
|
||||
/// Representa un artículo de documentación
|
||||
/// </summary>
|
||||
public class DocumentItem
|
||||
{
|
||||
// ID único del documento
|
||||
public Guid Id { get; } = Guid.NewGuid();
|
||||
|
||||
/// <summary>
|
||||
/// Título del documento
|
||||
/// </summary>
|
||||
public string Title { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Contenido del documento
|
||||
/// </summary>
|
||||
public string Content { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Fecha de creación
|
||||
/// </summary>
|
||||
public DateTime Created { get; set; } = DateTime.Now;
|
||||
|
||||
/// <summary>
|
||||
/// Formatea el documento para visualización
|
||||
/// </summary>
|
||||
public string FormatDocument()
|
||||
{
|
||||
return $""# {Title}\n\n{Content}"";
|
||||
}
|
||||
}
|
||||
}";
|
||||
|
||||
public static string CommentsFormatSnippet = @"
|
||||
namespace Documentation
|
||||
{
|
||||
public class DocumentItem
|
||||
{
|
||||
/// <summary>
|
||||
/// Última fecha de modificación
|
||||
/// </summary>
|
||||
public DateTime LastModified { get; set; } = DateTime.Now;
|
||||
|
||||
/// <summary>
|
||||
/// Etiquetas asociadas al documento
|
||||
/// </summary>
|
||||
public List<string> Tags { get; set; } = new List<string>();
|
||||
|
||||
/// <summary>
|
||||
/// Verifica si el documento contiene una etiqueta específica
|
||||
/// </summary>
|
||||
/// <param name=""tag"">Etiqueta a buscar</param>
|
||||
/// <returns>Verdadero si la etiqueta existe</returns>
|
||||
public bool HasTag(string tag)
|
||||
{
|
||||
return Tags.Contains(tag, StringComparer.OrdinalIgnoreCase);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Formatea el documento para visualización con metadatos
|
||||
/// </summary>
|
||||
public string FormatDocument()
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
sb.AppendLine($""# {Title}"");
|
||||
sb.AppendLine($""Created: {Created:yyyy-MM-dd}"");
|
||||
sb.AppendLine($""Modified: {LastModified:yyyy-MM-dd}"");
|
||||
|
||||
if (Tags.Count > 0)
|
||||
sb.AppendLine($""Tags: {string.Join(', ', Tags)}"");
|
||||
|
||||
sb.AppendLine();
|
||||
sb.Append(Content);
|
||||
|
||||
return sb.ToString();
|
||||
}
|
||||
}
|
||||
}";
|
||||
}
|
||||
}
|
|
@ -0,0 +1,597 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using CommunityToolkit.Mvvm.Input;
|
||||
using DocumentFormat.OpenXml.Wordprocessing;
|
||||
using ICSharpCode.AvalonEdit.Document;
|
||||
using Microsoft.Win32;
|
||||
|
||||
namespace CodeMerger.ViewModels
|
||||
{
|
||||
public class MainWindowViewModel : INotifyPropertyChanged
|
||||
{
|
||||
#region Campos Privados
|
||||
|
||||
private readonly cCodeMerger _codeMerger;
|
||||
private readonly Settings _settings;
|
||||
private string _searchText;
|
||||
private double _firstColumnWidth;
|
||||
private double _secondColumnWidth;
|
||||
private double _thirdColumnWidth;
|
||||
private TextDocument _originalDocument;
|
||||
private TextDocument _llmDocument;
|
||||
private TextDocument _mergedDocument;
|
||||
private CodeElement _originalStructure;
|
||||
private CodeElement _llmStructure;
|
||||
private CodeElement _mergedStructure;
|
||||
private ObservableCollection<string> _originalNamespaces;
|
||||
private ObservableCollection<string> _originalClasses;
|
||||
private string _selectedLLMNamespace;
|
||||
private string _selectedLLMClass;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructores
|
||||
|
||||
public MainWindowViewModel()
|
||||
{
|
||||
// Cargar configuración
|
||||
_settings = Settings.Load();
|
||||
|
||||
// Inicializar CodeMerger
|
||||
_codeMerger = new cCodeMerger();
|
||||
|
||||
// Inicializar documentos
|
||||
_originalDocument = new TextDocument();
|
||||
_llmDocument = new TextDocument();
|
||||
_mergedDocument = new TextDocument();
|
||||
|
||||
// Inicializar anchos de columnas
|
||||
_firstColumnWidth = _settings.FirstColumnWidth;
|
||||
_secondColumnWidth = _settings.SecondColumnWidth;
|
||||
_thirdColumnWidth = _settings.ThirdColumnWidth;
|
||||
|
||||
// Inicializar colecciones
|
||||
_originalNamespaces = new ObservableCollection<string>();
|
||||
_originalClasses = new ObservableCollection<string>();
|
||||
|
||||
// Inicializar comandos
|
||||
InitializeCommands();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Propiedades
|
||||
|
||||
public Settings Settings => _settings;
|
||||
|
||||
public string SearchText
|
||||
{
|
||||
get => _searchText;
|
||||
set
|
||||
{
|
||||
if (_searchText != value)
|
||||
{
|
||||
_searchText = value;
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public double FirstColumnWidth
|
||||
{
|
||||
get => _firstColumnWidth;
|
||||
set
|
||||
{
|
||||
if (_firstColumnWidth != value)
|
||||
{
|
||||
_firstColumnWidth = value;
|
||||
_settings.FirstColumnWidth = value;
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public double SecondColumnWidth
|
||||
{
|
||||
get => _secondColumnWidth;
|
||||
set
|
||||
{
|
||||
if (_secondColumnWidth != value)
|
||||
{
|
||||
_secondColumnWidth = value;
|
||||
_settings.SecondColumnWidth = value;
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public double ThirdColumnWidth
|
||||
{
|
||||
get => _thirdColumnWidth;
|
||||
set
|
||||
{
|
||||
if (_thirdColumnWidth != value)
|
||||
{
|
||||
_thirdColumnWidth = value;
|
||||
_settings.ThirdColumnWidth = value;
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public TextDocument OriginalDocument
|
||||
{
|
||||
get => _originalDocument;
|
||||
set
|
||||
{
|
||||
if (_originalDocument != value)
|
||||
{
|
||||
_originalDocument = value;
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public TextDocument LLMDocument
|
||||
{
|
||||
get => _llmDocument;
|
||||
set
|
||||
{
|
||||
if (_llmDocument != value)
|
||||
{
|
||||
_llmDocument = value;
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public TextDocument MergedDocument
|
||||
{
|
||||
get => _mergedDocument;
|
||||
set
|
||||
{
|
||||
if (_mergedDocument != value)
|
||||
{
|
||||
_mergedDocument = value;
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public CodeElement OriginalStructure
|
||||
{
|
||||
get => _originalStructure;
|
||||
set
|
||||
{
|
||||
if (_originalStructure != value)
|
||||
{
|
||||
_originalStructure = value;
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public CodeElement LLMStructure
|
||||
{
|
||||
get => _llmStructure;
|
||||
set
|
||||
{
|
||||
if (_llmStructure != value)
|
||||
{
|
||||
_llmStructure = value;
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public CodeElement MergedStructure
|
||||
{
|
||||
get => _mergedStructure;
|
||||
set
|
||||
{
|
||||
if (_mergedStructure != value)
|
||||
{
|
||||
_mergedStructure = value;
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public ObservableCollection<string> OriginalNamespaces
|
||||
{
|
||||
get => _originalNamespaces;
|
||||
set
|
||||
{
|
||||
if (_originalNamespaces != value)
|
||||
{
|
||||
_originalNamespaces = value;
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public ObservableCollection<string> OriginalClasses
|
||||
{
|
||||
get => _originalClasses;
|
||||
set
|
||||
{
|
||||
if (_originalClasses != value)
|
||||
{
|
||||
_originalClasses = value;
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public string SelectedLLMNamespace
|
||||
{
|
||||
get => _selectedLLMNamespace;
|
||||
set
|
||||
{
|
||||
if (_selectedLLMNamespace != value)
|
||||
{
|
||||
_selectedLLMNamespace = value;
|
||||
OnPropertyChanged();
|
||||
|
||||
// Actualizar namespace por defecto en CodeMerger
|
||||
if (!string.IsNullOrEmpty(value))
|
||||
_codeMerger.DefaultNamespace = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public string SelectedLLMClass
|
||||
{
|
||||
get => _selectedLLMClass;
|
||||
set
|
||||
{
|
||||
if (_selectedLLMClass != value)
|
||||
{
|
||||
_selectedLLMClass = value;
|
||||
OnPropertyChanged();
|
||||
|
||||
// Actualizar clase por defecto en CodeMerger
|
||||
if (!string.IsNullOrEmpty(value))
|
||||
_codeMerger.DefaultClass = value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Comandos
|
||||
|
||||
public ICommand PasteOriginalCommand { get; private set; }
|
||||
public ICommand CopyOriginalCommand { get; private set; }
|
||||
public ICommand PasteLLMCommand { get; private set; }
|
||||
public ICommand CopyLLMCommand { get; private set; }
|
||||
public ICommand CopyMergedCommand { get; private set; }
|
||||
public ICommand SearchCommand { get; private set; }
|
||||
public ICommand ClearAllCommand { get; private set; }
|
||||
public ICommand AnalyzeCodeCommand { get; private set; }
|
||||
public ICommand MergeCodeCommand { get; private set; }
|
||||
public ICommand ShowOriginalStructureCommand { get; private set; }
|
||||
public ICommand ShowLLMStructureCommand { get; private set; }
|
||||
public ICommand ShowMergedStructureCommand { get; private set; }
|
||||
|
||||
private void InitializeCommands()
|
||||
{
|
||||
PasteOriginalCommand = new RelayCommand(PasteOriginal);
|
||||
CopyOriginalCommand = new RelayCommand(CopyOriginal);
|
||||
PasteLLMCommand = new RelayCommand(PasteLLM);
|
||||
CopyLLMCommand = new RelayCommand(CopyLLM);
|
||||
CopyMergedCommand = new RelayCommand(CopyMerged);
|
||||
SearchCommand = new RelayCommand(Search);
|
||||
ClearAllCommand = new RelayCommand(ClearAll);
|
||||
AnalyzeCodeCommand = new RelayCommand(AnalyzeCode);
|
||||
MergeCodeCommand = new RelayCommand(MergeCode);
|
||||
ShowOriginalStructureCommand = new RelayCommand(ShowOriginalStructure);
|
||||
ShowLLMStructureCommand = new RelayCommand(ShowLLMStructure);
|
||||
ShowMergedStructureCommand = new RelayCommand(ShowMergedStructure);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Métodos de Comando
|
||||
|
||||
private void PasteOriginal()
|
||||
{
|
||||
if (Clipboard.ContainsText())
|
||||
{
|
||||
OriginalDocument.Text = Clipboard.GetText();
|
||||
LogInfo("Código original pegado desde el portapapeles");
|
||||
}
|
||||
}
|
||||
|
||||
private void CopyOriginal()
|
||||
{
|
||||
if (!string.IsNullOrEmpty(OriginalDocument.Text))
|
||||
{
|
||||
Clipboard.SetText(OriginalDocument.Text);
|
||||
LogInfo("Código original copiado al portapapeles");
|
||||
}
|
||||
}
|
||||
|
||||
private void PasteLLM()
|
||||
{
|
||||
if (Clipboard.ContainsText())
|
||||
{
|
||||
LLMDocument.Text = Clipboard.GetText();
|
||||
LogInfo("Código LLM pegado desde el portapapeles");
|
||||
}
|
||||
}
|
||||
|
||||
private void CopyLLM()
|
||||
{
|
||||
if (!string.IsNullOrEmpty(LLMDocument.Text))
|
||||
{
|
||||
Clipboard.SetText(LLMDocument.Text);
|
||||
LogInfo("Código LLM copiado al portapapeles");
|
||||
}
|
||||
}
|
||||
|
||||
private void CopyMerged()
|
||||
{
|
||||
if (!string.IsNullOrEmpty(MergedDocument.Text))
|
||||
{
|
||||
Clipboard.SetText(MergedDocument.Text);
|
||||
LogInfo("Código fusionado copiado al portapapeles");
|
||||
}
|
||||
}
|
||||
|
||||
private void Search()
|
||||
{
|
||||
if (string.IsNullOrEmpty(SearchText))
|
||||
return;
|
||||
|
||||
MessageBox.Show($"Función de búsqueda por implementar: {SearchText}");
|
||||
}
|
||||
|
||||
private void ClearAll()
|
||||
{
|
||||
OriginalDocument.Text = string.Empty;
|
||||
LLMDocument.Text = string.Empty;
|
||||
MergedDocument.Text = string.Empty;
|
||||
OriginalStructure = null;
|
||||
LLMStructure = null;
|
||||
MergedStructure = null;
|
||||
LogInfo("Todos los editores han sido limpiados");
|
||||
}
|
||||
|
||||
private void AnalyzeCode()
|
||||
{
|
||||
try
|
||||
{
|
||||
// Analizar código original
|
||||
if (!string.IsNullOrEmpty(OriginalDocument.Text))
|
||||
{
|
||||
OriginalStructure = _codeMerger.AnalyzeCode(OriginalDocument.Text);
|
||||
LogInfo("Código original analizado correctamente");
|
||||
|
||||
// Extraer namespaces y clases para las listas desplegables
|
||||
UpdateNamespacesAndClasses();
|
||||
}
|
||||
|
||||
// Analizar código LLM
|
||||
if (!string.IsNullOrEmpty(LLMDocument.Text))
|
||||
{
|
||||
LLMStructure = _codeMerger.AnalyzeCode(LLMDocument.Text);
|
||||
LogInfo("Código LLM analizado correctamente");
|
||||
}
|
||||
|
||||
// Analizar código fusionado (si existe)
|
||||
if (!string.IsNullOrEmpty(MergedDocument.Text))
|
||||
{
|
||||
MergedStructure = _codeMerger.AnalyzeCode(MergedDocument.Text);
|
||||
LogInfo("Código fusionado analizado correctamente");
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogError($"Error al analizar código: {ex.Message}");
|
||||
MessageBox.Show($"Error al analizar código: {ex.Message}", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
|
||||
}
|
||||
}
|
||||
|
||||
private void MergeCode()
|
||||
{
|
||||
try
|
||||
{
|
||||
if (string.IsNullOrEmpty(OriginalDocument.Text))
|
||||
{
|
||||
LogWarning("El código original está vacío");
|
||||
return;
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(LLMDocument.Text))
|
||||
{
|
||||
LogWarning("El código LLM está vacío");
|
||||
return;
|
||||
}
|
||||
|
||||
// Realizar el merge
|
||||
string mergedCode = _codeMerger.MergeCode(OriginalDocument.Text, LLMDocument.Text);
|
||||
MergedDocument.Text = mergedCode;
|
||||
|
||||
// Analizar el código fusionado
|
||||
MergedStructure = _codeMerger.AnalyzeCode(mergedCode);
|
||||
|
||||
// Mostrar log del merge
|
||||
string mergeLog = _codeMerger.GetLog();
|
||||
LogInfo("Código fusionado generado correctamente");
|
||||
LogMergeDetails(mergeLog);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogError($"Error al fusionar código: {ex.Message}");
|
||||
MessageBox.Show($"Error al fusionar código: {ex.Message}", "Error", MessageBoxButton.OK, MessageBoxImage.Error);
|
||||
}
|
||||
}
|
||||
|
||||
private void ShowOriginalStructure()
|
||||
{
|
||||
if (OriginalStructure == null)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(OriginalDocument.Text))
|
||||
{
|
||||
OriginalStructure = _codeMerger.AnalyzeCode(OriginalDocument.Text);
|
||||
}
|
||||
else
|
||||
{
|
||||
LogWarning("No hay código original para mostrar estructura");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
ShowStructureWindow("Estructura del Código Original", OriginalStructure);
|
||||
}
|
||||
|
||||
private void ShowLLMStructure()
|
||||
{
|
||||
if (LLMStructure == null)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(LLMDocument.Text))
|
||||
{
|
||||
LLMStructure = _codeMerger.AnalyzeCode(LLMDocument.Text);
|
||||
}
|
||||
else
|
||||
{
|
||||
LogWarning("No hay código LLM para mostrar estructura");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
ShowStructureWindow("Estructura del Código LLM", LLMStructure);
|
||||
}
|
||||
|
||||
private void ShowMergedStructure()
|
||||
{
|
||||
if (MergedStructure == null)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(MergedDocument.Text))
|
||||
{
|
||||
MergedStructure = _codeMerger.AnalyzeCode(MergedDocument.Text);
|
||||
}
|
||||
else
|
||||
{
|
||||
LogWarning("No hay código fusionado para mostrar estructura");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
ShowStructureWindow("Estructura del Código Fusionado", MergedStructure);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Métodos Auxiliares
|
||||
|
||||
private void UpdateNamespacesAndClasses()
|
||||
{
|
||||
OriginalNamespaces.Clear();
|
||||
OriginalClasses.Clear();
|
||||
|
||||
if (OriginalStructure != null)
|
||||
{
|
||||
// Extraer namespaces
|
||||
var namespaces = OriginalStructure.GetAllDescendantsOfType(CodeElement.ElementType.Namespace)
|
||||
.Where(n => !n.IsVirtualNamespace)
|
||||
.Select(n => n.Name)
|
||||
.ToList();
|
||||
|
||||
foreach (var ns in namespaces)
|
||||
{
|
||||
OriginalNamespaces.Add(ns);
|
||||
}
|
||||
|
||||
// Extraer clases
|
||||
var classes = OriginalStructure.GetAllDescendantsOfType(CodeElement.ElementType.Class)
|
||||
.Where(c => !c.IsVirtualClass)
|
||||
.Select(c => c.Name)
|
||||
.ToList();
|
||||
|
||||
foreach (var cls in classes)
|
||||
{
|
||||
OriginalClasses.Add(cls);
|
||||
}
|
||||
|
||||
// Seleccionar valores por defecto si hay opciones disponibles
|
||||
if (OriginalNamespaces.Count > 0 && string.IsNullOrEmpty(SelectedLLMNamespace))
|
||||
{
|
||||
SelectedLLMNamespace = OriginalNamespaces[0];
|
||||
}
|
||||
|
||||
if (OriginalClasses.Count > 0 && string.IsNullOrEmpty(SelectedLLMClass))
|
||||
{
|
||||
SelectedLLMClass = OriginalClasses[0];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void ShowStructureWindow(string title, CodeElement structure)
|
||||
{
|
||||
var structureWindow = new Controls.CodeStructureTreeView();
|
||||
structureWindow.Title = title;
|
||||
structureWindow.LoadCodeStructure(structure);
|
||||
structureWindow.Owner = Application.Current.MainWindow;
|
||||
structureWindow.Show();
|
||||
}
|
||||
|
||||
private void LogInfo(string message)
|
||||
{
|
||||
Application.Current.Dispatcher.Invoke(() =>
|
||||
{
|
||||
var logControl = (Application.Current.MainWindow as MainWindow)?.logControl;
|
||||
logControl?.LogInfo(message);
|
||||
});
|
||||
}
|
||||
|
||||
private void LogWarning(string message)
|
||||
{
|
||||
Application.Current.Dispatcher.Invoke(() =>
|
||||
{
|
||||
var logControl = (Application.Current.MainWindow as MainWindow)?.logControl;
|
||||
logControl?.LogWarning(message);
|
||||
});
|
||||
}
|
||||
|
||||
private void LogError(string message)
|
||||
{
|
||||
Application.Current.Dispatcher.Invoke(() =>
|
||||
{
|
||||
var logControl = (Application.Current.MainWindow as MainWindow)?.logControl;
|
||||
logControl?.LogError(message);
|
||||
});
|
||||
}
|
||||
|
||||
private void LogMergeDetails(string mergeLog)
|
||||
{
|
||||
Application.Current.Dispatcher.Invoke(() =>
|
||||
{
|
||||
var logControl = (Application.Current.MainWindow as MainWindow)?.logControl;
|
||||
logControl?.LogMergeDetails(mergeLog);
|
||||
});
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region INotifyPropertyChanged
|
||||
|
||||
public event PropertyChangedEventHandler PropertyChanged;
|
||||
|
||||
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
|
||||
{
|
||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue