|
|
|
@ -2,9 +2,18 @@ package de.srsoftware.belegscanner.gui;
@@ -2,9 +2,18 @@ package de.srsoftware.belegscanner.gui;
|
|
|
|
|
|
|
|
|
|
import java.awt.BorderLayout; |
|
|
|
|
import java.awt.Dimension; |
|
|
|
|
import java.awt.Point; |
|
|
|
|
import java.awt.event.ActionEvent; |
|
|
|
|
import java.io.File; |
|
|
|
|
import java.io.FilenameFilter; |
|
|
|
|
import java.io.IOException; |
|
|
|
|
import java.nio.file.Path; |
|
|
|
|
import java.util.Arrays; |
|
|
|
|
import java.util.Collections; |
|
|
|
|
import java.util.Date; |
|
|
|
|
import java.util.HashMap; |
|
|
|
|
import java.util.HashSet; |
|
|
|
|
import java.util.List; |
|
|
|
|
import java.util.Map.Entry; |
|
|
|
|
import java.util.Vector; |
|
|
|
|
import java.util.regex.Matcher; |
|
|
|
@ -12,6 +21,7 @@ import java.util.regex.Pattern;
@@ -12,6 +21,7 @@ import java.util.regex.Pattern;
|
|
|
|
|
|
|
|
|
|
import javax.swing.JFrame; |
|
|
|
|
|
|
|
|
|
import org.json.JSONArray; |
|
|
|
|
import org.slf4j.Logger; |
|
|
|
|
import org.slf4j.LoggerFactory; |
|
|
|
|
|
|
|
|
@ -25,6 +35,7 @@ public class MainFrame extends JFrame {
@@ -25,6 +35,7 @@ public class MainFrame extends JFrame {
|
|
|
|
|
|
|
|
|
|
private static final String HOME = System.getProperty("user.home"); |
|
|
|
|
private static final Pattern MARKEN = Pattern.compile("\\$([a-zA-Z]+)"); |
|
|
|
|
private static FilenameFilter PAGES = (dir,name) -> name.toLowerCase().endsWith("pdf") && name.toLowerCase().startsWith("page"); |
|
|
|
|
|
|
|
|
|
private StatusBar statusBar; |
|
|
|
|
private Toolbar toolbar; |
|
|
|
@ -41,7 +52,13 @@ public class MainFrame extends JFrame {
@@ -41,7 +52,13 @@ public class MainFrame extends JFrame {
|
|
|
|
|
|
|
|
|
|
private Configuration config; |
|
|
|
|
|
|
|
|
|
private int xSize = 209; |
|
|
|
|
private int ySize = 297; |
|
|
|
|
private int resoultion = 150; |
|
|
|
|
private String mode = "Color"; |
|
|
|
|
|
|
|
|
|
public MainFrame(Configuration config) { |
|
|
|
|
super("BelegScanner"); |
|
|
|
|
this.config = config; |
|
|
|
|
int width = config.getOrCreate("app.main.dimenstion.w",800); |
|
|
|
|
int height = config.getOrCreate("app.main.dimenstion.h",600); |
|
|
|
@ -57,8 +74,14 @@ public class MainFrame extends JFrame {
@@ -57,8 +74,14 @@ public class MainFrame extends JFrame {
|
|
|
|
|
toolbar.addCategoryListener(this::setCategory) |
|
|
|
|
.addDateListener(this::setDate) |
|
|
|
|
.addFieldListener(this::setField) |
|
|
|
|
.addFolderListener(this::openFolder) |
|
|
|
|
.addJoinListener(this::join) |
|
|
|
|
.addPathListener(this::setPath) |
|
|
|
|
.addScanListener(this::scan); |
|
|
|
|
.addScanListener(this::scan); |
|
|
|
|
|
|
|
|
|
int x = config.getOrCreate("app.main.position.x", 20); |
|
|
|
|
int y = config.getOrCreate("app.main.position.y", 20); |
|
|
|
|
setLocation(new Point(x, y)); |
|
|
|
|
|
|
|
|
|
setPreferredSize(new Dimension(width,height)); |
|
|
|
|
pack(); |
|
|
|
@ -72,9 +95,159 @@ public class MainFrame extends JFrame {
@@ -72,9 +95,159 @@ public class MainFrame extends JFrame {
|
|
|
|
|
toolbar.addFieldsFor(marks); |
|
|
|
|
}; |
|
|
|
|
|
|
|
|
|
private void join(ActionEvent ev) { |
|
|
|
|
new Thread(() -> joinFiles(patchedPath)).start(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private void joinFiles(String path) { |
|
|
|
|
LOG.debug("joinFiles({})",path); |
|
|
|
|
File folder = new File(path); |
|
|
|
|
if (!folder.exists()) return; |
|
|
|
|
|
|
|
|
|
List<String> pdfs = Arrays.asList(folder.list(PAGES)); |
|
|
|
|
Collections.sort(pdfs); |
|
|
|
|
|
|
|
|
|
Vector<String> cmd = new Vector<>(); |
|
|
|
|
cmd.add("pdftk"); |
|
|
|
|
cmd.addAll(pdfs); |
|
|
|
|
cmd.add("cat"); |
|
|
|
|
cmd.add("output"); |
|
|
|
|
cmd.add(folder.getName()+".pdf"); |
|
|
|
|
LOG.debug("executing {}",cmd); |
|
|
|
|
ProcessBuilder builder = new ProcessBuilder(cmd); |
|
|
|
|
builder.directory(folder); |
|
|
|
|
try { |
|
|
|
|
Process process = builder.start(); |
|
|
|
|
statusBar.setAction("Verbinde PDFs…"); |
|
|
|
|
int errorCode = process.waitFor(); |
|
|
|
|
if (errorCode != 0) { |
|
|
|
|
LOG.error("error code: {} for {}",errorCode,cmd); |
|
|
|
|
} else LOG.debug("error code: {}",errorCode); |
|
|
|
|
} catch (InterruptedException | IOException e) { |
|
|
|
|
LOG.error("{} terminated: ",builder,e); |
|
|
|
|
} |
|
|
|
|
for (String page : pdfs) Path.of(path,page).toFile().delete(); |
|
|
|
|
statusBar.setAction("Bereit."); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private void openFolder(ActionEvent ev) { |
|
|
|
|
new Thread(() -> openFolder(patchedPath)).start(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private void openFolder(String path) { |
|
|
|
|
File folder = new File(path); |
|
|
|
|
if (!folder.exists()) return; |
|
|
|
|
|
|
|
|
|
ProcessBuilder builder = new ProcessBuilder(List.of("killall","thunar")); |
|
|
|
|
builder.directory(folder); |
|
|
|
|
try { |
|
|
|
|
builder.start().waitFor(); |
|
|
|
|
} catch (IOException | InterruptedException e) { |
|
|
|
|
LOG.error("{} terminated: ",builder,e); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
builder = new ProcessBuilder("thunar"); |
|
|
|
|
builder.directory(folder); |
|
|
|
|
try { |
|
|
|
|
builder.start(); |
|
|
|
|
} catch (IOException e) { |
|
|
|
|
LOG.error("{} terminated: ",builder,e); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private void performScan(String path) { |
|
|
|
|
LOG.debug("performScan({})",path); |
|
|
|
|
toolbar.readyToScan(false); |
|
|
|
|
File folder = new File(path); |
|
|
|
|
if (!folder.exists()) { |
|
|
|
|
LOG.warn("Path '{}' does not exist!",path); |
|
|
|
|
folder.mkdirs(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
long timestamp = new Date().getTime(); |
|
|
|
|
String raw = timestamp+".jpg"; |
|
|
|
|
|
|
|
|
|
Vector<String> cmd = new Vector<>(); |
|
|
|
|
cmd.add("scanimage"); |
|
|
|
|
cmd.add("-x"); |
|
|
|
|
cmd.add(xSize+""); |
|
|
|
|
cmd.add("-y"); |
|
|
|
|
cmd.add(ySize+""); |
|
|
|
|
cmd.add("--mode"); |
|
|
|
|
cmd.add(mode); |
|
|
|
|
cmd.add("--resolution"); |
|
|
|
|
cmd.add(resoultion+""); |
|
|
|
|
cmd.add("-o"); |
|
|
|
|
cmd.add(raw); |
|
|
|
|
LOG.debug("executing {}",cmd); |
|
|
|
|
|
|
|
|
|
ProcessBuilder builder = new ProcessBuilder(cmd); |
|
|
|
|
builder.directory(folder); |
|
|
|
|
try { |
|
|
|
|
Process process = builder.start(); |
|
|
|
|
statusBar.setAction("Scanne nach "+path+"…"); |
|
|
|
|
int errorCode = process.waitFor(); |
|
|
|
|
if (errorCode != 0) { |
|
|
|
|
LOG.error("error code: {} for {}",errorCode,cmd); |
|
|
|
|
} else LOG.debug("error code: {}",errorCode); |
|
|
|
|
|
|
|
|
|
} catch (InterruptedException | IOException e) { |
|
|
|
|
LOG.error("{} terminated: ",builder,e); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
String pdf = "page."+timestamp+".pdf"; |
|
|
|
|
cmd = new Vector<>(); |
|
|
|
|
cmd.add("convert"); |
|
|
|
|
cmd.add(raw); |
|
|
|
|
cmd.add(pdf); |
|
|
|
|
builder = new ProcessBuilder(cmd); |
|
|
|
|
builder.directory(folder); |
|
|
|
|
try { |
|
|
|
|
Process process = builder.start(); |
|
|
|
|
statusBar.setAction("Kovertiere zu PDF…"); |
|
|
|
|
toolbar.readyToScan(true); |
|
|
|
|
int errorCode = process.waitFor(); |
|
|
|
|
if (errorCode != 0) { |
|
|
|
|
LOG.error("error code: {} for {}",errorCode,cmd); |
|
|
|
|
} else LOG.debug("error code: {}",errorCode); |
|
|
|
|
|
|
|
|
|
} catch (InterruptedException | IOException e) { |
|
|
|
|
LOG.error("{} terminated: ",builder,e); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
Path.of(path, raw).toFile().delete(); |
|
|
|
|
String ocr = "page."+timestamp+".ocr.pdf"; |
|
|
|
|
|
|
|
|
|
cmd = new Vector<>(); |
|
|
|
|
cmd.add("pdfsandwich"); |
|
|
|
|
cmd.add("-lang"); |
|
|
|
|
cmd.add("deu"); |
|
|
|
|
cmd.add("-rgb"); |
|
|
|
|
cmd.add("-o"); |
|
|
|
|
|
|
|
|
|
cmd.add(ocr); |
|
|
|
|
cmd.add(pdf); |
|
|
|
|
builder = new ProcessBuilder(cmd); |
|
|
|
|
builder.directory(folder); |
|
|
|
|
try { |
|
|
|
|
Process process = builder.start(); |
|
|
|
|
statusBar.setAction("Texterkennung…"); |
|
|
|
|
toolbar.readyToScan(true); |
|
|
|
|
int errorCode = process.waitFor(); |
|
|
|
|
if (errorCode != 0) { |
|
|
|
|
LOG.error("error code: {} for {}",errorCode,cmd); |
|
|
|
|
} else LOG.debug("error code: {}",errorCode); |
|
|
|
|
|
|
|
|
|
} catch (InterruptedException | IOException e) { |
|
|
|
|
LOG.error("{} terminated: ",builder,e); |
|
|
|
|
} |
|
|
|
|
Path.of(path, pdf).toFile().delete(); |
|
|
|
|
statusBar.setAction("Bereit."); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private void scan(ActionEvent ev) { |
|
|
|
|
LOG.debug("Scanning into '{}'",patchedPath); |
|
|
|
|
config.set("app.categories."+category+".path",path); |
|
|
|
|
updateConfig(); |
|
|
|
|
new Thread(() -> performScan(patchedPath)).start(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private void setCategory(String category) { |
|
|
|
@ -89,7 +262,9 @@ public class MainFrame extends JFrame {
@@ -89,7 +262,9 @@ public class MainFrame extends JFrame {
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private void setField(String key, String val) { |
|
|
|
|
fields.put(key, val); |
|
|
|
|
if (val == null || val.isEmpty()) { |
|
|
|
|
fields.remove(key); |
|
|
|
|
} else fields.put(key, val); |
|
|
|
|
updatePath(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -99,6 +274,23 @@ public class MainFrame extends JFrame {
@@ -99,6 +274,23 @@ public class MainFrame extends JFrame {
|
|
|
|
|
updatePath(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
private void updateConfig() { |
|
|
|
|
|
|
|
|
|
String prefix = "app.categories."+category+"."; |
|
|
|
|
for (Entry<String, String> entry : fields.entrySet()) { |
|
|
|
|
String key = entry.getKey(); |
|
|
|
|
String val = entry.getValue(); |
|
|
|
|
JSONArray arr = config.getOrCreateArray(prefix+"fields."+key); |
|
|
|
|
HashSet<Object> existing = new HashSet<>(); |
|
|
|
|
arr.forEach(existing::add); |
|
|
|
|
if (!existing.contains(val)) arr.put(val); |
|
|
|
|
} |
|
|
|
|
config.set(prefix+"path",path); |
|
|
|
|
Point loc = getLocation(); |
|
|
|
|
config.set("app.main.position.x", loc.x); |
|
|
|
|
config.set("app.main.position.y", loc.y); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
@SuppressWarnings("deprecation") |
|
|
|
|
private void updatePath() { |
|
|
|
|
LOG.debug("updatePath() [path = {}]",path); |
|
|
|
|