diff --git a/.classpath b/.classpath
new file mode 100644
index 0000000..899de31
--- /dev/null
+++ b/.classpath
@@ -0,0 +1,27 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/.gitignore b/.gitignore
index bdf4b0d..9e3e952 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,2 +1,4 @@
/backup
/Belegscanner
+/bin/
+/target/
diff --git a/.project b/.project
new file mode 100644
index 0000000..d57b672
--- /dev/null
+++ b/.project
@@ -0,0 +1,23 @@
+
+
+ BelegScanner
+
+
+
+
+
+ org.eclipse.jdt.core.javabuilder
+
+
+
+
+ org.eclipse.m2e.core.maven2Builder
+
+
+
+
+
+ org.eclipse.m2e.core.maven2Nature
+ org.eclipse.jdt.core.javanature
+
+
diff --git a/.settings/org.eclipse.jdt.core.prefs b/.settings/org.eclipse.jdt.core.prefs
new file mode 100644
index 0000000..b5490a0
--- /dev/null
+++ b/.settings/org.eclipse.jdt.core.prefs
@@ -0,0 +1,8 @@
+eclipse.preferences.version=1
+org.eclipse.jdt.core.compiler.codegen.targetPlatform=11
+org.eclipse.jdt.core.compiler.compliance=11
+org.eclipse.jdt.core.compiler.problem.enablePreviewFeatures=disabled
+org.eclipse.jdt.core.compiler.problem.forbiddenReference=warning
+org.eclipse.jdt.core.compiler.problem.reportPreviewFeatures=ignore
+org.eclipse.jdt.core.compiler.release=enabled
+org.eclipse.jdt.core.compiler.source=11
diff --git a/.settings/org.eclipse.m2e.core.prefs b/.settings/org.eclipse.m2e.core.prefs
new file mode 100644
index 0000000..f897a7f
--- /dev/null
+++ b/.settings/org.eclipse.m2e.core.prefs
@@ -0,0 +1,4 @@
+activeProfiles=
+eclipse.preferences.version=1
+resolveWorkspaceProjects=true
+version=1
diff --git a/Belegscanner.ico b/Belegscanner.ico
deleted file mode 100644
index 0341321..0000000
Binary files a/Belegscanner.ico and /dev/null differ
diff --git a/Belegscanner.lpi b/Belegscanner.lpi
deleted file mode 100644
index 1e5ac32..0000000
--- a/Belegscanner.lpi
+++ /dev/null
@@ -1,74 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/Belegscanner.lpr b/Belegscanner.lpr
deleted file mode 100644
index 530df48..0000000
--- a/Belegscanner.lpr
+++ /dev/null
@@ -1,21 +0,0 @@
-program Belegscanner;
-
-{$mode objfpc}{$H+}
-
-uses
- {$IFDEF UNIX}
- cthreads,
- {$ENDIF}
- Interfaces, // this includes the LCL widgetset
- Forms, scanner
- { you can add units after this };
-
-{$R *.res}
-
-begin
- RequireDerivedFormResource:=True;
- Application.Initialize;
- Application.CreateForm(TScanForm, ScanForm);
- Application.Run;
-end.
-
diff --git a/Belegscanner.lps b/Belegscanner.lps
deleted file mode 100644
index bda7fa5..0000000
--- a/Belegscanner.lps
+++ /dev/null
@@ -1,260 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/Belegscanner.res b/Belegscanner.res
deleted file mode 100644
index f6e8499..0000000
Binary files a/Belegscanner.res and /dev/null differ
diff --git a/pom.xml b/pom.xml
new file mode 100644
index 0000000..dea8da7
--- /dev/null
+++ b/pom.xml
@@ -0,0 +1,52 @@
+
+ 4.0.0
+ BelegScanner
+ BelegScanner
+ 0.0.2
+ BelegScanner
+
+
+
+ de.srsoftware
+ tools
+ 1.1.17
+ compile
+
+
+ de.srsoftware
+ tools.translations
+ 1.1.3
+ compile
+
+
+ de.srsoftware
+ tools.gui.selectcombobox
+ 0.1.1
+ compile
+
+
+ org.json
+ json
+ 20200518
+
+
+ ch.qos.logback
+ logback-classic
+ 1.2.3
+
+
+
+
+
+
+ maven-compiler-plugin
+ 3.8.1
+
+ 11
+
+
+
+
+
\ No newline at end of file
diff --git a/scanner.lfm b/scanner.lfm
deleted file mode 100644
index 04f4a05..0000000
--- a/scanner.lfm
+++ /dev/null
@@ -1,226 +0,0 @@
-object ScanForm: TScanForm
- Left = 2222
- Height = 880
- Top = 198
- Width = 1188
- Caption = 'Belegscanner'
- ClientHeight = 880
- ClientWidth = 1188
- OnCreate = FormCreate
- LCLVersion = '2.0.6.0'
- object TypeSelector: TComboBox
- Left = 904
- Height = 27
- Top = 208
- Width = 276
- Anchors = [akTop, akRight]
- Enabled = False
- ItemHeight = 0
- OnChange = TypeSelectorChange
- OnKeyDown = ComboKey
- TabOrder = 1
- Text = 'Herkunft'
- end
- object Origin: TComboBox
- Left = 904
- Height = 27
- Top = 240
- Width = 272
- Anchors = [akTop, akRight]
- Enabled = False
- ItemHeight = 0
- OnChange = OriginChange
- OnKeyDown = ComboKey
- TabOrder = 3
- Text = 'Start'
- end
- object Destination: TComboBox
- Left = 904
- Height = 27
- Top = 304
- Width = 272
- Anchors = [akTop, akRight]
- Enabled = False
- ItemHeight = 0
- OnChange = DestinationChange
- OnKeyDown = ComboKey
- TabOrder = 5
- Text = 'Ziel'
- end
- object FolderName: TLabel
- Left = 8
- Height = 17
- Top = 842
- Width = 101
- Anchors = [akLeft, akBottom]
- Caption = 'Ordnername'
- Font.Height = -16
- Font.Name = 'Sans'
- ParentColor = False
- ParentFont = False
- end
- object Product: TComboBox
- Left = 904
- Height = 27
- Top = 240
- Width = 276
- Anchors = [akTop, akRight]
- Enabled = False
- ItemHeight = 0
- OnChange = ProductChange
- OnKeyDown = ComboKey
- TabOrder = 2
- Text = 'Produkt'
- Visible = False
- end
- object ScanButton: TButton
- Left = 904
- Height = 49
- Top = 400
- Width = 272
- Anchors = [akTop, akRight]
- Caption = 'scannen!'
- Enabled = False
- OnClick = ScanButtonClick
- TabOrder = 8
- end
- object Resolution: TComboBox
- Left = 904
- Height = 27
- Top = 368
- Width = 72
- Anchors = [akTop, akRight]
- ItemHeight = 0
- ItemIndex = 0
- Items.Strings = (
- '150'
- '300'
- )
- TabOrder = 7
- Text = '150'
- end
- object DPI: TLabel
- Left = 984
- Height = 14
- Top = 376
- Width = 19
- Anchors = [akTop, akRight]
- Caption = 'dpi'
- ParentColor = False
- end
- object BaseFolder: TLabel
- Left = 8
- Height = 17
- Top = 818
- Width = 89
- Anchors = [akLeft, akBottom]
- Caption = 'BaseFolder'
- Font.Height = -16
- Font.Name = 'Sans'
- ParentColor = False
- ParentFont = False
- OnClick = BaseFolderClick
- end
- object Stop: TComboBox
- Left = 904
- Height = 27
- Top = 272
- Width = 272
- Anchors = [akTop, akRight]
- Enabled = False
- ItemHeight = 0
- OnChange = StopChange
- OnKeyDown = ComboKey
- TabOrder = 4
- Text = 'Zwischenhalt'
- end
- object Preview: TImage
- Left = 8
- Height = 800
- Top = 8
- Width = 880
- Anchors = [akTop, akLeft, akRight, akBottom]
- Center = True
- Proportional = True
- end
- object Calendar: TCalendar
- Left = 904
- Height = 190
- Top = 8
- Width = 276
- Anchors = [akTop, akRight]
- DateTime = 0
- OnChange = CalendarChange
- TabOrder = 0
- end
- object PicSize: TComboBox
- Left = 904
- Height = 27
- Top = 336
- Width = 272
- Anchors = [akTop, akRight]
- ItemHeight = 0
- TabOrder = 6
- Text = '209 x 297 mm'
- end
- object DropButton: TButton
- Left = 904
- Height = 32
- Top = 776
- Width = 276
- Anchors = [akRight, akBottom]
- Caption = 'Löschen'
- Enabled = False
- OnClick = DropButtonClick
- ParentShowHint = False
- ShowHint = True
- TabOrder = 9
- end
- object Swap: TButton
- Left = 1048
- Height = 30
- Top = 368
- Width = 128
- Anchors = [akTop, akRight]
- Caption = 'Start/Ziel tauschen'
- OnClick = SwapClick
- TabOrder = 10
- end
- object extButton: TButton
- Left = 904
- Height = 49
- Top = 456
- Width = 272
- Anchors = [akTop, akRight]
- Caption = 'extern öffnen'
- Enabled = False
- OnClick = extButtonClick
- TabOrder = 11
- end
- object dropBtn: TButton
- Left = 904
- Height = 49
- Top = 512
- Width = 272
- Anchors = [akTop, akRight]
- Caption = 'Datensatz löschen'
- OnClick = dropBtnClick
- TabOrder = 12
- end
- object OpenDir: TButton
- Left = 904
- Height = 32
- Top = 744
- Width = 276
- Anchors = [akRight, akBottom]
- Caption = 'Ordner öffnen'
- OnClick = OpenDirClick
- ParentShowHint = False
- ShowHint = True
- TabOrder = 13
- end
- object BaseFolderDialog: TSelectDirectoryDialog
- left = 520
- top = 128
- end
-end
diff --git a/scanner.pas b/scanner.pas
deleted file mode 100644
index e22b5ec..0000000
--- a/scanner.pas
+++ /dev/null
@@ -1,459 +0,0 @@
-unit scanner;
-
-{$mode objfpc}{$H+}
-
-interface
-
-uses
- Classes, SysUtils, FileUtil, Forms, Controls, Graphics, Dialogs, ExtDlgs,
- StdCtrls, ExtCtrls, Calendar, Unix;
-
-type
-
- { ScanThread }
- ScanThread = class(TThread)
- private
- dbtn, obtn, sbtn : TButton;
- folder,r :String;
- s:TPoint;
- p:TImage;
- protected
- procedure Execute; override;
- public
- constructor Create(scanButton: TButton; dir: String; size: TPoint; resolution: String; preview: TImage; dropButton: TButton; openButton: TButton);
- end;
-
- { TScanForm }
- TScanForm = class(TForm)
- dropBtn: TButton;
- OpenDir: TButton;
- extButton: TButton;
- Swap: TButton;
- DropButton: TButton;
- Calendar: TCalendar;
- PicSize: TComboBox;
- Preview: TImage;
- Stop: TComboBox;
- DPI: TLabel;
- BaseFolder: TLabel;
- Resolution: TComboBox;
- BaseFolderDialog: TSelectDirectoryDialog;
- ScanButton: TButton;
- Product: TComboBox;
- Destination: TComboBox;
- FolderName: TLabel;
- Origin: TComboBox;
- TypeSelector: TComboBox;
-
- procedure BaseFolderClick(Sender: TObject);
- procedure dropBtnClick(Sender: TObject);
- procedure extButtonClick(Sender: TObject);
- procedure DropButtonClick(Sender: TObject);
- procedure CalendarChange(Sender: TObject);
- procedure FormCreate(Sender: TObject);
- procedure OpenDirClick(Sender: TObject);
- procedure ProductChange(Sender: TObject);
- procedure DestinationChange(Sender: TObject);
- procedure OriginChange(Sender: TObject);
- procedure ScanButtonClick(Sender: TObject);
- procedure StopChange(Sender: TObject);
- procedure SwapClick(Sender: TObject);
- procedure TypeSelectorChange(Sender: TObject);
- function ExportConfig(): string;
- function ExportOptions(dropDown: TComboBox): string;
- procedure ComboKey(Sender: TObject; var Key: Word; Shift: TShiftState);
- procedure UpdateFolder();
- procedure MixLocations(d1: TComboBox; d2: TComboBox; d3: TComboBox);
- procedure DeleteStationFrom(combo: TComboBox; station: string; defaultName : string);
- procedure DeleteStation(station : string);
- private
- date: TDateTime;
- function getSize(): TPoint;
-
- public
- const
- SCANNING : Integer = 1;
- IDLE: Integer = 0;
- end;
-
-var
- ScanForm: TScanForm;
-
-implementation
-
-{$R *.lfm}
-
-{ ScanThread }
-
-constructor ScanThread.Create(scanButton: TButton; dir: String; size: TPoint; resolution: String; preview: TImage; dropButton: TButton; openButton: TButton );
-begin
- sbtn := scanButton;
- obtn := openButton;
- dbtn := dropButton;
- folder:=dir;
- s:=size;
- r:=resolution;
- p:=preview;
- inherited Create(false);
-end;
-
-procedure ScanThread.Execute;
-var
- fname: String;
- num: Integer;
- pic: TPicture;
-begin
- ForceDirectories(folder);
- num := 0;
- repeat
- num := num +1;
- fname := 'scan_';
- if (num<10) then fname:=fname+'0';
- if (num<100) then fname:=fname+'0';
- if (num<1000) then fname:=fname+'0';
- fname := fname+IntToStr(num)+'.jpg';
- until not FileExists(folder+fname);
- fpSystem('scanimage -x '+IntToStr(s.x)+' -y '+IntToStr(s.y)+' --mode Color --resolution '+r+' --format jpeg > "'+folder+fname+'"');
- try
- pic:=TPicture.Create;
- pic.LoadFromFile(folder+fname);
- p.Picture:=pic;
- p.Hint:=folder+fname;
- finally
- end;
- dbtn.Hint:=folder+fname;
- dbtn.Caption:=fname+' löschen';
- dbtn.Enabled:=true;
- obtn.Enabled:=true;
- sbtn.Enabled:=true;
- sbtn.Tag := TScanForm.IDLE;
-end;
-
-function allowed(s: String): boolean;
-begin
- Result := true;
- if (s = '') then Result := false;
- if (s = 'Start') then Result := false;
- if (s = 'Ziel') then Result := false;
- if (s = 'Zwischenhalt') then Result := false;
-end;
-
-procedure TScanForm.MixLocations(d1: TComboBox; d2: TComboBox; d3: TComboBox);
-var
- list: TStringList;
-begin
- list := TStringList.Create;
- list.Sorted := True;
- if (allowed(d1.Text)) then d1.Items.Add(d1.Text);
- if (allowed(d2.Text)) then d2.Items.Add(d2.Text);
- if (allowed(d3.Text)) then d3.Items.Add(d3.Text);
- list.Assign(d1.Items);
- list.AddStrings(d2.Items);
- list.AddStrings(d3.Items);
- d1.Items.Assign(list);
- d2.Items.Assign(list);
- d3.Items.Assign(list);
-end;
-
-function TScanForm.ExportConfig(): string;
-begin
- Result := 'folder:'+BaseFolder.Caption+#13;
- Result := Result + 'types:' + ExportOptions(TypeSelector) + #13;
- Result := Result + 'items:' + ExportOptions(Product) + #13;
- MixLocations(Origin, Destination, Stop);
- Result := Result + 'locations:' + ExportOptions(Origin) + #13;
- Result := Result + 'sizes:' + ExportOptions(PicSize) +#13;
-end;
-
-function TScanForm.ExportOptions(dropDown: TComboBox): string;
-var
- list: TStringList;
- item, current: string;
- i: integer;
- drop: Boolean;
-begin
- // make sure the current text appears in future lists
- item := dropDown.Text;
- drop := item.StartsWith(' ');
-
- if drop then
- begin
- i := 0;
- while i < dropDown.Items.Count do
- begin
- item := Trim(item);
- current := Trim(dropDown.Items[i]);
- if current = item then dropDown.Items.Delete(i) else i := i+1;
- end;
- end else dropDown.Items.Add(item);
-
- // create a StringList to sort and concatenate
- list := TStringList.Create;
- list.StrictDelimiter := True;
- list.Sorted := True;
-
- // put all items in the list, will sort and remove duplicates
- list.Assign(dropDown.Items);
-
- // update dropdown
- dropDown.Items.Assign(list);
-
- // return json array
- Result := list.DelimitedText
-end;
-
-procedure TScanForm.ComboKey(Sender: TObject; var Key: Word; Shift: TShiftState);
-var
- combo : TComboBox;
- index : integer;
- tx : string;
-begin
- if key = 40 then
- begin
- if TObject(Sender) is TComboBox then
- begin
- combo := TComboBox(Sender);
- tx := combo.Text;
- for index := 0 to combo.Items.Count-1 do
- begin
- if combo.Items[index].StartsWith(tx,true) then
- begin
- combo.ItemIndex:=index-1;
- Exit;
- end;
- end;
- end;
- end;
-end;
-
-procedure TScanForm.TypeSelectorChange(Sender: TObject);
-var
- state: boolean;
-begin
- TypeSelector.Tag := 1;
- state := TypeSelector.Text = 'Ticket';
- Origin.Enabled := state;
- Origin.Visible := state;
- Stop.Enabled := state;
- Stop.Visible := state;
- Destination.Enabled := state;
- Destination.Visible := state;
- Swap.Enabled:=state;
- Product.Enabled := not state;
- Product.Visible := not state;
- if (ScanButton.Tag <> TScanForm.SCANNING) then ScanButton.Enabled:=true;
- UpdateFolder();
-end;
-
-procedure TScanForm.CalendarChange(Sender: TObject);
-begin
- date := Calendar.DateTime;
- TypeSelector.Enabled := True;
- UpdateFolder();
-end;
-
-procedure TScanForm.OriginChange(Sender: TObject);
-begin
- Origin.Tag := 1;
- UpdateFolder();
-end;
-
-function TScanForm.getSize(): TPoint;
-var
- arr: TStringArray;
- s: String;
- w, h: Integer;
-begin
- s:=PicSize.Text;
- arr:=s.Split(['x','m']);
- w:=StrToInt(arr[0].Trim);
- h:=StrToInt(arr[1].Trim);
- PicSize.Caption:=IntToStr(w)+' x '+IntToStr(h)+' mm';
- Result := TPoint.Create(w,h);
-end;
-
-procedure TScanForm.ScanButtonClick(Sender: TObject);
-var
- config: TFileStream;
- filename: string;
- json: string;
- size: TPoint;
-begin
- ScanButton.Enabled:=false;
- ScanButton.Tag:=TScanForm.SCANNING;
- filename := GetEnvironmentVariable('HOME') + '/.config/belegscanner.conf';
- size := getSize();
- json := ExportConfig();
- try
- config := TFilestream.Create(filename, fmCreate);
- config.Write(json[1], json.Length);
- finally
- config.Free;
- end;
- ScanThread.Create(ScanButton,BaseFolder.Caption+'/'+FolderName.Caption+'/',size,Resolution.Caption,Preview,DropButton,extButton);
-end;
-
-procedure TScanForm.StopChange(Sender: TObject);
-begin
- Stop.Tag := 1;
- UpdateFolder();
-end;
-
-procedure TScanForm.SwapClick(Sender: TObject);
-var
- dummy: String;
-begin
- dummy:=Origin.Text;
- Origin.Text := Destination.Text;
- Destination.Text := dummy;
- UpdateFolder();
-end;
-
-procedure TScanForm.DestinationChange(Sender: TObject);
-begin
- Destination.Tag := 1;
- UpdateFolder();
-end;
-
-procedure TScanForm.ProductChange(Sender: TObject);
-begin
- Product.Tag := 1;
- UpdateFolder();
-end;
-
-
-procedure addItemsTo(combo: TComboBox; line: String);
-var
- parts: TStringArray;
- fixed, part: string;
-begin
- parts := line.Split(',');
- for part in parts do
- begin
- fixed := part.Replace('"','');
- if (fixed <> '') then combo.Items.Add(fixed);
- end;
-end;
-
-procedure TScanForm.FormCreate(Sender: TObject);
-var
- filename: String;
- lines: TStringList;
- line: String;
- index: integer;
-begin
- BaseFolder.Caption:=GetEnvironmentVariable('HOME');
- filename := GetEnvironmentVariable('HOME') + '/.config/belegscanner.conf';
- lines := TStringList.Create;
- Calendar.DateTime:=Now;
- try
- lines.LoadFromFile(filename);
- for index := 0 to lines.Count-1 do
- begin
- line:=lines.Strings[index];
- if line.StartsWith('folder:') then
- begin
- line:=line.Substring(7);
- BaseFolder.Caption:=line;
- end;
- if line.StartsWith('types:') then addItemsTo(TypeSelector,line.Substring(6));
- if line.StartsWith('items:') then addItemsTo(Product,line.Substring(6));
- if line.StartsWith('sizes:') then addItemsTo(PicSize,line.Substring(6));
- if line.StartsWith('locations:') then
- begin
- line := line.Substring(10);
- addItemsTo(Origin,line);
- addItemsTo(Destination,line);
- addItemsTo(Stop,line);
- end;
- end
- finally
- end;
-end;
-
-procedure TScanForm.OpenDirClick(Sender: TObject);
-begin
- WriteLn(BaseFolder.Caption);
- fpSystem('gio open "'+BaseFolder.Caption+'"');
-end;
-
-procedure TScanForm.BaseFolderClick(Sender: TObject);
-begin
- BaseFolderDialog.FileName:=BaseFolder.Caption;
- BaseFolderDialog.Execute;
- BaseFolder.Caption := BaseFolderDialog.FileName;
-end;
-
-procedure TScanForm.DeleteStationFrom(combo: TComboBox; station : string; defaultName : string);
-var
- index : integer;
-begin
- index := combo.Items.IndexOf(station);
- if index > -1 then
- begin
- combo.Items.Delete(index);
- combo.Text := defaultName;
- end;
-end;
-
-procedure TScanForm.DeleteStation(station : string);
-begin
- DeleteStationFrom(Origin,station,'Start');
- DeleteStationFrom(Stop,station,'Zwischenhalt');
- DeleteStationFrom(Destination,station,'Ziel');
-end;
-
-procedure TScanForm.dropBtnClick(Sender: TObject);
-var
- tx : string;
-begin
- tx := TypeSelector.Text;
- if (tx <> 'Herkunft') and (tx <> 'Ticket') then
- begin
- TypeSelector.Items.Delete(TypeSelector.ItemIndex);
- TypeSelector.Text := 'Herkunft';
- end;
-
- tx := Product.Text;
- if Product.Enabled and (tx <> 'Produkt') then
- begin
- Product.Items.Delete(Product.ItemIndex);
- Product.Text := 'Produkt';
- end;
-
- if Origin.Enabled and (Origin.Text <> 'Start') then deleteStation(Origin.Text);
- if Stop.Enabled and (Stop.Text <> 'Zwischenhalt') then deleteStation(Stop.Text);
- if Destination.Enabled and (Destination.Text <> 'Ziel') then deleteStation(Destination.Text);
-end;
-
-procedure TScanForm.extButtonClick(Sender: TObject);
-var
- cmd: string;
-begin
- cmd := 'gvfs-open "'+DropButton.Hint+'"';
- fpSystem(cmd);
-end;
-
-procedure TScanForm.DropButtonClick(Sender: TObject);
-begin
- DeleteFile(DropButton.Hint);
- Preview.Picture:=nil;
- DropButton.Enabled:=false;
- extButton.Enabled:=false;
-end;
-
-
-procedure TScanForm.UpdateFolder();
-var
- tx: string;
-begin
- tx := FormatDateTime('YYYY-MM-DD', date) + ' - ';
- if (Product.Enabled and (Product.Tag > 0) and not( Product.Text = '') and not (Product.Text = 'Produkt')) then tx := tx + Trim(Product.Text) + ' von ';
- if (TypeSelector.Tag > 0) then tx := tx + Trim(TypeSelector.Text);
- if (Origin.Enabled and (Origin.Tag > 0)) then tx := tx + ': ' + Trim(Origin.Text);
- if (Stop.Enabled and (Stop.Tag > 0) and not (Stop.Text = '')and not (Stop.Text = 'Zwischenhalt')) then tx := tx + ' - ' + Trim(Stop.Text);
- if (Destination.Enabled and (Destination.Tag > 0)) then tx := tx + ' - ' + Trim(Destination.Text);
- FolderName.Caption := tx;
-end;
-
-end.
diff --git a/src/main/java/de/srsoftware/belegscanner/Application.java b/src/main/java/de/srsoftware/belegscanner/Application.java
new file mode 100644
index 0000000..9181664
--- /dev/null
+++ b/src/main/java/de/srsoftware/belegscanner/Application.java
@@ -0,0 +1,14 @@
+package de.srsoftware.belegscanner;
+
+import java.io.IOException;
+
+import de.srsoftware.belegscanner.gui.MainFrame;
+
+public class Application {
+
+ public static void main(String[] args) throws IOException {
+ Configuration config = new Configuration(Constants.APPLICATION_NAME);
+ MainFrame app = new MainFrame(config);
+ app.setDefaultCloseOperation(MainFrame.EXIT_ON_CLOSE);
+ }
+}
diff --git a/src/main/java/de/srsoftware/belegscanner/Configuration.java b/src/main/java/de/srsoftware/belegscanner/Configuration.java
new file mode 100644
index 0000000..c8a512b
--- /dev/null
+++ b/src/main/java/de/srsoftware/belegscanner/Configuration.java
@@ -0,0 +1,145 @@
+package de.srsoftware.belegscanner;
+
+import java.io.ByteArrayOutputStream;
+import java.io.File;
+import java.io.FileReader;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.nio.charset.StandardCharsets;
+
+import org.json.JSONArray;
+import org.json.JSONObject;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class Configuration {
+
+ private static final Logger LOG = LoggerFactory.getLogger(Configuration.class);
+ private File file;
+ private JSONObject json = new JSONObject();
+
+ public Configuration(String appName) throws IOException {
+ String home = System.getProperty("user.home");
+ String fileName = new StringBuilder().append(home).append(File.separator).append(".config").append(File.separator).append(appName).append(File.separator).append("config.json").toString();
+ file = new File(fileName);
+ if (file.exists()) {
+ LOG.info("{} found, loading…",file);
+ FileReader in = new FileReader(file);
+ ByteArrayOutputStream buffer = new ByteArrayOutputStream();
+ OutputStreamWriter writer = new OutputStreamWriter(buffer);
+ in.transferTo(writer);
+ writer.close();
+ String jsonString = buffer.toString(StandardCharsets.UTF_8);
+ LOG.debug("Loaded json: {}",jsonString);
+ json = jsonString.startsWith("{") ? new JSONObject(jsonString) : new JSONObject();
+ in.close();
+ } else {
+ LOG.info("{} not found, creating new config.",file);
+ json = new JSONObject();
+ }
+ }
+
+ private void save() throws IOException {
+ LOG.debug("Trying to save config…");
+ File dir = file.getParentFile();
+ if (!dir.exists()) dir.mkdirs();
+ FileWriter out = new FileWriter(file);
+ json.write(out, 2, 0);
+ out.close();
+ }
+
+ public JSONArray getOrCreateArray(String key) {
+ LOG.debug("requesting {} from config.",key);
+ String[] parts = key.split("\\.");
+ JSONObject localJson = json;
+ boolean update = false;
+ JSONArray result = null;
+ for (int i=0; i T get(String key) {
+ LOG.debug("requesting {} from config.",key);
+ String[] parts = key.split("\\.");
+ JSONObject localJson = json;
+ for (int i=0; i T getOrCreate(String key, T preset) {
+ LOG.debug("requesting {} from config.",key);
+ String[] parts = key.split("\\.");
+ JSONObject localJson = json;
+ boolean update = false;
+ Object result = preset;
+ for (int i=0; i comboBox = new JComboBox<>();
+ private static ListlistForComboBox= new ArrayList();
+
+ /**
+ * Launch the application.
+ */
+ public static void main(String[] args) {
+ EventQueue.invokeLater(new Runnable() {
+ public void run() {
+ try {
+ FilterComboBoxText window = new FilterComboBoxText();
+ window.frame.setVisible(true);
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+ });
+
+ listForComboBox.add("Lion");
+ listForComboBox.add("LionKing");
+ listForComboBox.add("Mufasa");
+ listForComboBox.add("Nala");
+ listForComboBox.add("KingNala");
+ listForComboBox.add("Animals");
+ listForComboBox.add("Anims");
+ listForComboBox.add("Fish");
+ listForComboBox.add("Jelly Fish");
+ listForComboBox.add("I am the boss");
+
+
+ }
+
+ public FilterComboBoxText() {
+ initialize();
+ }
+
+ private void initialize() {
+ frame = new JFrame();
+ frame.setBounds(100, 100, 412, 165);
+ frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+ frame.getContentPane().setLayout(null);
+ comboBox.setEditable(true);
+
+ comboBox.addItemListener(new ItemListener() {
+ public void itemStateChanged(ItemEvent arg0) {
+
+ }
+ });
+
+ for(String detail : listForComboBox) comboBox.addItem(detail);
+ final JTextField textfield = (JTextField) comboBox.getEditor().getEditorComponent();
+ textfield.addKeyListener(new KeyAdapter() {
+ public void keyReleased(KeyEvent ke) {
+ SwingUtilities.invokeLater(new Runnable() {
+ public void run() {
+ if(!textfield.getText().isEmpty()){
+ comboBoxFilter(textfield.getText());
+ }
+ }
+ });
+
+ }
+ });
+ comboBox.setBounds(10, 39, 364, 29);
+ frame.getContentPane().add(comboBox);
+ }
+
+ public void comboBoxFilter(String enteredText) {
+ System.out.println(comboBox.getItemCount());
+
+ if (!comboBox.isPopupVisible()) {
+ comboBox.showPopup();
+ }
+
+ List filterArray= new ArrayList();
+ for (int i = 0; i < listForComboBox.size(); i++) {
+ if (listForComboBox.get(i).toLowerCase().contains(enteredText.toLowerCase())) {
+ filterArray.add(listForComboBox.get(i));
+ }
+ }
+ if (filterArray.size() > 0) {
+ DefaultComboBoxModel model = (DefaultComboBoxModel) comboBox.getModel();
+ model.removeAllElements();
+ model.addElement("");
+ for (String s: filterArray)
+ model.addElement(s);
+
+ JTextField textfield = (JTextField) comboBox.getEditor().getEditorComponent();
+ textfield.setText(enteredText);
+ }
+ }
+
+}
\ No newline at end of file
diff --git a/src/main/java/de/srsoftware/belegscanner/gui/MainFrame.java b/src/main/java/de/srsoftware/belegscanner/gui/MainFrame.java
new file mode 100644
index 0000000..8151f28
--- /dev/null
+++ b/src/main/java/de/srsoftware/belegscanner/gui/MainFrame.java
@@ -0,0 +1,118 @@
+package de.srsoftware.belegscanner.gui;
+
+import java.awt.BorderLayout;
+import java.awt.Dimension;
+import java.awt.event.ActionEvent;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.Map.Entry;
+import java.util.Vector;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+import javax.swing.JFrame;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import de.srsoftware.belegscanner.Configuration;
+
+
+public class MainFrame extends JFrame {
+ private static final Logger LOG = LoggerFactory.getLogger(MainFrame.class);
+
+ private static final long serialVersionUID = 210283601541223645L;
+
+ private static final String HOME = System.getProperty("user.home");
+ private static final Pattern MARKEN = Pattern.compile("\\$([a-zA-Z]+)");
+
+ private StatusBar statusBar;
+ private Toolbar toolbar;
+
+ private HashMap fields = new HashMap<>();
+
+ private String path = "";
+
+ private String category ="";
+
+ private Date date = new Date();
+
+ private String patchedPath = "";
+
+ private Configuration config;
+
+ public MainFrame(Configuration config) {
+ this.config = config;
+ int width = config.getOrCreate("app.main.dimenstion.w",800);
+ int height = config.getOrCreate("app.main.dimenstion.h",600);
+
+ BorderLayout layout = new BorderLayout();
+ setLayout(layout);
+
+ toolbar = new Toolbar(config);
+ statusBar = new StatusBar();
+
+ add(toolbar,BorderLayout.EAST);
+ add(statusBar,BorderLayout.SOUTH);
+ toolbar.addCategoryListener(this::setCategory)
+ .addDateListener(this::setDate)
+ .addFieldListener(this::setField)
+ .addPathListener(this::setPath)
+ .addScanListener(this::scan);
+
+ setPreferredSize(new Dimension(width,height));
+ pack();
+ setVisible(true);
+ }
+
+ private void addFieldsFor(String path) {
+ Vector marks = new Vector<>();
+ Matcher matches = MARKEN.matcher(path);
+ while (matches.find()) marks.add(matches.group(1));
+ toolbar.addFieldsFor(marks);
+ };
+
+ private void scan(ActionEvent ev) {
+ LOG.debug("Scanning into '{}'",patchedPath);
+ config.set("app.categories."+category+".path",path);
+ }
+
+ private void setCategory(String category) {
+ this.category = category;
+ updatePath();
+
+ }
+
+ private void setDate(Date date) {
+ this.date = date;
+ updatePath();
+ }
+
+ private void setField(String key, String val) {
+ fields.put(key, val);
+ updatePath();
+ }
+
+
+ private void setPath(String path) {
+ this.path = path;
+ updatePath();
+ }
+
+ @SuppressWarnings("deprecation")
+ private void updatePath() {
+ LOG.debug("updatePath() [path = {}]",path);
+ int year = 1900+date.getYear();
+ int month = date.getMonth()+1;
+ int day = date.getDate();
+ patchedPath = path.replace("$HOME",HOME)
+ .replace("$KATEGORIE", category)
+ .replace("$JAHR", year+"")
+ .replace("$MONAT", month<10 ? "0"+month : ""+month)
+ .replace("$TAG", day < 10 ? "0"+day : ""+day);
+
+ addFieldsFor(patchedPath);
+ for (Entry entry : fields.entrySet()) patchedPath = patchedPath.replace("$"+entry.getKey(), entry.getValue());
+ statusBar.setPath(patchedPath);
+ }
+}
diff --git a/src/main/java/de/srsoftware/belegscanner/gui/StatusBar.java b/src/main/java/de/srsoftware/belegscanner/gui/StatusBar.java
new file mode 100644
index 0000000..abee5a0
--- /dev/null
+++ b/src/main/java/de/srsoftware/belegscanner/gui/StatusBar.java
@@ -0,0 +1,27 @@
+package de.srsoftware.belegscanner.gui;
+
+import javax.swing.BoxLayout;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class StatusBar extends JPanel {
+
+ private static final Logger LOG = LoggerFactory.getLogger(StatusBar.class);
+
+ private static final long serialVersionUID = 8102800846089594705L;
+ private JLabel path;
+
+ public StatusBar() {
+ setLayout(new BoxLayout(this, BoxLayout.Y_AXIS));
+ add(path = new JLabel());
+ }
+
+ public StatusBar setPath(String path) {
+ LOG.debug("setPath({})",path);
+ this.path.setText(path);
+ return this;
+ }
+}
diff --git a/src/main/java/de/srsoftware/belegscanner/gui/Toolbar.java b/src/main/java/de/srsoftware/belegscanner/gui/Toolbar.java
new file mode 100644
index 0000000..388a283
--- /dev/null
+++ b/src/main/java/de/srsoftware/belegscanner/gui/Toolbar.java
@@ -0,0 +1,195 @@
+package de.srsoftware.belegscanner.gui;
+
+import java.awt.Component;
+import java.awt.Dimension;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.util.Date;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Vector;
+import java.util.stream.Collectors;
+
+import javax.swing.BoxLayout;
+import javax.swing.JButton;
+import javax.swing.JLabel;
+import javax.swing.JPanel;
+
+import org.json.JSONObject;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import de.srsoftware.belegscanner.Configuration;
+import de.srsoftware.tools.gui.DateChooser;
+import de.srsoftware.tools.gui.SelectComboBox;
+
+public class Toolbar extends JPanel {
+
+ private static final Logger LOG = LoggerFactory.getLogger(Toolbar.class);
+
+ public interface CategoryListener{
+ public void setCategory(String category);
+ }
+
+ public interface DateListener{
+ public void setDate(Date date);
+ }
+
+ public interface FieldListener{
+ public void setField(String name, String value);
+ }
+
+ public interface PathListener{
+ public void setPath(String path);
+ }
+
+
+ private static final long serialVersionUID = -5834326573752788233L;
+
+ private Vector