28 Commits

Author SHA1 Message Date
fierke a2d0b72899 [feat:] include Markdown.Avalonia for better rendering 2026-06-08 09:05:12 +02:00
fierke acaf0856ed [chore:] filter by germany for running-sheet creation 2026-06-08 08:52:46 +02:00
fierke 2da822e0e7 [chore:] added IsGermany()-function 2026-06-08 08:52:06 +02:00
fierke a4c7132756 [chore:] some log changes 2026-06-04 08:42:34 +02:00
fierke c32cd44184 [fix:] missing fields from the merge 2026-06-04 08:30:36 +02:00
fierke af3f8234c0 Merge branch 'running-sheets'
# Conflicts:
#	MainWindow.axaml.cs
#	Tasks/AddressCreation.cs
#	Tasks/PdfBuilder.cs
2026-06-04 08:28:52 +02:00
fierke 516ca58740 [fix:] plz/pplz was not normalized during address creation 2026-06-04 07:52:08 +02:00
fierke c140a20549 [chore:] textbox-changements global save 2026-06-03 16:38:00 +02:00
fierke ac717c5345 [fix:] file handling 2026-06-03 16:36:36 +02:00
fierke 1b200ee41e [chore:] set used_plz 2026-06-03 16:05:11 +02:00
fierke 0750c51448 [chore:] used_plz at KasPerson for the plz used in the final address) 2026-06-03 16:05:02 +02:00
fierke 5a47fedcf0 [feat:] basic running-sheet creation implementation (buggy, because of plzs) 2026-06-03 16:04:39 +02:00
fierke b22d33dc97 [chore:] implemented GetCustomerByID() 2026-06-03 16:03:49 +02:00
fierke 8b740304f6 [fix:] running-sheet configurations are ints 2026-06-03 16:03:29 +02:00
fierke 57b4ac5001 [chore:] initial page setup (running sheets) 2026-05-27 09:06:04 +02:00
fierke 1580d30d72 [chore:] ui element disableing (customer settings) 2026-05-27 08:42:25 +02:00
fierke 0dacaf19b9 [chore:] control name 2026-05-27 08:41:42 +02:00
fierke 75b6b1dc4d [chore:] various tiny improvements 2026-05-20 08:00:20 +02:00
fierke 1161a437c4 [fix:] wiki preview reloading after saving changes 2026-05-19 09:44:14 +02:00
fierke 605ba95848 [fix:] message box center screen startup 2026-05-19 09:32:06 +02:00
fierke eb38bafd23 [feat:] delete address sets (FINALLY, this was so hard to implement, it took almost 2 minutes) 2026-05-19 09:31:35 +02:00
fierke e2d5ae2a70 Merge pull request '[fix?:] windows paths (ai-based since windows is boring)' (#57) from windows-paths into main
Reviewed-on: #57

since this still works on any linux machines and theoretical on windows machines, we're merging it to prevent wrong commits cause i configured something wrong
2026-05-19 07:24:01 +00:00
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
10 changed files with 616 additions and 335 deletions
+28
View File
@@ -178,6 +178,34 @@ public class KasPerson
public string abteilung { get; set; } public string abteilung { get; set; }
public string funktionad { get; set; } public string funktionad { get; set; }
public string used_plz { get; set; } = "";
public bool IsGermany()
{
var trimmedLand = (land ?? "").Trim();
var trimmedLowerLand = trimmedLand.ToLower();
var isGermany = trimmedLowerLand == "germany" || trimmedLowerLand == "ger" ||
trimmedLowerLand == "" || trimmedLowerLand == "de" ||
trimmedLowerLand == "deutschland";
return isGermany;
}
public static void SetUsedPLZ(int id, string plz)
{
foreach (var set in Settings._instance.addressSets.addresses)
{
foreach (var add in set.KasPersons)
{
if (add.id == id)
{
add.used_plz = plz;
return;
}
}
}
}
public static int GenerateNewID(int base_id) public static int GenerateNewID(int base_id)
{ {
//var newid = 100000 + base_id; //var newid = 100000 + base_id;
+17 -1
View File
@@ -23,7 +23,7 @@ public class Settings
public static void Save() public static void Save()
{ {
if (!Directory.Exists(Global._instance.config_path)) if (!Directory.Exists(Global._instance.config_path) && !File.Exists((Global._instance.config_path)))
Directory.CreateDirectory(Global._instance.config_path); Directory.CreateDirectory(Global._instance.config_path);
// if (!string.IsNullOrEmpty(Global._instance.config_path)) _instance.settingsPath = Global._instance.config_path; // if (!string.IsNullOrEmpty(Global._instance.config_path)) _instance.settingsPath = Global._instance.config_path;
@@ -67,6 +67,9 @@ public class PdfExportSettings
public double fontSize { get; set; } = 9; public double fontSize { get; set; } = 9;
public double smallFontSize { get; set; } = 6; public double smallFontSize { get; set; } = 6;
public bool exportRunningSheets { get; set; } = true;
public int rsNumGrouped { get; set; } = 25;
public int rsPlzStartpoint { get; set; } = 2;
} }
public class Global public class Global
@@ -169,6 +172,19 @@ public class Customer
public char separator { get; set; } = ','; public char separator { get; set; } = ',';
public int ID { get; } public int ID { get; }
public static Customer GetCustomerByID(int id)
{
foreach (var customer in Settings._instance.customers.customers)
{
if (id == customer.ID)
{
return customer;
}
}
return null;
}
// public static int GetIDByCustomerListItem(string item_content) // public static int GetIDByCustomerListItem(string item_content)
// { // {
+1
View File
@@ -21,6 +21,7 @@
</PackageReference> </PackageReference>
<PackageReference Include="ISO3166" Version="1.0.4" /> <PackageReference Include="ISO3166" Version="1.0.4" />
<PackageReference Include="Lucide.Avalonia" Version="0.1.35" /> <PackageReference Include="Lucide.Avalonia" Version="0.1.35" />
<PackageReference Include="Markdown.Avalonia" Version="11.0.3" />
<PackageReference Include="Newtonsoft.Json" Version="13.0.4" /> <PackageReference Include="Newtonsoft.Json" Version="13.0.4" />
<PackageReference Include="PdfSharp" Version="6.1.1" /> <PackageReference Include="PdfSharp" Version="6.1.1" />
</ItemGroup> </ItemGroup>
+16 -8
View File
@@ -2,6 +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"
xmlns:md="https://github.com/whistyun/Markdown.Avalonia"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450" mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
MinWidth="1000" MinHeight="600" IsVisible="False" MinWidth="1000" MinHeight="600" IsVisible="False"
x:Class="Logof_Client.MainWindow" WindowState="Maximized" Icon="assets/icon.ico" x:Class="Logof_Client.MainWindow" WindowState="Maximized" Icon="assets/icon.ico"
@@ -78,7 +79,7 @@
</StackPanel> </StackPanel>
</MenuItem.Header> </MenuItem.Header>
</MenuItem> </MenuItem>
<MenuItem x:Name="MnIAdSetDelete" Click="MnIAdSetRename_OnClick" IsEnabled="False"> <MenuItem x:Name="MnIAdSetDelete" Click="MnIAdSetDelete_OnClick" IsEnabled="True">
<MenuItem.Header> <MenuItem.Header>
<StackPanel Orientation="Horizontal"> <StackPanel Orientation="Horizontal">
<LucideIcon Kind="Trash" Width="12" Height="12" Size="12" /> <LucideIcon Kind="Trash" Width="12" Height="12" Size="12" />
@@ -254,6 +255,7 @@
<Label Grid.Column="0" Content="Zellenrand rechts (mm)"></Label> <Label Grid.Column="0" Content="Zellenrand rechts (mm)"></Label>
<NumericUpDown Grid.Column="1" x:Name="NudExpMargCellPaddingRight" Minimum="0" Maximum="20" Value="5"></NumericUpDown> <NumericUpDown Grid.Column="1" x:Name="NudExpMargCellPaddingRight" Minimum="0" Maximum="20" Value="5"></NumericUpDown>
</Grid> </Grid>
<CheckBox Content="Laufzettel erstellen" x:Name="CbExpRnsEnable"></CheckBox>
</StackPanel> </StackPanel>
<StackPanel Grid.Column="1" Orientation="Vertical" Spacing="10"> <StackPanel Grid.Column="1" Orientation="Vertical" Spacing="10">
@@ -273,6 +275,10 @@
<Label Content="Zellenabstand links"></Label> <Label Content="Zellenabstand links"></Label>
<NumericUpDown Grid.Column="1" x:Name="TbExpMargMarginLeft" Minimum="0" Maximum="20" Value="0"></NumericUpDown> <NumericUpDown Grid.Column="1" x:Name="TbExpMargMarginLeft" Minimum="0" Maximum="20" Value="0"></NumericUpDown>
</Grid> </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>
<StackPanel Grid.Column="2" Orientation="Vertical" Spacing="10"> <StackPanel Grid.Column="2" Orientation="Vertical" Spacing="10">
@@ -292,6 +298,10 @@
<Label Grid.Column="0" Content="Schriftgröße (klein)"></Label> <Label Grid.Column="0" Content="Schriftgröße (klein)"></Label>
<NumericUpDown Grid.Column="1" x:Name="NudExpMargSmallFontSize" Minimum="3" Maximum="30" Value="6"></NumericUpDown> <NumericUpDown Grid.Column="1" x:Name="NudExpMargSmallFontSize" Minimum="3" Maximum="30" Value="6"></NumericUpDown>
</Grid> </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> </StackPanel>
</Grid> </Grid>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center"> <StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
@@ -361,9 +371,7 @@
</StackPanel> </StackPanel>
<Border Grid.Row="1" Margin="8" BorderBrush="#DDD" BorderThickness="1" CornerRadius="4"> <Border Grid.Row="1" Margin="8" BorderBrush="#DDD" BorderThickness="1" CornerRadius="4">
<ScrollViewer> <md:MarkdownScrollViewer x:Name="MsvWikiView"/>
<StackPanel Name="PreviewPanel" Margin="8" />
</ScrollViewer>
</Border> </Border>
</Grid> </Grid>
</Grid> </Grid>
@@ -388,7 +396,7 @@
<Label Grid.Column="0">config-Datei</Label> <Label Grid.Column="0">config-Datei</Label>
<StackPanel Grid.Column="1" Orientation="Vertical" Spacing="5"> <StackPanel Grid.Column="1" Orientation="Vertical" Spacing="5">
<StackPanel Orientation="Horizontal" Spacing="5"> <StackPanel Orientation="Horizontal" Spacing="5">
<TextBox x:Name="TbConfigPath" HorizontalAlignment="Stretch" <TextBox x:Name="TbConfigPath" HorizontalAlignment="Stretch" TextChanged="Tb_OnTextChanged"
Watermark="/home/username/.config/logofclient/" /> Watermark="/home/username/.config/logofclient/" />
<Button x:Name="BtnConfigPath" HorizontalAlignment="Right"> <Button x:Name="BtnConfigPath" HorizontalAlignment="Right">
<Button.Content> <Button.Content>
@@ -405,7 +413,7 @@
<Label Grid.Column="0">Wiki-Pfad</Label> <Label Grid.Column="0">Wiki-Pfad</Label>
<StackPanel Grid.Column="1" Orientation="Vertical" Spacing="5"> <StackPanel Grid.Column="1" Orientation="Vertical" Spacing="5">
<StackPanel Orientation="Horizontal" Spacing="5"> <StackPanel Orientation="Horizontal" Spacing="5">
<TextBox x:Name="TbWikiPath" HorizontalAlignment="Stretch" <TextBox x:Name="TbWikiPath" HorizontalAlignment="Stretch" TextChanged="Tb_OnTextChanged"
Watermark="/home/username/.config/logofclient/wiki" /> Watermark="/home/username/.config/logofclient/wiki" />
<Button IsEnabled="True" x:Name="BtnWikiPath" HorizontalAlignment="Right"> <Button IsEnabled="True" x:Name="BtnWikiPath" HorizontalAlignment="Right">
<Button.Content> <Button.Content>
@@ -422,7 +430,7 @@
<Label Grid.Column="0">Font-Pfad</Label> <Label Grid.Column="0">Font-Pfad</Label>
<StackPanel Grid.Column="1" Orientation="Vertical" Spacing="5"> <StackPanel Grid.Column="1" Orientation="Vertical" Spacing="5">
<StackPanel Orientation="Horizontal" Spacing="5"> <StackPanel Orientation="Horizontal" Spacing="5">
<TextBox x:Name="TbFontPath" HorizontalAlignment="Stretch" <TextBox x:Name="TbFontPath" HorizontalAlignment="Stretch" TextChanged="Tb_OnTextChanged"
Watermark="[App-Direcotry]/assets/fonts/" /> Watermark="[App-Direcotry]/assets/fonts/" />
<Button IsEnabled="True" x:Name="BtnFontPath" HorizontalAlignment="Right"> <Button IsEnabled="True" x:Name="BtnFontPath" HorizontalAlignment="Right">
<Button.Content> <Button.Content>
@@ -485,7 +493,7 @@
TextChanged="TbSettingsCustomerSenderAddress_OnTextChanged" TextChanged="TbSettingsCustomerSenderAddress_OnTextChanged"
x:Name="TbSettingsCustomerSenderAddress" /> x:Name="TbSettingsCustomerSenderAddress" />
</Grid> </Grid>
<Grid ColumnDefinitions="150,*,Auto"> <Grid ColumnDefinitions="150,*,Auto" x:Name="GrdCSVDividerButtonsAndTb">
<Label Content="CSV-Trennzeichen" /> <Label Content="CSV-Trennzeichen" />
<TextBox Grid.Column="1" Watermark="," <TextBox Grid.Column="1" Watermark=","
HorizontalAlignment="Stretch" Margin="0,0,5,0" HorizontalAlignment="Stretch" Margin="0,0,5,0"
+84 -19
View File
@@ -28,6 +28,7 @@ public partial class MainWindow : Window
Logger.Log($"Session on {DateTime.Now:G}"); Logger.Log($"Session on {DateTime.Now:G}");
Logger.Log("Initializing..."); Logger.Log("Initializing...");
InitializeComponent(); InitializeComponent();
SetSettingsCustomerEnabledState(false);
//Hide(); //Hide();
var s = new StartupWindow(); var s = new StartupWindow();
@@ -38,6 +39,11 @@ public partial class MainWindow : Window
Logger.Log("Loading settings..."); Logger.Log("Loading settings...");
Global.Load(); Global.Load();
Settings.Load(); Settings.Load();
if (!string.IsNullOrWhiteSpace(Global._instance.config_path))
TbConfigPath.Text = PathUtilities.NormalizeFileSystemPath(Global._instance.config_path);
LoadPdfExportOptions(); LoadPdfExportOptions();
HookPdfExportOptionEvents(); HookPdfExportOptionEvents();
@@ -132,6 +138,8 @@ public partial class MainWindow : Window
private void MnuExit_OnClick(object? sender, RoutedEventArgs e) private void MnuExit_OnClick(object? sender, RoutedEventArgs e)
{ {
Settings.Save();
Global.Save();
Environment.Exit(0); Environment.Exit(0);
} }
@@ -212,23 +220,29 @@ public partial class MainWindow : Window
private async void NavTree_SelectionChanged(object? sender, SelectionChangedEventArgs e) private async void NavTree_SelectionChanged(object? sender, SelectionChangedEventArgs e)
{
ReloadWikiItem();
}
private async void ReloadWikiItem()
{ {
if (NavTree.SelectedItem is TreeViewItem t && t.Tag is WikiItem item && !item.IsFolder) if (NavTree.SelectedItem is TreeViewItem t && t.Tag is WikiItem item && !item.IsFolder)
{ {
_selectedWikiFilePath = item.Path; _selectedWikiFilePath = item.Path;
var text = await _wikiService.LoadFileContentAsync(item.Path); var text = await _wikiService.LoadFileContentAsync(item.Path);
try MsvWikiView.Markdown = text;
{ // try
PreviewPanel.Children.Clear(); // {
var rendered = MarkdownRenderer.Render(text ?? string.Empty); // PreviewPanel.Children.Clear();
PreviewPanel.Children.Add(rendered); // var rendered = MarkdownRenderer.Render(text ?? string.Empty);
} // PreviewPanel.Children.Add(rendered);
catch (Exception ex) // }
{ // catch (Exception ex)
Logger.Log($"Error while rendering markdown: {ex.Message}", Logger.LogType.Error); // {
PreviewPanel.Children.Clear(); // Logger.Log($"Error while rendering markdown: {ex.Message}", Logger.LogType.Error);
PreviewPanel.Children.Add(new TextBlock { Text = text ?? string.Empty }); // PreviewPanel.Children.Clear();
} // PreviewPanel.Children.Add(new TextBlock { Text = text ?? string.Empty });
// }
EditButton.IsEnabled = true; EditButton.IsEnabled = true;
} }
@@ -255,6 +269,8 @@ public partial class MainWindow : Window
ExpandAndFindNode(nodes, selectPath, out var selectedNode) && ExpandAndFindNode(nodes, selectPath, out var selectedNode) &&
selectedNode != null) selectedNode != null)
NavTree.SelectedItem = selectedNode; NavTree.SelectedItem = selectedNode;
ReloadWikiItem();
}catch (Exception ex) }catch (Exception ex)
{ {
Logger.Log($"Error while populating nav tree: {ex.Message}", Logger.LogType.Error); Logger.Log($"Error while populating nav tree: {ex.Message}", Logger.LogType.Error);
@@ -444,6 +460,7 @@ public partial class MainWindow : Window
TbSettingsCustomerDescription.Text = ""; TbSettingsCustomerDescription.Text = "";
TbSettingsCustomerName.Text = ""; TbSettingsCustomerName.Text = "";
TbSettingsCustomerPatchInfo.Text = ""; TbSettingsCustomerPatchInfo.Text = "";
TbSettingsCustomerName.Focus();
Settings.Save(); Settings.Save();
RefreshCustomerItems(); RefreshCustomerItems();
@@ -469,6 +486,7 @@ public partial class MainWindow : Window
private void LstSettingsCustomers_OnSelectionChanged(object? sender, SelectionChangedEventArgs e) private void LstSettingsCustomers_OnSelectionChanged(object? sender, SelectionChangedEventArgs e)
{ {
SetSettingsCustomerEnabledState(false);
if (LstSettingsCustomers.SelectedIndex < 0) return; if (LstSettingsCustomers.SelectedIndex < 0) return;
Settings._instance.customers.current = Settings._instance.customers.current =
((Customer)LstSettingsCustomers.SelectedItems[0]); ((Customer)LstSettingsCustomers.SelectedItems[0]);
@@ -483,9 +501,19 @@ public partial class MainWindow : Window
TbSettingsCustomerPatchInfo.Text = Settings._instance.customers.current.patch.ToString(); TbSettingsCustomerPatchInfo.Text = Settings._instance.customers.current.patch.ToString();
else else
TbSettingsCustomerPatchInfo.Text = ""; TbSettingsCustomerPatchInfo.Text = "";
SetSettingsCustomerEnabledState();
//} //}
} }
private void SetSettingsCustomerEnabledState(bool enable = true)
{
List<Object> nboom = new() { BtnSettingsImportCustomerAddressPatch, GrdCSVDividerButtonsAndTb, TbSettingsCustomerDescription, TbSettingsCustomerName, BtnDeleteCustomer, TbSettingsCustomerSenderAddress};
foreach (var obj in nboom)
{
(obj as Control).IsEnabled = enable;
}
}
private async void EditButton_Click(object? sender, RoutedEventArgs e) private async void EditButton_Click(object? sender, RoutedEventArgs e)
{ {
if (string.IsNullOrWhiteSpace(_selectedWikiFilePath)) if (string.IsNullOrWhiteSpace(_selectedWikiFilePath))
@@ -494,7 +522,13 @@ public partial class MainWindow : Window
return; return;
} }
var editedWikiFilePath = _selectedWikiFilePath;
EditorWindow ew = new(_selectedWikiFilePath); EditorWindow ew = new(_selectedWikiFilePath);
ew.Closed += (_, _) =>
{
if (!string.IsNullOrWhiteSpace(editedWikiFilePath) && File.Exists(editedWikiFilePath))
PopulateNavTree(editedWikiFilePath, editedWikiFilePath);
};
ew.Show(); ew.Show();
//await MessageBox.Show(this, "Edit feature is currently disabled.", "Edit Disabled"); //await MessageBox.Show(this, "Edit feature is currently disabled.", "Edit Disabled");
@@ -739,8 +773,9 @@ public partial class MainWindow : Window
list.Add((KasAddressList)item); list.Add((KasAddressList)item);
try try
{ {
StartCombine(list, Convert.ToInt32(LstCustomers.SelectedItem), "difference", GetCombiningTyp()); StartCombine(list, Convert.ToInt32((LstCustomers.SelectedItem as Customer).ID), "difference", GetCombiningTyp());
}catch (Exception ex) }
catch (Exception ex)
{ {
Logger.Log($"Error while combining (difference): {ex.Message}", Logger.LogType.Error); Logger.Log($"Error while combining (difference): {ex.Message}", Logger.LogType.Error);
} }
@@ -769,7 +804,7 @@ public partial class MainWindow : Window
list.Add((KasAddressList)item); list.Add((KasAddressList)item);
try try
{ {
StartCombine(list, Convert.ToInt32(LstCustomers.SelectedItem.ToString().Split(" - ")[0]), "intersection", GetCombiningTyp()); StartCombine(list, Convert.ToInt32((LstCustomers.SelectedItem as Customer).ID), "intersection", GetCombiningTyp());
} }
catch (Exception ex) catch (Exception ex)
{ {
@@ -796,7 +831,7 @@ public partial class MainWindow : Window
foreach (var item in LstCustomerAdressSets.SelectedItems) foreach (var item in LstCustomerAdressSets.SelectedItems)
list.Add((KasAddressList)item); list.Add((KasAddressList)item);
StartCombine(list, Convert.ToInt32(LstCustomers.SelectedItem.ToString().Split(" - ")[0]), "symdiff", GetCombiningTyp()); 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)
@@ -828,13 +863,13 @@ public partial class MainWindow : Window
var filePath = await saveDialog.ShowAsync(this); var filePath = await saveDialog.ShowAsync(this);
Console.WriteLine($"RAW: {filePath}"); Logger.Log($"RAW: {filePath}");
if (!string.IsNullOrWhiteSpace(filePath)) if (!string.IsNullOrWhiteSpace(filePath))
{ {
filePath = PathUtilities.NormalizeFileSystemPath(filePath); filePath = PathUtilities.NormalizeFileSystemPath(filePath);
Console.WriteLine($"PATH: {filePath}"); Logger.Log($"PATH: {filePath}");
var builder = new PdfBuilder(Settings._instance.pdfExport); var builder = new PdfBuilder(Settings._instance.pdfExport);
@@ -844,7 +879,7 @@ public partial class MainWindow : Window
filePath filePath
); );
Console.WriteLine("PDF OK"); Logger.Log("PDF OK");
} }
} }
@@ -1237,4 +1272,34 @@ public partial class MainWindow : Window
} }
} }
private async void MnIAdSetDelete_OnClick(object? sender, RoutedEventArgs e)
{
if(await MessageBox.Show(this,"Wirklich löschen?","",MessageBoxButton.YesNo) == MessageBoxResult.Yes)
{
var cus_id = ((Customer)LstCustomers.SelectedItems[0]).ID;
var id = (LstCustomerAdressSets.SelectedItems[0] as KasAddressList).ID;
try
{
foreach (var set in Settings._instance.addressSets.addresses)
if (set.ID == id)
{
Settings._instance.addressSets.addresses.Remove(set);
Settings.Save();
RefreshAddressSetListItems(cus_id);
break;
}
}
catch (Exception ex)
{
MessageBox.Show(this, ex.StackTrace, "Fehler");
Logger.Log($"Error while deleting address set: {ex.Message}", Logger.LogType.Error);
}}
}
private void Tb_OnTextChanged(object? sender, TextChangedEventArgs e)
{
Global.Save();
}
} }
+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"
x:Class="Logof_Client.MessageBox" Icon="assets/icon.ico" x:Class="Logof_Client.MessageBox" Icon="assets/icon.ico"
Title="MessageBox"> Title="MessageBox">
<StackPanel> <StackPanel>
+26 -12
View File
@@ -43,8 +43,7 @@ public static class AddressCreator
public static string? CreateFinalMarkdownString(int id) public static string? CreateFinalMarkdownString(int id)
{ {
// Maximum seven lines of information // Maximum seven lines of information
try
{
// find the address // find the address
KasPerson? address = null; KasPerson? address = null;
var string_address = ""; var string_address = "";
@@ -105,7 +104,9 @@ public static class AddressCreator
// Alternative A: pplz valid and city existing // Alternative A: pplz valid and city existing
if (!string.IsNullOrEmpty(address.ort) && CheckPLZ(address.pplz, address.land)) if (!string.IsNullOrEmpty(address.ort) && CheckPLZ(address.pplz, address.land))
{ {
string_address = address.pplz + " " + address.ort + "\n" + string_address; string pplz = NormalizeGermanPLZ(address.pplz);
KasPerson.SetUsedPLZ(id, pplz);
string_address = pplz + " " + address.ort + "\n" + string_address;
address_line_count++; address_line_count++;
if (!string.IsNullOrWhiteSpace(address.postfach)) if (!string.IsNullOrWhiteSpace(address.postfach))
{ {
@@ -151,7 +152,9 @@ public static class AddressCreator
} // Alternative B: plz valid and city existing } // Alternative B: plz valid and city existing
else if (!string.IsNullOrEmpty(address.ort) && CheckPLZ(address.plz, address.land)) else if (!string.IsNullOrEmpty(address.ort) && CheckPLZ(address.plz, address.land))
{ {
string_address = address.plz + " " + address.ort + "\n" + string_address; string plz = NormalizeGermanPLZ(address.plz);
KasPerson.SetUsedPLZ(id, plz);
string_address = plz + " " + address.ort + "\n" + string_address;
address_line_count++; address_line_count++;
if (!string.IsNullOrWhiteSpace(address.strasse)) if (!string.IsNullOrWhiteSpace(address.strasse))
{ {
@@ -198,13 +201,6 @@ public static class AddressCreator
if (address_line_count > 1) return string_address; if (address_line_count > 1) return string_address;
return null; return null;
} }
catch (Exception ex)
{
Logger.Log($"Error while creating markdown string: {ex.Message}", Logger.LogType.Error);
}
return null;
}
public static string CreateNameLine(string anredezus, string anrede, string titel, string vorname, string adel, public static string CreateNameLine(string anredezus, string anrede, string titel, string vorname, string adel,
string name, string namezus) string name, string namezus)
@@ -231,7 +227,6 @@ public static class AddressCreator
} }
return null; return null;
} }
/// <summary> /// <summary>
@@ -277,4 +272,23 @@ public static class AddressCreator
return false; return false;
} }
public static string NormalizeGermanPLZ(string plz)
{
if(plz.Length == 5) return plz;
if(plz.Length > 5)
{
return plz.Substring(0, 5);
}
if (plz.Length < 5)
{
int toadd = 5 - plz.Length;
for (int i = 0; i < toadd; i++)
{
plz = "0" + plz;
}
}
return plz;
}
} }
+149
View File
@@ -134,6 +134,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);
if (_settings.exportRunningSheets)
{
ExportRunningSheets(addressSetId, outputPath);
}
CreateAddressLabelPdfWithPlaceholder(addresses, placeholderText, outputPath); CreateAddressLabelPdfWithPlaceholder(addresses, placeholderText, outputPath);
} }
catch (Exception ex) catch (Exception ex)
@@ -480,4 +491,142 @@ 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;
var grouped_nums = GroupAddresses(setID);
foreach (var result in grouped_nums)
{
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, width, height);
gfx.DrawLine(XPens.Black, margin, height, width, height);
var boldfont = new XFont("Cantarell", 11, XFontStyleEx.Bold);
var font = new XFont("Cantarell", 11, XFontStyleEx.Regular);
var bigboldfont = new XFont("Cantarell", 35, XFontStyleEx.Bold);
// Versandinfo
gfx.DrawString($"Versand {list.Name}", boldfont, XBrushes.Black,
new XRect(margin+5, margin, width-margin, 25), XStringFormats.CenterLeft);
gfx.DrawString($"Start: ", font, XBrushes.Black,
new XRect(margin+5, margin+25, width-margin, 25), XStringFormats.CenterLeft);
gfx.DrawString($"{result.Item3}", font, XBrushes.Black,
new XRect(margin+75, margin+25, width-margin, 25), XStringFormats.CenterLeft);
gfx.DrawString($"Ende: ", font, XBrushes.Black,
new XRect(margin+5, margin+40, width-margin, 25), XStringFormats.CenterLeft);
gfx.DrawString($"{result.Item4}", font, XBrushes.Black,
new XRect(margin+75, margin+40, width-margin, 25), XStringFormats.CenterLeft);
gfx.DrawString($"Kunde: ", font, XBrushes.Black,
new XRect(margin+5, margin+55, width-margin, 25), XStringFormats.CenterLeft);
gfx.DrawString($"{Customer.GetCustomerByID(list.owner_id).name}", font, XBrushes.Black,
new XRect(margin+75, margin+55, width-margin, 25), XStringFormats.CenterLeft);
gfx.DrawString($"Absender: ", font, XBrushes.Black,
new XRect(margin+5, margin+70, width-margin, 25), XStringFormats.CenterLeft);
gfx.DrawString($"{Customer.GetCustomerByID(list.owner_id).sender_address}", font, XBrushes.Black,
new XRect(margin+75, margin+70, width-margin, 25), XStringFormats.CenterLeft);
gfx.DrawString($"Anzahl: ", font, XBrushes.Black,
new XRect(margin+5, margin+85, width-margin, 25), XStringFormats.CenterLeft);
gfx.DrawString($"{result.Item5}", font, XBrushes.Black,
new XRect(margin+75, margin+85, width-margin, 25), XStringFormats.CenterLeft);
// logofclient ad
gfx.DrawString($"powered by logofclient", font, XBrushes.Black,
new XRect(margin+5, height-55, width-margin, 25), XStringFormats.CenterLeft);
gfx.DrawString($"(c) 2026 MyPapertown", font, XBrushes.Black,
new XRect(margin+5, height-40, width-margin, 25), XStringFormats.CenterLeft);
gfx.DrawString($"mypapercloud.de/logof", font, XBrushes.Black,
new XRect(margin+5, height-25, width-margin, 25), XStringFormats.CenterLeft);
int total_frac = 0;
foreach (var item in grouped_nums)
{
if (item.Item2 == result.Item2) total_frac++;
}
// group number
gfx.DrawString($"{result.Item2}", bigboldfont, XBrushes.Black,
new XRect(margin, margin, width-margin, (height-margin)/2), XStringFormats.Center);
gfx.DrawString($"Fraktion {result.Item1}/{total_frac}", font, XBrushes.Black,
new XRect(margin, margin, width-margin, (height-margin)/2 + 50), XStringFormats.Center);
}
document.Save(path);
}
/// <summary>
/// Calculates address groups to summarize for the single pages of the running sheets.
/// </summary>
/// <param name="setID"></param>
/// <returns>List of quadruples consisting of a number and the starting of the plz, as well as first, last plz and total amount of addresses</returns>
public List<(int, string, string, string, int)> GroupAddresses(int setID)
{
int grpcount = Settings._instance.pdfExport.rsNumGrouped; // Amount of addresses per group
int stpoint = Settings._instance.pdfExport.rsPlzStartpoint; // group starting point (first n characters of the plz)
KasAddressList list = Settings._instance.addressSets.GetAddressSetByID(setID);
if (list == null)
throw new Exception("AddressSet nicht gefunden");
List<(int, string, string, string, int)> output = new();
List<IGrouping<string, KasPerson>> sorted_list = list.KasPersons
.Where(x => !string.IsNullOrEmpty(x?.used_plz) &&
x.used_plz.Length >= stpoint && x.IsGermany())
.OrderBy(x => x.used_plz)
.GroupBy(x => x.used_plz.Substring(0, stpoint))
.ToList();
foreach (var group in sorted_list)
{
string start = group.Key;
int fraktion = 0;
for (int count = 0; count < group.Count(); count += grpcount)
{
fraktion++;
int currentGroupSize = Math.Min(grpcount, group.Count() - count);
string first = group.ElementAt(count).used_plz;
string last = group.ElementAt(count + currentGroupSize - 1).used_plz;
output.Add((fraktion, start, first, last, currentGroupSize));
}
}
return output;
}
} }
+1 -1
View File
@@ -35,7 +35,7 @@ public partial class EditorWindow : Window
try try
{ {
File.WriteAllText(filename, TbContent.Text); File.WriteAllText(filename, TbContent.Text);
MainWindow._instance.PopulateNavTree(); MainWindow._instance.PopulateNavTree(filename, filename);
} }
catch (Exception ex) catch (Exception ex)
{ {
+126 -126
View File
@@ -11,130 +11,130 @@ namespace Logof_Client.Wiki;
public static class MarkdownRenderer public static class MarkdownRenderer
{ {
public static Control Render(string markdown) // public static Control Render(string markdown)
{ // {
try // try
{ // {
var panel = new StackPanel { Spacing = 6 }; // var panel = new StackPanel { Spacing = 6 };
if (string.IsNullOrWhiteSpace(markdown)) return panel; // if (string.IsNullOrWhiteSpace(markdown)) return panel;
//
var doc = Markdown.Parse(markdown); // var doc = Markdown.Parse(markdown);
//
foreach (var block in doc) // foreach (var block in doc)
{ // {
switch (block) // switch (block)
{ // {
case HeadingBlock hb: // case HeadingBlock hb:
{ // {
var text = GetInlineText(hb.Inline); // var text = GetInlineText(hb.Inline);
var tb = new TextBlock // var tb = new TextBlock
{ // {
Text = text, // Text = text,
FontWeight = FontWeight.Bold, // FontWeight = FontWeight.Bold,
Margin = new Avalonia.Thickness(0, hb.Level == 1 ? 6 : 2, 0, 2) // Margin = new Avalonia.Thickness(0, hb.Level == 1 ? 6 : 2, 0, 2)
}; // };
tb.FontSize = hb.Level switch { 1 => 22, 2 => 18, 3 => 16, _ => 14 }; // tb.FontSize = hb.Level switch { 1 => 22, 2 => 18, 3 => 16, _ => 14 };
panel.Children.Add(tb); // panel.Children.Add(tb);
break; // break;
} // }
//
case ParagraphBlock pb: // case ParagraphBlock pb:
{ // {
var text = GetInlineText(pb.Inline); // var text = GetInlineText(pb.Inline);
var tb = new TextBlock { Text = text, TextWrapping = Avalonia.Media.TextWrapping.Wrap }; // var tb = new TextBlock { Text = text, TextWrapping = Avalonia.Media.TextWrapping.Wrap };
panel.Children.Add(tb); // panel.Children.Add(tb);
break; // break;
} // }
//
case FencedCodeBlock cb: // case FencedCodeBlock cb:
{ // {
var sb = new StringBuilder(); // var sb = new StringBuilder();
foreach (var line in cb.Lines.Lines) // foreach (var line in cb.Lines.Lines)
{ // {
sb.Append(line.ToString()); // sb.Append(line.ToString());
} // }
var codeBox = new TextBox // var codeBox = new TextBox
{ // {
Text = sb.ToString(), // Text = sb.ToString(),
FontFamily = "Consolas, monospace", // FontFamily = "Consolas, monospace",
IsReadOnly = true, // IsReadOnly = true,
AcceptsReturn = true // AcceptsReturn = true
}; // };
panel.Children.Add(codeBox); // panel.Children.Add(codeBox);
break; // break;
} // }
//
case ListBlock lb: // case ListBlock lb:
{ // {
var sp = new StackPanel { Spacing = 2 }; // var sp = new StackPanel { Spacing = 2 };
var number = 1; // var number = 1;
foreach (var item in lb) // foreach (var item in lb)
{ // {
if (item is ListItemBlock lib) // if (item is ListItemBlock lib)
{ // {
var itemText = new StringBuilder(); // var itemText = new StringBuilder();
foreach (var sub in lib) // foreach (var sub in lib)
{ // {
if (sub is ParagraphBlock pp) // if (sub is ParagraphBlock pp)
itemText.Append(GetInlineText(pp.Inline)); // itemText.Append(GetInlineText(pp.Inline));
} // }
var tb = new TextBlock { Text = (lb.IsOrdered ? (number++ + ". ") : "• ") + itemText.ToString() }; // var tb = new TextBlock { Text = (lb.IsOrdered ? (number++ + ". ") : "• ") + itemText.ToString() };
sp.Children.Add(tb); // sp.Children.Add(tb);
} // }
} // }
panel.Children.Add(sp); // panel.Children.Add(sp);
break; // break;
} // }
//
default: // default:
{ // {
// fallback: raw text // // fallback: raw text
panel.Children.Add(new TextBlock { Text = block.ToString() }); // panel.Children.Add(new TextBlock { Text = block.ToString() });
break; // break;
} // }
} // }
} // }
//
return panel; // return panel;
} catch (Exception ex) { Logger.Log($"Error while : {ex.Message}",Logger.LogType.Error);} // } catch (Exception ex) { Logger.Log($"Error while : {ex.Message}",Logger.LogType.Error);}
//
return new Panel(); // return new Panel();
} // }
//
private static string GetInlineText(ContainerInline? container) // private static string GetInlineText(ContainerInline? container)
{ // {
try // try
{ // {
if (container == null) return string.Empty; // if (container == null) return string.Empty;
var sb = new StringBuilder(); // var sb = new StringBuilder();
foreach (var inline in container) // foreach (var inline in container)
{ // {
switch (inline) // switch (inline)
{ // {
case LiteralInline li: // case LiteralInline li:
sb.Append(li.Content.ToString()); // sb.Append(li.Content.ToString());
break; // break;
case EmphasisInline ei: // case EmphasisInline ei:
sb.Append(GetInlineText(ei)); // sb.Append(GetInlineText(ei));
break; // break;
case CodeInline ci: // case CodeInline ci:
sb.Append(ci.Content); // sb.Append(ci.Content);
break; // break;
case LinkInline li: // case LinkInline li:
sb.Append(GetInlineText(li)); // sb.Append(GetInlineText(li));
break; // break;
case LineBreakInline: // case LineBreakInline:
sb.Append("\n"); // sb.Append("\n");
break; // break;
default: // default:
sb.Append(inline.ToString()); // sb.Append(inline.ToString());
break; // break;
} // }
} // }
//
return sb.ToString(); // return sb.ToString();
} catch (Exception ex) { Logger.Log($"Error while : {ex.Message}",Logger.LogType.Error);} // } catch (Exception ex) { Logger.Log($"Error while : {ex.Message}",Logger.LogType.Error);}
//
return null; // return null;
} // }
} }