# Copyright 2016 Hardcoded Software (http://www.hardcoded.net) # # This software is licensed under the "GPLv3" License as described in the "LICENSE" file, # which should be included with this package. The terms are also available at # http://www.gnu.org/licenses/gpl-3.0.html from PyQt5.QtCore import Qt, QSize, pyqtSlot, pyqtSignal from PyQt5.QtWidgets import (QLayout, QVBoxLayout, QAbstractItemView, QHBoxLayout, QSizePolicy, QGridLayout, QWidget, QSpacerItem, QSplitter, QFrame ) from hscommon.trans import trget from hscommon import desktop from ..details_dialog import DetailsDialog as DetailsDialogBase from ..details_table import DetailsTable from qtlib.util import createActions from qt.pe.image_viewer import ( ViewerToolBar, QWidgetImageViewer, ScrollAreaImageViewer, GraphicsViewViewer, QWidgetController, ScrollAreaController, GraphicsViewController) tr = trget("ui") class DetailsDialog(DetailsDialogBase): def __init__(self, parent, app): self.vController = None super().__init__(parent, app) def _setupUi(self): self.setWindowTitle(tr("Details")) self.resize(502, 502) self.setMinimumSize(QSize(250, 250)) # self.verticalLayout = QVBoxLayout(self) # self.verticalLayout.setSpacing(0) # self.verticalLayout.setContentsMargins(0, 0, 0, 0) self.splitter = QSplitter(Qt.Vertical, self) self.setCentralWidget(self.splitter) self.topFrame = QFrame() self.topFrame.setFrameShape(QFrame.StyledPanel) self.horizontalLayout = QGridLayout() # Minimum width for the toolbar in the middle: self.horizontalLayout.setColumnMinimumWidth(1, 10) self.horizontalLayout.setContentsMargins(0, 0, 0, 0) self.horizontalLayout.setColumnStretch(0,24) self.horizontalLayout.setColumnStretch(1,1) self.horizontalLayout.setColumnStretch(2,24) # This avoids toolbar getting incorrectly resized when window resizes self.horizontalLayout.setRowStretch(0,1) self.horizontalLayout.setRowStretch(1,24) self.horizontalLayout.setRowStretch(2,1) self.horizontalLayout.setSpacing(1) self.selectedImageViewer = GraphicsViewViewer(self, "selectedImage") # self.selectedImage = QLabel(self) # sizePolicy = QSizePolicy(QSizePolicy.Ignored, QSizePolicy.Ignored) # sizePolicy.setHorizontalStretch(0) # sizePolicy.setVerticalStretch(0) # sizePolicy.setHeightForWidth( # self.selectedImage.sizePolicy().hasHeightForWidth() # ) # self.selectedImage.setSizePolicy(sizePolicy) # self.selectedImage.setScaledContents(False) # self.selectedImage.setAlignment(Qt.AlignCenter) # # self.horizontalLayout.addWidget(self.selectedImage) self.horizontalLayout.addWidget(self.selectedImageViewer, 0, 0, 3, 1) # We use different types of controller depending on the # underlying widgets we use to display images # because their interface and methods might differ if isinstance(self.selectedImageViewer, QWidgetImageViewer): self.vController = QWidgetController(self) elif isinstance(self.selectedImageViewer, ScrollAreaImageViewer): self.vController = ScrollAreaController(self) elif isinstance(self.selectedImageViewer, GraphicsViewViewer): self.vController = GraphicsViewController(self) # self.horizontalLayout.addItem(QSpacerItem(5,0, QSizePolicy.Minimum), # 1, 3, 1, 1, Qt.Alignment(Qt.AlignRight)) self.verticalToolBar = ViewerToolBar(self, self.vController) # self.verticalToolBar.setMaximumWidth(10) self.verticalToolBar.setOrientation(Qt.Orientation(Qt.Vertical)) # self.subVLayout = QVBoxLayout(self) # self.subVLayout.addWidget(self.verticalToolBar) # self.horizontalLayout.addLayout(self.subVLayout) self.horizontalLayout.addWidget(self.verticalToolBar, 1, 1, 1, 1, Qt.AlignCenter) self.referenceImageViewer = GraphicsViewViewer(self, "referenceImage") # self.referenceImage = QLabel(self) # sizePolicy = QSizePolicy(QSizePolicy.Preferred, QSizePolicy.Preferred) # sizePolicy.setHorizontalStretch(0) # sizePolicy.setVerticalStretch(0) # self.verticalToolBar.setSizePolicy(sizePolicy) # sizePolicy.setHeightForWidth( # self.referenceImage.sizePolicy().hasHeightForWidth() # ) # self.referenceImageViewer.setSizePolicy(sizePolicy) # self.referenceImageViewer.setAlignment(Qt.AlignCenter) self.horizontalLayout.addWidget(self.referenceImageViewer, 0, 2, 3, 1) # self.verticalLayout.addLayout(self.horizontalLayout) self.topFrame.setLayout(self.horizontalLayout) self.splitter.addWidget(self.topFrame) # container = QWidget(self) # container.setLayout(self.horizontalLayout) # self.setLayout(self.horizontalLayout) # self.splitter.addWidget(self) self.splitter.setStretchFactor(0, 8) self.tableView = DetailsTable(self) sizePolicy = QSizePolicy(QSizePolicy.Expanding, QSizePolicy.Maximum) sizePolicy.setHorizontalStretch(0) sizePolicy.setVerticalStretch(0) # sizePolicy.setHeightForWidth(self.tableView.sizePolicy().hasHeightForWidth()) self.tableView.setSizePolicy(sizePolicy) # self.tableView.setMinimumSize(QSize(0, 190)) # self.tableView.setMaximumSize(QSize(16777215, 190)) self.tableView.setAlternatingRowColors(True) self.tableView.setSelectionBehavior(QAbstractItemView.SelectRows) self.tableView.setShowGrid(False) # self.verticalLayout.addLayout(self.tableView) self.splitter.addWidget(self.tableView) self.splitter.setStretchFactor(1, 1) # self.tableView.hide() self.vController.setupViewers(self.selectedImageViewer, self.referenceImageViewer) def _update(self): if self.vController is None: # Not yet constructed! return if not self.app.model.selected_dupes: # No item from the model, disable and clear everything. self.vController.resetViewersState() return dupe = self.app.model.selected_dupes[0] group = self.app.model.results.get_group_of_duplicate(dupe) ref = group.ref self.vController.updateView(ref, dupe, group) # --- Override def resizeEvent(self, event): # HACK 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 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\ # Before reference size: {self.referenceImageViewer.size()}") # self.selectedImageViewer.resize(self.referenceImageViewer.size()) # print(f"After selected size: {self.selectedImageViewer.size()}\n\ # After reference size: {self.referenceImageViewer.size()}") if self.vController is None or not self.vController.bestFit: return # Only update the scaled down pixmaps self.vController.updateBothImages() def show(self): # Compute the maximum size the table view can reach self.tableView.setMaximumHeight( self.tableView.rowHeight(1) * self.tableModel.model.row_count()\ + self.tableView.verticalHeader().sectionSize(0)) DetailsDialogBase.show(self) self._update() # model --> view def refresh(self): DetailsDialogBase.refresh(self) if self.isVisible(): self._update()