Ejemplo n.º 1
0
    def initUI(self):
        hbox = QHBoxLayout(self)

        self.lefttopframe = MyPixmap()
        # self.lefttopframe.frameWidth = 40
        self.lefttopframe.setMinimumWidth(150)
        self.lefttopframe.setFrameShape(QFrame.StyledPanel)
        # leftbottomframe = QFrame(self)
        self.dirmodel = QDirModel()
        qtree = QTreeView()
        qtree.setMaximumWidth(300)
        qtree.setModel(self.dirmodel)
        qtree.setRootIndex(
            self.dirmodel.index(QDir.currentPath() + '/mapeditor/Maps'))
        qtree.doubleClicked.connect(self.tree_clicked)

        # leftbottomframe.setFrameShape(QFrame.StyledPanel)
        splitter = QSplitter(Qt.Vertical)
        splitter.handleWidth = 20
        splitter.addWidget(self.lefttopframe)
        splitter.addWidget(qtree)

        self.rightframe = MyPixmap(self)
        # rightframe.set_tileset()
        self.rightframe.setFrameShape(QFrame.StyledPanel)
        splitter2 = QSplitter(Qt.Horizontal)
        splitter2.addWidget(splitter)
        splitter2.addWidget(self.rightframe)

        hbox.addWidget(splitter2)
        self.setLayout(hbox)
Ejemplo n.º 2
0
	def __init__ ( self, parent = None ):
		super ( ToolWindowManager, self ).__init__ ( parent )
		self.lastUsedArea = None
		self.suggestions = []
		self.wrappers = []
		self.areas = []
		self.toolWindowList = []
		self.draggedToolWindows = []
		#----
		self.borderSensitivity = 12
		testSplitter = QSplitter ()
		self.rubberBandLineWidth = testSplitter.handleWidth ()
		self.dragIndicator = QtWidgets.QLabel ( None, Qt.ToolTip) # 使用QLabel来显示拖拽的提示
		self.dragIndicator.setAttribute ( Qt.WA_ShowWithoutActivating)
		mainLayout = QtWidgets.QVBoxLayout ( self )
		mainLayout.setContentsMargins ( 0, 0, 0, 0 )
		
		wrapper = ToolWindowManagerWrapper ( self )
		wrapper.setWindowFlags ( wrapper.windowFlags () & ~Qt.Tool )
		mainLayout.addWidget ( wrapper )

		self.dropSuggestionSwitchTimer = QtCore.QTimer ( self )
		self.dropSuggestionSwitchTimer.timeout.connect ( self.showNextDropSuggestion )
		self.dropSuggestionSwitchTimer.setInterval ( 800 )
		self.dropCurrentSuggestionIndex = 0

		palette = QtGui.QPalette ()
		color = QtGui.QColor ( Qt.blue )
		color.setAlpha ( 80 )
		palette.setBrush ( QtGui.QPalette.Highlight, QtGui.QBrush ( color ) )
		
		self.rectRubberBand = QRubberBand ( QRubberBand.Rectangle, self )
		self.lineRubberBand = QRubberBand ( QRubberBand.Line, self )
		self.rectRubberBand.setPalette ( palette )
		self.lineRubberBand.setPalette ( palette )
Ejemplo n.º 3
0
class QuadView(QWidget):
    def __init__(self, parent, view1, view2, view3, view4=None):
        QWidget.__init__(self, parent)

        self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)

        self.installEventFilter(self)

        self.dockableContainer = []

        self.layout = QVBoxLayout()
        self.setLayout(self.layout)
        self.layout.setContentsMargins(0, 0, 0, 0)
        self.layout.setSpacing(0)

        self.splitVertical = QSplitter(Qt.Vertical, self)
        self.layout.addWidget(self.splitVertical)
        self.splitHorizontal1 = QSplitter(Qt.Horizontal, self.splitVertical)
        self.splitHorizontal1.setObjectName("splitter1")
        self.splitHorizontal2 = QSplitter(Qt.Horizontal, self.splitVertical)
        self.splitHorizontal2.setObjectName("splitter2")
        self.splitHorizontal1.splitterMoved.connect(self.horizontalSplitterMoved)
        self.splitHorizontal2.splitterMoved.connect(self.horizontalSplitterMoved)

        self.imageView2D_1 = view1

        self.imageView2D_2 = view2

        self.imageView2D_3 = view3

        self.dock1_ofSplitHorizontal1 = ImageView2DDockWidget(self.imageView2D_1)
        self.dock1_ofSplitHorizontal1.connectHud()
        self.dockableContainer.append(self.dock1_ofSplitHorizontal1)
        self.dock1_ofSplitHorizontal1.onDockButtonClicked.connect(
            lambda arg=self.dock1_ofSplitHorizontal1: self.on_dock(arg)
        )
        self.dock1_ofSplitHorizontal1.onMaxButtonClicked.connect(
            lambda arg=self.dock1_ofSplitHorizontal1: self.on_max(arg)
        )
        self.dock1_ofSplitHorizontal1.onMinButtonClicked.connect(
            lambda arg=self.dock1_ofSplitHorizontal1: self.on_min(arg)
        )
        self.splitHorizontal1.addWidget(self.dock1_ofSplitHorizontal1)

        self.dock2_ofSplitHorizontal1 = ImageView2DDockWidget(self.imageView2D_2)
        self.dock2_ofSplitHorizontal1.onDockButtonClicked.connect(
            lambda arg=self.dock2_ofSplitHorizontal1: self.on_dock(arg)
        )
        self.dock2_ofSplitHorizontal1.onMaxButtonClicked.connect(
            lambda arg=self.dock2_ofSplitHorizontal1: self.on_max(arg)
        )
        self.dock2_ofSplitHorizontal1.onMinButtonClicked.connect(
            lambda arg=self.dock2_ofSplitHorizontal1: self.on_min(arg)
        )
        self.dock2_ofSplitHorizontal1.connectHud()
        self.dockableContainer.append(self.dock2_ofSplitHorizontal1)
        self.splitHorizontal1.addWidget(self.dock2_ofSplitHorizontal1)

        self.dock1_ofSplitHorizontal2 = ImageView2DDockWidget(self.imageView2D_3)
        self.dock1_ofSplitHorizontal2.onDockButtonClicked.connect(
            lambda arg=self.dock1_ofSplitHorizontal2: self.on_dock(arg)
        )
        self.dock1_ofSplitHorizontal2.onMaxButtonClicked.connect(
            lambda arg=self.dock1_ofSplitHorizontal2: self.on_max(arg)
        )
        self.dock1_ofSplitHorizontal2.onMinButtonClicked.connect(
            lambda arg=self.dock1_ofSplitHorizontal2: self.on_min(arg)
        )
        self.dock1_ofSplitHorizontal2.connectHud()
        self.dockableContainer.append(self.dock1_ofSplitHorizontal2)
        self.splitHorizontal2.addWidget(self.dock1_ofSplitHorizontal2)

        self.dock2_ofSplitHorizontal2 = ImageView2DDockWidget(view4)
        self.dockableContainer.append(self.dock2_ofSplitHorizontal2)
        self.splitHorizontal2.addWidget(self.dock2_ofSplitHorizontal2)

        # this is a hack: with 0 ms it does not work...
        QTimer.singleShot(250, self._resizeEqual)

    def _resizeEqual(self):
        if not all([dock.isVisible() for dock in self.dockableContainer]):
            return
        w, h = (
            self.size().width() - self.splitHorizontal1.handleWidth(),
            self.size().height() - self.splitVertical.handleWidth(),
        )

        self.splitVertical.setSizes([h // 2, h // 2])

        if self.splitHorizontal1.count() == 2 and self.splitHorizontal2.count() == 2:
            # docks = [self.imageView2D_1, self.imageView2D_2, self.imageView2D_3, self.testView4]
            docks = []
            for splitter in [self.splitHorizontal1, self.splitHorizontal2]:
                for i in range(splitter.count()):
                    docks.append(splitter.widget(i).graphicsView)

            w1 = [docks[i].minimumSize().width() for i in [0, 2]]
            w2 = [docks[i].minimumSize().width() for i in [1, 3]]
            wLeft = max(w1)
            wRight = max(w2)
            if wLeft > wRight and wLeft > w // 2:
                wRight = w - wLeft
            elif wRight >= wLeft and wRight > w // 2:
                wLeft = w - wRight
            else:
                wLeft = w // 2
                wRight = w // 2
            self.splitHorizontal1.setSizes([wLeft, wRight])
            self.splitHorizontal2.setSizes([wLeft, wRight])

    def eventFilter(self, obj, event):
        if event.type() in [QEvent.WindowActivate, QEvent.Show]:
            self._synchronizeSplitter()
        return False

    def _synchronizeSplitter(self):
        sizes1 = self.splitHorizontal1.sizes()
        sizes2 = self.splitHorizontal2.sizes()
        if len(sizes1) > 0 and sizes1[0] > 0:
            self.splitHorizontal2.setSizes(sizes1)
        elif len(sizes2) > 0 and sizes2[0] > 0:
            self.splitHorizontal1.setSizes(sizes2)

    def resizeEvent(self, event):
        QWidget.resizeEvent(self, event)
        self._synchronizeSplitter()

    def horizontalSplitterMoved(self, x, y):
        if self.splitHorizontal1.count() != 2 or self.splitHorizontal2.count() != 2:
            return
        sizes = self.splitHorizontal1.sizes()
        # What. Nr2
        if self.splitHorizontal2.closestLegalPosition(x, y) < self.splitHorizontal2.closestLegalPosition(x, y):
            sizeLeft = self.splitHorizontal1.closestLegalPosition(x, y)
        else:
            sizeLeft = self.splitHorizontal2.closestLegalPosition(x, y)

        sizeRight = sizes[0] + sizes[1] - sizeLeft
        sizes = [sizeLeft, sizeRight]

        self.splitHorizontal1.setSizes(sizes)
        self.splitHorizontal2.setSizes(sizes)

    def addStatusBar(self, bar):
        self.statusBar = bar
        self.layout.addLayout(self.statusBar)

    def setGrayScaleToQuadStatusBar(self, gray):
        self.quadViewStatusBar.setGrayScale(gray)

    def setMouseCoordsToQuadStatusBar(self, x, y, z):
        self.quadViewStatusBar.setMouseCoords(x, y, z)

    def ensureMaximized(self, axis):
        """
        Maximize the view for the given axis if it isn't already maximized.
        """
        axisDict = {
            0: self.dock2_ofSplitHorizontal1,  # x
            1: self.dock1_ofSplitHorizontal2,  # y
            2: self.dock1_ofSplitHorizontal1,
        }  # z

        if not axisDict[axis]._isMaximized:
            self.switchMinMax(axis)

    def ensureMinimized(self, axis):
        """
        Minimize the view for the given axis if it isn't already minimized.
        """
        axisDict = {
            0: self.dock2_ofSplitHorizontal1,  # x
            1: self.dock1_ofSplitHorizontal2,  # y
            2: self.dock1_ofSplitHorizontal1,
        }  # z

        if axisDict[axis]._isMaximized:
            self.switchMinMax(axis)

    def switchMinMax(self, axis):
        """Switch an AxisViewWidget between from minimized to maximized and vice
        versa.

        Keyword arguments:
        axis -- the axis which is represented by the widget (no default)
                either string or integer
                'x' - 0
                'y' - 1
                'z' - 2
        """

        # TODO: get the mapping information from where it is set! if this is not
        # done properly - do it properly

        if type(axis) == str:
            axisDict = {
                "x": self.dock2_ofSplitHorizontal1,  # x
                "y": self.dock1_ofSplitHorizontal2,  # y
                "z": self.dock1_ofSplitHorizontal1,
            }  # z
        elif type(axis) == int:
            axisDict = {
                0: self.dock2_ofSplitHorizontal1,  # x
                1: self.dock1_ofSplitHorizontal2,  # y
                2: self.dock1_ofSplitHorizontal1,
            }  # z

        dockWidget = axisDict.pop(axis)
        for dWidget in list(axisDict.values()):
            if dWidget._isMaximized:
                dWidget.graphicsView._hud.maximizeButtonClicked.emit()
        dockWidget.graphicsView._hud.maximizeButtonClicked.emit()

    def switchXMinMax(self):
        self.switchMinMax("x")

    def switchYMinMax(self):
        self.switchMinMax("y")

    def switchZMinMax(self):
        self.switchMinMax("z")

    def on_dock(self, dockWidget):
        if dockWidget._isDocked:
            dockWidget.undockView()
            self.on_min(dockWidget)
            dockWidget.minimizeView()
        else:
            dockWidget.dockView()

    def on_max(self, dockWidget):
        dockWidget.setVisible(True)
        for dock in self.dockableContainer:
            if not dockWidget == dock:
                dock.setVisible(False)

        # Force sizes to be updated now
        QApplication.processEvents()

        # On linux, the vertical splitter doesn't seem to refresh unless we do so manually
        # Presumably, this is a QT bug.
        self.splitVertical.refresh()

        # Viewport doesn't update automatically...
        view = dockWidget.graphicsView
        view.viewport().setGeometry(view.rect())

    def on_min(self, dockWidget):

        for dock in self.dockableContainer:
            dock.setVisible(True)

        # Force sizes to be updated now
        QApplication.processEvents()
        self._resizeEqual()

        # Viewports don't update automatically...
        for dock in self.dockableContainer:
            view = dock.graphicsView
            if hasattr(view, "viewport"):
                view.viewport().setGeometry(view.rect())
Ejemplo n.º 4
0
class QuadView(QWidget):
    def __init__(self, parent, view1, view2, view3, view4=None):
        QWidget.__init__(self, parent)

        self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)

        self.installEventFilter(self)

        self.dockableContainer = []

        self.layout = QVBoxLayout()
        self.setLayout(self.layout)
        self.layout.setContentsMargins(0, 0, 0, 0)
        self.layout.setSpacing(0)

        self.splitVertical = QSplitter(Qt.Vertical, self)
        self.layout.addWidget(self.splitVertical)
        self.splitHorizontal1 = QSplitter(Qt.Horizontal, self.splitVertical)
        self.splitHorizontal1.setObjectName("splitter1")
        self.splitHorizontal2 = QSplitter(Qt.Horizontal, self.splitVertical)
        self.splitHorizontal2.setObjectName("splitter2")
        self.splitHorizontal1.splitterMoved.connect(
            self.horizontalSplitterMoved)
        self.splitHorizontal2.splitterMoved.connect(
            self.horizontalSplitterMoved)

        self.imageView2D_1 = view1

        self.imageView2D_2 = view2

        self.imageView2D_3 = view3

        self.dock1_ofSplitHorizontal1 = ImageView2DDockWidget(
            self.imageView2D_1)
        self.dock1_ofSplitHorizontal1.connectHud()
        self.dockableContainer.append(self.dock1_ofSplitHorizontal1)
        self.dock1_ofSplitHorizontal1.onDockButtonClicked.connect(
            lambda arg=self.dock1_ofSplitHorizontal1: self.on_dock(arg))
        self.dock1_ofSplitHorizontal1.onMaxButtonClicked.connect(
            lambda arg=self.dock1_ofSplitHorizontal1: self.on_max(arg))
        self.dock1_ofSplitHorizontal1.onMinButtonClicked.connect(
            lambda arg=self.dock1_ofSplitHorizontal1: self.on_min(arg))
        self.splitHorizontal1.addWidget(self.dock1_ofSplitHorizontal1)

        self.dock2_ofSplitHorizontal1 = ImageView2DDockWidget(
            self.imageView2D_2)
        self.dock2_ofSplitHorizontal1.onDockButtonClicked.connect(
            lambda arg=self.dock2_ofSplitHorizontal1: self.on_dock(arg))
        self.dock2_ofSplitHorizontal1.onMaxButtonClicked.connect(
            lambda arg=self.dock2_ofSplitHorizontal1: self.on_max(arg))
        self.dock2_ofSplitHorizontal1.onMinButtonClicked.connect(
            lambda arg=self.dock2_ofSplitHorizontal1: self.on_min(arg))
        self.dock2_ofSplitHorizontal1.connectHud()
        self.dockableContainer.append(self.dock2_ofSplitHorizontal1)
        self.splitHorizontal1.addWidget(self.dock2_ofSplitHorizontal1)

        self.dock1_ofSplitHorizontal2 = ImageView2DDockWidget(
            self.imageView2D_3)
        self.dock1_ofSplitHorizontal2.onDockButtonClicked.connect(
            lambda arg=self.dock1_ofSplitHorizontal2: self.on_dock(arg))
        self.dock1_ofSplitHorizontal2.onMaxButtonClicked.connect(
            lambda arg=self.dock1_ofSplitHorizontal2: self.on_max(arg))
        self.dock1_ofSplitHorizontal2.onMinButtonClicked.connect(
            lambda arg=self.dock1_ofSplitHorizontal2: self.on_min(arg))
        self.dock1_ofSplitHorizontal2.connectHud()
        self.dockableContainer.append(self.dock1_ofSplitHorizontal2)
        self.splitHorizontal2.addWidget(self.dock1_ofSplitHorizontal2)

        self.dock2_ofSplitHorizontal2 = ImageView2DDockWidget(view4)
        self.dockableContainer.append(self.dock2_ofSplitHorizontal2)
        self.splitHorizontal2.addWidget(self.dock2_ofSplitHorizontal2)

        #this is a hack: with 0 ms it does not work...
        QTimer.singleShot(250, self._resizeEqual)

    def _resizeEqual(self):
        if not all([dock.isVisible() for dock in self.dockableContainer]):
            return
        w, h = self.size().width() - self.splitHorizontal1.handleWidth(
        ), self.size().height() - self.splitVertical.handleWidth()

        self.splitVertical.setSizes([h // 2, h // 2])

        if self.splitHorizontal1.count() == 2 and self.splitHorizontal2.count(
        ) == 2:
            #docks = [self.imageView2D_1, self.imageView2D_2, self.imageView2D_3, self.testView4]
            docks = []
            for splitter in [self.splitHorizontal1, self.splitHorizontal2]:
                for i in range(splitter.count()):
                    docks.append(splitter.widget(i).graphicsView)

            w1 = [docks[i].minimumSize().width() for i in [0, 2]]
            w2 = [docks[i].minimumSize().width() for i in [1, 3]]
            wLeft = max(w1)
            wRight = max(w2)
            if wLeft > wRight and wLeft > w // 2:
                wRight = w - wLeft
            elif wRight >= wLeft and wRight > w // 2:
                wLeft = w - wRight
            else:
                wLeft = w // 2
                wRight = w // 2
            self.splitHorizontal1.setSizes([wLeft, wRight])
            self.splitHorizontal2.setSizes([wLeft, wRight])

    def eventFilter(self, obj, event):
        if (event.type() in [QEvent.WindowActivate, QEvent.Show]):
            self._synchronizeSplitter()
        return False

    def _synchronizeSplitter(self):
        sizes1 = self.splitHorizontal1.sizes()
        sizes2 = self.splitHorizontal2.sizes()
        if len(sizes1) > 0 and sizes1[0] > 0:
            self.splitHorizontal2.setSizes(sizes1)
        elif len(sizes2) > 0 and sizes2[0] > 0:
            self.splitHorizontal1.setSizes(sizes2)

    def resizeEvent(self, event):
        QWidget.resizeEvent(self, event)
        self._synchronizeSplitter()

    def horizontalSplitterMoved(self, x, y):
        if self.splitHorizontal1.count() != 2 or self.splitHorizontal2.count(
        ) != 2:
            return
        sizes = self.splitHorizontal1.sizes()
        #What. Nr2
        if self.splitHorizontal2.closestLegalPosition(
                x, y) < self.splitHorizontal2.closestLegalPosition(x, y):
            sizeLeft = self.splitHorizontal1.closestLegalPosition(x, y)
        else:
            sizeLeft = self.splitHorizontal2.closestLegalPosition(x, y)

        sizeRight = sizes[0] + sizes[1] - sizeLeft
        sizes = [sizeLeft, sizeRight]

        self.splitHorizontal1.setSizes(sizes)
        self.splitHorizontal2.setSizes(sizes)

    def addStatusBar(self, bar):
        self.statusBar = bar
        self.layout.addLayout(self.statusBar)

    def setGrayScaleToQuadStatusBar(self, gray):
        self.quadViewStatusBar.setGrayScale(gray)

    def setMouseCoordsToQuadStatusBar(self, x, y, z):
        self.quadViewStatusBar.setMouseCoords(x, y, z)

    def ensureMaximized(self, axis):
        """
        Maximize the view for the given axis if it isn't already maximized.
        """
        axisDict = {
            0: self.dock2_ofSplitHorizontal1,  # x
            1: self.dock1_ofSplitHorizontal2,  # y
            2: self.dock1_ofSplitHorizontal1
        }  # z

        if not axisDict[axis]._isMaximized:
            self.switchMinMax(axis)

    def ensureMinimized(self, axis):
        """
        Minimize the view for the given axis if it isn't already minimized.
        """
        axisDict = {
            0: self.dock2_ofSplitHorizontal1,  # x
            1: self.dock1_ofSplitHorizontal2,  # y
            2: self.dock1_ofSplitHorizontal1
        }  # z

        if axisDict[axis]._isMaximized:
            self.switchMinMax(axis)

    def switchMinMax(self, axis):
        """Switch an AxisViewWidget between from minimized to maximized and vice
        versa.

        Keyword arguments:
        axis -- the axis which is represented by the widget (no default)
                either string or integer 
                'x' - 0
                'y' - 1
                'z' - 2
        """

        #TODO: get the mapping information from where it is set! if this is not
        #done properly - do it properly

        if type(axis) == str:
            axisDict = {
                'x': self.dock2_ofSplitHorizontal1,  # x
                'y': self.dock1_ofSplitHorizontal2,  # y
                'z': self.dock1_ofSplitHorizontal1
            }  # z
        elif type(axis) == int:
            axisDict = {
                0: self.dock2_ofSplitHorizontal1,  # x
                1: self.dock1_ofSplitHorizontal2,  # y
                2: self.dock1_ofSplitHorizontal1
            }  # z

        dockWidget = axisDict.pop(axis)
        for dWidget in list(axisDict.values()):
            if dWidget._isMaximized:
                dWidget.graphicsView._hud.maximizeButtonClicked.emit()
        dockWidget.graphicsView._hud.maximizeButtonClicked.emit()

    def switchXMinMax(self):
        self.switchMinMax('x')

    def switchYMinMax(self):
        self.switchMinMax('y')

    def switchZMinMax(self):
        self.switchMinMax('z')

    def on_dock(self, dockWidget):
        if dockWidget._isDocked:
            dockWidget.undockView()
            self.on_min(dockWidget)
            dockWidget.minimizeView()
        else:
            dockWidget.dockView()

    def on_max(self, dockWidget):
        dockWidget.setVisible(True)
        for dock in self.dockableContainer:
            if not dockWidget == dock:
                dock.setVisible(False)

        # Force sizes to be updated now
        QApplication.processEvents()

        # On linux, the vertical splitter doesn't seem to refresh unless we do so manually
        # Presumably, this is a QT bug.
        self.splitVertical.refresh()

        # Viewport doesn't update automatically...
        view = dockWidget.graphicsView
        view.viewport().setGeometry(view.rect())

    def on_min(self, dockWidget):

        for dock in self.dockableContainer:
            dock.setVisible(True)

        # Force sizes to be updated now
        QApplication.processEvents()
        self._resizeEqual()

        # Viewports don't update automatically...
        for dock in self.dockableContainer:
            view = dock.graphicsView
            if hasattr(view, 'viewport'):
                view.viewport().setGeometry(view.rect())
class DestinationPanel(ScrollAreaNoFrame):
    def __init__(self, parent) -> None:
        super().__init__(parent)
        assert parent is not None
        self.rapidApp = parent
        self.prefs = self.rapidApp.prefs

        self.setObjectName("destinationPanelScrollArea")

        self.splitter = QSplitter(parent=self)

        self.splitter.setObjectName("destinationPanelSplitter")
        self.splitter.setOrientation(Qt.Vertical)

        self.createDestinationViews()
        self.splitter.addWidget(self.photoDestinationContainer)
        self.splitter.addWidget(self.videoDestination)

        self.splitter.setCollapsible(0, False)
        self.splitter.setCollapsible(1, False)
        self.setWidget(self.splitter)
        self.setWidgetResizable(True)

    def createDestinationViews(self) -> None:
        """
        Create the widgets that let the user choose where to download photos and videos
        to, and that show them how much storage space there is available for their
        files.
        """

        self.photoDestination = QPanelView(label=_("Photos"), )
        self.photoDestination.setObjectName("photoDestinationPanelView")
        self.videoDestination = QPanelView(label=_("Videos"), )
        self.videoDestination.setObjectName("videoDestinationPanelView")

        # Display storage space when photos and videos are being downloaded to the same
        # partition. That is, "combined" means not combined widgets, but combined
        # display of destination download stats the user sees

        self.combinedDestinationDisplay = DestinationDisplay(
            parent=self, rapidApp=self.rapidApp)
        self.combinedDestinationDisplayContainer = QPanelView(
            _("Projected Storage Use"), )
        self.combinedDestinationDisplay.setObjectName(
            "combinedDestinationDisplay")
        self.combinedDestinationDisplayContainer.addWidget(
            self.combinedDestinationDisplay)
        self.combinedDestinationDisplayContainer.setObjectName(
            "combinedDestinationDisplayContainer")

        # Display storage space when photos and videos are being downloaded to different
        # partitions.
        # Also display the file system folder chooser for both destinations.

        self.photoDestinationDisplay = DestinationDisplay(
            menu=True,
            file_type=FileType.photo,
            parent=self,
            rapidApp=self.rapidApp)
        self.photoDestinationDisplay.setDestination(
            self.prefs.photo_download_folder)
        self.photoDestinationDisplay.setObjectName("photoDestinationDisplay")
        self.photoDestinationWidget = ComputerWidget(
            objectName="photoDestination",
            view=self.photoDestinationDisplay,
            fileSystemView=self.rapidApp.photoDestinationFSView,
            select_text=_("Select a destination folder"),
        )

        self.videoDestinationDisplay = DestinationDisplay(
            menu=True,
            file_type=FileType.video,
            parent=self,
            rapidApp=self.rapidApp)
        self.videoDestinationDisplay.setObjectName("videoDestinationDisplay")
        self.videoDestinationDisplay.setDestination(
            self.prefs.video_download_folder)
        self.videoDestinationWidget = ComputerWidget(
            objectName="videoDestination",
            view=self.videoDestinationDisplay,
            fileSystemView=self.rapidApp.videoDestinationFSView,
            select_text=_("Select a destination folder"),
        )

        self.photoDestination.addWidget(self.photoDestinationWidget)
        self.videoDestination.addWidget(self.videoDestinationWidget)

        for widget in (self.photoDestinationWidget,
                       self.videoDestinationWidget,
                       self.combinedDestinationDisplay):
            self.verticalScrollBarVisible.connect(
                widget.containerVerticalScrollBar)
        self.horizontalScrollBarVisible.connect(
            self.videoDestinationWidget.containerHorizontalScrollBar)

        layout = QVBoxLayout()
        layout.setContentsMargins(0, 0, 0, 0)
        layout.setSpacing(self.splitter.handleWidth())
        layout.addWidget(self.combinedDestinationDisplayContainer)
        layout.addWidget(self.photoDestination)

        self.photoDestinationContainer = QWidget()
        self.photoDestinationContainer.setObjectName(
            "photoDestinationContainer")
        self.photoDestinationContainer.setLayout(layout)

    def updateDestinationPanelViews(
        self,
        same_dev: bool,
        merge: bool,
        marked_summary: MarkedSummary,
        downloading_to: Optional[DefaultDict[int, Set[FileType]]] = None,
    ) -> bool:
        """
        Updates the header bar and storage space view for the
        photo and video download destinations.

        :return True if destinations required for the download exist,
         and there is sufficient space on them, else False.
        """

        size_photos_marked = marked_summary.size_photos_marked
        size_videos_marked = marked_summary.size_videos_marked
        marked = marked_summary.marked

        destinations_good = True

        if same_dev:
            files_to_display = DisplayingFilesOfType.photos_and_videos
            self.combinedDestinationDisplay.downloading_to = downloading_to
            self.combinedDestinationDisplay.setDestination(
                self.prefs.photo_download_folder)
            self.combinedDestinationDisplay.setDownloadAttributes(
                marked=marked,
                photos_size=size_photos_marked,
                videos_size=size_videos_marked,
                files_to_display=files_to_display,
                display_type=DestinationDisplayType.usage_only,
                merge=merge,
            )
            display_type = DestinationDisplayType.folder_only
            self.combinedDestinationDisplayContainer.setVisible(True)
            destinations_good = (
                self.combinedDestinationDisplay.sufficientSpaceAvailable())
        else:
            files_to_display = DisplayingFilesOfType.photos
            display_type = DestinationDisplayType.folders_and_usage
            self.combinedDestinationDisplayContainer.setVisible(False)

        if self.prefs.photo_download_folder:
            self.photoDestinationDisplay.downloading_to = downloading_to
            self.photoDestinationDisplay.setDownloadAttributes(
                marked=marked,
                photos_size=size_photos_marked,
                videos_size=0,
                files_to_display=files_to_display,
                display_type=display_type,
                merge=merge,
            )
            self.photoDestinationWidget.setViewVisible(True)
            if display_type == DestinationDisplayType.folders_and_usage:
                destinations_good = (
                    self.photoDestinationDisplay.sufficientSpaceAvailable())
        else:
            # Photo download folder was invalid or simply not yet set
            self.photoDestinationWidget.setViewVisible(False)
            if size_photos_marked:
                destinations_good = False

        if not same_dev:
            files_to_display = DisplayingFilesOfType.videos
        if self.prefs.video_download_folder:
            self.videoDestinationDisplay.downloading_to = downloading_to
            self.videoDestinationDisplay.setDownloadAttributes(
                marked=marked,
                photos_size=0,
                videos_size=size_videos_marked,
                files_to_display=files_to_display,
                display_type=display_type,
                merge=merge,
            )
            self.videoDestinationWidget.setViewVisible(True)
            if display_type == DestinationDisplayType.folders_and_usage:
                destinations_good = (
                    self.videoDestinationDisplay.sufficientSpaceAvailable()
                    and destinations_good)
        else:
            # Video download folder was invalid or simply not yet set
            self.videoDestinationWidget.setViewVisible(False)
            if size_videos_marked:
                destinations_good = False

        return destinations_good