35 Commits

Author SHA1 Message Date
fierke 6c1d0e7a70 [chore:] initial rs pdf page builder 2026-05-13 14:26:30 +02:00
fierke a72722745b [chore:] running sheet parameters in settings 2026-05-11 17:44:38 +02:00
fierke bd565960ba [chore:] running sheet creation call 2026-05-11 17:42:14 +02:00
fierke 58fed451a1 [chore:] more running sheet frontend 2026-05-11 17:41:57 +02:00
fierke ddea77bf3f [feat:] running sheets frontend 2026-05-11 11:13:14 +02:00
fierke 0e4da1b150 [fix:] calling combinging methods used initial string-id we removed years ago 👀 2026-05-11 10:24:15 +02:00
fierke 7fe45ce4e3 [feat:] csv-divider-buttons 2026-05-06 07:07:41 +02:00
fierke a46539c3cc [fix:] wrong sorting of imported address sets 2026-05-06 06:35:23 +02:00
fierke 72a5630db1 [chore:] enable shortener usage 2026-05-06 06:34:48 +02:00
fierke 7697edac5e [fix:] shorten-button was enabled too early 2026-05-06 06:33:55 +02:00
fierke 028b9793db [chore:] basic address shortener 2026-05-06 06:33:37 +02:00
fierke 2c5f2ed48b [feat:] (opt) delete original sets after merging 2026-05-03 09:21:57 +02:00
fierke f0598a39ec [chore:] listbox item type is no string anymore (hopefully I tested everything?) 2026-05-02 16:27:43 +02:00
fierke f9e419d573 [chore:] cleanup 2026-05-02 16:20:18 +02:00
fierke 56233e6f5c [chore:] tiny improvements for address check 2026-05-02 15:39:42 +02:00
fierke 488830cdad [fix:] multiple little fixed for the combining methods 2026-05-02 12:56:27 +02:00
fierke 52fbefb803 [chore:] added missing help- and about-links 2026-04-29 14:58:53 +02:00
fierke c5aabc2a02 [fix:] window focus 2026-04-28 11:00:51 +02:00
fierke 4a9f9a1ff0 [fix:] startup location 2026-04-28 11:00:40 +02:00
fierke fab14eb107 [fix:] naming window for rest-set not visible if not necessary 2026-04-28 11:00:26 +02:00
fierke 2dcc1bd657 Merge remote-tracking branch 'origin/main' 2026-04-28 10:54:09 +02:00
fierke 3767fece48 [fix:] make customer delete button working 2026-04-28 10:53:53 +02:00
fierke 842608e96f Merge remote-tracking branch 'origin/main'
# Conflicts:
#	MainWindow.axaml
#	MainWindow.axaml.cs
2026-04-27 17:39:19 +02:00
fierke d9ee3e2fc9 [chore:] deleting address sets 2026-04-27 17:39:08 +02:00
fierke 80d1498cc7 [chore:] if it happens it happens 2026-04-27 13:07:22 +02:00
fierke de2f453553 [chore:] editor window margins 2026-04-27 13:07:01 +02:00
fierke 7e168c4d0f [fix:] line breaks in editor window now possible 2026-04-27 13:06:29 +02:00
fierke 9becedbd97 [chore:] better file- and folder creating 2026-04-27 09:04:16 +02:00
fierke 16982c3d95 [fix:] adding ".md" if not added by user (wiki) 2026-04-27 08:49:53 +02:00
fierke 93771dd110 [fix:] trying to fix one-item-too-much-issue 2026-04-27 08:49:27 +02:00
fierke 3e14731429 Merge pull request 'export-margin-options implementation' (#33) from export-margin-options into main
Reviewed-on: #33
2026-04-23 14:22:58 +00:00
fierke df6c187a00 [chore:] combining export margin options gui with settings and PdfBuilder.cs 2026-04-23 12:30:35 +02:00
fierke 98b5198f6f [chore:] added smallFontSize and fixed usage of fontSize and smallFontSize 2026-04-23 09:03:25 +02:00
fierke 1a6459d60b [chore:] grid visibility (calc man :D) 2026-04-23 09:03:00 +02:00
fierke 43e6c35beb [gui:] export margin options gui 2026-04-23 09:02:45 +02:00
16 changed files with 797 additions and 337 deletions
+22
View File
@@ -60,6 +60,11 @@ public class KasAddressList //Address-Set
var id = listItemName.Split(" - ")[0]; var id = listItemName.Split(" - ")[0];
return int.Parse(id); return int.Parse(id);
} }
public override string ToString()
{
return Name + " (" + KasPersons.Count + " Einträge)";
}
} }
public class KasPerson public class KasPerson
@@ -188,6 +193,18 @@ public class KasPerson
return highest + base_id + 1; return highest + base_id + 1;
} }
public override string ToString()
{
if (refsid != null && refsid != 0)
{
return refsid + " - " + name;
}
else
{
return id + " - " + name;
}
}
} }
public class KasPersonError public class KasPersonError
@@ -212,4 +229,9 @@ public class KasPersonError
return output; return output;
} }
public string ToString(KasPerson person)
{
return "ID:"+person.id + "; Name: " +person.name +"; Errors: " + GetString();
}
} }
+34 -6
View File
@@ -10,6 +10,7 @@ public class Settings
public static Settings _instance = new(); public static Settings _instance = new();
public AddressSets addressSets = new(); public AddressSets addressSets = new();
public Customers customers = new(); public Customers customers = new();
public PdfExportSettings pdfExport { get; set; } = new();
public string settingsPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), public string settingsPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData),
"logofclient", "config.json"); "logofclient", "config.json");
@@ -52,6 +53,28 @@ public class Settings
} }
} }
public class PdfExportSettings
{
public double cellPaddingTopMm { get; set; } = 5;
public double cellPaddingBottomMm { get; set; } = 5;
public double cellPaddingLeftMm { get; set; } = 5;
public double cellPaddingRightMm { get; set; } = 5;
public double pageMarginTopMm { get; set; } = 0;
public double pageMarginBottomMm { get; set; } = 0;
public double pageMarginLeftMm { get; set; } = 0;
public double pageMarginRightMm { get; set; } = 0;
public int rowsPerPage { get; set; } = 7;
public int columnsPerPage { get; set; } = 3;
public double fontSize { get; set; } = 9;
public double smallFontSize { get; set; } = 6;
public bool exportRunningSheets { get; set; } = true;
public double rsNumGrouped { get; set; } = 25;
public double rsPlzStartpoint { get; set; } = 2;
}
public class Global public class Global
{ {
public static Global _instance; public static Global _instance;
@@ -115,7 +138,7 @@ public class Global
public class Customers public class Customers
{ {
public List<Customer> customers = new(); public List<Customer> customers = new();
public int current { get; set; } = 0; public Customer current { get; set; } = null;
} }
public class Customer public class Customer
@@ -130,6 +153,11 @@ public class Customer
ID = highestID + 1; ID = highestID + 1;
} }
public override string ToString()
{
return name;
}
public string name { get; set; } = ""; public string name { get; set; } = "";
public string description { get; set; } = ""; public string description { get; set; } = "";
public string sender_address { get; set; } = ""; public string sender_address { get; set; } = "";
@@ -138,11 +166,11 @@ public class Customer
public int ID { get; } public int ID { get; }
public static int GetIDByCustomerListItem(string item_content) // public static int GetIDByCustomerListItem(string item_content)
{ // {
var id = item_content.Split(" - ")[0]; // var id = item_content.Split(" - ")[0];
return int.Parse(id); // return int.Parse(id);
} // }
} }
public class AddressSets public class AddressSets
+126 -40
View File
@@ -28,7 +28,7 @@
<Label FontSize="20" Content="Addressverwaltung" VerticalContentAlignment="Center" /> <Label FontSize="20" Content="Addressverwaltung" VerticalContentAlignment="Center" />
</StackPanel> </StackPanel>
</TabItem.Header> </TabItem.Header>
<Grid RowDefinitions="2*,*,*"> <Grid RowDefinitions="3*,80,2*">
<Grid ColumnDefinitions="*,*" Grid.Row="0"> <Grid ColumnDefinitions="*,*" Grid.Row="0">
<!-- Kunden --> <!-- Kunden -->
<Grid Margin="30,30,10,30"> <Grid Margin="30,30,10,30">
@@ -78,6 +78,14 @@
</StackPanel> </StackPanel>
</MenuItem.Header> </MenuItem.Header>
</MenuItem> </MenuItem>
<MenuItem x:Name="MnIAdSetDelete" Click="MnIAdSetRename_OnClick" IsEnabled="False">
<MenuItem.Header>
<StackPanel Orientation="Horizontal">
<LucideIcon Kind="Trash" Width="12" Height="12" Size="12" />
<Label Content="Löschen" VerticalContentAlignment="Center" />
</StackPanel>
</MenuItem.Header>
</MenuItem>
</ContextMenu> </ContextMenu>
</ListBox.ContextMenu> </ListBox.ContextMenu>
</ListBox> </ListBox>
@@ -91,23 +99,10 @@
</Button> </Button>
</Grid> </Grid>
</Grid> </Grid>
<!-- <Grid Grid.Row="0"> --> <!-- <Grid ColumnDefinitions="*,*,*" Grid.Row="1"> -->
<!-- <StackPanel Orientation="Horizontal" VerticalAlignment="Center" --> <StackPanel Grid.Row="1" Orientation="Horizontal" Spacing="10" HorizontalAlignment="Center"
<!-- HorizontalAlignment="Center"> -->
<!-- <TextBox x:Name="TbFilename" Watermark="Dateipfad" Width="400" -->
<!-- VerticalContentAlignment="Center" /> -->
<!-- <Button x:Name="BtnChooseFile" Margin="10,0,0,0" Click="BtnChooseFile_OnClick"> -->
<!-- <StackPanel Orientation="Horizontal"> -->
<!-- <LucideIcon Kind="FolderOpen" Width="16" Height="16" Size="16" /> -->
<!-- <Label Content="Öffnen" VerticalContentAlignment="Center" /> -->
<!-- </StackPanel> -->
<!-- </Button> -->
<!-- </StackPanel> -->
<!-- </Grid> -->
<Grid Grid.ColumnDefinitions="*,*" Grid.Row="1">
<StackPanel Grid.Column="0" Width="250" Orientation="Vertical" HorizontalAlignment="Right"
Margin="0,0,5,0"> Margin="0,0,5,0">
<Button HorizontalAlignment="Stretch" HorizontalContentAlignment="Center" <Button Width="250" HorizontalContentAlignment="Center"
Margin="0,0,0,10" IsEnabled="False" Margin="0,0,0,10" IsEnabled="False"
x:Name="BtnCheck" Click="BtnCheck_OnClick"> x:Name="BtnCheck" Click="BtnCheck_OnClick">
<StackPanel Orientation="Horizontal"> <StackPanel Orientation="Horizontal">
@@ -116,7 +111,7 @@
FontWeight="Bold" /> FontWeight="Bold" />
</StackPanel> </StackPanel>
</Button> </Button>
<Button HorizontalAlignment="Stretch" IsEnabled="False" <Button Width="250" IsEnabled="False"
HorizontalContentAlignment="Center" HorizontalContentAlignment="Center"
Click="BtnCombine_OnClick" x:Name="BtnCombine" Click="BtnCombine_OnClick" x:Name="BtnCombine"
Margin="0,0,0,10"> Margin="0,0,0,10">
@@ -126,19 +121,7 @@
FontWeight="Bold" /> FontWeight="Bold" />
</StackPanel> </StackPanel>
</Button> </Button>
<Button HorizontalAlignment="Stretch" IsEnabled="False" <Button Width="250" IsEnabled="False" Click="BtnShorten_OnClick"
HorizontalContentAlignment="Center" x:Name="BtnRepair"
Margin="0,0,0,10">
<StackPanel Orientation="Horizontal">
<LucideIcon Kind="Hammer" Width="36" Height="36" />
<Label Content="Reparieren" VerticalContentAlignment="Center" FontSize="15"
FontWeight="Bold" />
</StackPanel>
</Button>
</StackPanel>
<StackPanel Grid.Column="1" Width="250" Orientation="Vertical" HorizontalAlignment="Left"
Margin="5,0,0,0">
<Button HorizontalAlignment="Stretch" IsEnabled="False"
HorizontalContentAlignment="Center" x:Name="BtnShorten" HorizontalContentAlignment="Center" x:Name="BtnShorten"
Margin="0,0,0,10"> Margin="0,0,0,10">
<StackPanel Orientation="Horizontal"> <StackPanel Orientation="Horizontal">
@@ -147,7 +130,7 @@
FontWeight="Bold" /> FontWeight="Bold" />
</StackPanel> </StackPanel>
</Button> </Button>
<Button HorizontalAlignment="Stretch" IsEnabled="False" <Button Width="250" IsEnabled="False"
Click="BtnGenerateLabels_OnClick" Click="BtnGenerateLabels_OnClick"
HorizontalContentAlignment="Center" x:Name="BtnGenerateLabels" HorizontalContentAlignment="Center" x:Name="BtnGenerateLabels"
Margin="0,0,0,10"> Margin="0,0,0,10">
@@ -158,8 +141,17 @@
FontWeight="Bold" /> FontWeight="Bold" />
</StackPanel> </StackPanel>
</Button> </Button>
<Button Width="250" IsEnabled="False"
HorizontalContentAlignment="Center" x:Name="BtnRepair"
Margin="0,0,0,10">
<StackPanel Orientation="Horizontal">
<LucideIcon Kind="Hammer" Width="36" Height="36" />
<Label Content="Reparieren" VerticalContentAlignment="Center" FontSize="15"
FontWeight="Bold" />
</StackPanel>
</Button>
</StackPanel> </StackPanel>
</Grid> <!-- </Grid> -->
<Grid Grid.Row="2" Margin="20" IsVisible="True" x:Name="GrdCalcMan"> <Grid Grid.Row="2" Margin="20" IsVisible="True" x:Name="GrdCalcMan">
<Image Source="assets/calc_man.png" VerticalAlignment="Center" HorizontalAlignment="Center" /> <Image Source="assets/calc_man.png" VerticalAlignment="Center" HorizontalAlignment="Center" />
</Grid> </Grid>
@@ -228,10 +220,92 @@
</StackPanel> </StackPanel>
<Label FontSize="9" Content="Nur Elemente, die NICHT doppelt sind" /> <Label FontSize="9" Content="Nur Elemente, die NICHT doppelt sind" />
</StackPanel> </StackPanel>
</Button> </Button>
</StackPanel> </StackPanel>
<CheckBox HorizontalAlignment="Center" x:Name="CbMergeExportUnmerged" IsChecked="False">Speichere Unverarbeitete in neuem Verteiler</CheckBox> <StackPanel Orientation="Horizontal" HorizontalAlignment="Center" Spacing="50">
<StackPanel Orientation="Vertical" >
<RadioButton Content="Vergleiche nach refsid" IsChecked="True" x:Name="RbComprefsid"></RadioButton>
<RadioButton Content="Vergleiche nach finaler Adresse" IsChecked="False" x:Name="RbCompfinAd"></RadioButton>
</StackPanel>
<StackPanel Orientation="Vertical">
<CheckBox HorizontalAlignment="Left" x:Name="CbMergeExportUnmerged" IsChecked="False">Speichere Unverarbeitete in neuem Verteiler</CheckBox>
<CheckBox HorizontalAlignment="Left" x:Name="CbMergeDeleteOld" IsChecked="False">Lösche ursprüngliche Sets</CheckBox>
</StackPanel>
</StackPanel>
</StackPanel>
</Grid>
<Grid Grid.Row="2" Margin="20" ColumnDefinitions="*,5*,*" IsVisible="False" x:Name="GrdExportMarginOptions">
<StackPanel Grid.Column="1" Orientation="Vertical" Spacing="20">
<Grid ColumnDefinitions="*,*,*" ColumnSpacing="20">
<StackPanel Orientation="Vertical" Spacing="10">
<Grid ColumnDefinitions="*,*">
<Label Grid.Column="0" Content="Zellenrand oben (mm)"></Label>
<NumericUpDown Grid.Column="1" x:Name="NudExpMargCellPaddingTop" Minimum="0" Maximum="20" Value="5"></NumericUpDown>
</Grid>
<Grid ColumnDefinitions="*,*">
<Label Grid.Column="0" Content="Zellenrand unten (mm)"></Label>
<NumericUpDown Grid.Column="1" x:Name="NudExpMargCellPaddingBot" Minimum="0" Maximum="20" Value="5"></NumericUpDown>
</Grid>
<Grid ColumnDefinitions="*,*">
<Label Grid.Column="0" Content="Zellenrand links (mm)"></Label>
<NumericUpDown Grid.Column="1" x:Name="NudExpMargCellPaddingLeft" Minimum="0" Maximum="20" Value="5"></NumericUpDown>
</Grid>
<Grid ColumnDefinitions="*,*">
<Label Grid.Column="0" Content="Zellenrand rechts (mm)"></Label>
<NumericUpDown Grid.Column="1" x:Name="NudExpMargCellPaddingRight" Minimum="0" Maximum="20" Value="5"></NumericUpDown>
</Grid>
<CheckBox Content="Laufzettel erstellen" x:Name="CbExpRnsEnable"></CheckBox>
</StackPanel>
<StackPanel Grid.Column="1" Orientation="Vertical" Spacing="10">
<Grid ColumnDefinitions="*,*">
<Label Content="Zellenabstand oben"></Label>
<NumericUpDown Grid.Column="1" x:Name="TbExpMargMarginTop" Minimum="0" Maximum="20" Value="0"></NumericUpDown>
</Grid>
<Grid ColumnDefinitions="*,*">
<Label Content="Zellenabstand unten"></Label>
<NumericUpDown Grid.Column="1" x:Name="TbExpMargMarginBottom" Minimum="0" Maximum="20" Value="0"></NumericUpDown>
</Grid>
<Grid ColumnDefinitions="*,*">
<Label Content="Zellenabstand rechts"></Label>
<NumericUpDown Grid.Column="1" x:Name="TbExpMargMarginRight" Minimum="0" Maximum="20" Value="0"></NumericUpDown>
</Grid>
<Grid ColumnDefinitions="*,*">
<Label Content="Zellenabstand links"></Label>
<NumericUpDown Grid.Column="1" x:Name="TbExpMargMarginLeft" Minimum="0" Maximum="20" Value="0"></NumericUpDown>
</Grid>
<Grid ColumnDefinitions="*,*">
<Label Grid.Column="0" Content="Anzahl gruppierter Sendungen"></Label>
<NumericUpDown Grid.Column="1" x:Name="NudExpRnsPlzcount" Minimum="1" Maximum="10000" Value="25"></NumericUpDown>
</Grid>
</StackPanel>
<StackPanel Grid.Column="2" Orientation="Vertical" Spacing="10">
<Grid ColumnDefinitions="*,*">
<Label Content="Zeilen pro Seite"></Label>
<NumericUpDown Grid.Column="1" x:Name="TbExpMargRowsPerPage" Minimum="1" Maximum="10" Value="7"></NumericUpDown>
</Grid>
<Grid ColumnDefinitions="*,*">
<Label Grid.Column="0" Content="Spalten pro Seite"></Label>
<NumericUpDown Grid.Column="1" x:Name="NudExpMargColumnsPerPage" Minimum="1" Maximum="8" Value="3"></NumericUpDown>
</Grid>
<Grid ColumnDefinitions="*,*">
<Label Grid.Column="0" Content="Schriftgröße (groß)"></Label>
<NumericUpDown Grid.Column="1" x:Name="NudExpMargFontSize" Minimum="5" Maximum="30" Value="9"></NumericUpDown>
</Grid>
<Grid ColumnDefinitions="*,*">
<Label Grid.Column="0" Content="Schriftgröße (klein)"></Label>
<NumericUpDown Grid.Column="1" x:Name="NudExpMargSmallFontSize" Minimum="3" Maximum="30" Value="6"></NumericUpDown>
</Grid>
<Grid ColumnDefinitions="*,*">
<Label Grid.Column="0" Content="Gruppierpunkt"></Label>
<NumericUpDown Grid.Column="1" x:Name="NudExpRnsPlzStartpoint" Minimum="1" Maximum="10" Value="2"></NumericUpDown>
</Grid>
</StackPanel>
</Grid>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
<Button Content="Start" Click="BtnStartGenerateLabels_OnClick"></Button>
</StackPanel>
</StackPanel> </StackPanel>
</Grid> </Grid>
</Grid> </Grid>
@@ -270,8 +344,12 @@
<Grid ColumnDefinitions="300,*"> <Grid ColumnDefinitions="300,*">
<Border Grid.Column="0" Background="#FFF" BorderBrush="#DDD" BorderThickness="0,0,1,0"> <Border Grid.Column="0" Background="#FFF" BorderBrush="#DDD" BorderThickness="0,0,1,0">
<StackPanel> <StackPanel>
<Button Content="+ Hinzufügen" Margin="10" x:Name="BtnWikiAddFile" <StackPanel Spacing="10" Orientation="Horizontal" Margin="10">
Click="BtnWikiAddFile_OnClick" /> <Button Content="+ Datei" x:Name="BtnWikiAddFile"
Click="BtnWikiAddFile_OnClick" />
<Button Content="+ Ordner" x:Name="BtnWikiAddFolder"
Click="BtnWikiAddFolder_OnClick" />
</StackPanel>
<ScrollViewer HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto"> <ScrollViewer HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto">
<TreeView Name="NavTree" Margin="10" /> <TreeView Name="NavTree" Margin="10" />
</ScrollViewer> </ScrollViewer>
@@ -416,12 +494,20 @@
TextChanged="TbSettingsCustomerSenderAddress_OnTextChanged" TextChanged="TbSettingsCustomerSenderAddress_OnTextChanged"
x:Name="TbSettingsCustomerSenderAddress" /> x:Name="TbSettingsCustomerSenderAddress" />
</Grid> </Grid>
<Grid ColumnDefinitions="150,*"> <Grid ColumnDefinitions="150,*,Auto">
<Label Content="CSV-Trennzeichen" /> <Label Content="CSV-Trennzeichen" />
<TextBox Grid.Column="1" Watermark="," <TextBox Grid.Column="1" Watermark=","
HorizontalAlignment="Stretch" HorizontalAlignment="Stretch" Margin="0,0,5,0"
TextChanged="TbSettingsCustomerCsvSeparator_OnTextChanged" TextChanged="TbSettingsCustomerCsvSeparator_OnTextChanged"
x:Name="TbSettingsCustomerCsvSeparator" /> x:Name="TbSettingsCustomerCsvSeparator" />
<StackPanel Grid.Column="2" Orientation="Horizontal" Spacing="5">
<Button Click="ChangeCSVDivider" Content=","></Button>
<Button Click="ChangeCSVDivider" Content=";"></Button>
<Button Click="ChangeCSVDivider" Content="TAB"></Button>
<Button Click="ChangeCSVDivider" Content="|"></Button>
<Button Click="ChangeCSVDivider" Content="SPACE"></Button>
<Button Click="ChangeCSVDivider" Content=":"></Button>
</StackPanel>
</Grid> </Grid>
<Grid ColumnDefinitions="150,*"> <Grid ColumnDefinitions="150,*">
<Label Content="Address-Patch-Info" /> <Label Content="Address-Patch-Info" />
@@ -448,7 +534,7 @@
VerticalContentAlignment="Center" /> VerticalContentAlignment="Center" />
</StackPanel> </StackPanel>
</Button> </Button>
<Button Background="#99963434" HorizontalAlignment="Stretch" <Button Background="#99963434" HorizontalAlignment="Stretch" x:Name="BtnDeleteCustomer" Click="BtnDeleteCustomer_OnClick"
HorizontalContentAlignment="Center"> HorizontalContentAlignment="Center">
<StackPanel Orientation="Horizontal"> <StackPanel Orientation="Horizontal">
<LucideIcon Kind="Trash" Width="16" Height="16" Size="16" /> <LucideIcon Kind="Trash" Width="16" Height="16" Size="16" />
+346 -142
View File
@@ -5,6 +5,7 @@ using System.IO;
using System.Threading.Tasks; using System.Threading.Tasks;
using Avalonia.Controls; using Avalonia.Controls;
using Avalonia.Interactivity; using Avalonia.Interactivity;
using Avalonia.Controls.Primitives;
using Avalonia.Platform.Storage; using Avalonia.Platform.Storage;
using Logof_Client.Wiki; using Logof_Client.Wiki;
@@ -33,6 +34,8 @@ public partial class MainWindow : Window
WindowState = WindowState.Maximized; WindowState = WindowState.Maximized;
Global.Load(); Global.Load();
Settings.Load(); Settings.Load();
LoadPdfExportOptions();
HookPdfExportOptionEvents();
RefreshCountryView(); RefreshCountryView();
@@ -93,10 +96,31 @@ public partial class MainWindow : Window
new ResultWindow(result, addresSetID).Show(); new ResultWindow(result, addresSetID).Show();
Settings.Save();
//await MessageBox.Show(_instance, $"{result.Count} Einträge fehlerhaft.", "Fertig"); //await MessageBox.Show(_instance, $"{result.Count} Einträge fehlerhaft.", "Fertig");
} }
private async void StartAddressShortener(KasAddressList set)
{
//var addresses = DataImport.ImportKasAddressList(path); // Ihr Code hier
var progressWindow = new ProgressWindow();
progressWindow.Show(_instance);
var processor = new AddressShortener(progressWindow);
await processor.Perform(set);
// foreach (var item in result)
// {
// }
progressWindow.Close();
Settings.Save();
//await MessageBox.Show(_instance, $"{result.Count} Einträge fehlerhaft.", "Fertig");
}
// private async void StartAddressRepair(Uri path) // private async void StartAddressRepair(Uri path)
// { // {
// var addresses = DataImport.ImportKasAddressList(path); // Ihr Code hier // var addresses = DataImport.ImportKasAddressList(path); // Ihr Code hier
@@ -122,12 +146,34 @@ public partial class MainWindow : Window
private void MnuAbout_OnClick(object? sender, RoutedEventArgs e) private void MnuAbout_OnClick(object? sender, RoutedEventArgs e)
{ {
throw new NotImplementedException(); try
{
Process.Start(new ProcessStartInfo
{
FileName = "https://mypapercloud.de/logof/",
UseShellExecute = true // Wichtig für Plattformübergreifendes Öffnen
});
}
catch (Exception ex)
{
Console.WriteLine($"Fehler beim Öffnen des Links: {ex.Message}");
}
} }
private void MnuHelp_OnClick(object? sender, RoutedEventArgs e) private void MnuHelp_OnClick(object? sender, RoutedEventArgs e)
{ {
throw new NotImplementedException(); try
{
Process.Start(new ProcessStartInfo
{
FileName = "https://mypapercloud.de/logof/wiki/",
UseShellExecute = true // Wichtig für Plattformübergreifendes Öffnen
});
}
catch (Exception ex)
{
Console.WriteLine($"Fehler beim Öffnen des Links: {ex.Message}");
}
} }
private void MnuGit_OnClick(object? sender, RoutedEventArgs e) private void MnuGit_OnClick(object? sender, RoutedEventArgs e)
@@ -146,27 +192,6 @@ public partial class MainWindow : Window
} }
} }
private async void BtnChooseFile_OnClick(object? sender, RoutedEventArgs e)
{
var topLevel = GetTopLevel(this);
var file = await topLevel!.StorageProvider.OpenFilePickerAsync(new FilePickerOpenOptions
{
Title = "KAS-CSV-Datei auswählen",
AllowMultiple = false,
FileTypeFilter = new[]
{
new FilePickerFileType(".csv-Datei")
{
Patterns = new[] { "*.csv" }
}
}
});
if (file == null) return;
//TbFilename.Text = file[0].Path.ToString();
filePath = file[0].Path;
}
private void BtnCheck_OnClick(object? sender, RoutedEventArgs e) private void BtnCheck_OnClick(object? sender, RoutedEventArgs e)
{ {
MakeCalcManVisible(); MakeCalcManVisible();
@@ -176,56 +201,24 @@ public partial class MainWindow : Window
return; return;
} }
StartAddressCheck(KasAddressList.GetIDByAddressSetListItem(LstCustomerAdressSets.SelectedItem.ToString())); StartAddressCheck(((KasAddressList)LstCustomerAdressSets.SelectedItem).ID);
} }
private void BtnCombine_OnClick(object? sender, RoutedEventArgs e) private void BtnCombine_OnClick(object? sender, RoutedEventArgs e)
{ {
GrdCalcMan.IsVisible = false; GrdCalcMan.IsVisible = false;
GrdCombineTypes.IsVisible = true; GrdCombineTypes.IsVisible = true;
GrdExportMarginOptions.IsVisible = false;
} }
private void MakeCalcManVisible() private void MakeCalcManVisible()
{ {
GrdCalcMan.IsVisible = true; GrdCalcMan.IsVisible = true;
GrdCombineTypes.IsVisible = false; GrdCombineTypes.IsVisible = false;
GrdExportMarginOptions.IsVisible = false;
} }
private async void StartCombine(Uri path)
{
MakeCalcManVisible();
var addresses = await DataImport.ImportKasAddressList(path);
var progressWindow = new ProgressWindow();
var address_list = new List<KasAddressList> { addresses.Item2 };
var topLevel = GetTopLevel(this);
var file = await topLevel!.StorageProvider.OpenFilePickerAsync(new FilePickerOpenOptions
{
Title = "Weitere KAS-CSV-Dateien auswählen",
AllowMultiple = true,
FileTypeFilter = new[]
{
new FilePickerFileType(".csv-Dateien")
{
Patterns = new[] { "*.csv" }
//Patterns = new[] { "*" }
}
}
});
if (file == null) return;
//filePath = file[0].Path;
foreach (var f in file) address_list.Add((await DataImport.ImportKasAddressList(f.Path)).Item2);
progressWindow.Show(_instance);
var processor = new CombineAddresses(progressWindow);
//var result = await processor.Perform(address_list);
progressWindow.Close();
}
private async void NavTree_SelectionChanged(object? sender, SelectionChangedEventArgs e) private async void NavTree_SelectionChanged(object? sender, SelectionChangedEventArgs e)
{ {
@@ -255,12 +248,20 @@ public partial class MainWindow : Window
} }
} }
public void PopulateNavTree() public void PopulateNavTree(string? expandToPath = null, string? selectPath = null)
{ {
var roots = _wikiService.GetRootItems(); var roots = _wikiService.GetRootItems();
var nodes = new List<TreeViewItem>(); var nodes = new List<TreeViewItem>();
foreach (var r in roots) nodes.Add(BuildNode(r)); foreach (var r in roots) nodes.Add(BuildNode(r));
NavTree.ItemsSource = nodes; NavTree.ItemsSource = nodes;
if (!string.IsNullOrWhiteSpace(expandToPath))
ExpandAndFindNode(nodes, expandToPath, out _);
if (!string.IsNullOrWhiteSpace(selectPath) &&
ExpandAndFindNode(nodes, selectPath, out var selectedNode) &&
selectedNode != null)
NavTree.SelectedItem = selectedNode;
} }
private TreeViewItem BuildNode(WikiItem item) private TreeViewItem BuildNode(WikiItem item)
@@ -273,6 +274,63 @@ public partial class MainWindow : Window
return node; return node;
} }
private string GetSelectedWikiTargetDirectory()
{
var wikiRoot = Global._instance.wiki_storage_path;
if (NavTree.SelectedItem is TreeViewItem treeItem && treeItem.Tag is WikiItem selectedItem)
{
if (selectedItem.IsFolder) return selectedItem.Path;
var parentDir = Path.GetDirectoryName(selectedItem.Path);
if (!string.IsNullOrWhiteSpace(parentDir)) return parentDir;
}
return wikiRoot;
}
private static bool PathsEqual(string left, string right)
{
var normalizedLeft = Path.GetFullPath(left)
.TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar);
var normalizedRight = Path.GetFullPath(right)
.TrimEnd(Path.DirectorySeparatorChar, Path.AltDirectorySeparatorChar);
var comparison = OperatingSystem.IsWindows()
? StringComparison.OrdinalIgnoreCase
: StringComparison.Ordinal;
return string.Equals(normalizedLeft, normalizedRight, comparison);
}
private bool ExpandAndFindNode(IEnumerable<TreeViewItem> nodes, string targetPath, out TreeViewItem? foundNode)
{
foreach (var node in nodes)
if (TryExpandToPath(node, targetPath, out foundNode))
return true;
foundNode = null;
return false;
}
private bool TryExpandToPath(TreeViewItem node, string targetPath, out TreeViewItem? foundNode)
{
if (node.Tag is WikiItem item && PathsEqual(item.Path, targetPath))
{
foundNode = node;
return true;
}
foreach (var childRaw in node.Items)
if (childRaw is TreeViewItem childNode &&
TryExpandToPath(childNode, targetPath, out foundNode))
{
node.IsExpanded = true;
return true;
}
foundNode = null;
return false;
}
private void OpenFolderButton_Click(object? sender, RoutedEventArgs e) private void OpenFolderButton_Click(object? sender, RoutedEventArgs e)
{ {
var path = Global._instance.wiki_storage_path; var path = Global._instance.wiki_storage_path;
@@ -345,48 +403,16 @@ public partial class MainWindow : Window
MessageBox.Show(this, "Bitte starten Sie das Programm neu, um die Änderungen wirksam zu machen.", "Achtung"); MessageBox.Show(this, "Bitte starten Sie das Programm neu, um die Änderungen wirksam zu machen.", "Achtung");
} }
private async Task<string> OpenSettingsSaveAsDialog()
{
var settingsFileName = "KAS-Adress-Liste";
try
{
var filePicker = new SaveFileDialog
{
Title = "Datei speichern...",
InitialFileName = $"{settingsFileName}.csv",
DefaultExtension = ".csv",
Filters = new List<FileDialogFilter>
{
new() { Name = "CSV-Datei", Extensions = { "csv" } }
}
};
var settingsSavePath = await filePicker.ShowAsync(this); private async void StartCombine(List<KasAddressList> address_lists, int owner_id, string type, CombineAddresses.CombineType comb_type)
if (settingsSavePath == null)
{
}
return settingsSavePath;
//SettingsManager.Save(settingsSavePath);
//Logger.Log("Settings saved at " + settingsSavePath);
}
catch (Exception ex)
{
//Logger.Log("Saving file not successful: " + ex.Message, Logger.LogType.Error);
await MessageBox.Show(this, ex.Message, "Fehler beim Speichern der Datei");
return null;
}
}
private async void StartCombine(List<KasAddressList> address_lists, int owner_id, string type)
{ {
var progressWindow = new ProgressWindow(); var progressWindow = new ProgressWindow();
progressWindow.Show(_instance); progressWindow.Show(_instance);
var processor = new CombineAddresses(progressWindow); var processor = new CombineAddresses(progressWindow);
var result = await processor.Perform(address_lists, type, CbMergeExportUnmerged.IsChecked); var result = await processor.Perform(address_lists, type, comb_type, CbMergeExportUnmerged.IsChecked, CbMergeDeleteOld.IsChecked);
if (result.Item1 != null) if (result.Item1 != null)
result.Item1.owner_id = owner_id; result.Item1.owner_id = owner_id;
@@ -426,7 +452,7 @@ public partial class MainWindow : Window
{ {
if (LstSettingsCustomers.SelectedIndex == null || LstSettingsCustomers.SelectedIndex == -1) return; if (LstSettingsCustomers.SelectedIndex == null || LstSettingsCustomers.SelectedIndex == -1) return;
foreach (var customer in Settings._instance.customers.customers) foreach (var customer in Settings._instance.customers.customers)
if (customer.ID == Settings._instance.customers.current) if (customer.ID == Settings._instance.customers.current.ID)
customer.name = TbSettingsCustomerName.Text; customer.name = TbSettingsCustomerName.Text;
//Settings.Save(); //Settings.Save();
//RefreshCustomerItems(); //RefreshCustomerItems();
@@ -436,19 +462,19 @@ public partial class MainWindow : Window
{ {
if (LstSettingsCustomers.SelectedIndex < 0) return; if (LstSettingsCustomers.SelectedIndex < 0) return;
Settings._instance.customers.current = Settings._instance.customers.current =
Customer.GetIDByCustomerListItem(LstSettingsCustomers.SelectedItems[0].ToString()); ((Customer)LstSettingsCustomers.SelectedItems[0]);
foreach (var customer in Settings._instance.customers.customers) //foreach (var customer in Settings._instance.customers.customers)
if (customer.ID == Settings._instance.customers.current) //if (customer.ID == Settings._instance.customers.current.ID)
{ //{
TbSettingsCustomerDescription.Text = customer.description; TbSettingsCustomerDescription.Text = Settings._instance.customers.current.description;
TbSettingsCustomerName.Text = customer.name; TbSettingsCustomerName.Text = Settings._instance.customers.current.name;
TbSettingsCustomerSenderAddress.Text = customer.sender_address; TbSettingsCustomerSenderAddress.Text = Settings._instance.customers.current.sender_address;
TbSettingsCustomerCsvSeparator.Text = customer.separator.ToString(); TbSettingsCustomerCsvSeparator.Text = Settings._instance.customers.current.separator.ToString();
if (customer.patch != null) if (Settings._instance.customers.current.patch != null)
TbSettingsCustomerPatchInfo.Text = customer.patch.ToString(); TbSettingsCustomerPatchInfo.Text = Settings._instance.customers.current.patch.ToString();
else else
TbSettingsCustomerPatchInfo.Text = ""; TbSettingsCustomerPatchInfo.Text = "";
} //}
} }
private async void EditButton_Click(object? sender, RoutedEventArgs e) private async void EditButton_Click(object? sender, RoutedEventArgs e)
@@ -481,8 +507,8 @@ public partial class MainWindow : Window
LstSettingsCustomers.Items.Clear(); LstSettingsCustomers.Items.Clear();
foreach (var customer in Settings._instance.customers.customers) foreach (var customer in Settings._instance.customers.customers)
{ {
LstCustomers.Items.Add(customer.ID + " - " + customer.name); LstCustomers.Items.Add(customer);
LstSettingsCustomers.Items.Add(customer.ID + " - " + customer.name); LstSettingsCustomers.Items.Add(customer);
} }
try try
@@ -498,7 +524,7 @@ public partial class MainWindow : Window
{ {
if (LstSettingsCustomers.SelectedIndex == null || LstSettingsCustomers.SelectedIndex == -1) return; if (LstSettingsCustomers.SelectedIndex == null || LstSettingsCustomers.SelectedIndex == -1) return;
foreach (var customer in Settings._instance.customers.customers) foreach (var customer in Settings._instance.customers.customers)
if (customer.ID == Settings._instance.customers.current) if (customer.ID == Settings._instance.customers.current.ID)
customer.description = TbSettingsCustomerDescription.Text; customer.description = TbSettingsCustomerDescription.Text;
//Settings.Save(); //Settings.Save();
} }
@@ -513,7 +539,7 @@ public partial class MainWindow : Window
{ {
MakeCalcManVisible(); MakeCalcManVisible();
if (LstCustomers.SelectedItems == null || LstCustomers.SelectedIndex == -1) return; if (LstCustomers.SelectedItems == null || LstCustomers.SelectedIndex == -1) return;
var customer_id = int.Parse(LstCustomers.SelectedItem.ToString().Split(" - ")[0]); var customer_id = ((Customer)LstCustomers.SelectedItem).ID;
RefreshAddressSetListItems(customer_id); RefreshAddressSetListItems(customer_id);
} }
@@ -538,7 +564,7 @@ public partial class MainWindow : Window
var selected_path = paths[0].Path; var selected_path = paths[0].Path;
foreach (var customer in Settings._instance.customers.customers) foreach (var customer in Settings._instance.customers.customers)
if (customer.ID == Customer.GetIDByCustomerListItem(LstCustomers.SelectedItems[0].ToString())) if (customer == ((Customer)LstCustomers.SelectedItems[0]))
{ {
if (customer.patch == null) if (customer.patch == null)
{ {
@@ -593,7 +619,7 @@ public partial class MainWindow : Window
foreach (var k in Settings._instance.addressSets.addresses) foreach (var k in Settings._instance.addressSets.addresses)
foreach (var customer in Settings._instance.customers.customers) foreach (var customer in Settings._instance.customers.customers)
if (customer.ID == k.owner_id && customer.ID == customer_id) if (customer.ID == k.owner_id && customer.ID == customer_id)
LstCustomerAdressSets.Items.Add(k.ID + " - " + k.Name + " (" + k.KasPersons.Count + " Einträge)"); LstCustomerAdressSets.Items.Add(k);
} }
private void LstCustomerAdressSets_OnSelectionChanged(object? sender, SelectionChangedEventArgs e) private void LstCustomerAdressSets_OnSelectionChanged(object? sender, SelectionChangedEventArgs e)
@@ -612,6 +638,7 @@ public partial class MainWindow : Window
BtnCheck.IsEnabled = true; BtnCheck.IsEnabled = true;
BtnCombine.IsEnabled = true; BtnCombine.IsEnabled = true;
BtnGenerateLabels.IsEnabled = true; BtnGenerateLabels.IsEnabled = true;
BtnShorten.IsEnabled = true;
// BtnRepair.IsEnabled = true; // BtnRepair.IsEnabled = true;
// BtnShorten.IsEnabled = true; // BtnShorten.IsEnabled = true;
@@ -640,7 +667,7 @@ public partial class MainWindow : Window
var selected_path = paths[0].Path; var selected_path = paths[0].Path;
foreach (var customer in Settings._instance.customers.customers) foreach (var customer in Settings._instance.customers.customers)
if (customer.ID == Customer.GetIDByCustomerListItem(LstSettingsCustomers.SelectedItems[0].ToString())) if (customer.ID == ((Customer)LstSettingsCustomers.SelectedItems[0]).ID)
customer.patch = AddressPatch.Import(selected_path); customer.patch = AddressPatch.Import(selected_path);
@@ -654,7 +681,7 @@ public partial class MainWindow : Window
? TbSettingsCustomerCsvSeparator.Text ? TbSettingsCustomerCsvSeparator.Text
: ","; : ",";
foreach (var customer in Settings._instance.customers.customers) foreach (var customer in Settings._instance.customers.customers)
if (customer.ID == Settings._instance.customers.current) if (customer.ID == Settings._instance.customers.current.ID)
try try
{ {
customer.separator = Convert.ToChar(sep); customer.separator = Convert.ToChar(sep);
@@ -673,11 +700,10 @@ public partial class MainWindow : Window
{ {
var list = new List<KasAddressList>(); var list = new List<KasAddressList>();
foreach (var item in LstCustomerAdressSets.SelectedItems) foreach (var item in LstCustomerAdressSets.SelectedItems)
list.Add(Settings._instance.addressSets.GetAddressSetByID( list.Add((KasAddressList)item);
Convert.ToInt32(item.ToString().Split(" - ")[0])));
try try
{ {
StartCombine(list, Convert.ToInt32(LstCustomers.SelectedItem.ToString().Split(" - ")[0]), "difference"); StartCombine(list, Convert.ToInt32((LstCustomers.SelectedItem as Customer).ID), "difference", GetCombiningTyp());
} }
catch catch
{ {
@@ -689,11 +715,10 @@ public partial class MainWindow : Window
{ {
var list = new List<KasAddressList>(); var list = new List<KasAddressList>();
foreach (var item in LstCustomerAdressSets.SelectedItems) foreach (var item in LstCustomerAdressSets.SelectedItems)
list.Add(Settings._instance.addressSets.GetAddressSetByID( list.Add((KasAddressList)item);
Convert.ToInt32(item.ToString().Split(" - ")[0])));
try try
{ {
StartCombine(list, Convert.ToInt32(LstCustomers.SelectedItem.ToString().Split(" - ")[0]), "union"); StartCombine(list, Convert.ToInt32((LstCustomers.SelectedItem as Customer).ID), "union", GetCombiningTyp());
} }
catch catch
{ {
@@ -706,30 +731,51 @@ public partial class MainWindow : Window
{ {
var list = new List<KasAddressList>(); var list = new List<KasAddressList>();
foreach (var item in LstCustomerAdressSets.SelectedItems) foreach (var item in LstCustomerAdressSets.SelectedItems)
list.Add(Settings._instance.addressSets.GetAddressSetByID( list.Add((KasAddressList)item);
Convert.ToInt32(item.ToString().Split(" - ")[0])));
try try
{ {
StartCombine(list, Convert.ToInt32(LstCustomers.SelectedItem.ToString().Split(" - ")[0]), "intersection"); StartCombine(list, Convert.ToInt32((LstCustomers.SelectedItem as Customer).ID), "intersection", GetCombiningTyp());
} }
catch catch (Exception ex)
{ {
Console.WriteLine("Error while trying to start intersection: " + ex.Message);
} }
} }
public CombineAddresses.CombineType GetCombiningTyp()
{
if (RbComprefsid.IsChecked == true)
{
return CombineAddresses.CombineType.refsid;
} else if (RbCompfinAd.IsChecked == true)
{
return CombineAddresses.CombineType.final_adress;
}
return CombineAddresses.CombineType.none;
}
private void BtnCombineSymmetricDifference_OnClick(object? sender, RoutedEventArgs e) private void BtnCombineSymmetricDifference_OnClick(object? sender, RoutedEventArgs e)
{ {
var list = new List<KasAddressList>(); var list = new List<KasAddressList>();
foreach (var item in LstCustomerAdressSets.SelectedItems) foreach (var item in LstCustomerAdressSets.SelectedItems)
list.Add(Settings._instance.addressSets.GetAddressSetByID( list.Add((KasAddressList)item);
Convert.ToInt32(item.ToString().Split(" - ")[0])));
StartCombine(list, Convert.ToInt32(LstCustomers.SelectedItem.ToString().Split(" - ")[0]), "symdiff"); StartCombine(list, Convert.ToInt32((LstCustomers.SelectedItem as Customer).ID), "symdiff", GetCombiningTyp());
} }
private async void BtnGenerateLabels_OnClick(object? sender, RoutedEventArgs e) private async void BtnGenerateLabels_OnClick(object? sender, RoutedEventArgs e)
{ {
GrdCalcMan.IsVisible = false;
GrdCombineTypes.IsVisible = false;
GrdExportMarginOptions.IsVisible = true;
LoadPdfExportOptions();
}
private async void BtnStartGenerateLabels_OnClick(object? sender, RoutedEventArgs e)
{
SavePdfExportOptions();
var saveDialog = new SaveFileDialog var saveDialog = new SaveFileDialog
{ {
DefaultExtension = "pdf", DefaultExtension = "pdf",
@@ -739,10 +785,10 @@ public partial class MainWindow : Window
if (!string.IsNullOrEmpty(filePath)) if (!string.IsNullOrEmpty(filePath))
{ {
var builder = new PdfBuilder(); var builder = new PdfBuilder(Settings._instance.pdfExport);
builder.CreateAddressLabelPdfFromAddressSetWithPlaceholder( builder.CreateAddressLabelPdfFromAddressSetWithPlaceholder((
Convert.ToInt32(LstCustomerAdressSets.SelectedItems[0].ToString().Split(" - ")[0]), (KasAddressList)LstCustomerAdressSets.SelectedItem).ID,
"Company Logo/Info", "Company Logo/Info",
filePath filePath
); );
@@ -750,11 +796,92 @@ public partial class MainWindow : Window
} }
} }
private void HookPdfExportOptionEvents()
{
var controls = GetPdfExportControls();
foreach (var control in controls) control.ValueChanged += PdfExportOption_OnValueChanged;
}
private void LoadPdfExportOptions()
{
var options = Settings._instance.pdfExport ?? new PdfExportSettings();
NudExpMargCellPaddingTop.Value = (decimal)options.cellPaddingTopMm;
NudExpMargCellPaddingBot.Value = (decimal)options.cellPaddingBottomMm;
NudExpMargCellPaddingLeft.Value = (decimal)options.cellPaddingLeftMm;
NudExpMargCellPaddingRight.Value = (decimal)options.cellPaddingRightMm;
TbExpMargMarginTop.Value = (decimal)options.pageMarginTopMm;
TbExpMargMarginBottom.Value = (decimal)options.pageMarginBottomMm;
TbExpMargMarginLeft.Value = (decimal)options.pageMarginLeftMm;
TbExpMargMarginRight.Value = (decimal)options.pageMarginRightMm;
TbExpMargRowsPerPage.Value = options.rowsPerPage;
NudExpMargColumnsPerPage.Value = options.columnsPerPage;
NudExpMargFontSize.Value = (decimal)options.fontSize;
NudExpMargSmallFontSize.Value = (decimal)options.smallFontSize;
}
private void SavePdfExportOptions()
{
Settings._instance.pdfExport = new PdfExportSettings
{
cellPaddingTopMm = ReadDouble(NudExpMargCellPaddingTop),
cellPaddingBottomMm = ReadDouble(NudExpMargCellPaddingBot),
cellPaddingLeftMm = ReadDouble(NudExpMargCellPaddingLeft),
cellPaddingRightMm = ReadDouble(NudExpMargCellPaddingRight),
pageMarginTopMm = ReadDouble(TbExpMargMarginTop),
pageMarginBottomMm = ReadDouble(TbExpMargMarginBottom),
pageMarginLeftMm = ReadDouble(TbExpMargMarginLeft),
pageMarginRightMm = ReadDouble(TbExpMargMarginRight),
rowsPerPage = ReadInt(TbExpMargRowsPerPage, 7),
columnsPerPage = ReadInt(NudExpMargColumnsPerPage, 3),
fontSize = ReadDouble(NudExpMargFontSize),
smallFontSize = ReadDouble(NudExpMargSmallFontSize)
};
Settings.Save();
}
private void PdfExportOption_OnValueChanged(object? sender, NumericUpDownValueChangedEventArgs e)
{
SavePdfExportOptions();
}
private double ReadDouble(NumericUpDown control)
{
return (double)(control.Value ?? 0);
}
private int ReadInt(NumericUpDown control, int fallback)
{
return (int)Math.Round(control.Value ?? fallback);
}
private NumericUpDown[] GetPdfExportControls()
{
return
[
NudExpMargCellPaddingTop,
NudExpMargCellPaddingBot,
NudExpMargCellPaddingLeft,
NudExpMargCellPaddingRight,
TbExpMargMarginTop,
TbExpMargMarginBottom,
TbExpMargMarginLeft,
TbExpMargMarginRight,
TbExpMargRowsPerPage,
NudExpMargColumnsPerPage,
NudExpMargFontSize,
NudExpMargSmallFontSize
];
}
private void TbSettingsCustomerSenderAddress_OnTextChanged(object? sender, TextChangedEventArgs e) private void TbSettingsCustomerSenderAddress_OnTextChanged(object? sender, TextChangedEventArgs e)
{ {
if (LstSettingsCustomers.SelectedIndex == null || LstSettingsCustomers.SelectedIndex == -1) return; if (LstSettingsCustomers.SelectedIndex == null || LstSettingsCustomers.SelectedIndex == -1) return;
foreach (var customer in Settings._instance.customers.customers) foreach (var customer in Settings._instance.customers.customers)
if (customer.ID == Settings._instance.customers.current) if (customer.ID == Settings._instance.customers.current.ID)
customer.sender_address = TbSettingsCustomerSenderAddress.Text; customer.sender_address = TbSettingsCustomerSenderAddress.Text;
} }
@@ -895,18 +1022,52 @@ public partial class MainWindow : Window
private async void BtnWikiAddFile_OnClick(object? sender, RoutedEventArgs e) private async void BtnWikiAddFile_OnClick(object? sender, RoutedEventArgs e)
{ {
var result = await NamingWindow.Show(this); var result = await NamingWindow.Show(this);
if (result != null) if (string.IsNullOrWhiteSpace(result)) return;
try
{ result = result.Trim();
File.WriteAllText(Path.Combine(Global._instance.wiki_storage_path, result), ""); if (!result.EndsWith(".md", StringComparison.OrdinalIgnoreCase)) result += ".md";
PopulateNavTree();
} if (!Directory.Exists(Global._instance.wiki_storage_path))
catch (Exception ex) Directory.CreateDirectory(Global._instance.wiki_storage_path);
{
MessageBox.Show(this, ex.StackTrace, "Fehler"); try
} {
var targetDirectory = GetSelectedWikiTargetDirectory();
Directory.CreateDirectory(targetDirectory);
var newFilePath = Path.Combine(targetDirectory, result);
File.WriteAllText(newFilePath, "");
PopulateNavTree(targetDirectory, newFilePath);
}
catch (Exception ex)
{
MessageBox.Show(this, ex.StackTrace, "Fehler");
}
} }
private async void BtnWikiAddFolder_OnClick(object? sender, RoutedEventArgs e)
{
var result = await NamingWindow.Show(this);
if (string.IsNullOrWhiteSpace(result)) return;
result = result.Trim();
if (!Directory.Exists(Global._instance.wiki_storage_path))
Directory.CreateDirectory(Global._instance.wiki_storage_path);
try
{
var targetDirectory = GetSelectedWikiTargetDirectory();
var newFolderPath = Path.Combine(targetDirectory, result);
Directory.CreateDirectory(newFolderPath);
PopulateNavTree(targetDirectory, newFolderPath);
}
catch (Exception ex)
{
MessageBox.Show(this, ex.StackTrace, "Fehler");
}
}
private async void MnIAdSetRename_OnClick(object? sender, RoutedEventArgs e) private async void MnIAdSetRename_OnClick(object? sender, RoutedEventArgs e)
{ {
if (LstCustomerAdressSets.SelectedItems.Count > 0) if (LstCustomerAdressSets.SelectedItems.Count > 0)
@@ -917,7 +1078,7 @@ public partial class MainWindow : Window
{ {
var id = KasAddressList.GetIDByAddressSetListItem(LstCustomerAdressSets.SelectedItems[0] var id = KasAddressList.GetIDByAddressSetListItem(LstCustomerAdressSets.SelectedItems[0]
.ToString()); .ToString());
var cus_id = Customer.GetIDByCustomerListItem(LstCustomers.SelectedItems[0].ToString()); var cus_id = ((Customer)LstCustomers.SelectedItems[0]).ID;
foreach (var set in Settings._instance.addressSets.addresses) foreach (var set in Settings._instance.addressSets.addresses)
if (set.ID == id) if (set.ID == id)
{ {
@@ -933,4 +1094,47 @@ public partial class MainWindow : Window
MessageBox.Show(this, ex.StackTrace, "Fehler"); MessageBox.Show(this, ex.StackTrace, "Fehler");
} }
} }
private void BtnDeleteCustomer_OnClick(object? sender, RoutedEventArgs e)
{
if (LstSettingsCustomers.SelectedIndex == null || LstSettingsCustomers.SelectedIndex == -1) return;
try
{
Settings._instance.customers.customers.Remove((Customer)LstSettingsCustomers.SelectedItem);
}
catch (Exception ex)
{
MessageBox.Show(this, "Unknown Error: " + ex.Message, "Error");
}
RefreshCustomerItems();
}
private void BtnShorten_OnClick(object? sender, RoutedEventArgs e)
{
MakeCalcManVisible();
if (LstCustomerAdressSets.SelectedIndex == -1)
{
MessageBox.Show(null, "Bitte zunächst ein Adress-Set auswählen", "Kein Adress-Set ausgewählt");
return;
}
StartAddressShortener((KasAddressList)LstCustomerAdressSets.SelectedItem);
}
private void ChangeCSVDivider(object sender, RoutedEventArgs e)
{
try
{
string div = (sender as Button).Content as string;
if (div == "TAB") div = "\t";
if (div == "SPACE") div = " ";
TbSettingsCustomerCsvSeparator.Text = div;
Settings.Save();
}
catch
{
Console.WriteLine("Error while parsing");
}
}
} }
+1 -1
View File
@@ -2,7 +2,7 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" SizeToContent="WidthAndHeight" mc:Ignorable="d" SizeToContent="WidthAndHeight" WindowStartupLocation="CenterScreen" Topmost="True"
x:Class="Logof_Client.NamingWindow" x:Class="Logof_Client.NamingWindow"
Title="NamingWindow"> Title="NamingWindow">
<StackPanel Orientation="Vertical"> <StackPanel Orientation="Vertical">
+2
View File
@@ -1,4 +1,5 @@
using System; using System;
using System.Runtime.CompilerServices;
using System.Threading.Tasks; using System.Threading.Tasks;
using Avalonia.Controls; using Avalonia.Controls;
@@ -45,6 +46,7 @@ public partial class NamingWindow : Window
if (parent != null) if (parent != null)
wind.ShowDialog(parent); wind.ShowDialog(parent);
else wind.Show(); else wind.Show();
wind.Focus();
return tcs.Task; return tcs.Task;
} }
+1 -1
View File
@@ -3,7 +3,7 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" d:DesignWidth="800" Width="800" MinWidth="800" MaxWidth="800" d:DesignHeight="150" mc:Ignorable="d" d:DesignWidth="800" Width="800" MinWidth="800" MaxWidth="800" d:DesignHeight="150"
Height="150" MinHeight="150" MaxHeight="150" Icon="assets/icon.ico" Height="150" MinHeight="150" MaxHeight="150" Icon="assets/icon.ico" WindowStartupLocation="CenterScreen" Topmost="True"
x:Class="Logof_Client.ProgressWindow" Title="Verarbeitung läuft..."> x:Class="Logof_Client.ProgressWindow" Title="Verarbeitung läuft...">
<Grid> <Grid>
<!-- <ScrollViewer x:Name="ScvLog"> --> <!-- <ScrollViewer x:Name="ScvLog"> -->
+2 -2
View File
@@ -16,9 +16,9 @@ public partial class ProgressWindow : Window
PbProgress.Value = percentage; PbProgress.Value = percentage;
} }
public void AddToLog(string message) public void AddToLog(string message, string percent)
{ {
TbLog.Text = message; TbLog.Text = message + $"\n{percent}%";
//ScvLog.ScrollToEnd(); //ScvLog.ScrollToEnd();
} }
} }
+3 -1
View File
@@ -20,7 +20,9 @@
Margin="10,10,10,10" /> Margin="10,10,10,10" />
</Grid> </Grid>
<ScrollViewer Grid.Column="1" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto"> <ScrollViewer Grid.Column="1" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto">
<StackPanel x:Name="StkResults" Orientation="Vertical" Margin="10" /> <!-- <TextBlock x:Name="TbResults"></TextBlock> -->
<ListBox x:Name="LbResults"></ListBox>
<!-- <StackPanel x:Name="StkResults" Orientation="Vertical" Margin="10" /> -->
</ScrollViewer> </ScrollViewer>
</Grid> </Grid>
+12 -4
View File
@@ -32,8 +32,12 @@ public partial class ResultWindow : Window
var result_with_errors = result.Where(p => p.PersonError != null).ToList(); var result_with_errors = result.Where(p => p.PersonError != null).ToList();
LblResultCount.Content = $"{result_with_errors.Count}/{ur_result.Count} Ergebnisse"; LblResultCount.Content = $"{result_with_errors.Count}/{ur_result.Count} Ergebnisse";
StkResults.Children.Clear(); // TbResults.Text = "";
foreach (var person in result_with_errors) StkResults.Children.Add(CreatePersonGrid(person)); // foreach (var person in result_with_errors) TbResults.Text += person.PersonError.GetString()+"\n";
LbResults.Items.Clear();
foreach (var person in result_with_errors) LbResults.Items.Add(person.PersonError.ToString(person));
// StkResults.Children.Clear();
// foreach (var person in result_with_errors) StkResults.Children.Add(CreatePersonGrid(person));
} }
private Grid CreatePersonGrid(KasPerson person) private Grid CreatePersonGrid(KasPerson person)
@@ -201,8 +205,12 @@ public partial class ResultWindow : Window
LblResultCount.Content = $"{temp_result.Count}/{ur_result.Count} Ergebnisse"; LblResultCount.Content = $"{temp_result.Count}/{ur_result.Count} Ergebnisse";
StkResults.Children.Clear(); LbResults.Items.Clear();
foreach (var person in temp_result) StkResults.Children.Add(CreatePersonGrid(person)); foreach (var person in temp_result) LbResults.Items.Add(person.PersonError.ToString(person));
// TbResults.Text = "";
// foreach (var person in temp_result) TbResults.Text += person.PersonError.GetString() +"\n";
// StkResults.Children.Clear();
// foreach (var person in temp_result) StkResults.Children.Add(CreatePersonGrid(person));
} }
+2 -1
View File
@@ -1,3 +1,4 @@
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Threading; using System.Threading;
@@ -247,7 +248,7 @@ public class AddressCheck
await Dispatcher.UIThread.InvokeAsync(() => await Dispatcher.UIThread.InvokeAsync(() =>
{ {
if (hasFaults) if (hasFaults)
_progress.AddToLog($"Person mit id {person.id} ist fehlerhaft"); _progress.AddToLog($"Person mit id {person.id} ist fehlerhaft", Convert.ToInt32(percent).ToString());
_progress.ChangePercentage(percent); _progress.ChangePercentage(percent);
}); });
+79
View File
@@ -0,0 +1,79 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Threading.Tasks.Dataflow;
namespace Logof_Client;
public class AddressShortener(ProgressWindow progressWindow)
{
private readonly ProgressWindow _progress = progressWindow;
public async Task Perform(KasAddressList list)
{
// find doubled addresses by refsid
List<int> doubled_ids = new List<int>();
for (int i = 0; i < list.KasPersons.Count; i++)
{
var address = list.KasPersons[i];
for (int j = 0; j < list.KasPersons.Count; j++)
{
if (i == j) continue;
var sec_address = list.KasPersons[j];
if (address.refsid == sec_address.refsid && !doubled_ids.Contains(address.refsid) && address.refsid != 0)
{
doubled_ids.Add(address.refsid);
}
}
}
// delete doubled addresses by refsid
foreach (int id in doubled_ids)
{
// does this remove both of the doubled addresses?
list.KasPersons.Remove(list.KasPersons.FirstOrDefault(x => x.refsid == id));
}
List<int> toRemove = new List<int>();
foreach (var address in list.KasPersons)
{
try
{
if (address.PersonError.errors.Contains(AddressCheck.ErrorTypes.NoPLZorPPLZ))
{
toRemove.Add(address.id);
}
else if (address.PersonError.errors.Contains(AddressCheck.ErrorTypes.PlzNotUsable) &&
address.PersonError.errors.Contains(AddressCheck.ErrorTypes.PPlzNotUsable))
{
toRemove.Add(address.id);
} else if (address.PersonError.errors.Contains(AddressCheck.ErrorTypes.PlzNotUsable) &&
address.PersonError.warnings.Contains(AddressCheck.WarningTypes.NoPPLZ))
{
toRemove.Add(address.id);
}
else if (address.PersonError.errors.Contains(AddressCheck.ErrorTypes.PPlzNotUsable) &&
address.PersonError.warnings.Contains(AddressCheck.WarningTypes.NoPLZ))
{
toRemove.Add(address.id);
}
}
catch
{
Console.WriteLine("PersonError not accessible: " + address.id);
}
}
// delete doubled addresses by refsid
foreach (int id in toRemove)
{
// does this remove both of the doubled addresses?
list.KasPersons.Remove(list.KasPersons.Find(x => x.id == id));
}
//return null;
}
}
+52 -80
View File
@@ -16,14 +16,37 @@ public class CombineAddresses
_progress = progressWindow; _progress = progressWindow;
} }
public async Task<(KasAddressList, KasAddressList)> Perform(List<KasAddressList> address_lists, string type, public enum CombineType
{
refsid,
final_adress,
none
}
public async Task<(KasAddressList, KasAddressList)> Perform(List<KasAddressList> address_lists, string type, CombineType comb_type,
bool? exportUnused, bool? deleteOld)
{
var result = await Execute(address_lists,type,comb_type,exportUnused);
if (deleteOld == true)
{
foreach (var list in address_lists)
{
Settings._instance.addressSets.addresses.Remove(list);
}
}
return result;
}
private async Task<(KasAddressList, KasAddressList)> Execute(List<KasAddressList> address_lists, string type, CombineType comb_type,
bool? exportUnused) bool? exportUnused)
{ {
if (type == "difference") return await Difference(address_lists, exportUnused); if (type == "difference") return await Difference(address_lists, comb_type, exportUnused);
if (type == "union") return await Union(address_lists, exportUnused); if (type == "union") return await Union(address_lists, comb_type, exportUnused);
if (type == "intersection") return await Intersection(address_lists, exportUnused); if (type == "intersection") return await Intersection(address_lists, comb_type, exportUnused);
if (type == "symdiff") return await SymmetricDifference(address_lists, exportUnused); if (type == "symdiff") return await SymmetricDifference(address_lists, comb_type, exportUnused);
return (null, null); return (null, null);
} }
@@ -35,10 +58,12 @@ public class CombineAddresses
/// <param name="second">Second address to compare</param> /// <param name="second">Second address to compare</param>
/// <param name="only_refsid">If true, only a refsid-check will be done</param> /// <param name="only_refsid">If true, only a refsid-check will be done</param>
/// <returns></returns> /// <returns></returns>
public bool CompareAddresses(KasPerson first, KasPerson second, bool only_refsid = false) public bool CompareAddresses(KasPerson first, KasPerson second, CombineType comb_type)
{ {
if (first.refsid == second.refsid) return true; // A refsid of 0 means "missing", so it must not collapse unrelated entries.
if (!only_refsid) if(comb_type == CombineType.refsid)
if (first.refsid != 0 && second.refsid != 0 && first.refsid == second.refsid) return true;
if (comb_type == CombineType.final_adress)
if (first.name == second.name && if (first.name == second.name &&
first.anrede == second.anrede && first.anrede == second.anrede &&
first.anredzus == second.anredzus && first.anredzus == second.anredzus &&
@@ -67,7 +92,7 @@ public class CombineAddresses
return false; return false;
} }
public async Task<(KasAddressList, KasAddressList)> Difference(List<KasAddressList> address_lists, public async Task<(KasAddressList, KasAddressList)> Difference(List<KasAddressList> address_lists, CombineType comb_type,
bool? return_unused, bool? return_unused,
Progress? progress = null) Progress? progress = null)
{ {
@@ -85,11 +110,13 @@ public class CombineAddresses
for (var i = 1; i < address_lists.Count; i++) for (var i = 1; i < address_lists.Count; i++)
restUnion.AddRange(address_lists[i].KasPersons); restUnion.AddRange(address_lists[i].KasPersons);
var result = new KasAddressList(await KasAddressList.GenerateName("difference")); var result = new KasAddressList(await KasAddressList.GenerateName("difference"));
var second_result = new KasAddressList(await KasAddressList.GenerateName("difference_rest", false)); var second_result = new KasAddressList("none");
if(return_unused == true)
second_result = new KasAddressList(await KasAddressList.GenerateName("difference_rest", false));
foreach (var person in address_lists[0].KasPersons) foreach (var person in address_lists[0].KasPersons)
{ {
var isDouble = restUnion.Any(p => CompareAddresses(person, p)); var isDouble = restUnion.Any(p => CompareAddresses(person, p, comb_type));
if (!isDouble) if (!isDouble)
result.KasPersons.Add(person); result.KasPersons.Add(person);
else else
@@ -108,11 +135,13 @@ public class CombineAddresses
} }
public async Task<(KasAddressList, KasAddressList)> Union(List<KasAddressList> address_lists, bool? return_unused, public async Task<(KasAddressList, KasAddressList)> Union(List<KasAddressList> address_lists, CombineType comb_type, bool? return_unused,
Progress progress = null) Progress progress = null)
{ {
var result = new KasAddressList(await KasAddressList.GenerateName("union")); var result = new KasAddressList(await KasAddressList.GenerateName("union"));
var second_result = new KasAddressList(await KasAddressList.GenerateName("union_rest", false)); var second_result = new KasAddressList("none");
if(return_unused == true)
second_result = new KasAddressList(await KasAddressList.GenerateName("union_rest", false));
if (address_lists == null || address_lists.Count == 0) if (address_lists == null || address_lists.Count == 0)
return (result, null); return (result, null);
@@ -123,7 +152,7 @@ public class CombineAddresses
foreach (var list in address_lists) foreach (var list in address_lists)
foreach (var person in list.KasPersons) foreach (var person in list.KasPersons)
{ {
if (!result.KasPersons.Any(existing => CompareAddresses(existing, person))) if (!result.KasPersons.Any(existing => CompareAddresses(existing, person, comb_type)))
result.KasPersons.Add(person); result.KasPersons.Add(person);
else else
second_result.KasPersons.Add(person); second_result.KasPersons.Add(person);
@@ -150,11 +179,12 @@ public class CombineAddresses
return null; return null;
} }
public async Task<(KasAddressList, KasAddressList)> Intersection(List<KasAddressList> address_lists, public async Task<(KasAddressList, KasAddressList)> Intersection(List<KasAddressList> address_lists, CombineType comb_type,
bool? return_unused, Progress progress = null) bool? return_unused, Progress progress = null)
{ {
var result = new KasAddressList(await KasAddressList.GenerateName("intersection")); var result = new KasAddressList(await KasAddressList.GenerateName("intersection"));
var second_result = new KasAddressList(await KasAddressList.GenerateName("intersection_rest", false)); var second_result = new KasAddressList("none");
if(return_unused == true) second_result = new KasAddressList(await KasAddressList.GenerateName("intersection_rest", false));
if (address_lists == null || address_lists.Count == 0) if (address_lists == null || address_lists.Count == 0)
return (result, null); return (result, null);
@@ -170,7 +200,7 @@ public class CombineAddresses
{ {
// Prüfen, ob Person in *allen* anderen Listen vorkommt // Prüfen, ob Person in *allen* anderen Listen vorkommt
var isInAll = otherLists.All(list => var isInAll = otherLists.All(list =>
list.KasPersons.Any(existing => CompareAddresses(existing, person))); list.KasPersons.Any(existing => CompareAddresses(existing, person, comb_type)));
if (isInAll) if (isInAll)
result.KasPersons.Add(person); result.KasPersons.Add(person);
@@ -197,11 +227,12 @@ public class CombineAddresses
} }
public async Task<(KasAddressList, KasAddressList)> SymmetricDifference(List<KasAddressList> address_lists, public async Task<(KasAddressList, KasAddressList)> SymmetricDifference(List<KasAddressList> address_lists, CombineType comb_type,
bool? return_unused, Progress progress = null) bool? return_unused, Progress progress = null)
{ {
var result = new KasAddressList(await KasAddressList.GenerateName("symmetric_difference")); var result = new KasAddressList(await KasAddressList.GenerateName("symmetric_difference"));
var second_result = new KasAddressList(await KasAddressList.GenerateName("symmetric_rest", false)); var second_result = new KasAddressList("none");
if(return_unused == true) second_result = new KasAddressList(await KasAddressList.GenerateName("symmetric_rest", false));
if (address_lists == null || address_lists.Count == 0) if (address_lists == null || address_lists.Count == 0)
return (result, null); return (result, null);
@@ -216,7 +247,7 @@ public class CombineAddresses
foreach (var person in list.KasPersons) foreach (var person in list.KasPersons)
{ {
// Prüfen, ob schon vorhanden // Prüfen, ob schon vorhanden
var existing = allPersons.FirstOrDefault(p => CompareAddresses(p.person, person)); var existing = allPersons.FirstOrDefault(p => CompareAddresses(p.person, person, comb_type));
if (existing.person != null) if (existing.person != null)
{ {
// Falls schon drin → Vorkommen erhöhen // Falls schon drin → Vorkommen erhöhen
@@ -254,65 +285,6 @@ public class CombineAddresses
return (result, null); return (result, null);
} }
// private async Task<KasAddressList> Merge(KasAddressList first, KasAddressList second, int num, int total)
// {
// foreach (var sec in second.KasPersons)
// {
// var is_new = true;
// foreach (var fi in first.KasPersons)
// {
// if (fi.refsid == sec.refsid)
// {
// is_new = false;
// break;
// }
//
// if (fi.name == sec.name &&
// fi.anrede == sec.anrede &&
// fi.anredzus == sec.anredzus &&
// fi.namezus == sec.namezus &&
// fi.titel == sec.titel &&
// fi.adel == sec.adel &&
// fi.strasse == sec.strasse &&
// fi.strasse2 == sec.strasse2 &&
// fi.vorname == sec.vorname &&
// fi.ort == sec.ort &&
// fi.land == sec.land &&
// fi.plz == sec.plz &&
// fi.pplz == sec.pplz &&
// fi.funktion == sec.funktion &&
// fi.funktion2 == sec.funktion2 &&
// fi.funktionad == sec.funktionad &&
// fi.abteilung == sec.abteilung &&
// fi.postfach == sec.postfach &&
// fi.name1 == sec.name1 &&
// fi.name2 == sec.name2 &&
// fi.name3 == sec.name3 &&
// fi.name4 == sec.name4 &&
// fi.name5 == sec.name5)
// {
// is_new = false;
// break;
// }
// }
//
// if (is_new) first.KasPersons.Add(sec);
// var subperc = second.KasPersons.IndexOf(sec) / second.KasPersons.Count;
// var percent = (num + (double)subperc) / total * 100;
// await Dispatcher.UIThread.InvokeAsync(() =>
// {
// if (is_new)
// _progress.AddToLog($"Person mit refsid {sec.refsid} ergänzt");
// else
// _progress.AddToLog($"Person mit refsid {sec.refsid} bereits vorhanden");
//
// _progress.ChangePercentage(percent);
// });
// }
//
// return first;
// }
} }
public class Progress public class Progress
+101 -49
View File
@@ -11,35 +11,15 @@ namespace Logof_Client;
public class PdfBuilder public class PdfBuilder
{ {
// Table layout private readonly PdfExportSettings _settings;
private const int CellsPerRow = 3;
private const int CellsPerPage = 21; // 3 columns × 7 rows
private readonly XFont _boldFont; private readonly XFont _boldFont;
private readonly double _cellHeight = 42.43; // mm
private readonly double _cellPaddingBottom = 5; // mm
// Padding inside cells
private readonly double _cellPaddingLeft = 5; // mm
private readonly double _cellPaddingTop = 5; // mm
// Cell dimensions (in mm)
private readonly double _cellWidth = 70; // mm
// Font settings
private readonly double _fontSize = 9;
private readonly double _marginBottom = 1; // mm
// Paper and layout settings
private readonly double _marginLeft = 0; // mm
private readonly double _marginRight = 0; // mm
private readonly double _marginTop = 0; // mm
private readonly XFont _regularFont; private readonly XFont _regularFont;
private readonly XFont _smallFont; private readonly XFont _smallFont;
public PdfBuilder() public PdfBuilder(PdfExportSettings? settings = null)
{ {
EnsureFontResolverRegistered(); EnsureFontResolverRegistered();
_settings = settings ?? new PdfExportSettings();
// Select first font from build output fonts folder (AppContext.BaseDirectory/fonts) // Select first font from build output fonts folder (AppContext.BaseDirectory/fonts)
var chosenFamily = "Arial"; var chosenFamily = "Arial";
@@ -57,9 +37,9 @@ public class PdfBuilder
chosenFamily = "Arial"; chosenFamily = "Arial";
} }
_boldFont = new XFont(chosenFamily, 9, XFontStyleEx.Bold); _boldFont = new XFont(chosenFamily, _settings.fontSize, XFontStyleEx.Bold);
_regularFont = new XFont(chosenFamily, 9, XFontStyleEx.Regular); _regularFont = new XFont(chosenFamily, _settings.fontSize, XFontStyleEx.Regular);
_smallFont = new XFont(chosenFamily, 6, XFontStyleEx.Regular); _smallFont = new XFont(chosenFamily, _settings.smallFontSize, XFontStyleEx.Regular);
} }
private static void EnsureFontResolverRegistered() private static void EnsureFontResolverRegistered()
@@ -124,7 +104,17 @@ public class PdfBuilder
addresses.Add(addr); addresses.Add(addr);
} }
if (addresses.Count == 0)
{
MessageBox.Show(MainWindow._instance, "Keine validen Adressen konnten generiert werden. Abbruch.", "Fehler");
return;
}
CreateAddressLabelPdfWithPlaceholder(addresses, placeholderText, outputPath); CreateAddressLabelPdfWithPlaceholder(addresses, placeholderText, outputPath);
if (_settings.exportRunningSheets)
{
ExportRunningSheets(addressSetId, outputPath);
}
} }
/// <summary> /// <summary>
@@ -159,20 +149,17 @@ public class PdfBuilder
private void DrawPage(XGraphics gfx, List<string> addresses, ref int addressIndex) private void DrawPage(XGraphics gfx, List<string> addresses, ref int addressIndex)
{ {
var cellCount = 0; for (var row = 0; row < _settings.rowsPerPage; row++)
for (var row = 0; row < 7; row++)
{ {
for (var col = 0; col < 3; col++) for (var col = 0; col < _settings.columnsPerPage; col++)
{ {
if (addressIndex >= addresses.Count) break; if (addressIndex >= addresses.Count) break;
var x = MmToPoints(_marginLeft + col * _cellWidth); var x = MmToPoints(_settings.pageMarginLeftMm + col * GetCellWidthMm());
var y = MmToPoints(_marginTop + row * _cellHeight); var y = MmToPoints(_settings.pageMarginTopMm + row * GetCellHeightMm());
DrawCell(gfx, x, y, addresses[addressIndex]); DrawCell(gfx, x, y, addresses[addressIndex]);
addressIndex++; addressIndex++;
cellCount++;
} }
if (addressIndex >= addresses.Count) break; if (addressIndex >= addresses.Count) break;
@@ -182,13 +169,11 @@ public class PdfBuilder
private void DrawPageWithPlaceholder(XGraphics gfx, List<string> addresses, ref int addressIndex, private void DrawPageWithPlaceholder(XGraphics gfx, List<string> addresses, ref int addressIndex,
ref bool isFirstCell, string placeholderText) ref bool isFirstCell, string placeholderText)
{ {
var cellCount = 0; for (var row = 0; row < _settings.rowsPerPage; row++)
for (var col = 0; col < _settings.columnsPerPage; col++)
for (var row = 0; row < 7; row++)
for (var col = 0; col < 3; col++)
{ {
var x = MmToPoints(_marginLeft + col * _cellWidth); var x = MmToPoints(_settings.pageMarginLeftMm + col * GetCellWidthMm());
var y = MmToPoints(_marginTop + row * _cellHeight); var y = MmToPoints(_settings.pageMarginTopMm + row * GetCellHeightMm());
// First cell: placeholder // First cell: placeholder
if (isFirstCell) if (isFirstCell)
@@ -205,15 +190,13 @@ public class PdfBuilder
{ {
DrawEmptyCell(gfx, x, y); DrawEmptyCell(gfx, x, y);
} }
cellCount++;
} }
} }
private void DrawCell(XGraphics gfx, double x, double y, string? address) private void DrawCell(XGraphics gfx, double x, double y, string? address)
{ {
var cellWidthPoints = MmToPoints(_cellWidth); var cellWidthPoints = MmToPoints(GetCellWidthMm());
var cellHeightPoints = MmToPoints(_cellHeight); var cellHeightPoints = MmToPoints(GetCellHeightMm());
// Draw cell border // Draw cell border
var rect = new XRect(x, y, cellWidthPoints, cellHeightPoints); var rect = new XRect(x, y, cellWidthPoints, cellHeightPoints);
@@ -225,8 +208,8 @@ public class PdfBuilder
private void DrawEmptyCell(XGraphics gfx, double x, double y) private void DrawEmptyCell(XGraphics gfx, double x, double y)
{ {
var cellWidthPoints = MmToPoints(_cellWidth); var cellWidthPoints = MmToPoints(GetCellWidthMm());
var cellHeightPoints = MmToPoints(_cellHeight); var cellHeightPoints = MmToPoints(GetCellHeightMm());
var rect = new XRect(x, y, cellWidthPoints, cellHeightPoints); var rect = new XRect(x, y, cellWidthPoints, cellHeightPoints);
gfx.DrawRectangle(XPens.Black, rect); gfx.DrawRectangle(XPens.Black, rect);
@@ -234,11 +217,12 @@ public class PdfBuilder
private void DrawMarkdownText(XGraphics gfx, string text, double x, double y, double cellWidth, double cellHeight) private void DrawMarkdownText(XGraphics gfx, string text, double x, double y, double cellWidth, double cellHeight)
{ {
var paddingLeftPoints = MmToPoints(_cellPaddingLeft); var paddingLeftPoints = MmToPoints(_settings.cellPaddingLeftMm);
var paddingTopPoints = MmToPoints(_cellPaddingTop); var paddingRightPoints = MmToPoints(_settings.cellPaddingRightMm);
var paddingBottomPoints = MmToPoints(_cellPaddingBottom); var paddingTopPoints = MmToPoints(_settings.cellPaddingTopMm);
var paddingBottomPoints = MmToPoints(_settings.cellPaddingBottomMm);
var maxWidth = cellWidth - paddingLeftPoints * 2; var maxWidth = Math.Max(0, cellWidth - paddingLeftPoints - paddingRightPoints);
// Split text by newlines and remove empty trailing lines // Split text by newlines and remove empty trailing lines
var rawLines = text.Split(new[] { "\n" }, StringSplitOptions.None); var rawLines = text.Split(new[] { "\n" }, StringSplitOptions.None);
@@ -382,6 +366,18 @@ public class PdfBuilder
return mm * 2.834645669; return mm * 2.834645669;
} }
private double GetCellWidthMm()
{
var availableWidthMm = 210d - _settings.pageMarginLeftMm - _settings.pageMarginRightMm;
return availableWidthMm / _settings.columnsPerPage;
}
private double GetCellHeightMm()
{
var availableHeightMm = 297d - _settings.pageMarginTopMm - _settings.pageMarginBottomMm;
return availableHeightMm / _settings.rowsPerPage;
}
// Configuration methods to allow customization // Configuration methods to allow customization
/// <summary> /// <summary>
@@ -401,4 +397,60 @@ public class PdfBuilder
if (left < 0 || top < 0 || right < 0 || bottom < 0) if (left < 0 || top < 0 || right < 0 || bottom < 0)
throw new ArgumentException("Margins cannot be negative"); throw new ArgumentException("Margins cannot be negative");
} }
public void ExportRunningSheets(int setID, string path)
{
if (path.EndsWith(".pdf"))
{
path = path.Substring(0, path.Length - 4);
path = path + "-Laufzettel.pdf";
}
else
{
path = path + "-Laufzettel.pdf";
}
CreateRunningSheets(setID, path);
}
public void CreateRunningSheets(int setID, string path)
{
KasAddressList list = Settings._instance.addressSets.GetAddressSetByID(setID);
var document = new PdfDocument();
document.Info.Title = $"Laufzettel für {list.Name}";
document.Info.Subject = "powered by logofclient";
document.Info.Author = "logofclient";
int margin = 50;
List<(int, int)> grouped_nums = GroupAddresses(setID);
var page = document.AddPage();
page.Size = PageSize.A4;
var gfx = XGraphics.FromPdfPage(page);
var width = page.Width.Point-margin;
var height = page.Height.Point-margin;
gfx.DrawLine(XPens.Black, margin, margin, margin, height);
gfx.DrawLine(XPens.Black, margin, margin, width, margin);
gfx.DrawLine(XPens.Black, width, margin, margin, height);
gfx.DrawLine(XPens.Black, margin, height, width, margin);
var font = new XFont("Times New Roman", 20, XFontStyleEx.BoldItalic);
gfx.DrawString($"Versand {list.Name}", font, XBrushes.Black,
new XRect(0, 0, page.Width.Point, page.Height.Point), XStringFormats.Center);
document.Save(path);
}
public List<(int, int)> GroupAddresses(int setID)
{
return null;
}
} }
+3 -3
View File
@@ -2,16 +2,16 @@
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="Logof_Client.Wiki.EditorWindow" x:Class="Logof_Client.Wiki.EditorWindow"
Title="Wiki Editor" MinWidth="600" MinHeight="350" WindowState="Maximized"> Title="Wiki Editor" MinWidth="600" MinHeight="350" WindowState="Maximized">
<Grid> <Grid Margin="10,0,10,10">
<Grid.RowDefinitions> <Grid.RowDefinitions>
<RowDefinition Height="50" /> <RowDefinition Height="50" />
<RowDefinition Height="*" /> <RowDefinition Height="*" />
</Grid.RowDefinitions> </Grid.RowDefinitions>
<StackPanel Grid.Row="0" Orientation="Horizontal"> <StackPanel Grid.Row="0" Spacing="10" Orientation="Horizontal">
<Button x:Name="BtnSave" Content="Speichern" Click="BtnSave_OnClick" /> <Button x:Name="BtnSave" Content="Speichern" Click="BtnSave_OnClick" />
<Button x:Name="BtnSaveAs" Content="Speichern unter..." Click="BtnSaveAs_OnClick" /> <Button x:Name="BtnSaveAs" Content="Speichern unter..." Click="BtnSaveAs_OnClick" />
<Button x:Name="BtnDelete" Content="Löschen" Click="BtnDelete_OnClick" /> <Button x:Name="BtnDelete" Content="Löschen" Click="BtnDelete_OnClick" />
</StackPanel> </StackPanel>
<TextBox Grid.Row="1" x:Name="TbContent" /> <TextBox AcceptsTab="True" AcceptsReturn="True" Grid.Row="1" x:Name="TbContent" />
</Grid> </Grid>
</Window> </Window>
+5 -1
View File
@@ -52,7 +52,11 @@ public partial class EditorWindow : Window
{ {
var result = await MessageBox.Show(null, "Sicher?", "Sicher?", MessageBoxButton.YesNo); var result = await MessageBox.Show(null, "Sicher?", "Sicher?", MessageBoxButton.YesNo);
if (result == MessageBoxResult.No) return; if (result == MessageBoxResult.No) return;
File.Delete(filename); try
{
File.Delete(filename);
} catch {}
MainWindow._instance.PopulateNavTree(); MainWindow._instance.PopulateNavTree();
Close(); Close();
} }