mirror of
https://github.com/freedomofpress/dangerzone.git
synced 2025-04-28 18:02:38 +02:00
Start making settings widget
This commit is contained in:
parent
acf46980f3
commit
b527776e28
7 changed files with 371 additions and 98 deletions
|
@ -25,22 +25,7 @@ def main(filename):
|
||||||
# Common object
|
# Common object
|
||||||
common = Common()
|
common = Common()
|
||||||
|
|
||||||
# Main window
|
if filename != "":
|
||||||
main_window = MainWindow(app, common)
|
|
||||||
|
|
||||||
# If a filename wasn't passed in, get with with a dialog
|
|
||||||
if filename == "":
|
|
||||||
filename = QtWidgets.QFileDialog.getOpenFileName(
|
|
||||||
main_window,
|
|
||||||
"Open document",
|
|
||||||
filter="Documents (*.pdf *.docx *.doc *.xlsx *.xls *.pptx *.ppt *.odt *.fodt *.ods *.fods *.odp *.fodp *.odg *.fodg *.odf)",
|
|
||||||
)
|
|
||||||
if filename[0] == "":
|
|
||||||
print("No document was not selected")
|
|
||||||
return
|
|
||||||
|
|
||||||
filename = filename[0]
|
|
||||||
else:
|
|
||||||
# Validate filename
|
# Validate filename
|
||||||
filename = os.path.abspath(os.path.expanduser(filename))
|
filename = os.path.abspath(os.path.expanduser(filename))
|
||||||
try:
|
try:
|
||||||
|
@ -51,6 +36,8 @@ def main(filename):
|
||||||
except PermissionError:
|
except PermissionError:
|
||||||
print("Permission denied")
|
print("Permission denied")
|
||||||
return
|
return
|
||||||
|
common.set_document_filename(filename)
|
||||||
|
|
||||||
main_window.start(filename)
|
# Main window
|
||||||
|
main_window = MainWindow(app, common)
|
||||||
sys.exit(app.exec_())
|
sys.exit(app.exec_())
|
||||||
|
|
|
@ -2,6 +2,7 @@ import sys
|
||||||
import os
|
import os
|
||||||
import inspect
|
import inspect
|
||||||
import tempfile
|
import tempfile
|
||||||
|
from PyQt5 import QtGui
|
||||||
|
|
||||||
|
|
||||||
class Common(object):
|
class Common(object):
|
||||||
|
@ -16,6 +17,176 @@ class Common(object):
|
||||||
print(f"pixel_dir is: {self.pixel_dir.name}")
|
print(f"pixel_dir is: {self.pixel_dir.name}")
|
||||||
print(f"safe_dir is: {self.safe_dir.name}")
|
print(f"safe_dir is: {self.safe_dir.name}")
|
||||||
|
|
||||||
|
self.document_filename = None
|
||||||
|
|
||||||
|
self.fixed_font = QtGui.QFontDatabase.systemFont(QtGui.QFontDatabase.FixedFont)
|
||||||
|
|
||||||
|
self.ocr_languages = {
|
||||||
|
"Afrikaans": "ar",
|
||||||
|
"Amharic": "amh",
|
||||||
|
"Arabic": "ara",
|
||||||
|
"Assamese": "asm",
|
||||||
|
"Azerbaijani": "aze",
|
||||||
|
"Azerbaijani (Cyrillic)": "aze_cyrl",
|
||||||
|
"Belarusian": "bel",
|
||||||
|
"Bengali": "ben",
|
||||||
|
"Tibetan Standard": "bod",
|
||||||
|
"Bosnian": "bos",
|
||||||
|
"Breton": "bre",
|
||||||
|
"Bulgarian": "bul",
|
||||||
|
"Catalan": "cat",
|
||||||
|
"Cebuano": "ceb",
|
||||||
|
"Czech": "ces",
|
||||||
|
"Chinese - Simplified": "chi_sim",
|
||||||
|
"Chinese - Simplified (vertical)": "chi_sim_vert",
|
||||||
|
"Chinese - Traditional": "chi_tra",
|
||||||
|
"Chinese - Traditional (vertical)": "chi_tra_vert",
|
||||||
|
"Cherokee": "chr",
|
||||||
|
"Corsican": "cos",
|
||||||
|
"Welsh": "cym",
|
||||||
|
"Danish": "dan",
|
||||||
|
"German": "deu",
|
||||||
|
"Divehi": "div",
|
||||||
|
"Dzongkha": "dzo",
|
||||||
|
"Greek": "ell",
|
||||||
|
"English": "eng",
|
||||||
|
"English, Middle (1100-1500)": "enm",
|
||||||
|
"Esperanto": "epo",
|
||||||
|
"Estonian": "est",
|
||||||
|
"Basque": "eus",
|
||||||
|
"Faroese": "fao",
|
||||||
|
"Persian": "fas",
|
||||||
|
"Filipino": "fil",
|
||||||
|
"Finnish": "fin",
|
||||||
|
"French": "fra",
|
||||||
|
"Frankish": "frk",
|
||||||
|
"French, Middle (ca.1400-1600)": "frm",
|
||||||
|
"Frisian (Western)": "fry",
|
||||||
|
"Gaelic (Scots)": "gla",
|
||||||
|
"Irish": "gle",
|
||||||
|
"Galician": "glg",
|
||||||
|
"Gujarati": "guj",
|
||||||
|
"Hatian": "hat",
|
||||||
|
"Hebrew": "heb",
|
||||||
|
"Hindi": "hin",
|
||||||
|
"Croatian": "hrv",
|
||||||
|
"Hungarian": "hun",
|
||||||
|
"Armenian": "hye",
|
||||||
|
"Inuktitut": "iku",
|
||||||
|
"Indonesian": "ind",
|
||||||
|
"Icelandic": "isl",
|
||||||
|
"Italian": "ita",
|
||||||
|
"Italian - Old": "ita_old",
|
||||||
|
"Javanese": "jav",
|
||||||
|
"Japanese": "jpn",
|
||||||
|
"Japanese (vertical)": "jpn_vert",
|
||||||
|
"Kannada": "kan",
|
||||||
|
"Georgian": "kat",
|
||||||
|
"Old Georgian": "kat_old",
|
||||||
|
"Kazakh": "kaz",
|
||||||
|
"Khmer": "khm",
|
||||||
|
"Kyrgyz": "kir",
|
||||||
|
"Korean": "kor",
|
||||||
|
"Korean (vertical)": "kor_vert",
|
||||||
|
"Kurdish (Arabic)": "kur_ara",
|
||||||
|
"Lao": "lao",
|
||||||
|
"Latin": "lat",
|
||||||
|
"Latvian": "lav",
|
||||||
|
"Lithuanian": "lit",
|
||||||
|
"Luxembourgish": "ltz",
|
||||||
|
"Malayalam": "mal",
|
||||||
|
"Marathi": "mar",
|
||||||
|
"Macedonian": "mkd",
|
||||||
|
"Maltese": "mlt",
|
||||||
|
"Mongolian": "mon",
|
||||||
|
"Maori": "mri",
|
||||||
|
"Malay": "msa",
|
||||||
|
"Burmese": "mya",
|
||||||
|
"Nepali": "nep",
|
||||||
|
"Dutch": "nld",
|
||||||
|
"Norwegian": "nor",
|
||||||
|
"Occitan (post 1500)": "oci",
|
||||||
|
"Oriya": "ori",
|
||||||
|
"script and orientation": "osd",
|
||||||
|
"Punjabi": "pan",
|
||||||
|
"Polish": "pol",
|
||||||
|
"Portuguese": "por",
|
||||||
|
"Pashto": "pus",
|
||||||
|
"Quechua": "que",
|
||||||
|
"Romanian": "ron",
|
||||||
|
"Russian": "rus",
|
||||||
|
"Sanskrit": "san",
|
||||||
|
"Sinhala": "sin",
|
||||||
|
"Slovakian": "slk",
|
||||||
|
"Slovenian": "slv",
|
||||||
|
"Sindhi": "snd",
|
||||||
|
"Spanish": "spa",
|
||||||
|
"Spanish, Castilian - Old": "spa_old",
|
||||||
|
"Albanian": "sqi",
|
||||||
|
"Serbian": "srp",
|
||||||
|
"Serbian (Latin)": "srp_latn",
|
||||||
|
"Sundanese": "sun",
|
||||||
|
"Swahili": "swa",
|
||||||
|
"Swedish": "swe",
|
||||||
|
"Syriac": "syr",
|
||||||
|
"Tamil": "tam",
|
||||||
|
"Tatar": "tat",
|
||||||
|
"Telugu": "tel",
|
||||||
|
"Tajik": "tgk",
|
||||||
|
"Thai": "tha",
|
||||||
|
"Tigrinya": "tir",
|
||||||
|
"Tonga": "ton",
|
||||||
|
"Turkish": "tur",
|
||||||
|
"Uyghur": "uig",
|
||||||
|
"Ukrainian": "ukr",
|
||||||
|
"Urdu": "urd",
|
||||||
|
"Uzbek": "uzb",
|
||||||
|
"Uzbek (Cyrillic)": "uzb_cyrl",
|
||||||
|
"Vietnamese": "vie",
|
||||||
|
"Yiddish": "yid",
|
||||||
|
"Yoruba": "yor",
|
||||||
|
"Arabic script": "Arabic",
|
||||||
|
"Armenian script": "Armenian",
|
||||||
|
"Bengali script": "Bengali",
|
||||||
|
"Canadian Aboriginal script": "Canadian_Aboriginal",
|
||||||
|
"Cherokee script": "Cherokee",
|
||||||
|
"Cyrillic script": "Cyrillic",
|
||||||
|
"Devanagari script": "Devanagari",
|
||||||
|
"Ethiopic script": "Ethiopic",
|
||||||
|
"Fraktur script": "Fraktur",
|
||||||
|
"Georgian script": "Georgian",
|
||||||
|
"Greek script": "Greek",
|
||||||
|
"Gujarati script": "Gujarati",
|
||||||
|
"Gurmukhi script": "Gurmukhi",
|
||||||
|
"Han - Simplified script": "HanS",
|
||||||
|
"Han - Simplified (vertical) script": "HanS_vert",
|
||||||
|
"Han - Traditional script": "HanT",
|
||||||
|
"Han - Traditional (vertical) script": "HanT_vert",
|
||||||
|
"Hangul script": "Hangul",
|
||||||
|
"Hangul (vertical) script": "Hangul_vert",
|
||||||
|
"Hebrew script": "Hebrew",
|
||||||
|
"Japanese script": "Japanese",
|
||||||
|
"Japanese (vertical) script": "Japanese_vert",
|
||||||
|
"Kannada script": "Kannada",
|
||||||
|
"Khmer script": "Khmer",
|
||||||
|
"Lao script": "Lao",
|
||||||
|
"Latin script": "Latin",
|
||||||
|
"Malayalam script": "Malayalam",
|
||||||
|
"Myanmar script": "Myanmar",
|
||||||
|
"Oriya (Odia) script": "Oriya",
|
||||||
|
"Sinhala script": "Sinhala",
|
||||||
|
"Syriac script": "Syriac",
|
||||||
|
"Tamil script": "Tamil",
|
||||||
|
"Telugu script": "Telugu",
|
||||||
|
"Thaana script": "Thaana",
|
||||||
|
"Thai script": "Thai",
|
||||||
|
"Tibetan script": "Tibetan",
|
||||||
|
"Vietnamese script": "Vietnamese",
|
||||||
|
}
|
||||||
|
|
||||||
|
def set_document_filename(self, filename):
|
||||||
|
self.document_filename = filename
|
||||||
|
|
||||||
def get_resource_path(self, filename):
|
def get_resource_path(self, filename):
|
||||||
if getattr(sys, "dangerzone_dev", False):
|
if getattr(sys, "dangerzone_dev", False):
|
||||||
# Look for resources directory relative to python file
|
# Look for resources directory relative to python file
|
||||||
|
|
|
@ -2,7 +2,8 @@ import shutil
|
||||||
import os
|
import os
|
||||||
from PyQt5 import QtCore, QtGui, QtWidgets
|
from PyQt5 import QtCore, QtGui, QtWidgets
|
||||||
|
|
||||||
from .tasks import PullImageTask, BuildContainerTask, ConvertToPixels, ConvertToPDF
|
from .settings_widget import SettingsWidget
|
||||||
|
from .tasks_widget import TasksWidget
|
||||||
|
|
||||||
|
|
||||||
class MainWindow(QtWidgets.QMainWindow):
|
class MainWindow(QtWidgets.QMainWindow):
|
||||||
|
@ -15,94 +16,43 @@ class MainWindow(QtWidgets.QMainWindow):
|
||||||
self.setMinimumWidth(500)
|
self.setMinimumWidth(500)
|
||||||
self.setMinimumHeight(400)
|
self.setMinimumHeight(400)
|
||||||
|
|
||||||
self.task_label = QtWidgets.QLabel()
|
# Header
|
||||||
self.task_label.setAlignment(QtCore.Qt.AlignCenter)
|
logo = QtWidgets.QLabel()
|
||||||
self.task_label.setStyleSheet("QLabel { font-weight: bold; font-size: 20px; }")
|
logo.setPixmap(
|
||||||
|
QtGui.QPixmap.fromImage(
|
||||||
font = QtGui.QFontDatabase.systemFont(QtGui.QFontDatabase.FixedFont)
|
QtGui.QImage(self.common.get_resource_path("icon.png"))
|
||||||
self.task_details = QtWidgets.QLabel()
|
|
||||||
self.task_details.setStyleSheet(
|
|
||||||
"QLabel { background-color: #ffffff; font-size: 12px; padding: 10px; }"
|
|
||||||
)
|
)
|
||||||
self.task_details.setFont(font)
|
|
||||||
self.task_details.setAlignment(QtCore.Qt.AlignTop)
|
|
||||||
|
|
||||||
self.details_scrollarea = QtWidgets.QScrollArea()
|
|
||||||
self.details_scrollarea.setWidgetResizable(True)
|
|
||||||
self.details_scrollarea.setWidget(self.task_details)
|
|
||||||
self.details_scrollarea.verticalScrollBar().rangeChanged.connect(
|
|
||||||
self.scroll_to_bottom
|
|
||||||
)
|
)
|
||||||
|
header_label = QtWidgets.QLabel("dangerzone")
|
||||||
|
header_label.setFont(self.common.fixed_font)
|
||||||
|
header_label.setStyleSheet("QLabel { font-weight: bold; font-size: 50px; }")
|
||||||
|
header_layout = QtWidgets.QHBoxLayout()
|
||||||
|
header_layout.addStretch()
|
||||||
|
header_layout.addWidget(logo)
|
||||||
|
header_layout.addSpacing(10)
|
||||||
|
header_layout.addWidget(header_label)
|
||||||
|
header_layout.addStretch()
|
||||||
|
|
||||||
|
# Settings
|
||||||
|
self.settings_widget = SettingsWidget(self.common)
|
||||||
|
self.settings_widget.show()
|
||||||
|
|
||||||
|
# Tasks
|
||||||
|
self.tasks_widget = TasksWidget(self.common)
|
||||||
|
self.tasks_widget.hide()
|
||||||
|
|
||||||
|
# Layout
|
||||||
layout = QtWidgets.QVBoxLayout()
|
layout = QtWidgets.QVBoxLayout()
|
||||||
layout.addWidget(self.task_label)
|
layout.addLayout(header_layout)
|
||||||
layout.addWidget(self.details_scrollarea, stretch=1)
|
layout.addWidget(self.settings_widget, stretch=1)
|
||||||
|
layout.addWidget(self.tasks_widget, stretch=1)
|
||||||
|
|
||||||
central_widget = QtWidgets.QWidget()
|
central_widget = QtWidgets.QWidget()
|
||||||
central_widget.setLayout(layout)
|
central_widget.setLayout(layout)
|
||||||
self.setCentralWidget(central_widget)
|
self.setCentralWidget(central_widget)
|
||||||
|
|
||||||
self.tasks = [PullImageTask, BuildContainerTask, ConvertToPixels, ConvertToPDF]
|
|
||||||
|
|
||||||
def start(self, filename):
|
|
||||||
print(f"Input document: {filename}")
|
|
||||||
self.common.document_filename = filename
|
|
||||||
self.show()
|
self.show()
|
||||||
|
|
||||||
self.next_task()
|
|
||||||
|
|
||||||
def next_task(self):
|
|
||||||
if len(self.tasks) == 0:
|
|
||||||
self.save_safe_pdf()
|
|
||||||
return
|
|
||||||
|
|
||||||
self.task_details.setText("")
|
|
||||||
|
|
||||||
self.current_task = self.tasks.pop(0)(self.common)
|
|
||||||
self.current_task.update_label.connect(self.update_label)
|
|
||||||
self.current_task.update_details.connect(self.update_details)
|
|
||||||
self.current_task.task_finished.connect(self.next_task)
|
|
||||||
self.current_task.task_failed.connect(self.task_failed)
|
|
||||||
self.current_task.start()
|
|
||||||
|
|
||||||
def update_label(self, s):
|
|
||||||
self.task_label.setText(s)
|
|
||||||
|
|
||||||
def update_details(self, s):
|
|
||||||
self.task_details.setText(s)
|
|
||||||
|
|
||||||
def task_failed(self, err):
|
|
||||||
self.task_label.setText("Task failed :(")
|
|
||||||
self.task_details.setWordWrap(True)
|
|
||||||
self.task_details.setText(
|
|
||||||
f"Directory with pixel data: {self.common.pixel_dir.name}\n\n{err}"
|
|
||||||
)
|
|
||||||
|
|
||||||
def save_safe_pdf(self):
|
|
||||||
suggested_filename = (
|
|
||||||
f"{os.path.splitext(self.common.document_filename)[0]}-safe.pdf"
|
|
||||||
)
|
|
||||||
|
|
||||||
filename = QtWidgets.QFileDialog.getSaveFileName(
|
|
||||||
self, "Save safe PDF", suggested_filename, filter="Documents (*.pdf)"
|
|
||||||
)
|
|
||||||
if filename[0] == "":
|
|
||||||
print("Save file dialog canceled")
|
|
||||||
else:
|
|
||||||
source_filename = f"{self.common.safe_dir.name}/safe-output-compressed.pdf"
|
|
||||||
dest_filename = filename[0]
|
|
||||||
shutil.move(source_filename, dest_filename)
|
|
||||||
|
|
||||||
# Clean up
|
|
||||||
self.common.pixel_dir.cleanup()
|
|
||||||
self.common.safe_dir.cleanup()
|
|
||||||
|
|
||||||
# Quit
|
|
||||||
self.app.quit()
|
|
||||||
|
|
||||||
def scroll_to_bottom(self, minimum, maximum):
|
|
||||||
self.details_scrollarea.verticalScrollBar().setValue(maximum)
|
|
||||||
|
|
||||||
def closeEvent(self, e):
|
def closeEvent(self, e):
|
||||||
e.accept()
|
e.accept()
|
||||||
self.app.quit()
|
self.app.quit()
|
||||||
|
|
79
dangerzone/settings_widget.py
Normal file
79
dangerzone/settings_widget.py
Normal file
|
@ -0,0 +1,79 @@
|
||||||
|
from PyQt5 import QtCore, QtGui, QtWidgets
|
||||||
|
|
||||||
|
|
||||||
|
class SettingsWidget(QtWidgets.QWidget):
|
||||||
|
def __init__(self, common):
|
||||||
|
super(SettingsWidget, self).__init__()
|
||||||
|
self.common = common
|
||||||
|
|
||||||
|
# Dangerous document selection
|
||||||
|
self.dangerous_doc_label = QtWidgets.QLabel()
|
||||||
|
self.dangerous_doc_label.hide()
|
||||||
|
self.dangerous_doc_button = QtWidgets.QPushButton(
|
||||||
|
"Select dangerous document ..."
|
||||||
|
)
|
||||||
|
self.dangerous_doc_button.setStyleSheet("QPushButton { font-weight: bold }")
|
||||||
|
|
||||||
|
dangerous_doc_layout = QtWidgets.QHBoxLayout()
|
||||||
|
dangerous_doc_layout.addWidget(self.dangerous_doc_label)
|
||||||
|
dangerous_doc_layout.addWidget(self.dangerous_doc_button)
|
||||||
|
dangerous_doc_layout.addStretch()
|
||||||
|
|
||||||
|
# Save safe version
|
||||||
|
self.save_checkbox = QtWidgets.QCheckBox("Save safe PDF")
|
||||||
|
self.save_lineedit = QtWidgets.QLineEdit()
|
||||||
|
self.save_lineedit.setReadOnly(True)
|
||||||
|
self.save_browse_button = QtWidgets.QPushButton("Save as...")
|
||||||
|
|
||||||
|
save_layout = QtWidgets.QHBoxLayout()
|
||||||
|
save_layout.addWidget(self.save_checkbox)
|
||||||
|
save_layout.addWidget(self.save_lineedit)
|
||||||
|
save_layout.addWidget(self.save_browse_button)
|
||||||
|
save_layout.addStretch()
|
||||||
|
|
||||||
|
# OCR document
|
||||||
|
self.ocr_checkbox = QtWidgets.QCheckBox("OCR document, language")
|
||||||
|
self.ocr_combobox = QtWidgets.QComboBox()
|
||||||
|
for k in self.common.ocr_languages:
|
||||||
|
self.ocr_combobox.addItem(k, QtCore.QVariant(self.common.ocr_languages[k]))
|
||||||
|
|
||||||
|
ocr_layout = QtWidgets.QHBoxLayout()
|
||||||
|
ocr_layout.addWidget(self.ocr_checkbox)
|
||||||
|
ocr_layout.addWidget(self.ocr_combobox)
|
||||||
|
ocr_layout.addStretch()
|
||||||
|
|
||||||
|
# Open safe document
|
||||||
|
self.open_checkbox = QtWidgets.QCheckBox("Open safe document")
|
||||||
|
self.open_combobox = QtWidgets.QComboBox()
|
||||||
|
|
||||||
|
open_layout = QtWidgets.QHBoxLayout()
|
||||||
|
open_layout.addWidget(self.open_checkbox)
|
||||||
|
open_layout.addWidget(self.open_combobox)
|
||||||
|
open_layout.addStretch()
|
||||||
|
|
||||||
|
# Update container
|
||||||
|
self.update_checkbox = QtWidgets.QCheckBox("Update container")
|
||||||
|
update_layout = QtWidgets.QHBoxLayout()
|
||||||
|
update_layout.addWidget(self.update_checkbox)
|
||||||
|
update_layout.addStretch()
|
||||||
|
|
||||||
|
# Button
|
||||||
|
self.button_start = QtWidgets.QPushButton("Convert to Save Document")
|
||||||
|
self.button_start.setStyleSheet(
|
||||||
|
"QPushButton { font-size: 16px; font-weight: bold; padding: 10px; }"
|
||||||
|
)
|
||||||
|
button_layout = QtWidgets.QHBoxLayout()
|
||||||
|
button_layout.addStretch()
|
||||||
|
button_layout.addWidget(self.button_start)
|
||||||
|
button_layout.addStretch()
|
||||||
|
|
||||||
|
# Layout
|
||||||
|
layout = QtWidgets.QVBoxLayout()
|
||||||
|
layout.addLayout(dangerous_doc_layout)
|
||||||
|
layout.addLayout(save_layout)
|
||||||
|
layout.addLayout(ocr_layout)
|
||||||
|
layout.addLayout(open_layout)
|
||||||
|
layout.addLayout(update_layout)
|
||||||
|
layout.addLayout(button_layout)
|
||||||
|
layout.addStretch()
|
||||||
|
self.setLayout(layout)
|
88
dangerzone/tasks_widget.py
Normal file
88
dangerzone/tasks_widget.py
Normal file
|
@ -0,0 +1,88 @@
|
||||||
|
from PyQt5 import QtCore, QtGui, QtWidgets
|
||||||
|
|
||||||
|
from .tasks import PullImageTask, BuildContainerTask, ConvertToPixels, ConvertToPDF
|
||||||
|
|
||||||
|
|
||||||
|
class TasksWidget(QtWidgets.QWidget):
|
||||||
|
def __init__(self, common):
|
||||||
|
super(TasksWidget, self).__init__()
|
||||||
|
self.common = common
|
||||||
|
|
||||||
|
self.task_label = QtWidgets.QLabel()
|
||||||
|
self.task_label.setAlignment(QtCore.Qt.AlignCenter)
|
||||||
|
self.task_label.setStyleSheet("QLabel { font-weight: bold; font-size: 20px; }")
|
||||||
|
|
||||||
|
self.task_details = QtWidgets.QLabel()
|
||||||
|
self.task_details.setStyleSheet(
|
||||||
|
"QLabel { background-color: #ffffff; font-size: 12px; padding: 10px; }"
|
||||||
|
)
|
||||||
|
self.task_details.setFont(self.common.fixed_font)
|
||||||
|
self.task_details.setAlignment(QtCore.Qt.AlignTop)
|
||||||
|
|
||||||
|
self.details_scrollarea = QtWidgets.QScrollArea()
|
||||||
|
self.details_scrollarea.setWidgetResizable(True)
|
||||||
|
self.details_scrollarea.setWidget(self.task_details)
|
||||||
|
self.details_scrollarea.verticalScrollBar().rangeChanged.connect(
|
||||||
|
self.scroll_to_bottom
|
||||||
|
)
|
||||||
|
|
||||||
|
self.tasks = [PullImageTask, BuildContainerTask, ConvertToPixels, ConvertToPDF]
|
||||||
|
|
||||||
|
def start(self, filename):
|
||||||
|
print(f"Input document: {filename}")
|
||||||
|
self.common.set_document_filename(filename)
|
||||||
|
self.show()
|
||||||
|
|
||||||
|
self.next_task()
|
||||||
|
|
||||||
|
def next_task(self):
|
||||||
|
if len(self.tasks) == 0:
|
||||||
|
self.save_safe_pdf()
|
||||||
|
return
|
||||||
|
|
||||||
|
self.task_details.setText("")
|
||||||
|
|
||||||
|
self.current_task = self.tasks.pop(0)(self.common)
|
||||||
|
self.current_task.update_label.connect(self.update_label)
|
||||||
|
self.current_task.update_details.connect(self.update_details)
|
||||||
|
self.current_task.task_finished.connect(self.next_task)
|
||||||
|
self.current_task.task_failed.connect(self.task_failed)
|
||||||
|
self.current_task.start()
|
||||||
|
|
||||||
|
def update_label(self, s):
|
||||||
|
self.task_label.setText(s)
|
||||||
|
|
||||||
|
def update_details(self, s):
|
||||||
|
self.task_details.setText(s)
|
||||||
|
|
||||||
|
def task_failed(self, err):
|
||||||
|
self.task_label.setText("Task failed :(")
|
||||||
|
self.task_details.setWordWrap(True)
|
||||||
|
self.task_details.setText(
|
||||||
|
f"Directory with pixel data: {self.common.pixel_dir.name}\n\n{err}"
|
||||||
|
)
|
||||||
|
|
||||||
|
def save_safe_pdf(self):
|
||||||
|
suggested_filename = (
|
||||||
|
f"{os.path.splitext(self.common.document_filename)[0]}-safe.pdf"
|
||||||
|
)
|
||||||
|
|
||||||
|
filename = QtWidgets.QFileDialog.getSaveFileName(
|
||||||
|
self, "Save safe PDF", suggested_filename, filter="Documents (*.pdf)"
|
||||||
|
)
|
||||||
|
if filename[0] == "":
|
||||||
|
print("Save file dialog canceled")
|
||||||
|
else:
|
||||||
|
source_filename = f"{self.common.safe_dir.name}/safe-output-compressed.pdf"
|
||||||
|
dest_filename = filename[0]
|
||||||
|
shutil.move(source_filename, dest_filename)
|
||||||
|
|
||||||
|
# Clean up
|
||||||
|
self.common.pixel_dir.cleanup()
|
||||||
|
self.common.safe_dir.cleanup()
|
||||||
|
|
||||||
|
# Quit
|
||||||
|
self.app.quit()
|
||||||
|
|
||||||
|
def scroll_to_bottom(self, minimum, maximum):
|
||||||
|
self.details_scrollarea.verticalScrollBar().setValue(maximum)
|
|
@ -1,9 +1,7 @@
|
||||||
FROM ubuntu:18.04
|
FROM ubuntu:18.04
|
||||||
|
|
||||||
RUN apt-get update && \
|
RUN apt-get update && \
|
||||||
apt-get install -y file poppler-utils imagemagick ghostscript tesseract-ocr libreoffice
|
apt-get install -y file poppler-utils imagemagick ghostscript tesseract-ocr tesseract-ocr-all libreoffice
|
||||||
|
|
||||||
# TODO: when we support OCR in other languages, we need tesseract-ocr-all
|
|
||||||
|
|
||||||
# Fix imagemagick policy to allow writing PDFs
|
# Fix imagemagick policy to allow writing PDFs
|
||||||
RUN sed -i '/rights="none" pattern="PDF"/c\<policy domain="coder" rights="read|write" pattern="PDF" />' /etc/ImageMagick-6/policy.xml
|
RUN sed -i '/rights="none" pattern="PDF"/c\<policy domain="coder" rights="read|write" pattern="PDF" />' /etc/ImageMagick-6/policy.xml
|
||||||
|
|
BIN
share/icon.png
Normal file
BIN
share/icon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.8 KiB |
Loading…
Reference in a new issue