Helpviewer/History/HistoryMenu.py

changeset 0
de9c2efb9d02
child 7
c679fb30c8f3
equal deleted inserted replaced
-1:000000000000 0:de9c2efb9d02
1 # -*- coding: utf-8 -*-
2
3 # Copyright (c) 2009 Detlev Offenbach <detlev@die-offenbachs.de>
4 #
5
6 """
7 Module implementing the history menu.
8 """
9
10 import sys
11
12 from PyQt4.QtCore import *
13 from PyQt4.QtGui import *
14
15 from E4Gui.E4ModelMenu import E4ModelMenu
16
17 import Helpviewer.HelpWindow
18
19 from HistoryModel import HistoryModel
20 from HistoryDialog import HistoryDialog
21
22 import UI.PixmapCache
23
24 class HistoryMenuModel(QAbstractProxyModel):
25 """
26 Class implementing a model for the history menu.
27
28 It maps the first bunch of items of the source model to the root.
29 """
30 MOVEDROWS = 15
31
32 def __init__(self, sourceModel, parent = None):
33 """
34 Constructor
35
36 @param sourceModel reference to the source model (QAbstractItemModel)
37 @param parent reference to the parent object (QObject)
38 """
39 QAbstractProxyModel.__init__(self, parent)
40
41 self.__treeModel = sourceModel
42
43 self.setSourceModel(sourceModel)
44
45 def bumpedRows(self):
46 """
47 Public method to determine the number of rows moved to the root.
48
49 @return number of rows moved to the root (integer)
50 """
51 first = self.__treeModel.index(0, 0)
52 if not first.isValid():
53 return 0
54 return min(self.__treeModel.rowCount(first), self.MOVEDROWS)
55
56 def columnCount(self, parent = QModelIndex()):
57 """
58 Public method to get the number of columns.
59
60 @param parent index of parent (QModelIndex)
61 @return number of columns (integer)
62 """
63 return self.__treeModel.columnCount(self.mapToSource(parent))
64
65 def rowCount(self, parent = QModelIndex()):
66 """
67 Public method to determine the number of rows.
68
69 @param parent index of parent (QModelIndex)
70 @return number of rows (integer)
71 """
72 if parent.column() > 0:
73 return 0
74
75 if not parent.isValid():
76 folders = self.sourceModel().rowCount()
77 bumpedItems = self.bumpedRows()
78 if bumpedItems <= self.MOVEDROWS and \
79 bumpedItems == self.sourceModel().rowCount(self.sourceModel().index(0, 0)):
80 folders -= 1
81 return bumpedItems + folders
82
83 if parent.internalId() == sys.maxint:
84 if parent.row() < self.bumpedRows():
85 return 0
86
87 idx = self.mapToSource(parent)
88 defaultCount = self.sourceModel().rowCount(idx)
89 if idx == self.sourceModel().index(0, 0):
90 return defaultCount - self.bumpedRows()
91
92 return defaultCount
93
94 def mapFromSource(self, sourceIndex):
95 """
96 Public method to map an index to the proxy model index.
97
98 @param sourceIndex reference to a source model index (QModelIndex)
99 @return proxy model index (QModelIndex)
100 """
101 assert False
102 sourceRow = self.__treeModel.mapToSource(sourceIndex).row()
103 return self.createIndex(sourceIndex.row(), sourceIndex.column(), sourceRow)
104
105 def mapToSource(self, proxyIndex):
106 """
107 Public method to map an index to the source model index.
108
109 @param proxyIndex reference to a proxy model index (QModelIndex)
110 @return source model index (QModelIndex)
111 """
112 if not proxyIndex.isValid():
113 return QModelIndex()
114
115 if proxyIndex.internalId() == sys.maxint:
116 bumpedItems = self.bumpedRows()
117 if proxyIndex.row() < bumpedItems:
118 return self.__treeModel.index(proxyIndex.row(), proxyIndex.column(),
119 self.__treeModel.index(0, 0))
120 if bumpedItems <= self.MOVEDROWS and \
121 bumpedItems == self.sourceModel().rowCount(self.__treeModel.index(0, 0)):
122 bumpedItems -= 1
123 return self.__treeModel.index(proxyIndex.row() - bumpedItems,
124 proxyIndex.column())
125
126 historyIndex = self.__treeModel.sourceModel()\
127 .index(proxyIndex.internalId(), proxyIndex.column())
128 treeIndex = self.__treeModel.mapFromSource(historyIndex)
129 return treeIndex
130
131 def index(self, row, column, parent = QModelIndex()):
132 """
133 Public method to create an index.
134
135 @param row row number for the index (integer)
136 @param column column number for the index (integer)
137 @param parent index of the parent item (QModelIndex)
138 @return requested index (QModelIndex)
139 """
140 if row < 0 or \
141 column < 0 or \
142 column >= self.columnCount(parent) or \
143 parent.column() > 0:
144 return QModelIndex()
145
146 if not parent.isValid():
147 return self.createIndex(row, column, sys.maxint)
148
149 treeIndexParent = self.mapToSource(parent)
150
151 bumpedItems = 0
152 if treeIndexParent == self.sourceModel().index(0, 0):
153 bumpedItems = self.bumpedRows()
154 treeIndex = self.__treeModel.index(row + bumpedItems, column, treeIndexParent)
155 historyIndex = self.__treeModel.mapToSource(treeIndex)
156 historyRow = historyIndex.row()
157 if historyRow == -1:
158 historyRow = treeIndex.row()
159 return self.createIndex(row, column, historyRow)
160
161 def parent(self, index):
162 """
163 Public method to get the parent index.
164
165 @param index index of item to get parent (QModelIndex)
166 @return index of parent (QModelIndex)
167 """
168 offset = index.internalId()
169 if offset == sys.maxint or not index.isValid():
170 return QModelIndex()
171
172 historyIndex = self.__treeModel.sourceModel().index(index.internalId(), 0)
173 treeIndex = self.__treeModel.mapFromSource(historyIndex)
174 treeIndexParent = treeIndex.parent()
175
176 soureRow = self.sourceModel().mapToSource(treeIndexParent).row()
177 bumpedItems = self.bumpedRows()
178 if bumpedItems <= self.MOVEDROWS and \
179 bumpedItems == self.sourceModel().rowCount(self.sourceModel().index(0, 0)):
180 bumpedItems -= 1
181
182 return self.createIndex(bumpedItems + treeIndexParent.row(),
183 treeIndexParent.column(),
184 sourceRow)
185
186 def mimeData(self, indexes):
187 """
188 Public method to return the mime data.
189
190 @param indexes list of indexes (QModelIndexList)
191 @return mime data (QMimeData)
192 """
193 urls = []
194 for index in indexes:
195 url = index.data(HistoryModel.UrlRole).toUrl()
196 urls.append(url)
197
198 mdata = QMimeData()
199 mdata.setUrls(urls)
200 return mdata
201
202 class HistoryMenu(E4ModelMenu):
203 """
204 Class implementing the history menu.
205
206 @signal openUrl(const QUrl&, const QString&) emitted to open a URL in the current
207 tab
208 @signal newUrl(const QUrl&, const QString&) emitted to open a URL in a new tab
209 """
210 def __init__(self, parent = None):
211 """
212 Constructor
213
214 @param parent reference to the parent widget (QWidget)
215 """
216 E4ModelMenu.__init__(self, parent)
217
218 self.__historyManager = None
219 self.__historyMenuModel = None
220 self.__initialActions = []
221
222 self.setMaxRows(7)
223
224 self.connect(self, SIGNAL("activated(const QModelIndex&)"), self.__activated)
225 self.setStatusBarTextRole(HistoryModel.UrlStringRole)
226
227 def __activated(self, idx):
228 """
229 Private slot handling the activated signal.
230
231 @param idx index of the activated item (QModelIndex)
232 """
233 if self._keyboardModifiers & Qt.ControlModifier:
234 self.emit(SIGNAL("newUrl(const QUrl&, const QString&)"),
235 idx.data(HistoryModel.UrlRole).toUrl(),
236 idx.data(HistoryModel.TitleRole).toString())
237 else:
238 self.emit(SIGNAL("openUrl(const QUrl&, const QString&)"),
239 idx.data(HistoryModel.UrlRole).toUrl(),
240 idx.data(HistoryModel.TitleRole).toString())
241
242 def prePopulated(self):
243 """
244 Public method to add any actions before the tree.
245
246 @return flag indicating if any actions were added (boolean)
247 """
248 if self.__historyManager is None:
249 self.__historyManager = Helpviewer.HelpWindow.HelpWindow.historyManager()
250 self.__historyMenuModel = \
251 HistoryMenuModel(self.__historyManager.historyTreeModel(), self)
252 self.setModel(self.__historyMenuModel)
253
254 # initial actions
255 for act in self.__initialActions:
256 self.addAction(act)
257 if len(self.__initialActions) != 0:
258 self.addSeparator()
259 self.setFirstSeparator(self.__historyMenuModel.bumpedRows())
260
261 return False
262
263 def postPopulated(self):
264 """
265 Public method to add any actions after the tree.
266 """
267 if len(self.__historyManager.history()) > 0:
268 self.addSeparator()
269
270 act = self.addAction(UI.PixmapCache.getIcon("history.png"),
271 self.trUtf8("Show All History..."))
272 self.connect(act, SIGNAL("triggered()"), self.__showHistoryDialog)
273 act = self.addAction(UI.PixmapCache.getIcon("historyClear.png"),
274 self.trUtf8("Clear History..."))
275 self.connect(act, SIGNAL("triggered()"), self.__clearHistoryDialog)
276
277 def setInitialActions(self, actions):
278 """
279 Public method to set the list of actions that should appear first in the menu.
280
281 @param actions list of initial actions (list of QAction)
282 """
283 self.__initialActions = actions[:]
284 for act in self.__initialActions:
285 self.addAction(act)
286
287 def __showHistoryDialog(self):
288 """
289 Private slot to show the history dialog.
290 """
291 dlg = HistoryDialog(self)
292 dlg.setAttribute(Qt.WA_DeleteOnClose)
293 self.connect(dlg, SIGNAL("newUrl(const QUrl&, const QString&)"),
294 self, SIGNAL("newUrl(const QUrl&, const QString&)"))
295 self.connect(dlg, SIGNAL("openUrl(const QUrl&, const QString&)"),
296 self, SIGNAL("openUrl(const QUrl&, const QString&)"))
297 dlg.show()
298
299 def __clearHistoryDialog(self):
300 """
301 Private slot to clear the history.
302 """
303 if self.__historyManager is not None and \
304 QMessageBox.question(None,
305 self.trUtf8("Clear History"),
306 self.trUtf8("""Do you want to clear the history?"""),
307 QMessageBox.StandardButtons(\
308 QMessageBox.No | \
309 QMessageBox.Yes),
310 QMessageBox.No) == QMessageBox.Yes:
311 self.__historyManager.clear()

eric ide

mercurial