Speichern und Laden der Konfiguration wieder implementiert, UI verbessert
Signed-off-by: Stephan Richter <s.richter@srsoftware.de>
This commit is contained in:
@@ -9,8 +9,7 @@ Diese Anwendung soll helfen
|
||||
|
||||
## TODOs
|
||||
|
||||
* Pfad in Dok-Liste verbessern (Zeigt im Moment Seite mit an)
|
||||
* diese Anleitung vervollständigen
|
||||
* einfaches Löschen von Kategorien
|
||||
* entfernen der Seitennummer beim Binden
|
||||
* Monatsnamen als Platzhalter
|
||||
* einfacheres Starten mit der richtigen Sprache
|
||||
@@ -2,29 +2,38 @@ Actions : Aktionen
|
||||
Adjusting brightness… : Helligkeitskorrektur…
|
||||
Adjustments : Verbesserungen
|
||||
Apps missing : Anwendungen fehlen
|
||||
Category : Kategorie
|
||||
CATEGORY : KATEGORIE
|
||||
Profile : Profil
|
||||
PROFILE : PROFIL
|
||||
Click here to open directory : Hier klicken, um das Verzeichnis zu öffnen
|
||||
Configuration problem : Konfigurations-Problem
|
||||
Conversion failed. : Konvertierung fehlgeschlagen.
|
||||
Converting to PDF… : Kovertiere zu PDF…
|
||||
current resolution : aktuelle Auflösung
|
||||
DAY : TAG
|
||||
December : Dezember
|
||||
Directory : Ordner
|
||||
display preview : Vorschau anzeigen
|
||||
drop file : Datei löschen
|
||||
done : fertig
|
||||
Error code\: {} for {} : Fehlercode: {} für {}
|
||||
February : Februar
|
||||
Finished text recognition. : Texterkennung beendet.
|
||||
German language support missing! : Unterstützung für deutsche Sprache fehlt!
|
||||
Height : Höhe
|
||||
help : Hilfe
|
||||
Improve brightness : Helligkeit verbessern
|
||||
January : Januar
|
||||
Joining PDFs… : Verbinde PDFs…
|
||||
join PDFs : PDFs zusammenführen
|
||||
July : Juli
|
||||
Language support : Sprach-Unterstützung
|
||||
May : Mai
|
||||
March : März
|
||||
MONTH : MONAT
|
||||
Month : Monat
|
||||
month : monat
|
||||
OCR failed. : OCR fehlgeschlagen.
|
||||
October : Oktober
|
||||
open folder : Ordner öffnen
|
||||
PAGE : SEITE
|
||||
Path '{}' does not exist! : Pfad '{}' existiert nicht!
|
||||
@@ -33,6 +42,7 @@ Please install the package : Bitte installiere das Paket
|
||||
Please remove the line<br/><br/>policy<br/><br/>from 'file'. : Bitte entferne die Zeile<br/><br/>policy<br/><br/> aus 'file'.
|
||||
PDFs joined. : Zusammengefügt.
|
||||
Press Shift + Delete to remove an entry. : Drücken Sie Umschalt + Entf um einen Eintrag zu löschen
|
||||
Remove [PAGE] when stitching : [Seite] beim Zusammenfügen entfernen
|
||||
Scan failed. : Scannen fehlgeschlagen.
|
||||
Scanning… : Scanne…
|
||||
scan! : scannen!
|
||||
@@ -43,4 +53,4 @@ Text recognition… : Texterkennung…
|
||||
This application requires the following helper commands to be installed\: : Diese Anwendung erfordert es, dass auch die folgenden Hilfsprogramme installiert sind:
|
||||
Width : Breite
|
||||
YEAR : JAHR
|
||||
Your ImageMagick configuration prohibits conversion of jpg to pdf! : Deine ImageMagick-Konfiguration verbietet die Umwandlung von jpg zu PDF!
|
||||
Your ImageMagick configuration prohibits conversion of jpg to pdf! : Deine ImageMagick-Konfiguration verbietet die Umwandlung von jpg zu PDF!
|
||||
@@ -159,7 +159,7 @@ public class Configuration {
|
||||
* @param key Search path in the form path.to.array
|
||||
* @param value the value to add/replace
|
||||
*/
|
||||
public void set(String key, Object value) {
|
||||
public Configuration set(String key, Object value) {
|
||||
LOG.debug("setting {} to {}",key,value);
|
||||
String[] parts = key.split("\\.");
|
||||
JSONObject localJson = json;
|
||||
@@ -177,5 +177,6 @@ public class Configuration {
|
||||
localJson = localJson.getJSONObject(localKey);
|
||||
}
|
||||
LOG.debug("altered json: {}",json);
|
||||
return this;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,9 +1,13 @@
|
||||
package de.srsoftware.belegscanner;
|
||||
|
||||
import de.srsoftware.belegscanner.gui.DocTable;
|
||||
import de.srsoftware.belegscanner.gui.ImproveSelector;
|
||||
import de.srsoftware.belegscanner.gui.MainFrame;
|
||||
import de.srsoftware.belegscanner.gui.ResolutionSelector;
|
||||
import de.srsoftware.belegscanner.gui.RotationSelector;
|
||||
import de.srsoftware.belegscanner.gui.StatusBar;
|
||||
import de.srsoftware.belegscanner.gui.Toolbar;
|
||||
import de.srsoftware.belegscanner.gui.TypeSelector;
|
||||
import de.srsoftware.belegscanner.model.api.Page;
|
||||
import de.srsoftware.belegscanner.model.api.Project;
|
||||
import de.srsoftware.tools.gui.DateChooser;
|
||||
@@ -12,19 +16,20 @@ import org.json.JSONObject;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.Vector;
|
||||
|
||||
import static de.srsoftware.belegscanner.Application.main;
|
||||
import static de.srsoftware.belegscanner.Application.t;
|
||||
import static de.srsoftware.belegscanner.Constants.CONFIG_TARGET;
|
||||
import static de.srsoftware.belegscanner.Constants.DEFAULT_HEIGHT;
|
||||
import static de.srsoftware.belegscanner.Constants.DEFAULT_WIDTH;
|
||||
import static de.srsoftware.belegscanner.Constants.JPG;
|
||||
import static de.srsoftware.belegscanner.Constants.OCR;
|
||||
import static de.srsoftware.belegscanner.Constants.PDF;
|
||||
@@ -37,33 +42,35 @@ public class Worker {
|
||||
private SelectComboBox pathPicker;
|
||||
private StatusBar statusBar;
|
||||
private DateChooser datePicker;
|
||||
private String category,rawPath, resolvedPath;
|
||||
private String profile,rawPath, resolvedPath, type=OCR;
|
||||
private Toolbar toolbar;
|
||||
private DocTable docTable;
|
||||
private boolean improveBrightness,scanning;
|
||||
private int resolution;
|
||||
private boolean improveBrightness,scanning,removePageOnStitching;
|
||||
private int resolution,rotationAngle;
|
||||
private Dimension dimension;
|
||||
private String mode = "Color";
|
||||
private MainFrame mainFrame;
|
||||
private int rotationAngle;
|
||||
|
||||
private JTextField heightField, widthField;
|
||||
private ResolutionSelector resolutionSelector;
|
||||
private ImproveSelector improveSelector;
|
||||
private RotationSelector rotationSelector;
|
||||
private TypeSelector typeSelector;
|
||||
|
||||
|
||||
public Worker(Configuration config) {
|
||||
this.config = config;
|
||||
}
|
||||
|
||||
public void dropCategory(String droppedCat) {
|
||||
LOG.debug("Worker.dropCategory({})",droppedCat);
|
||||
public void dropProfile(String droppedProfile) {
|
||||
LOG.debug("Worker.dropProfile({})",droppedProfile);
|
||||
}
|
||||
public JSONObject getCategories() {
|
||||
return config.getOrCreate("app.categories",new JSONObject());
|
||||
public JSONObject getProfiles() {
|
||||
return config.getOrCreate("profiles",new JSONObject());
|
||||
}
|
||||
|
||||
private Optional<JSONObject> getCategory(String name){
|
||||
var cats = getCategories();
|
||||
return cats.has(name) ? (cats.get(name) instanceof JSONObject cat ? Optional.of(cat) : Optional.empty()) : Optional.empty();
|
||||
}
|
||||
public String getType() {
|
||||
return config.getOrCreate(CONFIG_TARGET, PDF);
|
||||
return type;
|
||||
}
|
||||
|
||||
public void resolvePath(){
|
||||
@@ -74,9 +81,13 @@ public class Worker {
|
||||
int month = date.getMonth()+1;
|
||||
int day = date.getDate();
|
||||
resolvedPath = rawPath.replace("$"+t("HOME"),HOME)
|
||||
.replace("$"+t("CATEGORY"), category)
|
||||
.replace("$"+t("PROFILE"), profile)
|
||||
.replace("$"+t("YEAR"), year+"")
|
||||
.replace("$"+t("MONTH"), month<10 ? "0"+month : ""+month)
|
||||
.replace("$"+t("Month"),monthName(month))
|
||||
.replace("$"+t("month"),monthName(month).toLowerCase())
|
||||
.replace("$"+t("Mon"),monthNameShort(month))
|
||||
.replace("$"+t("mon"),monthNameShort(month).toLowerCase())
|
||||
.replace("$"+t("DAY"), day < 10 ? "0"+day : ""+day);
|
||||
|
||||
var start = resolvedPath.indexOf("$");
|
||||
@@ -97,6 +108,43 @@ public class Worker {
|
||||
}
|
||||
toolbar.dropUnusedAdditionalFields();
|
||||
statusBar.setPath(resolvedPath+"."+extension());
|
||||
mainFrame.pack();
|
||||
}
|
||||
|
||||
private String monthName(int month) {
|
||||
return switch (month){
|
||||
case 1: yield t("January");
|
||||
case 2: yield t("February");
|
||||
case 3: yield t("March");
|
||||
case 4: yield t("April");
|
||||
case 5: yield t("May");
|
||||
case 6: yield t("June");
|
||||
case 7: yield t("July");
|
||||
case 8: yield t("August");
|
||||
case 9: yield t("September");
|
||||
case 10: yield t("October");
|
||||
case 11: yield t("November");
|
||||
case 12: yield t("December");
|
||||
default: yield t("Error");
|
||||
};
|
||||
}
|
||||
|
||||
private String monthNameShort(int month) {
|
||||
return switch (month){
|
||||
case 1: yield t("Jan");
|
||||
case 2: yield t("Feb");
|
||||
case 3: yield t("Mar");
|
||||
case 4: yield t("Apr");
|
||||
case 5: yield t("May");
|
||||
case 6: yield t("Jun");
|
||||
case 7: yield t("Jul");
|
||||
case 8: yield t("Aug");
|
||||
case 9: yield t("Sep");
|
||||
case 10: yield t("Oct");
|
||||
case 11: yield t("Nov");
|
||||
case 12: yield t("Dec");
|
||||
default: yield t("Error");
|
||||
};
|
||||
}
|
||||
|
||||
private String extension() {
|
||||
@@ -119,9 +167,29 @@ public class Worker {
|
||||
}
|
||||
|
||||
public void scan() {
|
||||
saveProfile();
|
||||
new Thread(this::performScan).start();
|
||||
}
|
||||
|
||||
private void saveProfile() {
|
||||
var prefix = String.join(".","profiles",profile,"");
|
||||
|
||||
Map.of(
|
||||
"path",rawPath,
|
||||
"size",Map.of("height",dimension.height,"width",dimension.width),
|
||||
"resolution",resolution,
|
||||
"improvements", Map.of("brightness",improveBrightness,"drop_page",removePageOnStitching),
|
||||
"rotation",rotationAngle,
|
||||
"target_type",type)
|
||||
.entrySet()
|
||||
.forEach(e -> config.set(prefix+e.getKey(),e.getValue()));
|
||||
try {
|
||||
config.save();
|
||||
} catch (IOException e) {
|
||||
LOG.error("Failed to save profile",e);
|
||||
}
|
||||
}
|
||||
|
||||
private void performScan(){
|
||||
LOG.debug("scan()");
|
||||
var project = docTable.getProject(resolvedPath).orElseGet(() -> docTable.createProject(resolvedPath));
|
||||
@@ -366,21 +434,48 @@ public class Worker {
|
||||
this.statusBar = statusBar;
|
||||
}
|
||||
|
||||
public void setType(String type) {
|
||||
LOG.debug("setType({})",type);
|
||||
config.set(CONFIG_TARGET, type);
|
||||
public void setType(String newType) {
|
||||
LOG.debug("setType({})",newType);
|
||||
type = newType;
|
||||
resolvePath();
|
||||
}
|
||||
|
||||
public void setCat(String newCat) {
|
||||
LOG.debug("setCat({}})",newCat);
|
||||
this.category = newCat;
|
||||
getCategory(newCat).map(cat -> cat.get(Constants.PATH))
|
||||
.map(o -> o instanceof String path ? path : null)
|
||||
.ifPresent(path -> {
|
||||
pathPicker.setText(path);
|
||||
setPath(path);
|
||||
});
|
||||
public void loadProfile(String newProfile) {
|
||||
LOG.debug("setCat({}})",newProfile);
|
||||
profile = newProfile;
|
||||
var prefix = String.join(".","profiles",profile,"");
|
||||
Optional.ofNullable((String)config.get(prefix+"path")).ifPresent(path -> {
|
||||
pathPicker.setText(path);
|
||||
setPath(path);
|
||||
});
|
||||
Optional.ofNullable((Integer)config.get(prefix+"size.height")).ifPresent(h -> {
|
||||
heightField.setText(""+h);
|
||||
dimension = new Dimension(dimension.width,h);
|
||||
});
|
||||
Optional.ofNullable((Integer)config.get(prefix+"size.width")).ifPresent(w -> {
|
||||
widthField.setText(""+w);
|
||||
dimension = new Dimension(w,dimension.height);
|
||||
});
|
||||
Optional.ofNullable((Integer)config.get(prefix+"resolution")).ifPresent(res -> {
|
||||
resolutionSelector.set(res);
|
||||
resolution = res;
|
||||
});
|
||||
Optional.ofNullable((Boolean)config.get(prefix+"improvements.brightness")).ifPresent(b -> {
|
||||
improveSelector.setImproveBrightness(b);
|
||||
improveBrightness = b;
|
||||
});
|
||||
Optional.ofNullable((Boolean)config.get(prefix+"improvements.drop_page")).ifPresent(d -> {
|
||||
improveSelector.setDropPage(d);
|
||||
removePageOnStitching = d;
|
||||
});
|
||||
Optional.ofNullable((Integer)config.get(prefix+"rotation")).ifPresent(angle -> {
|
||||
rotationSelector.set(angle);
|
||||
rotationAngle = angle;
|
||||
});
|
||||
Optional.ofNullable(config.get(prefix+"target_type")).map(Object::toString).ifPresent(t -> {
|
||||
typeSelector.set(t);
|
||||
type = t;
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -410,9 +505,10 @@ public class Worker {
|
||||
return this;
|
||||
}
|
||||
|
||||
public void setRotation(int angle) {
|
||||
public Worker setRotation(int angle) {
|
||||
LOG.debug("setRotation({})",angle);
|
||||
rotationAngle = angle;
|
||||
return this;
|
||||
}
|
||||
|
||||
public void join(Project project) {
|
||||
@@ -438,7 +534,8 @@ public class Worker {
|
||||
}
|
||||
cmd.add("cat");
|
||||
cmd.add("output");
|
||||
File joinedPDF = new File(project.pattern().replace("["+PAGE+"]",firstPage+"…"+lastPage+".pdf"));
|
||||
var pageReplace = removePageOnStitching ? "" : firstPage+"…"+lastPage;
|
||||
File joinedPDF = new File(project.pattern().replace("["+PAGE+"]",pageReplace).trim()+".pdf");
|
||||
String target = joinedPDF.getName();
|
||||
cmd.add(target);
|
||||
|
||||
@@ -471,4 +568,29 @@ public class Worker {
|
||||
LOG.error("Failed to show help",e);
|
||||
}
|
||||
}
|
||||
|
||||
public void setRemovePageOnStitching(boolean newValue) {
|
||||
removePageOnStitching = newValue;
|
||||
}
|
||||
|
||||
public void setDimensionPicker(JTextField height, JTextField width) {
|
||||
heightField = height;
|
||||
widthField = width;
|
||||
}
|
||||
|
||||
public void setResolutionSelector(ResolutionSelector newVal) {
|
||||
resolutionSelector = newVal;
|
||||
}
|
||||
|
||||
public void setImproveSelector(ImproveSelector newVal) {
|
||||
improveSelector = newVal;
|
||||
}
|
||||
|
||||
public void setRotationSelector(RotationSelector newVal) {
|
||||
rotationSelector = newVal;
|
||||
}
|
||||
|
||||
public void setTypeSelector(TypeSelector newVal) {
|
||||
typeSelector = newVal;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -56,7 +56,7 @@ public class DocTable extends JPanel{
|
||||
rows.put(project.pattern(), this);
|
||||
constraints.gridy = ++rowCounter;
|
||||
constraints.gridx = 0;
|
||||
add(pathLabel = new JLabel(project.nextFile().getParent()), constraints);
|
||||
add(pathLabel = new JLabel(project.nextFile().toString()), constraints);
|
||||
constraints.gridx = 1;
|
||||
add(status = new JLabel("neu"),constraints);
|
||||
|
||||
|
||||
@@ -10,10 +10,14 @@ import java.awt.event.KeyAdapter;
|
||||
import java.awt.event.KeyEvent;
|
||||
|
||||
import static de.srsoftware.belegscanner.Application.t;
|
||||
import static de.srsoftware.belegscanner.Constants.DEFAULT_HEIGHT;
|
||||
import static de.srsoftware.belegscanner.Constants.DEFAULT_WIDTH;
|
||||
import static java.awt.BorderLayout.CENTER;
|
||||
import static java.awt.BorderLayout.NORTH;
|
||||
import static java.awt.BorderLayout.SOUTH;
|
||||
import static java.awt.BorderLayout.WEST;
|
||||
import static javax.swing.BoxLayout.X_AXIS;
|
||||
import static javax.swing.BoxLayout.Y_AXIS;
|
||||
|
||||
public class FormatSelector extends JPanel {
|
||||
private static final Logger LOG = LoggerFactory.getLogger(FormatSelector.class);
|
||||
@@ -21,24 +25,25 @@ public class FormatSelector extends JPanel {
|
||||
private final Worker worker;
|
||||
|
||||
public FormatSelector(Worker worker){
|
||||
setLayout(new BoxLayout(this,BoxLayout.Y_AXIS));
|
||||
setLayout(new BoxLayout(this,Y_AXIS));
|
||||
this.worker = worker;
|
||||
JPanel widthSelector = new JPanel();
|
||||
widthSelector.setLayout(new BorderLayout());
|
||||
widthSelector.setLayout(new BoxLayout(widthSelector,X_AXIS));
|
||||
widthSelector.setMaximumSize(new Dimension(600, 40));
|
||||
|
||||
widthSelector.add(new JLabel(t("Width")+": "), WEST);
|
||||
widthSelector.add(width = new JTextField(209+""), CENTER);
|
||||
widthSelector.add(new JLabel("px"),BorderLayout.EAST);
|
||||
widthSelector.add(new JLabel(t("Width")+": "));
|
||||
widthSelector.add(width = new JTextField(DEFAULT_WIDTH));
|
||||
widthSelector.add(new JLabel("px"));
|
||||
|
||||
add(widthSelector,NORTH);
|
||||
|
||||
var heightSelector = new JPanel();
|
||||
heightSelector.setLayout(new BorderLayout());
|
||||
heightSelector.setLayout(new BoxLayout(heightSelector, X_AXIS));
|
||||
heightSelector.setMaximumSize(new Dimension(600, 40));
|
||||
|
||||
heightSelector.add(new JLabel(t("Height")+": "), WEST);
|
||||
heightSelector.add(height = new JTextField(297+""), CENTER);
|
||||
heightSelector.add(new JLabel("px"),BorderLayout.EAST);
|
||||
heightSelector.add(new JLabel(t("Height")+": "));
|
||||
heightSelector.add(height = new JTextField(DEFAULT_HEIGHT));
|
||||
heightSelector.add(new JLabel("px"));
|
||||
add(heightSelector,SOUTH);
|
||||
|
||||
KeyAdapter dimensionListener = new KeyAdapter() {
|
||||
@@ -55,6 +60,7 @@ public class FormatSelector extends JPanel {
|
||||
|
||||
width.addKeyListener(dimensionListener);
|
||||
height.addKeyListener(dimensionListener);
|
||||
worker.setDimensionPicker(height,width);
|
||||
updateDim();
|
||||
}
|
||||
|
||||
|
||||
@@ -7,22 +7,35 @@ import java.awt.*;
|
||||
|
||||
import static de.srsoftware.belegscanner.Application.t;
|
||||
import static java.awt.BorderLayout.NORTH;
|
||||
import static java.awt.BorderLayout.SOUTH;
|
||||
import static java.awt.BorderLayout.WEST;
|
||||
|
||||
public class ImproveSelector extends JPanel {
|
||||
|
||||
private boolean improveBrightness;
|
||||
private final JCheckBox brightnessCheckbox,stitchPages;
|
||||
|
||||
public ImproveSelector(Worker worker) {
|
||||
super(new BorderLayout());
|
||||
ButtonGroup group = new ButtonGroup();
|
||||
add(new JLabel(t("Adjustments")), NORTH);
|
||||
var checkbox = new JCheckBox(t("Improve brightness"));
|
||||
add(checkbox,WEST);
|
||||
brightnessCheckbox = new JCheckBox(t("Improve brightness"));
|
||||
add(brightnessCheckbox,WEST);
|
||||
stitchPages = new JCheckBox(t("Remove [PAGE] when stitching"));
|
||||
add(stitchPages,SOUTH);
|
||||
setMaximumSize(new Dimension(600,200));
|
||||
checkbox.addActionListener(e -> {
|
||||
worker.setImproveBrightness(checkbox.isSelected());
|
||||
|
||||
brightnessCheckbox.addActionListener(e -> {
|
||||
worker.setImproveBrightness(brightnessCheckbox.isSelected());
|
||||
});
|
||||
stitchPages.addActionListener(e -> {
|
||||
worker.setRemovePageOnStitching(stitchPages.isSelected());
|
||||
});
|
||||
worker.setImproveSelector(this);
|
||||
}
|
||||
|
||||
public void setImproveBrightness(boolean newVal) {
|
||||
brightnessCheckbox.setSelected(newVal);
|
||||
}
|
||||
|
||||
public void setDropPage(boolean newVal) {
|
||||
stitchPages.setSelected(newVal);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,20 +2,19 @@ package de.srsoftware.belegscanner.gui;
|
||||
|
||||
import de.srsoftware.belegscanner.Configuration;
|
||||
import de.srsoftware.belegscanner.Worker;
|
||||
import org.icepdf.ri.common.SwingController;
|
||||
import org.icepdf.ri.common.views.DocumentViewController;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.awt.event.WindowAdapter;
|
||||
import java.awt.event.WindowEvent;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Arrays;
|
||||
import java.util.Date;
|
||||
import java.util.HashMap;
|
||||
@@ -60,7 +59,7 @@ public class MainFrame extends JFrame {
|
||||
|
||||
private String path = "";
|
||||
|
||||
private String category ="";
|
||||
private String profile ="";
|
||||
|
||||
private Date date = new Date();
|
||||
|
||||
@@ -97,7 +96,21 @@ public class MainFrame extends JFrame {
|
||||
int width = config.getOrCreate(APP_WIDTH,800);
|
||||
int height = config.getOrCreate(APP_HEIGHT,600);
|
||||
setPreferredSize(new Dimension(width,height));
|
||||
|
||||
addWindowListener(new WindowAdapter() {
|
||||
@Override
|
||||
public void windowClosing(WindowEvent e) {
|
||||
super.windowClosing(e);
|
||||
try {
|
||||
config.set(APP_X,getX())
|
||||
.set(APP_Y,getY())
|
||||
.set(APP_WIDTH,getWidth())
|
||||
.set(APP_HEIGHT,getHeight())
|
||||
.save();
|
||||
} catch (IOException ex) {
|
||||
LOG.error("Failed to save config!");
|
||||
}
|
||||
}
|
||||
});
|
||||
pack();
|
||||
setVisible(true);
|
||||
}
|
||||
@@ -210,6 +223,7 @@ public class MainFrame extends JFrame {
|
||||
if (file == null){
|
||||
if (previewComponent != null) remove(previewComponent);
|
||||
previewComponent = null;
|
||||
pack();
|
||||
return;
|
||||
}
|
||||
String filename = file.toString();
|
||||
|
||||
@@ -4,44 +4,59 @@ import de.srsoftware.belegscanner.Worker;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.util.List;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import static de.srsoftware.belegscanner.Application.t;
|
||||
import static java.awt.BorderLayout.CENTER;
|
||||
import static java.awt.BorderLayout.EAST;
|
||||
import static java.awt.BorderLayout.NORTH;
|
||||
import static java.awt.BorderLayout.WEST;
|
||||
|
||||
public class ResolutionSelector extends JPanel{
|
||||
|
||||
private class ResolutionButton extends JRadioButton{
|
||||
int resolution;
|
||||
|
||||
ResolutionButton(ButtonGroup group, JLabel label, int resolution){
|
||||
super(resolution+" px");
|
||||
this.resolution = resolution;
|
||||
buttons.add(this);
|
||||
group.add(this);
|
||||
addActionListener(ev -> {
|
||||
label.setText("aktuelle Auflösung: "+worker.setResolution(resolution)+"px");
|
||||
});
|
||||
if (resolution==150) setSelected(true);
|
||||
}
|
||||
|
||||
public void selectOnMatch(int newVal) {
|
||||
setSelected(resolution == newVal);
|
||||
}
|
||||
}
|
||||
private final Worker worker;
|
||||
|
||||
private List<ResolutionButton> buttons = new ArrayList<>();
|
||||
|
||||
public ResolutionSelector(Worker worker) {
|
||||
super(new BorderLayout());
|
||||
this.worker = worker;
|
||||
;
|
||||
|
||||
ButtonGroup group = new ButtonGroup();
|
||||
JLabel label = new JLabel(t("current resolution") + ": " + worker.setResolution(150) + "px");
|
||||
add(label, NORTH);
|
||||
add(resolutionButton(group, label, 150), WEST);
|
||||
add(resolutionButton(group, label, 300), CENTER);
|
||||
add(resolutionButton(group, label, 600), EAST);
|
||||
var buttons = new JPanel();
|
||||
buttons.setLayout(new BoxLayout(buttons,BoxLayout.X_AXIS));
|
||||
buttons.add(new ResolutionButton(group, label, 150));
|
||||
buttons.add(new ResolutionButton(group, label, 300));
|
||||
buttons.add(new ResolutionButton(group, label, 600));
|
||||
buttons.add(Box.createHorizontalGlue());
|
||||
add(buttons,CENTER);
|
||||
setMaximumSize(new Dimension(600, 200));
|
||||
worker.setResolutionSelector(this);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* create one radio button for the resoultionSelector
|
||||
* @param group
|
||||
* @param label
|
||||
* @param resolution
|
||||
* @return
|
||||
*/
|
||||
private JRadioButton resolutionButton(ButtonGroup group, JLabel label, int resolution) {
|
||||
JRadioButton btn = new JRadioButton(resolution+" px");
|
||||
btn.addActionListener(ev -> {
|
||||
label.setText("aktuelle Auflösung: "+worker.setResolution(resolution)+"px");
|
||||
});
|
||||
group.add(btn);
|
||||
if (resolution==150) btn.setSelected(true);
|
||||
return btn;
|
||||
|
||||
|
||||
public void set(int resolution) {
|
||||
buttons.forEach(btn -> btn.selectOnMatch(resolution));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,9 @@ package de.srsoftware.belegscanner.gui;
|
||||
import de.srsoftware.belegscanner.Worker;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.util.List;
|
||||
import java.awt.*;
|
||||
import java.util.ArrayList;
|
||||
|
||||
import static de.srsoftware.belegscanner.Application.t;
|
||||
import static java.awt.BorderLayout.CENTER;
|
||||
@@ -12,37 +14,49 @@ import static java.awt.BorderLayout.WEST;
|
||||
|
||||
public class RotationSelector extends JPanel {
|
||||
|
||||
|
||||
private class RotationButton extends JRadioButton{
|
||||
|
||||
private final int angle;
|
||||
|
||||
public RotationButton(ButtonGroup group, int angle) {
|
||||
super(angle+"°");
|
||||
this.angle = angle;
|
||||
if (angle==150) setSelected(true);
|
||||
addActionListener(ev -> {
|
||||
worker.setRotation(angle);
|
||||
});
|
||||
group.add(this);
|
||||
buttons.add(this);
|
||||
}
|
||||
|
||||
public void enableIf(int newVal) {
|
||||
setSelected(angle == newVal);
|
||||
}
|
||||
}
|
||||
|
||||
private List<RotationButton> buttons = new ArrayList<>();
|
||||
private final Worker worker;
|
||||
private final JRadioButton noRotation;
|
||||
|
||||
public RotationSelector(Worker worker) {
|
||||
setLayout(new BoxLayout(this,BoxLayout.X_AXIS));
|
||||
this.worker = worker;
|
||||
super(new BorderLayout());
|
||||
this.worker = worker.setRotation(0);
|
||||
ButtonGroup group = new ButtonGroup();
|
||||
worker.setRotation(0);
|
||||
add(noRotation = rotatatonButton(group, 0));
|
||||
add(rotatatonButton(group, 90));
|
||||
add(rotatatonButton(group, 180));
|
||||
add(rotatatonButton(group, -90));
|
||||
var radios = new JPanel();
|
||||
radios.setLayout(new BoxLayout(radios,BoxLayout.X_AXIS));
|
||||
radios.add(noRotation = new RotationButton(group, 0));
|
||||
radios.add(new RotationButton(group, 90));
|
||||
radios.add(new RotationButton(group, 180));
|
||||
radios.add(new RotationButton(group, -90));
|
||||
noRotation.setSelected(true);
|
||||
add(new JLabel(t("Rotation")));
|
||||
add(new JLabel(t("Rotation")),NORTH);
|
||||
add(radios,CENTER);
|
||||
setMaximumSize(new Dimension(600, 200));
|
||||
worker.setRotationSelector(this);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* create one radio button for the resoultionSelector
|
||||
* @param group
|
||||
* @param angle
|
||||
* @return
|
||||
*/
|
||||
private JRadioButton rotatatonButton(ButtonGroup group, int angle) {
|
||||
JRadioButton btn = new JRadioButton(angle+"°");
|
||||
btn.addActionListener(ev -> {
|
||||
worker.setRotation(angle);
|
||||
});
|
||||
group.add(btn);
|
||||
if (angle==150) btn.setSelected(true);
|
||||
return btn;
|
||||
public void set(Integer angle) {
|
||||
buttons.forEach(b -> b.enableIf(angle));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,18 +2,14 @@ package de.srsoftware.belegscanner.gui;
|
||||
|
||||
import java.awt.Component;
|
||||
import java.awt.Dimension;
|
||||
import java.sql.Struct;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Vector;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import javax.swing.*;
|
||||
import javax.swing.border.EmptyBorder;
|
||||
|
||||
import de.srsoftware.belegscanner.Constants;
|
||||
import de.srsoftware.belegscanner.Worker;
|
||||
import org.json.JSONObject;
|
||||
import org.slf4j.Logger;
|
||||
@@ -33,9 +29,8 @@ import static javax.swing.BoxLayout.Y_AXIS;
|
||||
*/
|
||||
public class Toolbar extends JPanel {
|
||||
|
||||
private final SelectComboBox pathPicker, catPicker;
|
||||
private final SelectComboBox pathPicker, profilePicker;
|
||||
private static final int OFFSET = 2;
|
||||
|
||||
private class AdditionalInput {
|
||||
private final JPanel panel;
|
||||
private final SelectComboBox input;
|
||||
@@ -70,7 +65,7 @@ public class Toolbar extends JPanel {
|
||||
worker.setToolbar(this);
|
||||
setLayout(new BoxLayout(this, Y_AXIS));
|
||||
add(datePicker());
|
||||
add(input(t("Category"),catPicker = categoryPicker()));
|
||||
add(input(t("Profile"), profilePicker = profilePicker()));
|
||||
add(input(t("Path"),pathPicker = pathPicker()));
|
||||
add(new FormatSelector(worker));
|
||||
add(new ResolutionSelector(worker));
|
||||
@@ -83,14 +78,14 @@ public class Toolbar extends JPanel {
|
||||
buttonBox.add(Box.createRigidArea(new Dimension(10,10)));
|
||||
buttonBox.add(helpButton());
|
||||
add(buttonBox);
|
||||
add(Box.createGlue());
|
||||
add(Box.createVerticalGlue());
|
||||
Arrays.stream(getComponents()).filter(c -> c instanceof JPanel).map(JPanel.class::cast).forEach(p -> p.setBorder(BORDER));
|
||||
}
|
||||
|
||||
|
||||
|
||||
private SelectComboBox categoryPicker() {
|
||||
return new SelectComboBox(worker.getCategories().keySet()).onUpdateText(worker::setCat).onDelete(worker::dropCategory);
|
||||
private SelectComboBox profilePicker() {
|
||||
return new SelectComboBox(worker.getProfiles().keySet()).onUpdateText(worker::loadProfile).onDelete(worker::dropProfile);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -146,12 +141,12 @@ public class Toolbar extends JPanel {
|
||||
* @return
|
||||
*/
|
||||
private SelectComboBox pathPicker() {
|
||||
JSONObject cats = worker.getCategories();
|
||||
for (String catName : cats.keySet()) {
|
||||
JSONObject catInfo = cats.getJSONObject(catName);
|
||||
if (catInfo.has("path")) paths.add(catInfo.get("path"));
|
||||
JSONObject profiles = worker.getProfiles();
|
||||
for (String profileName : profiles.keySet()) {
|
||||
JSONObject profileInfo = profiles.getJSONObject(profileName);
|
||||
if (profileInfo.has("path")) paths.add(profileInfo.get("path"));
|
||||
}
|
||||
paths.add("$"+t("HOME")+"/$"+t("YEAR")+"/$"+t("MONTH")+"-$"+t("DAY")+" - $"+t("CATEGORY")+"/$"+t("PAGE"));
|
||||
paths.add("$"+t("HOME")+"/$"+t("YEAR")+"/$"+t("MONTH")+"-$"+t("DAY")+" - $"+t("PROFILE")+"/$"+t("EXTRA")+" - "+t("Page")+" $"+t("PAGE"));
|
||||
return worker.setPathPicker(new SelectComboBox(paths));
|
||||
}
|
||||
|
||||
|
||||
@@ -5,6 +5,8 @@ import de.srsoftware.belegscanner.Worker;
|
||||
|
||||
import javax.swing.*;
|
||||
import java.awt.*;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static de.srsoftware.belegscanner.Application.t;
|
||||
import static de.srsoftware.belegscanner.Constants.CONFIG_TARGET;
|
||||
@@ -14,36 +16,49 @@ import static de.srsoftware.belegscanner.Constants.PDF;
|
||||
import static java.awt.BorderLayout.CENTER;
|
||||
import static java.awt.BorderLayout.NORTH;
|
||||
import static java.awt.BorderLayout.WEST;
|
||||
import static javax.swing.BoxLayout.X_AXIS;
|
||||
|
||||
public class TypeSelector extends JPanel {
|
||||
|
||||
private class TypeButton extends JRadioButton{
|
||||
|
||||
private final String type;
|
||||
|
||||
public TypeButton(ButtonGroup group, String type) {
|
||||
super(t(type));
|
||||
this.type = type;
|
||||
addActionListener(ev -> worker.setType(type));
|
||||
group.add(this);
|
||||
buttons.add(this);
|
||||
}
|
||||
|
||||
public void enableOn(String type) {
|
||||
setSelected(this.type.equals(type));
|
||||
}
|
||||
}
|
||||
private final Worker worker;
|
||||
|
||||
private List<TypeButton> buttons = new ArrayList<>();
|
||||
|
||||
public TypeSelector(Worker worker){
|
||||
super(new BorderLayout());
|
||||
this.worker = worker;
|
||||
ButtonGroup group = new ButtonGroup();
|
||||
JLabel label = new JLabel(t("Target type"));
|
||||
String target = worker.getType();
|
||||
add(label, NORTH);
|
||||
add(typeButton(group,t(JPG),target), WEST);
|
||||
add(typeButton(group,t(PDF),target), CENTER);
|
||||
add(typeButton(group,t(OCR),target),BorderLayout.EAST);
|
||||
var buttons = new JPanel();
|
||||
buttons.setLayout(new BoxLayout(buttons,X_AXIS));
|
||||
buttons.add(new TypeButton(group,JPG));
|
||||
buttons.add(new TypeButton(group,PDF));
|
||||
buttons.add(new TypeButton(group,OCR));
|
||||
add(buttons,CENTER);
|
||||
setMaximumSize(new Dimension(600,200));
|
||||
worker.setTypeSelector(this);
|
||||
set(OCR);
|
||||
}
|
||||
|
||||
/**
|
||||
* create one radio button for the typeSelector
|
||||
* @param group
|
||||
* @param label
|
||||
* @param selection
|
||||
* @return
|
||||
*/
|
||||
private JRadioButton typeButton(ButtonGroup group, String label,String selection) {
|
||||
JRadioButton btn = new JRadioButton(label);
|
||||
group.add(btn);
|
||||
btn.addActionListener(ev -> worker.setType(label));
|
||||
if (label.equals(selection)) btn.setSelected(true);
|
||||
return btn;
|
||||
public void set(String type) {
|
||||
buttons.forEach(b -> b.enableOn(type));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user