Add project files.

This commit is contained in:
Miguel 2025-02-28 14:43:44 +01:00
parent 0e8e1640c3
commit 7284f9b00e
17 changed files with 3196 additions and 0 deletions

9
App.xaml Normal file
View File

@ -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>

13
App.xaml.cs Normal file
View File

@ -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
{
}

10
AssemblyInfo.cs Normal file
View File

@ -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)
)]

1353
CodeMerger.cs Normal file

File diff suppressed because it is too large Load Diff

18
CodeMergerNG.csproj Normal file
View File

@ -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>

25
CodeMergerNG.sln Normal file
View File

@ -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

View File

@ -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>

View File

@ -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();
}
}
}

View File

@ -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>

View File

@ -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}");
}
}
}
}
}

View File

@ -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>

View File

@ -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}");
}
}
}
}

136
MainWindow.xaml Normal file
View File

@ -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>

110
MainWindow.xaml.cs Normal file
View File

@ -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 == '_';
}
}
}

205
Settings.cs Normal file
View File

@ -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
}
}

View File

@ -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();
}
}
}";
}
}

View File

@ -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
}
}