From 56912a71084415eac2f447650279d833d9857686 Mon Sep 17 00:00:00 2001 From: glubsy Date: Mon, 13 Jul 2020 05:06:04 +0200 Subject: [PATCH 1/2] Make details dialog dockable --- qt/app.py | 4 +++- qt/details_dialog.py | 4 ++-- qt/pe/details_dialog.py | 18 +++++++++++------- 3 files changed, 16 insertions(+), 10 deletions(-) diff --git a/qt/app.py b/qt/app.py index ac59dd0a..74b9ab74 100644 --- a/qt/app.py +++ b/qt/app.py @@ -7,7 +7,7 @@ import sys import os.path as op -from PyQt5.QtCore import QTimer, QObject, QUrl, pyqtSignal +from PyQt5.QtCore import QTimer, QObject, QUrl, pyqtSignal, Qt from PyQt5.QtGui import QDesktopServices from PyQt5.QtWidgets import QApplication, QFileDialog, QDialog, QMessageBox @@ -284,6 +284,8 @@ class DupeGuru(QObject): self.resultWindow.setParent(None) self.resultWindow = ResultWindow(self.directories_dialog, self) self.details_dialog = self._get_details_dialog_class()(self.resultWindow, self) + self.resultWindow.addDockWidget( + Qt.BottomDockWidgetArea, self.details_dialog) def show_results_window(self): self.showResultsWindow() diff --git a/qt/details_dialog.py b/qt/details_dialog.py index 57cc650b..3c06a641 100644 --- a/qt/details_dialog.py +++ b/qt/details_dialog.py @@ -7,12 +7,12 @@ # http://www.gnu.org/licenses/gpl-3.0.html from PyQt5.QtCore import Qt -from PyQt5.QtWidgets import QMainWindow +from PyQt5.QtWidgets import QDockWidget from .details_table import DetailsModel -class DetailsDialog(QMainWindow): +class DetailsDialog(QDockWidget): def __init__(self, parent, app, **kwargs): super().__init__(parent, Qt.Tool, **kwargs) self.app = app diff --git a/qt/pe/details_dialog.py b/qt/pe/details_dialog.py index 07ecdfcb..933105b9 100644 --- a/qt/pe/details_dialog.py +++ b/qt/pe/details_dialog.py @@ -25,8 +25,8 @@ class DetailsDialog(DetailsDialogBase): self.setWindowTitle(tr("Details")) self.resize(502, 502) self.setMinimumSize(QSize(250, 250)) + self.setAllowedAreas(Qt.AllDockWidgetAreas) self.splitter = QSplitter(Qt.Vertical, self) - self.setCentralWidget(self.splitter) self.topFrame = QFrame() self.topFrame.setFrameShape(QFrame.StyledPanel) self.horizontalLayout = QGridLayout() @@ -73,6 +73,8 @@ class DetailsDialog(DetailsDialogBase): # Late population needed here for connections to the toolbar self.vController.setupViewers( self.selectedImageViewer, self.referenceImageViewer) + # self.setCentralWidget(self.splitter) # only as QMainWindow + self.setWidget(self.splitter) # only as QDockWidget def _update(self): if self.vController is None: # Not yet constructed! @@ -89,15 +91,17 @@ class DetailsDialog(DetailsDialogBase): # --- Override def resizeEvent(self, event): - # HACK referenceViewer might be 1 pixel shorter in width + # HACK This ensures same size while shrinking. + # ReferenceViewer might be 1 pixel shorter in width # due to the toolbar in the middle keeping the same width, # so resizing in the GridLayout's engine leads to not enough space # left for the panel on the right. - # This ensures same size while shrinking at least: - self.horizontalLayout.setColumnMinimumWidth( - 0, self.selectedImageViewer.size().width()) - self.horizontalLayout.setColumnMinimumWidth( - 2, self.selectedImageViewer.size().width()) + # This doesn't work as a QDockWidget however! + # self.horizontalLayout.setColumnMinimumWidth( + # 0, self.selectedImageViewer.size().width()) + # self.horizontalLayout.setColumnMinimumWidth( + # 2, self.selectedImageViewer.size().width()) + # This works when expanding but it's ugly: if self.selectedImageViewer.size().width() > self.referenceImageViewer.size().width(): # print(f"""Before selected size: {self.selectedImageViewer.size()}\n""", From 3eddeb6aebc99126e62eb05af60333ba3bd22e82 Mon Sep 17 00:00:00 2001 From: glubsy Date: Tue, 14 Jul 2020 17:37:48 +0200 Subject: [PATCH 2/2] Fix ME/SE details dialogs, add preferences * Fix ME and SE versions of details dialog not displaying their content properly after change to QDockWidget * Add option to toggle titlebar and orientation of titlebar in preferences dialog * Fix setting layout on PE details dialog window while layout already set, by removing the self (parent) reference in constructing the QSplitter --- qt/app.py | 5 ++++- qt/details_dialog.py | 20 +++++++++++++++++++- qt/me/details_dialog.py | 5 ++++- qt/pe/details_dialog.py | 6 +++--- qt/preferences.py | 6 ++++++ qt/preferences_dialog.py | 19 ++++++++++++++++++- qt/se/details_dialog.py | 5 ++++- 7 files changed, 58 insertions(+), 8 deletions(-) diff --git a/qt/app.py b/qt/app.py index 74b9ab74..7a5b60f6 100644 --- a/qt/app.py +++ b/qt/app.py @@ -54,11 +54,11 @@ class DupeGuru(QObject): def _setup(self): core.pe.photo.PLAT_SPECIFIC_PHOTO_CLASS = PlatSpecificPhoto self._setupActions() + self.details_dialog = None self._update_options() self.recentResults = Recent(self, "recentResults") self.recentResults.mustOpenItem.connect(self.model.load_from) self.resultWindow = None - self.details_dialog = None self.directories_dialog = DirectoriesDialog(self) self.progress_window = ProgressWindow( self.directories_dialog, self.model.progress_window @@ -152,6 +152,9 @@ class DupeGuru(QObject): self.model.options["match_scaled"] = self.prefs.match_scaled self.model.options["picture_cache_type"] = self.prefs.picture_cache_type + if self.details_dialog: + self.details_dialog.update_options() + # --- Private def _get_details_dialog_class(self): if self.model.app_mode == AppMode.Picture: diff --git a/qt/details_dialog.py b/qt/details_dialog.py index 3c06a641..56555c30 100644 --- a/qt/details_dialog.py +++ b/qt/details_dialog.py @@ -7,7 +7,7 @@ # http://www.gnu.org/licenses/gpl-3.0.html from PyQt5.QtCore import Qt -from PyQt5.QtWidgets import QDockWidget +from PyQt5.QtWidgets import QDockWidget, QWidget from .details_table import DetailsModel @@ -17,7 +17,9 @@ class DetailsDialog(QDockWidget): super().__init__(parent, Qt.Tool, **kwargs) self.app = app self.model = app.model.details_panel + self.setAllowedAreas(Qt.AllDockWidgetAreas) self._setupUi() + self.update_options() # To avoid saving uninitialized geometry on appWillSavePrefs, we track whether our dialog # has been shown. If it has, we know that our geometry should be saved. self._shown_once = False @@ -36,6 +38,22 @@ class DetailsDialog(QDockWidget): self._shown_once = True super().show() + def update_options(self): + # This disables the title bar (if we had not set one before already) + # essentially making it a simple floating window, not dockable anymore + if not self.app.prefs.details_dialog_titlebar_enabled \ + and not self.titleBarWidget(): + self.setTitleBarWidget(QWidget()) + elif self.titleBarWidget() is not None: + # resets to the default title bar + self.setTitleBarWidget(None) + + features = self.features() + if self.app.prefs.details_dialog_vertical_titlebar: + self.setFeatures(features | QDockWidget.DockWidgetVerticalTitleBar) + elif features & QDockWidget.DockWidgetVerticalTitleBar: + self.setFeatures(features ^ QDockWidget.DockWidgetVerticalTitleBar) + # --- Events def appWillSavePrefs(self): if self._shown_once: diff --git a/qt/me/details_dialog.py b/qt/me/details_dialog.py index 935a34c6..ecb947d0 100644 --- a/qt/me/details_dialog.py +++ b/qt/me/details_dialog.py @@ -5,7 +5,7 @@ # http://www.gnu.org/licenses/gpl-3.0.html from PyQt5.QtCore import QSize -from PyQt5.QtWidgets import QVBoxLayout, QAbstractItemView +from PyQt5.QtWidgets import QVBoxLayout, QAbstractItemView, QWidget from hscommon.trans import trget from ..details_dialog import DetailsDialog as DetailsDialogBase @@ -27,3 +27,6 @@ class DetailsDialog(DetailsDialogBase): self.tableView.setSelectionBehavior(QAbstractItemView.SelectRows) self.tableView.setShowGrid(False) self.verticalLayout.addWidget(self.tableView) + self.centralWidget = QWidget() + self.centralWidget.setLayout(self.verticalLayout) + self.setWidget(self.centralWidget) diff --git a/qt/pe/details_dialog.py b/qt/pe/details_dialog.py index 933105b9..2bf01b48 100644 --- a/qt/pe/details_dialog.py +++ b/qt/pe/details_dialog.py @@ -25,8 +25,7 @@ class DetailsDialog(DetailsDialogBase): self.setWindowTitle(tr("Details")) self.resize(502, 502) self.setMinimumSize(QSize(250, 250)) - self.setAllowedAreas(Qt.AllDockWidgetAreas) - self.splitter = QSplitter(Qt.Vertical, self) + self.splitter = QSplitter(Qt.Vertical) self.topFrame = QFrame() self.topFrame.setFrameShape(QFrame.StyledPanel) self.horizontalLayout = QGridLayout() @@ -96,7 +95,8 @@ class DetailsDialog(DetailsDialogBase): # due to the toolbar in the middle keeping the same width, # so resizing in the GridLayout's engine leads to not enough space # left for the panel on the right. - # This doesn't work as a QDockWidget however! + # This work as a QMainWindow, but doesn't work as a QDockWidget: + # resize can only grow. Might need some custom sizeHint somewhere... # self.horizontalLayout.setColumnMinimumWidth( # 0, self.selectedImageViewer.size().width()) # self.horizontalLayout.setColumnMinimumWidth( diff --git a/qt/preferences.py b/qt/preferences.py index c9691cca..39e55b1e 100644 --- a/qt/preferences.py +++ b/qt/preferences.py @@ -31,6 +31,8 @@ class Preferences(PreferencesBase): self.tableFontSize = get("TableFontSize", self.tableFontSize) self.reference_bold_font = get('ReferenceBoldFont', self.reference_bold_font) + self.details_dialog_titlebar_enabled = get('DetailsDialogTitleBarEnabled', self.details_dialog_titlebar_enabled) + self.details_dialog_vertical_titlebar = get('DetailsDialogVerticalTitleBar', self.details_dialog_vertical_titlebar) self.resultWindowIsMaximized = get( "ResultWindowIsMaximized", self.resultWindowIsMaximized ) @@ -67,6 +69,8 @@ class Preferences(PreferencesBase): self.tableFontSize = QApplication.font().pointSize() self.reference_bold_font = True + self.details_dialog_titlebar_enabled = True + self.details_dialog_vertical_titlebar = True self.resultWindowIsMaximized = False self.resultWindowRect = None self.directoriesWindowRect = None @@ -100,6 +104,8 @@ class Preferences(PreferencesBase): set_("TableFontSize", self.tableFontSize) set_('ReferenceBoldFont', self.reference_bold_font) + set_('DetailsDialogTitleBarEnabled', self.details_dialog_titlebar_enabled) + set_('DetailsDialogVerticalTitleBar', self.details_dialog_vertical_titlebar) set_("ResultWindowIsMaximized", self.resultWindowIsMaximized) self.set_rect("ResultWindowRect", self.resultWindowRect) self.set_rect("DirectoriesWindowRect", self.directoriesWindowRect) diff --git a/qt/preferences_dialog.py b/qt/preferences_dialog.py index eb3462e3..2603eeb4 100644 --- a/qt/preferences_dialog.py +++ b/qt/preferences_dialog.py @@ -117,8 +117,21 @@ class PreferencesDialogBase(QDialog): self.widgetsVLayout.addLayout( horizontalWrap([self.fontSizeLabel, self.fontSizeSpinBox, None]) ) - self._setupAddCheckbox("reference_bold_font", tr("Bold font for reference.")) + self._setupAddCheckbox("reference_bold_font", + tr("Bold font for reference.")) self.widgetsVLayout.addWidget(self.reference_bold_font) + + self._setupAddCheckbox("details_dialog_titlebar_enabled", + tr("Details dialog displays a title bar and is dockable")) + self.widgetsVLayout.addWidget(self.details_dialog_titlebar_enabled) + self._setupAddCheckbox("details_dialog_vertical_titlebar", + tr("Details dialog displays a vertical title bar.")) + self.widgetsVLayout.addWidget(self.details_dialog_vertical_titlebar) + self.details_dialog_vertical_titlebar.setEnabled( + self.details_dialog_titlebar_enabled.isChecked()) + self.details_dialog_titlebar_enabled.stateChanged.connect( + self.details_dialog_vertical_titlebar.setEnabled) + self.languageLabel = QLabel(tr("Language:"), self) self.languageComboBox = QComboBox(self) for lang in self.supportedLanguages: @@ -190,6 +203,8 @@ class PreferencesDialogBase(QDialog): setchecked(self.ignoreHardlinkMatches, prefs.ignore_hardlink_matches) setchecked(self.debugModeBox, prefs.debug_mode) setchecked(self.reference_bold_font, prefs.reference_bold_font) + setchecked(self.details_dialog_titlebar_enabled , prefs.details_dialog_titlebar_enabled) + setchecked(self.details_dialog_vertical_titlebar, prefs.details_dialog_vertical_titlebar) self.copyMoveDestinationComboBox.setCurrentIndex(prefs.destination_type) self.customCommandEdit.setText(prefs.custom_command) self.fontSizeSpinBox.setValue(prefs.tableFontSize) @@ -210,6 +225,8 @@ class PreferencesDialogBase(QDialog): prefs.ignore_hardlink_matches = ischecked(self.ignoreHardlinkMatches) prefs.debug_mode = ischecked(self.debugModeBox) prefs.reference_bold_font = ischecked(self.reference_bold_font) + prefs.details_dialog_titlebar_enabled = ischecked(self.details_dialog_titlebar_enabled) + prefs.details_dialog_vertical_titlebar = ischecked(self.details_dialog_vertical_titlebar) prefs.destination_type = self.copyMoveDestinationComboBox.currentIndex() prefs.custom_command = str(self.customCommandEdit.text()) prefs.tableFontSize = self.fontSizeSpinBox.value() diff --git a/qt/se/details_dialog.py b/qt/se/details_dialog.py index 812c649f..0f922dc4 100644 --- a/qt/se/details_dialog.py +++ b/qt/se/details_dialog.py @@ -5,7 +5,7 @@ # http://www.gnu.org/licenses/gpl-3.0.html from PyQt5.QtCore import QSize -from PyQt5.QtWidgets import QVBoxLayout, QAbstractItemView +from PyQt5.QtWidgets import QVBoxLayout, QAbstractItemView, QWidget from hscommon.trans import trget from ..details_dialog import DetailsDialog as DetailsDialogBase @@ -27,3 +27,6 @@ class DetailsDialog(DetailsDialogBase): self.tableView.setSelectionBehavior(QAbstractItemView.SelectRows) self.tableView.setShowGrid(False) self.verticalLayout.addWidget(self.tableView) + self.centralWidget = QWidget() + self.centralWidget.setLayout(self.verticalLayout) + self.setWidget(self.centralWidget)