|
1 # -*- coding: utf-8 -*- |
|
2 |
|
3 # Copyright (c) 2009 - 2016 Detlev Offenbach <detlev@die-offenbachs.de> |
|
4 # |
|
5 |
|
6 """ |
|
7 Module implementing the bookmarks menu. |
|
8 """ |
|
9 |
|
10 from __future__ import unicode_literals |
|
11 |
|
12 from PyQt5.QtCore import pyqtSignal, Qt, QUrl |
|
13 from PyQt5.QtGui import QCursor |
|
14 from PyQt5.QtWidgets import QMenu |
|
15 |
|
16 from E5Gui.E5ModelMenu import E5ModelMenu |
|
17 |
|
18 from .BookmarksModel import BookmarksModel |
|
19 from .BookmarkNode import BookmarkNode |
|
20 |
|
21 |
|
22 class BookmarksMenu(E5ModelMenu): |
|
23 """ |
|
24 Class implementing the bookmarks menu base class. |
|
25 |
|
26 @signal openUrl(QUrl, str) emitted to open a URL with the given title in |
|
27 the current tab |
|
28 @signal newUrl(QUrl, str) emitted to open a URL with the given title in a |
|
29 new tab |
|
30 """ |
|
31 openUrl = pyqtSignal(QUrl, str) |
|
32 newUrl = pyqtSignal(QUrl, str) |
|
33 |
|
34 def __init__(self, parent=None): |
|
35 """ |
|
36 Constructor |
|
37 |
|
38 @param parent reference to the parent widget (QWidget) |
|
39 """ |
|
40 E5ModelMenu.__init__(self, parent) |
|
41 |
|
42 self.activated.connect(self.__activated) |
|
43 self.setStatusBarTextRole(BookmarksModel.UrlStringRole) |
|
44 self.setSeparatorRole(BookmarksModel.SeparatorRole) |
|
45 |
|
46 self.setContextMenuPolicy(Qt.CustomContextMenu) |
|
47 self.customContextMenuRequested.connect(self.__contextMenuRequested) |
|
48 |
|
49 def createBaseMenu(self): |
|
50 """ |
|
51 Public method to get the menu that is used to populate sub menu's. |
|
52 |
|
53 @return reference to the menu (BookmarksMenu) |
|
54 """ |
|
55 menu = BookmarksMenu(self) |
|
56 menu.openUrl.connect(self.openUrl) |
|
57 menu.newUrl.connect(self.newUrl) |
|
58 return menu |
|
59 |
|
60 def __activated(self, idx): |
|
61 """ |
|
62 Private slot handling the activated signal. |
|
63 |
|
64 @param idx index of the activated item (QModelIndex) |
|
65 """ |
|
66 if self._keyboardModifiers & Qt.ControlModifier: |
|
67 self.newUrl.emit( |
|
68 idx.data(BookmarksModel.UrlRole), |
|
69 idx.data(Qt.DisplayRole)) |
|
70 else: |
|
71 self.openUrl.emit( |
|
72 idx.data(BookmarksModel.UrlRole), |
|
73 idx.data(Qt.DisplayRole)) |
|
74 self.resetFlags() |
|
75 |
|
76 def postPopulated(self): |
|
77 """ |
|
78 Public method to add any actions after the tree. |
|
79 """ |
|
80 if self.isEmpty(): |
|
81 return |
|
82 |
|
83 parent = self.rootIndex() |
|
84 |
|
85 hasBookmarks = False |
|
86 |
|
87 for i in range(parent.model().rowCount(parent)): |
|
88 child = parent.model().index(i, 0, parent) |
|
89 |
|
90 if child.data(BookmarksModel.TypeRole) == BookmarkNode.Bookmark: |
|
91 hasBookmarks = True |
|
92 break |
|
93 |
|
94 if not hasBookmarks: |
|
95 return |
|
96 |
|
97 self.addSeparator() |
|
98 act = self.addAction(self.tr("Open all in Tabs")) |
|
99 act.triggered.connect(self.openAll) |
|
100 |
|
101 def openAll(self): |
|
102 """ |
|
103 Public slot to open all the menu's items. |
|
104 """ |
|
105 menu = self.sender().parent() |
|
106 if menu is None: |
|
107 return |
|
108 |
|
109 parent = menu.rootIndex() |
|
110 if not parent.isValid(): |
|
111 return |
|
112 |
|
113 for i in range(parent.model().rowCount(parent)): |
|
114 child = parent.model().index(i, 0, parent) |
|
115 |
|
116 if child.data(BookmarksModel.TypeRole) != BookmarkNode.Bookmark: |
|
117 continue |
|
118 |
|
119 if i == 0: |
|
120 self.openUrl.emit( |
|
121 child.data(BookmarksModel.UrlRole), |
|
122 child.data(Qt.DisplayRole)) |
|
123 else: |
|
124 self.newUrl.emit( |
|
125 child.data(BookmarksModel.UrlRole), |
|
126 child.data(Qt.DisplayRole)) |
|
127 |
|
128 def __contextMenuRequested(self, pos): |
|
129 """ |
|
130 Private slot to handle the context menu request. |
|
131 |
|
132 @param pos position the context menu shall be shown (QPoint) |
|
133 """ |
|
134 act = self.actionAt(pos) |
|
135 |
|
136 if act is not None and \ |
|
137 act.menu() is None and \ |
|
138 self.index(act).isValid(): |
|
139 menu = QMenu() |
|
140 v = act.data() |
|
141 |
|
142 menuAction = menu.addAction( |
|
143 self.tr("&Open"), self.__openBookmark) |
|
144 menuAction.setData(v) |
|
145 menuAction = menu.addAction( |
|
146 self.tr("Open in New &Tab\tCtrl+LMB"), |
|
147 self.__openBookmarkInNewTab) |
|
148 menuAction.setData(v) |
|
149 menu.addSeparator() |
|
150 |
|
151 menuAction = menu.addAction( |
|
152 self.tr("&Remove"), self.__removeBookmark) |
|
153 menuAction.setData(v) |
|
154 menu.addSeparator() |
|
155 |
|
156 menuAction = menu.addAction( |
|
157 self.tr("&Properties..."), self.__edit) |
|
158 menuAction.setData(v) |
|
159 |
|
160 execAct = menu.exec_(QCursor.pos()) |
|
161 if execAct is not None: |
|
162 self.close() |
|
163 parent = self.parent() |
|
164 while parent is not None and isinstance(parent, QMenu): |
|
165 parent.close() |
|
166 parent = parent.parent() |
|
167 |
|
168 def __openBookmark(self): |
|
169 """ |
|
170 Private slot to open a bookmark in the current browser tab. |
|
171 """ |
|
172 idx = self.index(self.sender()) |
|
173 |
|
174 self.openUrl.emit( |
|
175 idx.data(BookmarksModel.UrlRole), |
|
176 idx.data(Qt.DisplayRole)) |
|
177 |
|
178 def __openBookmarkInNewTab(self): |
|
179 """ |
|
180 Private slot to open a bookmark in a new browser tab. |
|
181 """ |
|
182 idx = self.index(self.sender()) |
|
183 |
|
184 self.newUrl.emit( |
|
185 idx.data(BookmarksModel.UrlRole), |
|
186 idx.data(Qt.DisplayRole)) |
|
187 |
|
188 def __removeBookmark(self): |
|
189 """ |
|
190 Private slot to remove a bookmark. |
|
191 """ |
|
192 idx = self.index(self.sender()) |
|
193 self.removeEntry(idx) |
|
194 |
|
195 def __edit(self): |
|
196 """ |
|
197 Private slot to edit a bookmarks properties. |
|
198 """ |
|
199 from .BookmarkPropertiesDialog import BookmarkPropertiesDialog |
|
200 |
|
201 idx = self.index(self.sender()) |
|
202 node = self.model().node(idx) |
|
203 dlg = BookmarkPropertiesDialog(node) |
|
204 dlg.exec_() |
|
205 |
|
206 ############################################################################## |
|
207 |
|
208 |
|
209 class BookmarksMenuBarMenu(BookmarksMenu): |
|
210 """ |
|
211 Class implementing a dynamically populated menu for bookmarks. |
|
212 |
|
213 @signal openUrl(QUrl, str) emitted to open a URL with the given title in |
|
214 the current tab |
|
215 """ |
|
216 openUrl = pyqtSignal(QUrl, str) |
|
217 |
|
218 def __init__(self, parent=None): |
|
219 """ |
|
220 Constructor |
|
221 |
|
222 @param parent reference to the parent widget (QWidget) |
|
223 """ |
|
224 BookmarksMenu.__init__(self, parent) |
|
225 |
|
226 self.__bookmarksManager = None |
|
227 self.__initialActions = [] |
|
228 |
|
229 def prePopulated(self): |
|
230 """ |
|
231 Public method to add any actions before the tree. |
|
232 |
|
233 @return flag indicating if any actions were added (boolean) |
|
234 """ |
|
235 import WebBrowser.WebBrowserWindow |
|
236 |
|
237 self.__bookmarksManager = WebBrowser.WebBrowserWindow.WebBrowserWindow\ |
|
238 .bookmarksManager() |
|
239 self.setModel(self.__bookmarksManager.bookmarksModel()) |
|
240 self.setRootIndex(self.__bookmarksManager.bookmarksModel() |
|
241 .nodeIndex(self.__bookmarksManager.menu())) |
|
242 |
|
243 # initial actions |
|
244 for act in self.__initialActions: |
|
245 if act == "--SEPARATOR--": |
|
246 self.addSeparator() |
|
247 else: |
|
248 self.addAction(act) |
|
249 if len(self.__initialActions) != 0: |
|
250 self.addSeparator() |
|
251 |
|
252 self.createMenu( |
|
253 self.__bookmarksManager.bookmarksModel() |
|
254 .nodeIndex(self.__bookmarksManager.toolbar()), |
|
255 1, self) |
|
256 return True |
|
257 |
|
258 def postPopulated(self): |
|
259 """ |
|
260 Public method to add any actions after the tree. |
|
261 """ |
|
262 if self.isEmpty(): |
|
263 return |
|
264 |
|
265 parent = self.rootIndex() |
|
266 |
|
267 hasBookmarks = False |
|
268 |
|
269 for i in range(parent.model().rowCount(parent)): |
|
270 child = parent.model().index(i, 0, parent) |
|
271 |
|
272 if child.data(BookmarksModel.TypeRole) == BookmarkNode.Bookmark: |
|
273 hasBookmarks = True |
|
274 break |
|
275 |
|
276 if not hasBookmarks: |
|
277 return |
|
278 |
|
279 self.addSeparator() |
|
280 act = self.addAction(self.tr("Default Home Page")) |
|
281 act.setData("eric:home") |
|
282 act.triggered.connect(self.__defaultBookmarkTriggered) |
|
283 act = self.addAction(self.tr("Speed Dial")) |
|
284 act.setData("eric:speeddial") |
|
285 act.triggered.connect(self.__defaultBookmarkTriggered) |
|
286 self.addSeparator() |
|
287 act = self.addAction(self.tr("Open all in Tabs")) |
|
288 act.triggered.connect(self.openAll) |
|
289 |
|
290 def setInitialActions(self, actions): |
|
291 """ |
|
292 Public method to set the list of actions that should appear first in |
|
293 the menu. |
|
294 |
|
295 @param actions list of initial actions (list of QAction) |
|
296 """ |
|
297 self.__initialActions = actions[:] |
|
298 for act in self.__initialActions: |
|
299 self.addAction(act) |
|
300 |
|
301 def __defaultBookmarkTriggered(self): |
|
302 """ |
|
303 Private slot handling the default bookmark menu entries. |
|
304 """ |
|
305 act = self.sender() |
|
306 urlStr = act.data() |
|
307 if urlStr.startswith("eric:"): |
|
308 self.openUrl.emit(QUrl(urlStr), "") |