eric6/Helpviewer/Bookmarks/BookmarksDialog.py

changeset 6942
2602857055c5
parent 6645
ad476851d7e0
equal deleted inserted replaced
6941:f99d60d6b59b 6942:2602857055c5
1 # -*- coding: utf-8 -*-
2
3 # Copyright (c) 2009 - 2019 Detlev Offenbach <detlev@die-offenbachs.de>
4 #
5
6 """
7 Module implementing a dialog to manage bookmarks.
8 """
9
10 from __future__ import unicode_literals
11
12 from PyQt5.QtCore import pyqtSignal, Qt, QUrl, QModelIndex
13 from PyQt5.QtGui import QFontMetrics, QCursor
14 from PyQt5.QtWidgets import QDialog, QMenu, QApplication
15
16 from E5Gui.E5TreeSortFilterProxyModel import E5TreeSortFilterProxyModel
17
18 from .Ui_BookmarksDialog import Ui_BookmarksDialog
19
20
21 class BookmarksDialog(QDialog, Ui_BookmarksDialog):
22 """
23 Class implementing a dialog to manage bookmarks.
24
25 @signal openUrl(QUrl, str) emitted to open a URL in the current tab
26 @signal newUrl(QUrl, str) emitted to open a URL in a new tab
27 """
28 openUrl = pyqtSignal(QUrl, str)
29 newUrl = pyqtSignal(QUrl, str)
30
31 def __init__(self, parent=None, manager=None):
32 """
33 Constructor
34
35 @param parent reference to the parent widget (QWidget
36 @param manager reference to the bookmarks manager object
37 (BookmarksManager)
38 """
39 super(BookmarksDialog, self).__init__(parent)
40 self.setupUi(self)
41 self.setWindowFlags(Qt.Window)
42
43 self.__bookmarksManager = manager
44 if self.__bookmarksManager is None:
45 import Helpviewer.HelpWindow
46 self.__bookmarksManager = Helpviewer.HelpWindow.HelpWindow\
47 .bookmarksManager()
48
49 self.__bookmarksModel = self.__bookmarksManager.bookmarksModel()
50 self.__proxyModel = E5TreeSortFilterProxyModel(self)
51 self.__proxyModel.setFilterKeyColumn(-1)
52 self.__proxyModel.setSourceModel(self.__bookmarksModel)
53
54 self.searchEdit.textChanged.connect(
55 self.__proxyModel.setFilterFixedString)
56
57 self.bookmarksTree.setModel(self.__proxyModel)
58 self.bookmarksTree.setExpanded(self.__proxyModel.index(0, 0), True)
59 fm = QFontMetrics(self.font())
60 header = fm.width("m") * 40
61 self.bookmarksTree.header().resizeSection(0, header)
62 self.bookmarksTree.header().setStretchLastSection(True)
63 self.bookmarksTree.setContextMenuPolicy(Qt.CustomContextMenu)
64
65 self.bookmarksTree.activated.connect(self.__activated)
66 self.bookmarksTree.customContextMenuRequested.connect(
67 self.__customContextMenuRequested)
68
69 self.removeButton.clicked.connect(
70 self.bookmarksTree.removeSelected)
71 self.addFolderButton.clicked.connect(self.__newFolder)
72
73 self.__expandNodes(self.__bookmarksManager.bookmarks())
74
75 def closeEvent(self, evt):
76 """
77 Protected method to handle the closing of the dialog.
78
79 @param evt reference to the event object (QCloseEvent) (ignored)
80 """
81 self.__shutdown()
82
83 def reject(self):
84 """
85 Public method called when the dialog is rejected.
86 """
87 self.__shutdown()
88 super(BookmarksDialog, self).reject()
89
90 def __shutdown(self):
91 """
92 Private method to perform shutdown actions for the dialog.
93 """
94 if self.__saveExpandedNodes(self.bookmarksTree.rootIndex()):
95 self.__bookmarksManager.changeExpanded()
96
97 def __saveExpandedNodes(self, parent):
98 """
99 Private method to save the child nodes of an expanded node.
100
101 @param parent index of the parent node (QModelIndex)
102 @return flag indicating a change (boolean)
103 """
104 changed = False
105 for row in range(self.__proxyModel.rowCount(parent)):
106 child = self.__proxyModel.index(row, 0, parent)
107 sourceIndex = self.__proxyModel.mapToSource(child)
108 childNode = self.__bookmarksModel.node(sourceIndex)
109 wasExpanded = childNode.expanded
110 if self.bookmarksTree.isExpanded(child):
111 childNode.expanded = True
112 changed |= self.__saveExpandedNodes(child)
113 else:
114 childNode.expanded = False
115 changed |= (wasExpanded != childNode.expanded)
116
117 return changed
118
119 def __expandNodes(self, node):
120 """
121 Private method to expand all child nodes of a node.
122
123 @param node reference to the bookmark node to expand (BookmarkNode)
124 """
125 for childNode in node.children():
126 if childNode.expanded:
127 idx = self.__bookmarksModel.nodeIndex(childNode)
128 idx = self.__proxyModel.mapFromSource(idx)
129 self.bookmarksTree.setExpanded(idx, True)
130 self.__expandNodes(childNode)
131
132 def __customContextMenuRequested(self, pos):
133 """
134 Private slot to handle the context menu request for the bookmarks tree.
135
136 @param pos position the context menu was requested (QPoint)
137 """
138 from .BookmarkNode import BookmarkNode
139
140 menu = QMenu()
141 idx = self.bookmarksTree.indexAt(pos)
142 idx = idx.sibling(idx.row(), 0)
143 sourceIndex = self.__proxyModel.mapToSource(idx)
144 node = self.__bookmarksModel.node(sourceIndex)
145 if idx.isValid() and node.type() != BookmarkNode.Folder:
146 menu.addAction(
147 self.tr("&Open"), self.__openBookmarkInCurrentTab)
148 menu.addAction(
149 self.tr("Open in New &Tab"), self.__openBookmarkInNewTab)
150 menu.addSeparator()
151 act = menu.addAction(self.tr("Edit &Name"), self.__editName)
152 act.setEnabled(idx.flags() & Qt.ItemIsEditable)
153 if idx.isValid() and node.type() != BookmarkNode.Folder:
154 menu.addAction(self.tr("Edit &Address"), self.__editAddress)
155 menu.addSeparator()
156 act = menu.addAction(
157 self.tr("&Delete"), self.bookmarksTree.removeSelected)
158 act.setEnabled(idx.flags() & Qt.ItemIsDragEnabled)
159 menu.addSeparator()
160 act = menu.addAction(self.tr("&Properties..."), self.__edit)
161 act.setEnabled(idx.flags() & Qt.ItemIsEditable)
162 menu.exec_(QCursor.pos())
163
164 def __activated(self, idx):
165 """
166 Private slot to handle the activation of an entry.
167
168 @param idx reference to the entry index (QModelIndex)
169 """
170 self.__openBookmark(
171 QApplication.keyboardModifiers() & Qt.ControlModifier)
172
173 def __openBookmarkInCurrentTab(self):
174 """
175 Private slot to open a bookmark in the current browser tab.
176 """
177 self.__openBookmark(False)
178
179 def __openBookmarkInNewTab(self):
180 """
181 Private slot to open a bookmark in a new browser tab.
182 """
183 self.__openBookmark(True)
184
185 def __openBookmark(self, newTab):
186 """
187 Private method to open a bookmark.
188
189 @param newTab flag indicating to open the bookmark in a new tab
190 (boolean)
191 """
192 from .BookmarkNode import BookmarkNode
193 from .BookmarksModel import BookmarksModel
194
195 idx = self.bookmarksTree.currentIndex()
196 sourceIndex = self.__proxyModel.mapToSource(idx)
197 node = self.__bookmarksModel.node(sourceIndex)
198 if not idx.parent().isValid() or \
199 node is None or \
200 node.type() == BookmarkNode.Folder:
201 return
202 if newTab:
203 self.newUrl.emit(
204 idx.sibling(idx.row(), 1).data(BookmarksModel.UrlRole),
205 idx.sibling(idx.row(), 0).data(Qt.DisplayRole))
206 else:
207 self.openUrl.emit(
208 idx.sibling(idx.row(), 1).data(BookmarksModel.UrlRole),
209 idx.sibling(idx.row(), 0).data(Qt.DisplayRole))
210
211 def __editName(self):
212 """
213 Private slot to edit the name part of a bookmark.
214 """
215 idx = self.bookmarksTree.currentIndex()
216 idx = idx.sibling(idx.row(), 0)
217 self.bookmarksTree.edit(idx)
218
219 def __editAddress(self):
220 """
221 Private slot to edit the address part of a bookmark.
222 """
223 idx = self.bookmarksTree.currentIndex()
224 idx = idx.sibling(idx.row(), 1)
225 self.bookmarksTree.edit(idx)
226
227 def __edit(self):
228 """
229 Private slot to edit a bookmarks properties.
230 """
231 from .BookmarkPropertiesDialog import BookmarkPropertiesDialog
232
233 idx = self.bookmarksTree.currentIndex()
234 sourceIndex = self.__proxyModel.mapToSource(idx)
235 node = self.__bookmarksModel.node(sourceIndex)
236 dlg = BookmarkPropertiesDialog(node)
237 dlg.exec_()
238
239 def __newFolder(self):
240 """
241 Private slot to add a new bookmarks folder.
242 """
243 from .BookmarkNode import BookmarkNode
244
245 currentIndex = self.bookmarksTree.currentIndex()
246 idx = QModelIndex(currentIndex)
247 sourceIndex = self.__proxyModel.mapToSource(idx)
248 sourceNode = self.__bookmarksModel.node(sourceIndex)
249 row = -1 # append new folder as the last item per default
250
251 if sourceNode is not None and \
252 sourceNode.type() != BookmarkNode.Folder:
253 # If the selected item is not a folder, add a new folder to the
254 # parent folder, but directly below the selected item.
255 idx = idx.parent()
256 row = currentIndex.row() + 1
257
258 if not idx.isValid():
259 # Select bookmarks menu as default.
260 idx = self.__proxyModel.index(1, 0)
261
262 idx = self.__proxyModel.mapToSource(idx)
263 parent = self.__bookmarksModel.node(idx)
264 node = BookmarkNode(BookmarkNode.Folder)
265 node.title = self.tr("New Folder")
266 self.__bookmarksManager.addBookmark(parent, node, row)

eric ide

mercurial