src/eric7/HelpViewer/OpenPagesWidget.py

branch
eric7
changeset 9209
b99e7fd55fd3
parent 8898
cf11386c25ec
child 9221
bf71ee032bb4
equal deleted inserted replaced
9208:3fc8dfeb6ebe 9209:b99e7fd55fd3
1 # -*- coding: utf-8 -*-
2
3 # Copyright (c) 2021 - 2022 Detlev Offenbach <detlev@die-offenbachs.de>
4 #
5
6 """
7 Module implementing a widget showing the list of open pages.
8 """
9
10 from PyQt6.QtCore import pyqtSlot, pyqtSignal, Qt, QPoint
11 from PyQt6.QtGui import QGuiApplication, QClipboard
12 from PyQt6.QtWidgets import QListWidget, QAbstractItemView, QMenu
13
14 import UI.PixmapCache
15
16
17 class OpenPagesWidget(QListWidget):
18 """
19 Class implementing a widget showing the list of open pages.
20
21 @signal currentPageChanged(index) emitted to signal a change of the current
22 page index
23 """
24 currentPageChanged = pyqtSignal(int)
25
26 def __init__(self, stack, parent=None):
27 """
28 Constructor
29
30 @param stack reference to the stack widget containing the open
31 help pages
32 @type QStackedWidget
33 @param parent reference to the parent widget (defaults to None)
34 @type QWidget (optional)
35 """
36 super().__init__(parent)
37 self.setObjectName("OpenPagesWidget")
38
39 self.__helpViewer = parent
40
41 self.setAlternatingRowColors(True)
42 self.setSelectionMode(
43 QAbstractItemView.SelectionMode.SingleSelection)
44 self.setContextMenuPolicy(
45 Qt.ContextMenuPolicy.CustomContextMenu)
46 self.currentRowChanged.connect(
47 self.__currentRowChanged)
48 self.customContextMenuRequested.connect(
49 self.__showContextMenu)
50
51 self.__stack = stack
52 self.__stack.currentChanged.connect(self.__currentPageChanged)
53
54 self.__initContextMenu()
55
56 self.__defaultFont = self.font()
57 self.__boldFont = self.font()
58 self.__boldFont.setBold(True)
59
60 def __initContextMenu(self):
61 """
62 Private method to initialize the context menu.
63 """
64 self.__menu = QMenu(self)
65 self.__menu.addAction(
66 UI.PixmapCache.getIcon("tabClose"),
67 self.tr('Close'), self.__contextMenuClose)
68 self.closeOthersMenuAct = self.__menu.addAction(
69 UI.PixmapCache.getIcon("tabCloseOther"),
70 self.tr("Close Others"),
71 self.__contextMenuCloseOthers)
72 self.__menu.addAction(
73 self.tr('Close All'), self.__contextMenuCloseAll)
74 self.__menu.addSeparator()
75 self.__copyUrlAct = self.__menu.addAction(
76 self.tr("Copy URL to Clipboard"),
77 self.__contextMenuCopyUrlToClipboard)
78
79 @pyqtSlot(QPoint)
80 def __showContextMenu(self, point):
81 """
82 Private slot to handle the customContextMenuRequested signal of
83 the viewlist.
84
85 @param point position to open the menu at
86 @type QPoint
87 """
88 itm = self.itemAt(point)
89 self.__copyUrlAct.setEnabled(bool(itm) and itm.text() != "about:blank")
90 self.closeOthersMenuAct.setEnabled(self.count() > 1)
91 self.__menu.popup(self.mapToGlobal(point))
92
93 @pyqtSlot(int)
94 def __currentPageChanged(self, index):
95 """
96 Private slot to handle a change of the shown page.
97
98 @param index index of the current page
99 @type int
100 """
101 for row in range(self.count()):
102 itm = self.item(row)
103 itm.setFont(
104 self.__boldFont if row == index else self.__defaultFont
105 )
106
107 @pyqtSlot(int)
108 def __currentRowChanged(self, row):
109 """
110 Private slot handling a change of the current row.
111
112 @param row current row
113 @type int
114 """
115 self.__stack.setCurrentIndex(row)
116 self.currentPageChanged.emit(row)
117
118 def addPage(self, viewer, background=False):
119 """
120 Public method to add a viewer page to our list.
121
122 @param viewer reference to the viewer object
123 @type HelpViewerImpl
124 @param background flag indicating to not change the current page
125 (defaults to False)
126 @type bool (optional)
127 """
128 self.addItem(viewer.pageTitle())
129 viewer.titleChanged.connect(
130 lambda: self.__viewerTitleChanged(viewer))
131
132 if not background:
133 self.setCurrentRow(
134 self.count() - 1)
135 if self.count() == 1:
136 self.__currentPageChanged(0)
137
138 def insertPage(self, index, viewer, background=False):
139 """
140 Public method to insert a viewer page into our list.
141
142 @param index index to insert at
143 @type int
144 @param viewer reference to the viewer object
145 @type HelpViewerImpl
146 @param background flag indicating to not change the current page
147 (defaults to False)
148 @type bool (optional)
149 """
150 currentRow = self.currentRow()
151 self.insertItem(index, viewer.pageTitle())
152 viewer.titleChanged.connect(
153 lambda: self.__viewerTitleChanged(viewer))
154
155 if not background:
156 self.setCurrentRow(index)
157 else:
158 self.setCurrentRow(currentRow)
159
160 def __viewerTitleChanged(self, viewer):
161 """
162 Private method to handle the change of a viewer title.
163
164 @param viewer reference to the viewer that change title
165 @type HelpViewerImpl
166 """
167 index = self.__stack.indexOf(viewer)
168 itm = self.item(index)
169 itm.setText(viewer.pageTitle())
170 self.currentPageChanged.emit(index)
171
172 #######################################################################
173 ## Context menu action methods
174 #######################################################################
175
176 @pyqtSlot()
177 def __contextMenuClose(self):
178 """
179 Private slot to close a page via the context menu.
180 """
181 self.closeCurrentPage()
182
183 @pyqtSlot()
184 def __contextMenuCloseOthers(self):
185 """
186 Private slot to close all other pages via the context menu.
187 """
188 self.closeOtherPages()
189
190 @pyqtSlot()
191 def __contextMenuCloseAll(self):
192 """
193 Private slot to close all pages via the context menu.
194 """
195 self.closeAllPages()
196
197 @pyqtSlot()
198 def __contextMenuCopyUrlToClipboard(self):
199 """
200 Private slot to copy the URL to the clipboard.
201 """
202 row = self.currentRow()
203 viewer = self.__stack.widget(row)
204 url = viewer.link()
205 if url.isValid():
206 urlStr = url.toString()
207
208 # copy the URL to both clipboard areas
209 QGuiApplication.clipboard().setText(
210 urlStr, QClipboard.Mode.Clipboard)
211 QGuiApplication.clipboard().setText(
212 urlStr, QClipboard.Mode.Selection)
213
214 def __removeViewer(self, row):
215 """
216 Private method to remove a viewer page.
217
218 @param row row associated with the viewer
219 @type int
220 """
221 viewer = self.__stack.widget(row)
222 self.__stack.removeWidget(viewer)
223 viewer.deleteLater()
224
225 itm = self.takeItem(row)
226 del itm
227
228 #######################################################################
229 ## Slots for external access below
230 #######################################################################
231
232 @pyqtSlot()
233 def closeCurrentPage(self):
234 """
235 Public slot to close the current page.
236 """
237 row = self.currentRow()
238 self.__removeViewer(row)
239
240 if self.count() == 0:
241 self.__helpViewer.addPage()
242
243 @pyqtSlot()
244 def closeOtherPages(self):
245 """
246 Public slot to close all other pages.
247 """
248 currentRow = self.currentRow()
249 for row in range(self.count() - 1, -1, -1):
250 if row != currentRow:
251 self.__removeViewer(row)
252
253 @pyqtSlot()
254 def closeAllPages(self):
255 """
256 Public slot to close all pages.
257 """
258 while self.count() != 0:
259 self.__removeViewer(0)
260 self.__helpViewer.addPage()

eric ide

mercurial