|
|
|
@ -1,36 +1,28 @@
@@ -1,36 +1,28 @@
|
|
|
|
|
package de.srsoftware.belegscanner.gui; |
|
|
|
|
|
|
|
|
|
import java.awt.BorderLayout; |
|
|
|
|
import java.awt.Component; |
|
|
|
|
import java.awt.Dimension; |
|
|
|
|
import java.awt.event.ActionEvent; |
|
|
|
|
import java.awt.event.ActionListener; |
|
|
|
|
import java.awt.event.KeyAdapter; |
|
|
|
|
import java.awt.event.KeyEvent; |
|
|
|
|
import java.sql.Struct; |
|
|
|
|
import java.util.Arrays; |
|
|
|
|
import java.util.Date; |
|
|
|
|
import java.util.HashMap; |
|
|
|
|
import java.util.HashSet; |
|
|
|
|
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 org.json.JSONArray; |
|
|
|
|
import de.srsoftware.belegscanner.Constants; |
|
|
|
|
import de.srsoftware.belegscanner.Worker; |
|
|
|
|
import org.json.JSONObject; |
|
|
|
|
import org.slf4j.Logger; |
|
|
|
|
import org.slf4j.LoggerFactory; |
|
|
|
|
|
|
|
|
|
import de.srsoftware.belegscanner.Configuration; |
|
|
|
|
import de.srsoftware.belegscanner.Constants; |
|
|
|
|
import de.srsoftware.tools.gui.DateChooser; |
|
|
|
|
import de.srsoftware.tools.gui.SelectComboBox; |
|
|
|
|
|
|
|
|
|
import static de.srsoftware.belegscanner.Application.*; |
|
|
|
|
import static de.srsoftware.belegscanner.Constants.*; |
|
|
|
|
import static java.awt.BorderLayout.*; |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* create the application's toolbar |
|
|
|
@ -39,208 +31,58 @@ import static java.awt.BorderLayout.*;
@@ -39,208 +31,58 @@ import static java.awt.BorderLayout.*;
|
|
|
|
|
*/ |
|
|
|
|
public class Toolbar extends JPanel { |
|
|
|
|
|
|
|
|
|
private static final Logger LOG = LoggerFactory.getLogger(Toolbar.class); |
|
|
|
|
|
|
|
|
|
public interface CategoryListener{ |
|
|
|
|
public void setCategory(String category); |
|
|
|
|
} |
|
|
|
|
private final SelectComboBox pathPicker, catPicker; |
|
|
|
|
private static final int OFFSET = 2; |
|
|
|
|
|
|
|
|
|
public interface DateListener{ |
|
|
|
|
public void setDate(Date date); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
public interface DimensionListener{ |
|
|
|
|
public void setDimension(Dimension dimension); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private class AdditionalInput { |
|
|
|
|
private final JPanel panel; |
|
|
|
|
private final SelectComboBox input; |
|
|
|
|
private boolean required; |
|
|
|
|
|
|
|
|
|
public interface FieldListener{ |
|
|
|
|
public void setField(String name, String value); |
|
|
|
|
} |
|
|
|
|
AdditionalInput(JPanel panel, SelectComboBox input, boolean required){ |
|
|
|
|
this.panel = panel; |
|
|
|
|
this.input = input; |
|
|
|
|
this.required = required; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
public interface PathListener{ |
|
|
|
|
public void setPath(String path); |
|
|
|
|
public void notRequired () { |
|
|
|
|
required = false; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private static final Logger LOG = LoggerFactory.getLogger(Toolbar.class); |
|
|
|
|
private final Worker worker; |
|
|
|
|
private static final long serialVersionUID = -5834326573752788233L; |
|
|
|
|
private static final int OFFSET = 2; |
|
|
|
|
private static EmptyBorder BORDER = new EmptyBorder(0,5,5,5); |
|
|
|
|
|
|
|
|
|
private static Map<String, AdditionalInput> additionalInputs = new HashMap<>(); |
|
|
|
|
|
|
|
|
|
private Vector<Object> paths = new Vector<>(); |
|
|
|
|
|
|
|
|
|
private HashMap<String,JPanel> additonalComponents = new HashMap<>(); |
|
|
|
|
private HashSet<CategoryListener> categoryListeners = new HashSet<>(); |
|
|
|
|
private HashSet<DateListener> dateListeners = new HashSet<>(); |
|
|
|
|
private HashSet<FieldListener> fieldListeners = new HashSet<>(); |
|
|
|
|
private HashSet<PathListener> pathListeners = new HashSet<>(); |
|
|
|
|
private HashSet<ActionListener> scanListeners = new HashSet<>(); |
|
|
|
|
private HashSet<DimensionListener> dimensionListeners = new HashSet<>(); |
|
|
|
|
|
|
|
|
|
private DateChooser date; |
|
|
|
|
|
|
|
|
|
private Configuration config; |
|
|
|
|
|
|
|
|
|
private SelectComboBox pathPicker; |
|
|
|
|
|
|
|
|
|
private JButton scanButton; |
|
|
|
|
|
|
|
|
|
private JTextField width; |
|
|
|
|
private JTextField height; |
|
|
|
|
private SelectComboBox catPicker; |
|
|
|
|
private int resolution = 150; |
|
|
|
|
private boolean improveBrightness = false; |
|
|
|
|
/** |
|
|
|
|
* create toolbar |
|
|
|
|
* @param config |
|
|
|
|
*/ |
|
|
|
|
public Toolbar(Configuration config) { |
|
|
|
|
this.config = config; |
|
|
|
|
public Toolbar(Worker worker) { |
|
|
|
|
this.worker = worker; |
|
|
|
|
worker.setToolbar(this); |
|
|
|
|
setLayout(new BoxLayout(this, BoxLayout.Y_AXIS)); |
|
|
|
|
add(datePicker()); |
|
|
|
|
add(input(t("Category"),catPicker = categoryPicker(config))); |
|
|
|
|
add(input(t("Category"),catPicker = categoryPicker())); |
|
|
|
|
add(input(t("Path"),pathPicker = pathPicker())); |
|
|
|
|
addFormatSelector(); |
|
|
|
|
add(resolutionSelector()); |
|
|
|
|
add(improveSelector()); |
|
|
|
|
add(typeSelector()); |
|
|
|
|
add(new FormatSelector(worker)); |
|
|
|
|
add(new ResolutionSelector()); |
|
|
|
|
add(new ImproveSelector()); |
|
|
|
|
add(new TypeSelector(worker)); |
|
|
|
|
add(scanButton()); |
|
|
|
|
add(Box.createGlue()); |
|
|
|
|
Arrays.stream(getComponents()).filter(c -> c instanceof JPanel).map(JPanel.class::cast).forEach(p -> p.setBorder(BORDER)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* add a listener for updates of the categoriy field |
|
|
|
|
* @param listener |
|
|
|
|
* @return |
|
|
|
|
*/ |
|
|
|
|
public Toolbar addCategoryListener(CategoryListener listener) { |
|
|
|
|
categoryListeners.add(listener); |
|
|
|
|
return this; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* add a listener for updates of the date selector |
|
|
|
|
* @param listener |
|
|
|
|
* @return |
|
|
|
|
*/ |
|
|
|
|
public Toolbar addDateListener(DateListener listener) { |
|
|
|
|
dateListeners.add(listener); |
|
|
|
|
return this; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* add a listener for changes to the dimension form |
|
|
|
|
* @param listener |
|
|
|
|
* @return |
|
|
|
|
*/ |
|
|
|
|
public Toolbar addDimensionListener(DimensionListener listener) { |
|
|
|
|
dimensionListeners.add(listener); |
|
|
|
|
return this; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* add an input field for a variable placeholder |
|
|
|
|
* @param marks |
|
|
|
|
*/ |
|
|
|
|
public void addFieldsFor(Vector<String> marks) { |
|
|
|
|
LOG.debug("addFieldsFor({})",marks); |
|
|
|
|
|
|
|
|
|
List<String> deleted = additonalComponents.keySet().stream().filter(key -> !marks.contains(key)).collect(Collectors.toList()); |
|
|
|
|
deleted.forEach(name -> remove(additonalComponents.remove(name))); |
|
|
|
|
|
|
|
|
|
for (String name : marks) { |
|
|
|
|
if (additonalComponents.containsKey(name)) continue; |
|
|
|
|
SelectComboBox valuePicker = new SelectComboBox(new Vector<>()).onUpdateText(newText -> updateField(name,newText)); |
|
|
|
|
JPanel input = input(name, valuePicker); |
|
|
|
|
if (t("PAGE").equals(name)) { |
|
|
|
|
valuePicker.setText("1"); |
|
|
|
|
SwingUtilities.invokeLater(() -> updateField(name,"1")); |
|
|
|
|
} |
|
|
|
|
input.setBorder(BORDER); |
|
|
|
|
add(input,getComponentCount()-OFFSET); |
|
|
|
|
additonalComponents.put(name, input); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* add a form that enables the user to set the size of the scanning area |
|
|
|
|
*/ |
|
|
|
|
private void addFormatSelector() { |
|
|
|
|
JPanel dummy = new JPanel(); |
|
|
|
|
dummy.setLayout(new BorderLayout()); |
|
|
|
|
dummy.setMaximumSize(new Dimension(600, 40)); |
|
|
|
|
|
|
|
|
|
dummy.add(new JLabel(t("Width")+": "), WEST); |
|
|
|
|
dummy.add(width = new JTextField(209+""), CENTER); |
|
|
|
|
dummy.add(new JLabel("px"),BorderLayout.EAST); |
|
|
|
|
add(dummy); |
|
|
|
|
|
|
|
|
|
dummy = new JPanel(); |
|
|
|
|
dummy.setLayout(new BorderLayout()); |
|
|
|
|
dummy.setMaximumSize(new Dimension(600, 40)); |
|
|
|
|
|
|
|
|
|
dummy.add(new JLabel(t("Height")+": "), WEST); |
|
|
|
|
dummy.add(height = new JTextField(297+""), CENTER); |
|
|
|
|
dummy.add(new JLabel("px"),BorderLayout.EAST); |
|
|
|
|
add(dummy); |
|
|
|
|
|
|
|
|
|
KeyAdapter dimensionListener = new KeyAdapter() { |
|
|
|
|
@Override |
|
|
|
|
public void keyReleased(KeyEvent e) { |
|
|
|
|
updateDimensions(); |
|
|
|
|
} |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
width.addKeyListener(dimensionListener); |
|
|
|
|
height.addKeyListener(dimensionListener); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* add a listener for updates of the variable fields |
|
|
|
|
* @param listener |
|
|
|
|
* @return |
|
|
|
|
*/ |
|
|
|
|
public Toolbar addFieldListener(FieldListener listener) { |
|
|
|
|
fieldListeners.add(listener); |
|
|
|
|
return this; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* add a listener for updates of the target path |
|
|
|
|
* @param listener |
|
|
|
|
* @return |
|
|
|
|
*/ |
|
|
|
|
public Toolbar addPathListener(PathListener listener){ |
|
|
|
|
pathListeners.add(listener); |
|
|
|
|
return this; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* add a listener for the scan button |
|
|
|
|
* @param listener |
|
|
|
|
* @return |
|
|
|
|
*/ |
|
|
|
|
public Toolbar addScanListener(ActionListener listener) { |
|
|
|
|
scanListeners.add(listener); |
|
|
|
|
return this; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* create a auto complete text field for the category selection |
|
|
|
|
* @param config |
|
|
|
|
* @return |
|
|
|
|
*/ |
|
|
|
|
private SelectComboBox categoryPicker(Configuration config) { |
|
|
|
|
JSONObject elements = config.getOrCreate("app.categories",new JSONObject()); |
|
|
|
|
return new SelectComboBox(elements.keySet()) |
|
|
|
|
.onUpdateText(this::updateCat) |
|
|
|
|
.onDelete(this::dropCategory); |
|
|
|
|
private SelectComboBox categoryPicker() { |
|
|
|
|
return new SelectComboBox(worker.getCategories().keySet()).onUpdateText(worker::setCat).onDelete(worker::dropCategory); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
@ -251,93 +93,18 @@ public class Toolbar extends JPanel {
@@ -251,93 +93,18 @@ public class Toolbar extends JPanel {
|
|
|
|
|
date = new DateChooser(); |
|
|
|
|
Dimension dim = new Dimension(400, 250); |
|
|
|
|
date.setMaximumSize(dim); |
|
|
|
|
date.addActionListener(ev -> { |
|
|
|
|
resetPage(); |
|
|
|
|
dateListeners.forEach(listener -> listener.setDate(date.getSelectedDate())); |
|
|
|
|
}); |
|
|
|
|
return date; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* delete a value (by key) from a JSONArray |
|
|
|
|
* @param arr |
|
|
|
|
* @param tx |
|
|
|
|
* @return |
|
|
|
|
*/ |
|
|
|
|
private List<Object> deleteValue(JSONArray arr, String tx) { |
|
|
|
|
for (int i = 0; i<arr.length(); i++) { |
|
|
|
|
if (arr.get(i).equals(tx)) { |
|
|
|
|
arr.remove(i); |
|
|
|
|
break; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
return arr.toList(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* drop a category from the category pickers list of known categories |
|
|
|
|
* @param catName |
|
|
|
|
*/ |
|
|
|
|
private void dropCategory(String catName) { |
|
|
|
|
LOG.debug("dropCategory({})",catName); |
|
|
|
|
Object o = config.get("app.categories"); |
|
|
|
|
if (o instanceof JSONObject) { |
|
|
|
|
JSONObject json = (JSONObject)o; |
|
|
|
|
json.remove(catName); |
|
|
|
|
catPicker.setElements(json.keySet()); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
worker.setDatePicker(date); |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* get date from the date picker |
|
|
|
|
* @return |
|
|
|
|
*/ |
|
|
|
|
public Date getDate() { |
|
|
|
|
return date.getSelectedDate(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public boolean getImproveBrightness(){ |
|
|
|
|
return improveBrightness; |
|
|
|
|
} |
|
|
|
|
/** |
|
|
|
|
* get resolution (set by resoultion form) |
|
|
|
|
* @return |
|
|
|
|
*/ |
|
|
|
|
public int getResolution() { |
|
|
|
|
return resolution; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* helper: returns the selector added as the second component of a JPanel |
|
|
|
|
* @param panel |
|
|
|
|
* @return null, of the panel has less than two children or the second child is no selector |
|
|
|
|
*/ |
|
|
|
|
public SelectComboBox getSelector(JPanel panel) { |
|
|
|
|
if (panel != null && panel.getComponentCount()>1) { |
|
|
|
|
Component child = panel.getComponent(1); |
|
|
|
|
if (child instanceof SelectComboBox) return (SelectComboBox) child; |
|
|
|
|
} |
|
|
|
|
return null; |
|
|
|
|
return date; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* set of checkboxes for adjustments |
|
|
|
|
* @return |
|
|
|
|
*/ |
|
|
|
|
private JPanel improveSelector() { |
|
|
|
|
ButtonGroup group = new ButtonGroup(); |
|
|
|
|
JPanel adjustmentSelector = new JPanel(new BorderLayout()); |
|
|
|
|
adjustmentSelector.add(new JLabel(t("Adjustments")), NORTH); |
|
|
|
|
var checkbox = new JCheckBox(t("Improve brightness")); |
|
|
|
|
adjustmentSelector.add(checkbox,WEST); |
|
|
|
|
adjustmentSelector.setMaximumSize(new Dimension(600,200)); |
|
|
|
|
checkbox.addActionListener(e -> { |
|
|
|
|
improveBrightness = checkbox.isSelected(); |
|
|
|
|
}); |
|
|
|
|
return adjustmentSelector; |
|
|
|
|
public void dropUnusedAdditionalFields() { |
|
|
|
|
additionalInputs.entrySet() |
|
|
|
|
.stream() |
|
|
|
|
.filter(entry -> !entry.getValue().required) |
|
|
|
|
.map(Map.Entry::getValue) |
|
|
|
|
.map(ai -> ai.panel) |
|
|
|
|
.forEach(this::remove); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
@ -356,221 +123,57 @@ public class Toolbar extends JPanel {
@@ -356,221 +123,57 @@ public class Toolbar extends JPanel {
|
|
|
|
|
return panel; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
public Toolbar resetPage(){ |
|
|
|
|
var page = t("PAGE"); |
|
|
|
|
var panel = additonalComponents.get(page); |
|
|
|
|
if (panel == null) return this; |
|
|
|
|
for (var child : panel.getComponents()){ |
|
|
|
|
if (child instanceof SelectComboBox scb){ |
|
|
|
|
scb.setText("1"); |
|
|
|
|
fieldListeners.forEach(l -> l.setField(page,"1")); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
return this; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
public Toolbar nextPage(){ |
|
|
|
|
var page = t("PAGE"); |
|
|
|
|
var panel = additonalComponents.get(page); |
|
|
|
|
if (panel == null) return this; |
|
|
|
|
for (var child : panel.getComponents()){ |
|
|
|
|
if (child instanceof SelectComboBox scb){ |
|
|
|
|
var val = scb.getText(); |
|
|
|
|
try { |
|
|
|
|
var newVal = ""+(Integer.parseInt(val)+1); |
|
|
|
|
scb.setText(newVal); |
|
|
|
|
fieldListeners.forEach(l -> l.setField(page,newVal)); |
|
|
|
|
} catch (NumberFormatException nfe){} |
|
|
|
|
} |
|
|
|
|
LOG.debug("component: {}",child); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
return this; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* creates an auto-complete text field for setting the scan target path |
|
|
|
|
* @return |
|
|
|
|
*/ |
|
|
|
|
private SelectComboBox pathPicker() { |
|
|
|
|
JSONObject cats = config.getOrCreate("app.categories",new JSONObject()); |
|
|
|
|
JSONObject cats = worker.getCategories(); |
|
|
|
|
for (String catName : cats.keySet()) { |
|
|
|
|
JSONObject catInfo = cats.getJSONObject(catName); |
|
|
|
|
if (catInfo.has("path")) paths.add(catInfo.get("path")); |
|
|
|
|
} |
|
|
|
|
paths.add("$"+t("HOME")+"/$"+t("YEAR")+"/$"+t("MONTH")+"-$"+t("DAY")+" - $"+t("CATEGORY")+"/$"+t("PAGE")); |
|
|
|
|
return new SelectComboBox(paths).onUpdateText(this::updatePath); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* enables/disables the toolbars scan button |
|
|
|
|
* @param val |
|
|
|
|
*/ |
|
|
|
|
public void readyToScan(boolean val) { |
|
|
|
|
scanButton.setEnabled(val); |
|
|
|
|
} |
|
|
|
|
/** |
|
|
|
|
* create one radio button for the resoultionSelector |
|
|
|
|
* @param group |
|
|
|
|
* @param label |
|
|
|
|
* @param i |
|
|
|
|
* @return |
|
|
|
|
*/ |
|
|
|
|
private JRadioButton resolutionButton(ButtonGroup group, JLabel label, int i) { |
|
|
|
|
JRadioButton btn = new JRadioButton(i+" px"); |
|
|
|
|
btn.addActionListener(ev -> { |
|
|
|
|
resolution = i; |
|
|
|
|
label.setText("aktuelle Auflösung: "+resolution+"px"); |
|
|
|
|
}); |
|
|
|
|
group.add(btn); |
|
|
|
|
if (i==150) btn.setSelected(true); |
|
|
|
|
return btn; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* create a radio group to select the resolution for scanning |
|
|
|
|
* @return |
|
|
|
|
*/ |
|
|
|
|
private JPanel resolutionSelector() { |
|
|
|
|
ButtonGroup group = new ButtonGroup(); |
|
|
|
|
JPanel resolutionSelector = new JPanel(new BorderLayout()); |
|
|
|
|
JLabel label = new JLabel(t("current resolution")+": "+resolution+"px"); |
|
|
|
|
resolutionSelector.add(label, NORTH); |
|
|
|
|
resolutionSelector.add(resolutionButton(group,label,150), WEST); |
|
|
|
|
resolutionSelector.add(resolutionButton(group,label,300), CENTER); |
|
|
|
|
resolutionSelector.add(resolutionButton(group,label,600),BorderLayout.EAST); |
|
|
|
|
resolutionSelector.setMaximumSize(new Dimension(600,200)); |
|
|
|
|
return resolutionSelector; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* create scan button |
|
|
|
|
* @return |
|
|
|
|
*/ |
|
|
|
|
private Component scanButton() { |
|
|
|
|
scanButton = new JButton(t("scan!")); |
|
|
|
|
scanButton.addActionListener(this::scanPressed); |
|
|
|
|
return scanButton; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* notify listeners when scan button clicked |
|
|
|
|
* @param evt |
|
|
|
|
*/ |
|
|
|
|
private void scanPressed(ActionEvent evt) { |
|
|
|
|
scanListeners.forEach(l->l.actionPerformed(evt)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* 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 -> config.set(CONFIG_TARGET, label)); |
|
|
|
|
if (label.equals(selection)) btn.setSelected(true); |
|
|
|
|
return btn; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* create a radio group to select the target type for scanning |
|
|
|
|
* @return |
|
|
|
|
*/ |
|
|
|
|
private JPanel typeSelector() { |
|
|
|
|
ButtonGroup group = new ButtonGroup(); |
|
|
|
|
JPanel typeSelector = new JPanel(new BorderLayout()); |
|
|
|
|
JLabel label = new JLabel(t("Target type")); |
|
|
|
|
String target = config.getOrCreate(CONFIG_TARGET, PDF); |
|
|
|
|
typeSelector.add(label, NORTH); |
|
|
|
|
typeSelector.add(typeButton(group,t(JPG),target), WEST); |
|
|
|
|
typeSelector.add(typeButton(group,t(PDF),target), CENTER); |
|
|
|
|
typeSelector.add(typeButton(group,t(OCR),target),BorderLayout.EAST); |
|
|
|
|
typeSelector.setMaximumSize(new Dimension(600,200)); |
|
|
|
|
return typeSelector; |
|
|
|
|
return worker.setPathPicker(new SelectComboBox(paths)); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* category updated: notify listeners and update dependent fields |
|
|
|
|
* @param newCat |
|
|
|
|
*/ |
|
|
|
|
private void updateCat(String newCat) { |
|
|
|
|
LOG.debug("updateCat({})",newCat); |
|
|
|
|
resetPage(); |
|
|
|
|
categoryListeners.forEach(l -> l.setCategory(newCat)); |
|
|
|
|
LOG.debug("Listeners notified."); |
|
|
|
|
if (!newCat.isEmpty()) { |
|
|
|
|
String prefix = "app.categories."+newCat+"."; |
|
|
|
|
String path = config.get(prefix+"path"); |
|
|
|
|
if (path != null) { |
|
|
|
|
pathPicker.setSelectedItem(path); |
|
|
|
|
updatePath(path); |
|
|
|
|
public String requireField(String varName){ |
|
|
|
|
LOG.debug("requireField({})",varName); |
|
|
|
|
var additionalInput = additionalInputs.get(varName); |
|
|
|
|
if (additionalInput == null) { |
|
|
|
|
LOG.debug("Field missing, creating…"); |
|
|
|
|
var input = new SelectComboBox(new Vector<>()); |
|
|
|
|
if (varName.equals(t(Constants.PAGE))){ |
|
|
|
|
return "["+varName+"]"; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
JSONObject fields = config.get(prefix+"fields"); |
|
|
|
|
if (fields != null) { |
|
|
|
|
LOG.debug("fields: {}",fields); |
|
|
|
|
for (String fieldName : fields.keySet()) { |
|
|
|
|
path = prefix+"fields."+fieldName; |
|
|
|
|
|
|
|
|
|
JSONArray arr = config.getOrCreateArray(path); |
|
|
|
|
SelectComboBox selector = getSelector(additonalComponents.get(fieldName)); |
|
|
|
|
if (selector != null) selector.setElements(arr.toList()).onDelete(tx -> selector.setElements(deleteValue(arr,tx))); |
|
|
|
|
} |
|
|
|
|
input.onUpdateText(newText -> worker.resolvePath()); |
|
|
|
|
JPanel panel = input(varName,input); |
|
|
|
|
additionalInputs.put(varName, additionalInput = new AdditionalInput(panel,input,true)); |
|
|
|
|
input.setBorder(BORDER); |
|
|
|
|
add(panel,getComponentCount()-OFFSET); |
|
|
|
|
} else { |
|
|
|
|
LOG.debug("Field preset, flagging as required"); |
|
|
|
|
additionalInput.required = true; |
|
|
|
|
if (!Arrays.asList(getComponents()).contains(additionalInput.panel)){ |
|
|
|
|
add(additionalInput.panel,getComponentCount()-OFFSET); |
|
|
|
|
} |
|
|
|
|
LOG.debug("Trying to read size"); |
|
|
|
|
Integer w = config.get(prefix+"size.w"); |
|
|
|
|
LOG.debug("w: {}",w); |
|
|
|
|
width.setText(w == null ? Constants.DEFAULT_WIDTH : w+""); |
|
|
|
|
Integer h = config.get(prefix+"size.h"); |
|
|
|
|
LOG.debug("h: {}",h); |
|
|
|
|
height.setText(h == null ? Constants.DEFAULT_HEIGHT : h+""); |
|
|
|
|
updateDimensions(); |
|
|
|
|
} else LOG.debug("newCat is empty!"); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* read new dimension from dimension form, notify listeners |
|
|
|
|
*/ |
|
|
|
|
protected void updateDimensions() { |
|
|
|
|
LOG.debug("updateDimensions()"); |
|
|
|
|
try { |
|
|
|
|
int w = Integer.parseInt(width.getText().trim()); |
|
|
|
|
int h = Integer.parseInt(height.getText().trim()); |
|
|
|
|
dimensionListeners.forEach(listener -> listener.setDimension(new Dimension(w < 0 ? 0 : w, h < 0 ? 0 : h))); |
|
|
|
|
} catch (NumberFormatException e) { |
|
|
|
|
LOG.warn("Invalid dimensions!"); |
|
|
|
|
} |
|
|
|
|
return additionalInput.input.getText(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* notify listeners of changes to the variable field's values |
|
|
|
|
* @param name |
|
|
|
|
* @param val |
|
|
|
|
*/ |
|
|
|
|
private void updateField(String name, String val) { |
|
|
|
|
LOG.debug("updateField({},{})",name,val); |
|
|
|
|
fieldListeners.forEach(l -> l.setField(name,val)); |
|
|
|
|
public void resetAdditionalFields() { |
|
|
|
|
additionalInputs.values().forEach(AdditionalInput::notRequired); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* notify listeners of changes to the path field |
|
|
|
|
* @param newPath |
|
|
|
|
* create scan button |
|
|
|
|
* @return |
|
|
|
|
*/ |
|
|
|
|
protected void updatePath(String newPath) { |
|
|
|
|
LOG.debug("updatePath({})",newPath); |
|
|
|
|
resetPage(); |
|
|
|
|
pathListeners.forEach(l -> l.setPath(newPath)); |
|
|
|
|
private Component scanButton() { |
|
|
|
|
scanButton = new JButton(t("scan!")); |
|
|
|
|
scanButton.addActionListener(ev -> worker.scan()); |
|
|
|
|
return scanButton; |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|