eric7/HelpViewer/OpenPagesWidget.py

branch
eric7
changeset 8683
e8a907801549
parent 8680
85503ff2fce9
child 8685
b0669ce1066d
--- a/eric7/HelpViewer/OpenPagesWidget.py	Tue Oct 12 21:55:56 2021 +0200
+++ b/eric7/HelpViewer/OpenPagesWidget.py	Wed Oct 13 18:15:30 2021 +0200
@@ -7,12 +7,14 @@
 Module implementing a widget showing the list of open pages.
 """
 
-from PyQt6.QtCore import pyqtSlot, pyqtSignal
+from PyQt6.QtCore import pyqtSlot, pyqtSignal, Qt, QPoint
+from PyQt6.QtGui import QGuiApplication, QClipboard
 from PyQt6.QtWidgets import (
-    QWidget, QLabel, QListWidget, QListWidgetItem, QVBoxLayout,
-    QAbstractItemView
+    QWidget, QLabel, QListWidget, QVBoxLayout, QAbstractItemView, QMenu
 )
 
+import UI.PixmapCache
+
 
 class OpenPagesWidget(QWidget):
     """
@@ -33,6 +35,8 @@
         super().__init__(parent)
         self.setObjectName("OpenPagesWidget")
         
+        self.__helpViewer = parent
+        
         self.__layout = QVBoxLayout()
         self.__layout.setContentsMargins(0, 0, 0, 0)
         
@@ -42,9 +46,13 @@
         self.__openPagesList = QListWidget(self)
         self.__openPagesList.setAlternatingRowColors(True)
         self.__openPagesList.setSelectionMode(
-            QAbstractItemView.SelectionMode.ExtendedSelection)
+            QAbstractItemView.SelectionMode.SingleSelection)
+        self.__openPagesList.setContextMenuPolicy(
+            Qt.ContextMenuPolicy.CustomContextMenu)
         self.__openPagesList.currentRowChanged.connect(
             self.__currentRowChanged)
+        self.__openPagesList.customContextMenuRequested.connect(
+            self.__showContextMenu)
         self.__layout.addWidget(self.__openPagesList)
         
         self.setLayout(self.__layout)
@@ -52,10 +60,44 @@
         self.__stack = stack
         self.__stack.currentChanged.connect(self.__currentPageChanged)
         
+        self.__initContextMenu()
+        
         self.__defaultFont = self.__openPagesList.font()
         self.__boldFont = self.__openPagesList.font()
         self.__boldFont.setBold(True)
     
+    def __initContextMenu(self):
+        """
+        Private method to initialize the context menu.
+        """
+        self.__menu = QMenu(self)
+        self.__menu.addAction(
+            UI.PixmapCache.getIcon("tabClose"),
+            self.tr('Close'), self.__contextMenuClose)
+        self.closeOthersMenuAct = self.__menu.addAction(
+            UI.PixmapCache.getIcon("tabCloseOther"),
+            self.tr("Close Others"),
+            self.__contextMenuCloseOthers)
+        self.__menu.addAction(
+            self.tr('Close All'), self.__contextMenuCloseAll)
+        self.__menu.addSeparator()
+        self.__copyUrlAct = self.__menu.addAction(
+            self.tr("Copy URL to Clipboard"),
+            self.__contextMenuCopyUrlToClipboard)
+    
+    @pyqtSlot(QPoint)
+    def __showContextMenu(self, point):
+        """
+        Private slot to handle the customContextMenuRequested signal of
+        the viewlist.
+        
+        @param point position to open the menu at
+        @type QPoint
+        """
+        itm = self.__openPagesList.itemAt(point)
+        self.__copyUrlAct.setEnabled(itm and itm.text() != "about:blank")
+        self.__menu.popup(self.__openPagesList.mapToGlobal(point))
+    
     @pyqtSlot(int)
     def __currentPageChanged(self, index):
         """
@@ -65,7 +107,7 @@
         @type int
         """
         for row in range(self.__openPagesList.count()):
-            itm = self.__openPagesList.item(index)
+            itm = self.__openPagesList.item(row)
             itm.setFont(
                 self.__boldFont if row == index else self.__defaultFont
             )
@@ -81,18 +123,47 @@
         self.__stack.setCurrentIndex(row)
         self.currentChanged.emit(row)
     
-    def addPage(self, viewer):
+    def addPage(self, viewer, background=False):
         """
         Public method to add a viewer page to our list.
         
         @param viewer reference to the viewer object
         @type HelpViewerImpl
+        @param background flag indicating to not change the current page
+            (defaults to False)
+        @type bool (optional)
         """
-        QListWidgetItem(viewer.title(), self.__openPagesList)
+        self.__openPagesList.addItem(viewer.title())
         viewer.titleChanged.connect(
             lambda: self.__viewerTitleChanged(viewer))
         
-        self.__currentPageChanged(self.__openPagesList.count() - 1)
+        if not background:
+            self.__openPagesList.setCurrentRow(
+                self.__openPagesList.count() - 1)
+        if self.__openPagesList.count() == 1:
+            self.__currentPageChanged(0)
+    
+    def insertPage(self, index, viewer, background=False):
+        """
+        Public method to insert a viewer page into our list.
+        
+        @param index index to insert at
+        @type int
+        @param viewer reference to the viewer object
+        @type HelpViewerImpl
+        @param background flag indicating to not change the current page
+            (defaults to False)
+        @type bool (optional)
+        """
+        currentRow = self.__openPagesList.currentRow()
+        self.__openPagesList.insertItem(index, viewer.title())
+        viewer.titleChanged.connect(
+            lambda: self.__viewerTitleChanged(viewer))
+        
+        if not background:
+            self.__openPagesList.setCurrentRow(index)
+        else:
+            self.__openPagesList.setCurrentRow(currentRow)
     
     def __viewerTitleChanged(self, viewer):
         """
@@ -105,3 +176,68 @@
         itm = self.__openPagesList.item(index)
         itm.setText(viewer.title())
         self.currentChanged.emit(index)
+    
+    #######################################################################
+    ## Context menu action methods
+    #######################################################################
+    
+    @pyqtSlot()
+    def __contextMenuClose(self):
+        """
+        Private slot to close a page.
+        """
+        row = self.__openPagesList.currentRow()
+        self.__removeViewer(row)
+        
+        if self.__openPagesList.count() == 0:
+            self.__helpViewer.addPage()
+    
+    @pyqtSlot()
+    def __contextMenuCloseOthers(self):
+        """
+        Private slot to close all other pages.
+        """
+        currentRow = self.__openPagesList.currentRow()
+        for row in range(self.__openPagesList.count() - 1, -1, -1):
+            if row != currentRow:
+                self.__removeViewer(row)
+    
+    @pyqtSlot()
+    def __contextMenuCloseAll(self):
+        """
+        Private slot to close all pages.
+        """
+        while self.__openPagesList.count() != 0:
+            self.__removeViewer(0)
+        self.__helpViewer.addPage()
+    
+    @pyqtSlot()
+    def __contextMenuCopyUrlToClipboard(self):
+        """
+        Private slot to copy the URL to the clipboard.
+        """
+        row = self.__openPagesList.currentRow()
+        viewer = self.__stack.widget(row)
+        url = viewer.url()
+        if url.isValid():
+            urlStr = url.toString()
+            
+            # copy the URL to both clipboard areas
+            QGuiApplication.clipboard().setText(
+                urlStr, QClipboard.Mode.Clipboard)
+            QGuiApplication.clipboard().setText(
+                urlStr, QClipboard.Mode.Selection)
+    
+    def __removeViewer(self, row):
+        """
+        Private method to remove a viewer page.
+        
+        @param row row associated with the viewer
+        @type int
+        """
+        viewer = self.__stack.widget(row)
+        self.__stack.removeWidget(viewer)
+        viewer.deleteLater()
+        
+        itm = self.__openPagesList.takeItem(row)
+        del itm

eric ide

mercurial