Initial refactor: GUI one-window multi-document support

Allows the user to:
  a) specify filenames via the terminal (for the GUI)
  b) select multiple documents via the GUI

The conversion process can't yet be started since the settings are
broken and disabled (expect mypy complaints).
This commit is contained in:
deeplow 2022-09-27 19:33:12 +01:00
parent a8001d4f3e
commit 2e477b8a12
No known key found for this signature in database
GPG key ID: 577982871529A52A
3 changed files with 49 additions and 57 deletions

View file

@ -92,22 +92,15 @@ def gui_main(filenames: Optional[List[str]]) -> bool:
del windows[window_id] del windows[window_id]
# Open a document in a window # Open a document in a window
def new_window(input_filename: Optional[str] = None) -> None: def new_window(filenames: Optional[List[str]] = []) -> None:
document = Document(input_filename)
window_id = uuid.uuid4().hex window_id = uuid.uuid4().hex
window = MainWindow(dangerzone, window_id, document) window = MainWindow(dangerzone, window_id)
if filenames:
window.content_widget.doc_selection_widget.document_selected.emit(filenames)
window.delete_window.connect(delete_window) window.delete_window.connect(delete_window)
windows[window_id] = window windows[window_id] = window
if input_filename: new_window(filenames)
window.content_widget.doc_selection_widget.document_selected.emit()
# Open a new window if not filename is passed
if filenames is None:
new_window()
else:
for filename in filenames:
new_window(filename)
# Open a new window, if all windows are closed # Open a new window, if all windows are closed
def application_activated() -> None: def application_activated() -> None:

View file

@ -5,7 +5,7 @@ import platform
import shutil import shutil
import subprocess import subprocess
import tempfile import tempfile
from typing import Optional from typing import List, Optional
from colorama import Fore, Style from colorama import Fore, Style
from PySide2 import QtCore, QtGui, QtWidgets from PySide2 import QtCore, QtGui, QtWidgets
@ -25,13 +25,11 @@ class MainWindow(QtWidgets.QMainWindow):
def __init__( def __init__(
self, self,
dangerzone: DangerzoneGui, dangerzone: DangerzoneGui,
window_id: str, window_id: str
document: Document,
) -> None: ) -> None:
super(MainWindow, self).__init__() super(MainWindow, self).__init__()
self.dangerzone = dangerzone self.dangerzone = dangerzone
self.window_id = window_id self.window_id = window_id
self.document = document
self.setWindowTitle("Dangerzone") self.setWindowTitle("Dangerzone")
self.setWindowIcon(self.dangerzone.get_window_icon()) self.setWindowIcon(self.dangerzone.get_window_icon())
@ -59,7 +57,7 @@ class MainWindow(QtWidgets.QMainWindow):
self.waiting_widget.finished.connect(self.waiting_finished) self.waiting_widget.finished.connect(self.waiting_finished)
# Content widget, contains all the window content except waiting widget # Content widget, contains all the window content except waiting widget
self.content_widget = ContentWidget(self.dangerzone, self.document) self.content_widget = ContentWidget(self.dangerzone)
self.content_widget.close_window.connect(self.close) self.content_widget.close_window.connect(self.close)
# Only use the waiting widget if container runtime isn't available # Only use the waiting widget if container runtime isn't available
@ -202,18 +200,16 @@ class WaitingWidget(QtWidgets.QWidget):
class ContentWidget(QtWidgets.QWidget): class ContentWidget(QtWidgets.QWidget):
close_window = QtCore.Signal() close_window = QtCore.Signal()
def __init__(self, dangerzone: DangerzoneGui, document: Document) -> None: def __init__(self, dangerzone: DangerzoneGui) -> None:
super(ContentWidget, self).__init__() super(ContentWidget, self).__init__()
self.dangerzone = dangerzone self.dangerzone = dangerzone
self.document = document
# Doc selection widget # Doc selection widget
self.doc_selection_widget = DocSelectionWidget(self.document) self.doc_selection_widget = DocSelectionWidget()
self.doc_selection_widget.document_selected.connect(self.document_selected) self.doc_selection_widget.document_selected.connect(self.document_selected)
# Settings # Settings
# self.settings_widget = SettingsWidget(self.dangerzone, self.document) # self.settings_widget = SettingsWidget(self.dangerzone, self.documents)
# self.doc_selection_widget.document_selected.connect( # self.doc_selection_widget.document_selected.connect(
# self.settings_widget.document_selected # self.settings_widget.document_selected
# ) # )
@ -222,7 +218,7 @@ class ContentWidget(QtWidgets.QWidget):
# self.settings_widget.hide() # self.settings_widget.hide()
# Convert # Convert
self.documents_list = DocumentsListWidget(self.dangerzone, self.document) self.documents_list = DocumentsListWidget(self.dangerzone)
self.documents_list.close_window.connect(self._close_window) self.documents_list.close_window.connect(self._close_window)
self.doc_selection_widget.document_selected.connect( self.doc_selection_widget.document_selected.connect(
self.documents_list.document_selected self.documents_list.document_selected
@ -250,11 +246,10 @@ class ContentWidget(QtWidgets.QWidget):
class DocSelectionWidget(QtWidgets.QWidget): class DocSelectionWidget(QtWidgets.QWidget):
document_selected = QtCore.Signal() document_selected = QtCore.Signal(list)
def __init__(self, document: Document) -> None: def __init__(self) -> None:
super(DocSelectionWidget, self).__init__() super(DocSelectionWidget, self).__init__()
self.document = document
# Dangerous document selection # Dangerous document selection
self.dangerous_doc_label = QtWidgets.QLabel() self.dangerous_doc_label = QtWidgets.QLabel()
@ -280,24 +275,26 @@ class DocSelectionWidget(QtWidgets.QWidget):
self.setLayout(layout) self.setLayout(layout)
def dangerous_doc_button_clicked(self) -> None: def dangerous_doc_button_clicked(self) -> None:
(filename, _) = QtWidgets.QFileDialog.getOpenFileName( (filenames, _) = QtWidgets.QFileDialog.getOpenFileNames(
self, self,
"Open document", "Open documents",
filter="Documents (*.pdf *.docx *.doc *.docm *.xlsx *.xls *.pptx *.ppt *.odt *.odg *.odp *.ods *.jpg *.jpeg *.gif *.png *.tif *.tiff)", filter="Documents (*.pdf *.docx *.doc *.docm *.xlsx *.xls *.pptx *.ppt *.odt *.odg *.odp *.ods *.jpg *.jpeg *.gif *.png *.tif *.tiff)",
) )
if filename != "": if filenames == []:
self.document.input_filename = filename # no files selected
self.document_selected.emit() return
self.document_selected.emit(filenames)
class SettingsWidget(QtWidgets.QWidget): class SettingsWidget(QtWidgets.QWidget):
start_clicked = QtCore.Signal() start_clicked = QtCore.Signal()
close_window = QtCore.Signal() close_window = QtCore.Signal()
def __init__(self, dangerzone: DangerzoneGui, document: Document) -> None: def __init__(self, dangerzone: DangerzoneGui, documents: List[Document]) -> None:
super(SettingsWidget, self).__init__() super(SettingsWidget, self).__init__()
self.dangerzone = dangerzone self.dangerzone = dangerzone
self.document = document self.documents = documents
# Dangerous document label # Dangerous document label
self.dangerous_doc_label = QtWidgets.QLabel() self.dangerous_doc_label = QtWidgets.QLabel()
@ -431,26 +428,26 @@ class SettingsWidget(QtWidgets.QWidget):
def document_selected(self) -> None: def document_selected(self) -> None:
# Update the danger doc label # Update the danger doc label
self.dangerous_doc_label.setText( self.dangerous_doc_label.setText(
f"Suspicious: {os.path.basename(self.document.input_filename)}" f"Suspicious: {os.path.basename(self.documents.input_filename)}"
) )
self.save_lineedit.setText(os.path.basename(self.document.output_filename)) self.save_lineedit.setText(os.path.basename(self.documents.output_filename))
def save_browse_button_clicked(self) -> None: def save_browse_button_clicked(self) -> None:
filename = QtWidgets.QFileDialog.getSaveFileName( filename = QtWidgets.QFileDialog.getSaveFileName(
self, self,
"Save safe PDF as...", "Save safe PDF as...",
self.document.output_filename, self.documents.output_filename,
filter="Documents (*.pdf)", filter="Documents (*.pdf)",
) )
if filename[0] != "": if filename[0] != "":
self.document.output_filename = filename[0] self.documents.output_filename = filename[0]
self.save_lineedit.setText(os.path.basename(self.document.output_filename)) self.save_lineedit.setText(os.path.basename(self.documents.output_filename))
def start_button_clicked(self) -> None: def start_button_clicked(self) -> None:
if self.save_checkbox.checkState() == QtCore.Qt.Unchecked: if self.save_checkbox.checkState() == QtCore.Qt.Unchecked:
# If not saving, then save it to a temp file instead # If not saving, then save it to a temp file instead
tmp = tempfile.mkstemp(suffix=".pdf", prefix="dangerzone_") tmp = tempfile.mkstemp(suffix=".pdf", prefix="dangerzone_")
self.document.output_filename = tmp[1] self.documents.output_filename = tmp[1]
# Update settings # Update settings
self.dangerzone.settings.set( self.dangerzone.settings.set(
@ -509,20 +506,22 @@ class ConvertThread(QtCore.QThread):
class DocumentsListWidget(QtWidgets.QListWidget): class DocumentsListWidget(QtWidgets.QListWidget):
close_window = QtCore.Signal() close_window = QtCore.Signal()
def __init__(self, dangerzone: DangerzoneGui, document: Document) -> None: def __init__(self, dangerzone: DangerzoneGui) -> None:
super().__init__() super().__init__()
self.document_widgets = [] self.dangerzone = dangerzone
self.document_widgets: List[DocumentWidget] = []
def document_selected(self, filenames: list) -> None:
for filename in filenames:
self.dangerzone.add_document(filename)
for document in self.dangerzone.get_unsafe_documents():
item = QtWidgets.QListWidgetItem() item = QtWidgets.QListWidgetItem()
item.setSizeHint(QtCore.QSize(500, 50)) item.setSizeHint(QtCore.QSize(500, 50))
widget = DocumentWidget(dangerzone, document) widget = DocumentWidget(self.dangerzone, document)
self.document_widgets.append(widget)
self.addItem(item) self.addItem(item)
self.setItemWidget(item, widget) self.setItemWidget(item, widget)
self.document_widgets.append(widget)
def document_selected(self) -> None:
for item in self.document_widgets:
item.document_selected()
def start(self) -> None: def start(self) -> None:
for item in self.document_widgets: for item in self.document_widgets:
@ -549,6 +548,9 @@ class DocumentWidget(QtWidgets.QWidget):
self.dangerous_doc_label.setStyleSheet( self.dangerous_doc_label.setStyleSheet(
"QLabel { font-size: 16px; font-weight: bold; }" "QLabel { font-size: 16px; font-weight: bold; }"
) )
self.dangerous_doc_label.setText(
f"Suspicious: {os.path.basename(self.document.input_filename)}"
)
# Label # Label
self.error_image = QtWidgets.QLabel() self.error_image = QtWidgets.QLabel()
@ -580,12 +582,6 @@ class DocumentWidget(QtWidgets.QWidget):
layout.addStretch() layout.addStretch()
self.setLayout(layout) self.setLayout(layout)
def document_selected(self) -> None:
# Update the danger doc label
self.dangerous_doc_label.setText(
f"Suspicious: {os.path.basename(self.document.input_filename)}"
)
def start(self) -> None: def start(self) -> None:
self.convert_t = ConvertThread(self.dangerzone, self.document) self.convert_t = ConvertThread(self.dangerzone, self.document)
self.convert_t.update.connect(self.update_progress) self.convert_t.update.connect(self.update_progress)

View file

@ -61,6 +61,9 @@ class DangerzoneCore(object):
with concurrent.futures.ThreadPoolExecutor(max_workers=max_jobs) as executor: with concurrent.futures.ThreadPoolExecutor(max_workers=max_jobs) as executor:
executor.map(convert_doc, self.documents) executor.map(convert_doc, self.documents)
def get_unsafe_documents(self) -> List[Document]:
return [doc for doc in self.documents if doc.is_unsafe()]
def get_safe_documents(self) -> List[Document]: def get_safe_documents(self) -> List[Document]:
return [doc for doc in self.documents if doc.is_safe()] return [doc for doc in self.documents if doc.is_safe()]