src/eric7/WebBrowser/Bookmarks/BookmarksManager.py

branch
eric7
changeset 9221
bf71ee032bb4
parent 9209
b99e7fd55fd3
child 9413
80c06d472826
equal deleted inserted replaced
9220:e9e7eca7efee 9221:bf71ee032bb4
10 import os 10 import os
11 import contextlib 11 import contextlib
12 import pathlib 12 import pathlib
13 13
14 from PyQt6.QtCore import ( 14 from PyQt6.QtCore import (
15 pyqtSignal, QT_TRANSLATE_NOOP, QObject, QFile, QIODevice, QXmlStreamReader, 15 pyqtSignal,
16 QDateTime, QUrl, QCoreApplication 16 QT_TRANSLATE_NOOP,
17 QObject,
18 QFile,
19 QIODevice,
20 QXmlStreamReader,
21 QDateTime,
22 QUrl,
23 QCoreApplication,
17 ) 24 )
18 from PyQt6.QtGui import QUndoStack, QUndoCommand 25 from PyQt6.QtGui import QUndoStack, QUndoCommand
19 from PyQt6.QtWidgets import QDialog 26 from PyQt6.QtWidgets import QDialog
20 27
21 from EricWidgets import EricMessageBox, EricFileDialog 28 from EricWidgets import EricMessageBox, EricFileDialog
34 41
35 42
36 class BookmarksManager(QObject): 43 class BookmarksManager(QObject):
37 """ 44 """
38 Class implementing the bookmarks manager. 45 Class implementing the bookmarks manager.
39 46
40 @signal entryAdded(BookmarkNode) emitted after a bookmark node has been 47 @signal entryAdded(BookmarkNode) emitted after a bookmark node has been
41 added 48 added
42 @signal entryRemoved(BookmarkNode, int, BookmarkNode) emitted after a 49 @signal entryRemoved(BookmarkNode, int, BookmarkNode) emitted after a
43 bookmark node has been removed 50 bookmark node has been removed
44 @signal entryChanged(BookmarkNode) emitted after a bookmark node has been 51 @signal entryChanged(BookmarkNode) emitted after a bookmark node has been
45 changed 52 changed
46 @signal bookmarksSaved() emitted after the bookmarks were saved 53 @signal bookmarksSaved() emitted after the bookmarks were saved
47 @signal bookmarksReloaded() emitted after the bookmarks were reloaded 54 @signal bookmarksReloaded() emitted after the bookmarks were reloaded
48 """ 55 """
56
49 entryAdded = pyqtSignal(BookmarkNode) 57 entryAdded = pyqtSignal(BookmarkNode)
50 entryRemoved = pyqtSignal(BookmarkNode, int, BookmarkNode) 58 entryRemoved = pyqtSignal(BookmarkNode, int, BookmarkNode)
51 entryChanged = pyqtSignal(BookmarkNode) 59 entryChanged = pyqtSignal(BookmarkNode)
52 bookmarksSaved = pyqtSignal() 60 bookmarksSaved = pyqtSignal()
53 bookmarksReloaded = pyqtSignal() 61 bookmarksReloaded = pyqtSignal()
54 62
55 def __init__(self, parent=None): 63 def __init__(self, parent=None):
56 """ 64 """
57 Constructor 65 Constructor
58 66
59 @param parent reference to the parent object (QObject) 67 @param parent reference to the parent object (QObject)
60 """ 68 """
61 super().__init__(parent) 69 super().__init__(parent)
62 70
63 self.__saveTimer = AutoSaver(self, self.save) 71 self.__saveTimer = AutoSaver(self, self.save)
64 self.entryAdded.connect(self.__saveTimer.changeOccurred) 72 self.entryAdded.connect(self.__saveTimer.changeOccurred)
65 self.entryRemoved.connect(self.__saveTimer.changeOccurred) 73 self.entryRemoved.connect(self.__saveTimer.changeOccurred)
66 self.entryChanged.connect(self.__saveTimer.changeOccurred) 74 self.entryChanged.connect(self.__saveTimer.changeOccurred)
67 75
68 self.__initialize() 76 self.__initialize()
69 77
70 def __initialize(self): 78 def __initialize(self):
71 """ 79 """
72 Private method to initialize some data. 80 Private method to initialize some data.
73 """ 81 """
74 self.__loaded = False 82 self.__loaded = False
75 self.__bookmarkRootNode = None 83 self.__bookmarkRootNode = None
76 self.__toolbar = None 84 self.__toolbar = None
77 self.__menu = None 85 self.__menu = None
78 self.__bookmarksModel = None 86 self.__bookmarksModel = None
79 self.__commands = QUndoStack() 87 self.__commands = QUndoStack()
80 88
81 @classmethod 89 @classmethod
82 def getFileName(cls): 90 def getFileName(cls):
83 """ 91 """
84 Class method to get the file name of the bookmark file. 92 Class method to get the file name of the bookmark file.
85 93
86 @return name of the bookmark file (string) 94 @return name of the bookmark file (string)
87 """ 95 """
88 return os.path.join(Utilities.getConfigDir(), "web_browser", 96 return os.path.join(Utilities.getConfigDir(), "web_browser", "bookmarks.xbel")
89 "bookmarks.xbel") 97
90
91 def close(self): 98 def close(self):
92 """ 99 """
93 Public method to close the bookmark manager. 100 Public method to close the bookmark manager.
94 """ 101 """
95 self.__saveTimer.saveIfNeccessary() 102 self.__saveTimer.saveIfNeccessary()
96 103
97 def undoRedoStack(self): 104 def undoRedoStack(self):
98 """ 105 """
99 Public method to get a reference to the undo stack. 106 Public method to get a reference to the undo stack.
100 107
101 @return reference to the undo stack (QUndoStack) 108 @return reference to the undo stack (QUndoStack)
102 """ 109 """
103 return self.__commands 110 return self.__commands
104 111
105 def changeExpanded(self): 112 def changeExpanded(self):
106 """ 113 """
107 Public method to handle a change of the expanded state. 114 Public method to handle a change of the expanded state.
108 """ 115 """
109 self.__saveTimer.changeOccurred() 116 self.__saveTimer.changeOccurred()
110 117
111 def reload(self): 118 def reload(self):
112 """ 119 """
113 Public method used to initiate a reloading of the bookmarks. 120 Public method used to initiate a reloading of the bookmarks.
114 """ 121 """
115 self.__initialize() 122 self.__initialize()
116 self.load() 123 self.load()
117 self.bookmarksReloaded.emit() 124 self.bookmarksReloaded.emit()
118 125
119 def load(self): 126 def load(self):
120 """ 127 """
121 Public method to load the bookmarks. 128 Public method to load the bookmarks.
122 129
123 @exception RuntimeError raised to indicate an error loading the 130 @exception RuntimeError raised to indicate an error loading the
124 bookmarks 131 bookmarks
125 """ 132 """
126 if self.__loaded: 133 if self.__loaded:
127 return 134 return
128 135
129 self.__loaded = True 136 self.__loaded = True
130 137
131 bookmarkFile = self.getFileName() 138 bookmarkFile = self.getFileName()
132 if not QFile.exists(bookmarkFile): 139 if not QFile.exists(bookmarkFile):
133 bookmarkFile = QFile(os.path.join( 140 bookmarkFile = QFile(
134 os.path.dirname(__file__), "DefaultBookmarks.xbel")) 141 os.path.join(os.path.dirname(__file__), "DefaultBookmarks.xbel")
142 )
135 bookmarkFile.open(QIODevice.OpenModeFlag.ReadOnly) 143 bookmarkFile.open(QIODevice.OpenModeFlag.ReadOnly)
136 144
137 from .XbelReader import XbelReader 145 from .XbelReader import XbelReader
146
138 reader = XbelReader() 147 reader = XbelReader()
139 self.__bookmarkRootNode = reader.read(bookmarkFile) 148 self.__bookmarkRootNode = reader.read(bookmarkFile)
140 if reader.error() != QXmlStreamReader.Error.NoError: 149 if reader.error() != QXmlStreamReader.Error.NoError:
141 EricMessageBox.warning( 150 EricMessageBox.warning(
142 None, 151 None,
143 self.tr("Loading Bookmarks"), 152 self.tr("Loading Bookmarks"),
144 self.tr( 153 self.tr(
145 """Error when loading bookmarks on line {0},""" 154 """Error when loading bookmarks on line {0},"""
146 """ column {1}:\n {2}""") 155 """ column {1}:\n {2}"""
147 .format(reader.lineNumber(), 156 ).format(
148 reader.columnNumber(), 157 reader.lineNumber(), reader.columnNumber(), reader.errorString()
149 reader.errorString())) 158 ),
150 159 )
160
151 others = [] 161 others = []
152 for index in range( 162 for index in range(len(self.__bookmarkRootNode.children()) - 1, -1, -1):
153 len(self.__bookmarkRootNode.children()) - 1, -1, -1):
154 node = self.__bookmarkRootNode.children()[index] 163 node = self.__bookmarkRootNode.children()[index]
155 if node.type() == BookmarkNode.Folder: 164 if node.type() == BookmarkNode.Folder:
156 if ( 165 if (
157 (node.title == self.tr("Toolbar Bookmarks") or 166 node.title == self.tr("Toolbar Bookmarks")
158 node.title == BOOKMARKBAR) and 167 or node.title == BOOKMARKBAR
159 self.__toolbar is None 168 ) and self.__toolbar is None:
160 ):
161 node.title = self.tr(BOOKMARKBAR) 169 node.title = self.tr(BOOKMARKBAR)
162 self.__toolbar = node 170 self.__toolbar = node
163 171
164 if ( 172 if (
165 (node.title == self.tr("Menu") or 173 node.title == self.tr("Menu") or node.title == BOOKMARKMENU
166 node.title == BOOKMARKMENU) and 174 ) and self.__menu is None:
167 self.__menu is None
168 ):
169 node.title = self.tr(BOOKMARKMENU) 175 node.title = self.tr(BOOKMARKMENU)
170 self.__menu = node 176 self.__menu = node
171 else: 177 else:
172 others.append(node) 178 others.append(node)
173 self.__bookmarkRootNode.remove(node) 179 self.__bookmarkRootNode.remove(node)
174 180
175 if len(self.__bookmarkRootNode.children()) > 0: 181 if len(self.__bookmarkRootNode.children()) > 0:
176 raise RuntimeError("Error loading bookmarks.") 182 raise RuntimeError("Error loading bookmarks.")
177 183
178 if self.__toolbar is None: 184 if self.__toolbar is None:
179 self.__toolbar = BookmarkNode(BookmarkNode.Folder, 185 self.__toolbar = BookmarkNode(BookmarkNode.Folder, self.__bookmarkRootNode)
180 self.__bookmarkRootNode)
181 self.__toolbar.title = self.tr(BOOKMARKBAR) 186 self.__toolbar.title = self.tr(BOOKMARKBAR)
182 else: 187 else:
183 self.__bookmarkRootNode.add(self.__toolbar) 188 self.__bookmarkRootNode.add(self.__toolbar)
184 189
185 if self.__menu is None: 190 if self.__menu is None:
186 self.__menu = BookmarkNode(BookmarkNode.Folder, 191 self.__menu = BookmarkNode(BookmarkNode.Folder, self.__bookmarkRootNode)
187 self.__bookmarkRootNode)
188 self.__menu.title = self.tr(BOOKMARKMENU) 192 self.__menu.title = self.tr(BOOKMARKMENU)
189 else: 193 else:
190 self.__bookmarkRootNode.add(self.__menu) 194 self.__bookmarkRootNode.add(self.__menu)
191 195
192 for node in others: 196 for node in others:
193 self.__menu.add(node) 197 self.__menu.add(node)
194 198
195 def save(self): 199 def save(self):
196 """ 200 """
197 Public method to save the bookmarks. 201 Public method to save the bookmarks.
198 """ 202 """
199 if not self.__loaded: 203 if not self.__loaded:
200 return 204 return
201 205
202 from .XbelWriter import XbelWriter 206 from .XbelWriter import XbelWriter
207
203 writer = XbelWriter() 208 writer = XbelWriter()
204 bookmarkFile = self.getFileName() 209 bookmarkFile = self.getFileName()
205 210
206 # save root folder titles in English (i.e. not localized) 211 # save root folder titles in English (i.e. not localized)
207 self.__menu.title = BOOKMARKMENU 212 self.__menu.title = BOOKMARKMENU
208 self.__toolbar.title = BOOKMARKBAR 213 self.__toolbar.title = BOOKMARKBAR
209 if not writer.write(bookmarkFile, self.__bookmarkRootNode): 214 if not writer.write(bookmarkFile, self.__bookmarkRootNode):
210 EricMessageBox.warning( 215 EricMessageBox.warning(
211 None, 216 None,
212 self.tr("Saving Bookmarks"), 217 self.tr("Saving Bookmarks"),
213 self.tr("""Error saving bookmarks to <b>{0}</b>.""") 218 self.tr("""Error saving bookmarks to <b>{0}</b>.""").format(
214 .format(bookmarkFile)) 219 bookmarkFile
215 220 ),
221 )
222
216 # restore localized titles 223 # restore localized titles
217 self.__menu.title = self.tr(BOOKMARKMENU) 224 self.__menu.title = self.tr(BOOKMARKMENU)
218 self.__toolbar.title = self.tr(BOOKMARKBAR) 225 self.__toolbar.title = self.tr(BOOKMARKBAR)
219 226
220 self.bookmarksSaved.emit() 227 self.bookmarksSaved.emit()
221 228
222 def addBookmark(self, parent, node, row=-1): 229 def addBookmark(self, parent, node, row=-1):
223 """ 230 """
224 Public method to add a bookmark. 231 Public method to add a bookmark.
225 232
226 @param parent reference to the node to add to (BookmarkNode) 233 @param parent reference to the node to add to (BookmarkNode)
227 @param node reference to the node to add (BookmarkNode) 234 @param node reference to the node to add (BookmarkNode)
228 @param row row number (integer) 235 @param row row number (integer)
229 """ 236 """
230 if not self.__loaded: 237 if not self.__loaded:
231 return 238 return
232 239
233 self.setTimestamp(node, BookmarkNode.TsAdded, 240 self.setTimestamp(node, BookmarkNode.TsAdded, QDateTime.currentDateTime())
234 QDateTime.currentDateTime()) 241
235
236 command = InsertBookmarksCommand(self, parent, node, row) 242 command = InsertBookmarksCommand(self, parent, node, row)
237 self.__commands.push(command) 243 self.__commands.push(command)
238 244
239 def removeBookmark(self, node): 245 def removeBookmark(self, node):
240 """ 246 """
241 Public method to remove a bookmark. 247 Public method to remove a bookmark.
242 248
243 @param node reference to the node to be removed (BookmarkNode) 249 @param node reference to the node to be removed (BookmarkNode)
244 """ 250 """
245 if not self.__loaded: 251 if not self.__loaded:
246 return 252 return
247 253
248 parent = node.parent() 254 parent = node.parent()
249 row = parent.children().index(node) 255 row = parent.children().index(node)
250 command = RemoveBookmarksCommand(self, parent, row) 256 command = RemoveBookmarksCommand(self, parent, row)
251 self.__commands.push(command) 257 self.__commands.push(command)
252 258
253 def setTitle(self, node, newTitle): 259 def setTitle(self, node, newTitle):
254 """ 260 """
255 Public method to set the title of a bookmark. 261 Public method to set the title of a bookmark.
256 262
257 @param node reference to the node to be changed (BookmarkNode) 263 @param node reference to the node to be changed (BookmarkNode)
258 @param newTitle title to be set (string) 264 @param newTitle title to be set (string)
259 """ 265 """
260 if not self.__loaded: 266 if not self.__loaded:
261 return 267 return
262 268
263 command = ChangeBookmarkCommand(self, node, newTitle, True) 269 command = ChangeBookmarkCommand(self, node, newTitle, True)
264 self.__commands.push(command) 270 self.__commands.push(command)
265 271
266 def setUrl(self, node, newUrl): 272 def setUrl(self, node, newUrl):
267 """ 273 """
268 Public method to set the URL of a bookmark. 274 Public method to set the URL of a bookmark.
269 275
270 @param node reference to the node to be changed (BookmarkNode) 276 @param node reference to the node to be changed (BookmarkNode)
271 @param newUrl URL to be set (string) 277 @param newUrl URL to be set (string)
272 """ 278 """
273 if not self.__loaded: 279 if not self.__loaded:
274 return 280 return
275 281
276 command = ChangeBookmarkCommand(self, node, newUrl, False) 282 command = ChangeBookmarkCommand(self, node, newUrl, False)
277 self.__commands.push(command) 283 self.__commands.push(command)
278 284
279 def setNodeChanged(self, node): 285 def setNodeChanged(self, node):
280 """ 286 """
281 Public method to signal changes of bookmarks other than title, URL 287 Public method to signal changes of bookmarks other than title, URL
282 or timestamp. 288 or timestamp.
283 289
284 @param node reference to the bookmark (BookmarkNode) 290 @param node reference to the bookmark (BookmarkNode)
285 """ 291 """
286 self.__saveTimer.changeOccurred() 292 self.__saveTimer.changeOccurred()
287 293
288 def setTimestamp(self, node, timestampType, timestamp): 294 def setTimestamp(self, node, timestampType, timestamp):
289 """ 295 """
290 Public method to set the URL of a bookmark. 296 Public method to set the URL of a bookmark.
291 297
292 @param node reference to the node to be changed (BookmarkNode) 298 @param node reference to the node to be changed (BookmarkNode)
293 @param timestampType type of the timestamp to set 299 @param timestampType type of the timestamp to set
294 (BookmarkNode.TsAdded, BookmarkNode.TsModified, 300 (BookmarkNode.TsAdded, BookmarkNode.TsModified,
295 BookmarkNode.TsVisited) 301 BookmarkNode.TsVisited)
296 @param timestamp timestamp to set (QDateTime) 302 @param timestamp timestamp to set (QDateTime)
297 """ 303 """
298 if not self.__loaded: 304 if not self.__loaded:
299 return 305 return
300 306
301 if timestampType == BookmarkNode.TsAdded: 307 if timestampType == BookmarkNode.TsAdded:
302 node.added = timestamp 308 node.added = timestamp
303 elif timestampType == BookmarkNode.TsModified: 309 elif timestampType == BookmarkNode.TsModified:
304 node.modified = timestamp 310 node.modified = timestamp
305 elif timestampType == BookmarkNode.TsVisited: 311 elif timestampType == BookmarkNode.TsVisited:
306 node.visited = timestamp 312 node.visited = timestamp
307 self.__saveTimer.changeOccurred() 313 self.__saveTimer.changeOccurred()
308 314
309 def incVisitCount(self, node): 315 def incVisitCount(self, node):
310 """ 316 """
311 Public method to increment the visit count of a bookmark. 317 Public method to increment the visit count of a bookmark.
312 318
313 @param node reference to the node to be changed (BookmarkNode) 319 @param node reference to the node to be changed (BookmarkNode)
314 """ 320 """
315 if not self.__loaded: 321 if not self.__loaded:
316 return 322 return
317 323
318 if node: 324 if node:
319 node.visitCount += 1 325 node.visitCount += 1
320 self.__saveTimer.changeOccurred() 326 self.__saveTimer.changeOccurred()
321 327
322 def setVisitCount(self, node, count): 328 def setVisitCount(self, node, count):
323 """ 329 """
324 Public method to set the visit count of a bookmark. 330 Public method to set the visit count of a bookmark.
325 331
326 @param node reference to the node to be changed (BookmarkNode) 332 @param node reference to the node to be changed (BookmarkNode)
327 @param count visit count to be set (int or str) 333 @param count visit count to be set (int or str)
328 """ 334 """
329 with contextlib.suppress(ValueError): 335 with contextlib.suppress(ValueError):
330 node.visitCount = int(count) 336 node.visitCount = int(count)
331 self.__saveTimer.changeOccurred() 337 self.__saveTimer.changeOccurred()
332 338
333 def bookmarks(self): 339 def bookmarks(self):
334 """ 340 """
335 Public method to get a reference to the root bookmark node. 341 Public method to get a reference to the root bookmark node.
336 342
337 @return reference to the root bookmark node (BookmarkNode) 343 @return reference to the root bookmark node (BookmarkNode)
338 """ 344 """
339 if not self.__loaded: 345 if not self.__loaded:
340 self.load() 346 self.load()
341 347
342 return self.__bookmarkRootNode 348 return self.__bookmarkRootNode
343 349
344 def menu(self): 350 def menu(self):
345 """ 351 """
346 Public method to get a reference to the bookmarks menu node. 352 Public method to get a reference to the bookmarks menu node.
347 353
348 @return reference to the bookmarks menu node (BookmarkNode) 354 @return reference to the bookmarks menu node (BookmarkNode)
349 """ 355 """
350 if not self.__loaded: 356 if not self.__loaded:
351 self.load() 357 self.load()
352 358
353 return self.__menu 359 return self.__menu
354 360
355 def toolbar(self): 361 def toolbar(self):
356 """ 362 """
357 Public method to get a reference to the bookmarks toolbar node. 363 Public method to get a reference to the bookmarks toolbar node.
358 364
359 @return reference to the bookmarks toolbar node (BookmarkNode) 365 @return reference to the bookmarks toolbar node (BookmarkNode)
360 """ 366 """
361 if not self.__loaded: 367 if not self.__loaded:
362 self.load() 368 self.load()
363 369
364 return self.__toolbar 370 return self.__toolbar
365 371
366 def bookmarksModel(self): 372 def bookmarksModel(self):
367 """ 373 """
368 Public method to get a reference to the bookmarks model. 374 Public method to get a reference to the bookmarks model.
369 375
370 @return reference to the bookmarks model (BookmarksModel) 376 @return reference to the bookmarks model (BookmarksModel)
371 """ 377 """
372 if self.__bookmarksModel is None: 378 if self.__bookmarksModel is None:
373 from .BookmarksModel import BookmarksModel 379 from .BookmarksModel import BookmarksModel
380
374 self.__bookmarksModel = BookmarksModel(self, self) 381 self.__bookmarksModel = BookmarksModel(self, self)
375 return self.__bookmarksModel 382 return self.__bookmarksModel
376 383
377 def importBookmarks(self): 384 def importBookmarks(self):
378 """ 385 """
379 Public method to import bookmarks. 386 Public method to import bookmarks.
380 """ 387 """
381 from .BookmarksImportDialog import BookmarksImportDialog 388 from .BookmarksImportDialog import BookmarksImportDialog
389
382 dlg = BookmarksImportDialog() 390 dlg = BookmarksImportDialog()
383 if dlg.exec() == QDialog.DialogCode.Accepted: 391 if dlg.exec() == QDialog.DialogCode.Accepted:
384 importRootNode = dlg.getImportedBookmarks() 392 importRootNode = dlg.getImportedBookmarks()
385 if importRootNode is not None: 393 if importRootNode is not None:
386 self.addBookmark(self.menu(), importRootNode) 394 self.addBookmark(self.menu(), importRootNode)
387 395
388 def exportBookmarks(self): 396 def exportBookmarks(self):
389 """ 397 """
390 Public method to export the bookmarks. 398 Public method to export the bookmarks.
391 """ 399 """
392 fileName, selectedFilter = EricFileDialog.getSaveFileNameAndFilter( 400 fileName, selectedFilter = EricFileDialog.getSaveFileNameAndFilter(
393 None, 401 None,
394 self.tr("Export Bookmarks"), 402 self.tr("Export Bookmarks"),
395 "eric7_bookmarks.xbel", 403 "eric7_bookmarks.xbel",
396 self.tr("XBEL bookmarks (*.xbel);;" 404 self.tr(
397 "XBEL bookmarks (*.xml);;" 405 "XBEL bookmarks (*.xbel);;"
398 "HTML Bookmarks (*.html)")) 406 "XBEL bookmarks (*.xml);;"
407 "HTML Bookmarks (*.html)"
408 ),
409 )
399 if not fileName: 410 if not fileName:
400 return 411 return
401 412
402 fpath = pathlib.Path(fileName) 413 fpath = pathlib.Path(fileName)
403 if not fpath.suffix: 414 if not fpath.suffix:
404 ex = selectedFilter.split("(*")[1].split(")")[0] 415 ex = selectedFilter.split("(*")[1].split(")")[0]
405 if ex: 416 if ex:
406 fpath = fpath.with_suffix(ex) 417 fpath = fpath.with_suffix(ex)
407 418
408 if fpath.suffix == ".html": 419 if fpath.suffix == ".html":
409 from .NsHtmlWriter import NsHtmlWriter 420 from .NsHtmlWriter import NsHtmlWriter
421
410 writer = NsHtmlWriter() 422 writer = NsHtmlWriter()
411 else: 423 else:
412 from .XbelWriter import XbelWriter 424 from .XbelWriter import XbelWriter
425
413 writer = XbelWriter() 426 writer = XbelWriter()
414 if not writer.write(str(fpath), self.__bookmarkRootNode): 427 if not writer.write(str(fpath), self.__bookmarkRootNode):
415 EricMessageBox.critical( 428 EricMessageBox.critical(
416 None, 429 None,
417 self.tr("Exporting Bookmarks"), 430 self.tr("Exporting Bookmarks"),
418 self.tr("""Error exporting bookmarks to <b>{0}</b>.""") 431 self.tr("""Error exporting bookmarks to <b>{0}</b>.""").format(fpath),
419 .format(fpath)) 432 )
420 433
421 def faviconChanged(self, url): 434 def faviconChanged(self, url):
422 """ 435 """
423 Public slot to update the icon image for an URL. 436 Public slot to update the icon image for an URL.
424 437
425 @param url URL of the icon to update (QUrl or string) 438 @param url URL of the icon to update (QUrl or string)
426 """ 439 """
427 if isinstance(url, QUrl): 440 if isinstance(url, QUrl):
428 url = url.toString() 441 url = url.toString()
429 nodes = self.bookmarksForUrl(url) 442 nodes = self.bookmarksForUrl(url)
430 for node in nodes: 443 for node in nodes:
431 self.bookmarksModel().entryChanged(node) 444 self.bookmarksModel().entryChanged(node)
432 445
433 def bookmarkForUrl(self, url, start=StartRoot): 446 def bookmarkForUrl(self, url, start=StartRoot):
434 """ 447 """
435 Public method to get a bookmark node for a given URL. 448 Public method to get a bookmark node for a given URL.
436 449
437 @param url URL of the bookmark to search for (QUrl or string) 450 @param url URL of the bookmark to search for (QUrl or string)
438 @param start indicator for the start of the search 451 @param start indicator for the start of the search
439 (StartRoot, StartMenu, StartToolBar) 452 (StartRoot, StartMenu, StartToolBar)
440 @return bookmark node for the given url (BookmarkNode) 453 @return bookmark node for the given url (BookmarkNode)
441 """ 454 """
445 startNode = self.__toolbar 458 startNode = self.__toolbar
446 else: 459 else:
447 startNode = self.__bookmarkRootNode 460 startNode = self.__bookmarkRootNode
448 if startNode is None: 461 if startNode is None:
449 return None 462 return None
450 463
451 if isinstance(url, QUrl): 464 if isinstance(url, QUrl):
452 url = url.toString() 465 url = url.toString()
453 466
454 return self.__searchBookmark(url, startNode) 467 return self.__searchBookmark(url, startNode)
455 468
456 def __searchBookmark(self, url, startNode): 469 def __searchBookmark(self, url, startNode):
457 """ 470 """
458 Private method get a bookmark node for a given URL. 471 Private method get a bookmark node for a given URL.
459 472
460 @param url URL of the bookmark to search for (string) 473 @param url URL of the bookmark to search for (string)
461 @param startNode reference to the node to start searching 474 @param startNode reference to the node to start searching
462 (BookmarkNode) 475 (BookmarkNode)
463 @return bookmark node for the given url (BookmarkNode) 476 @return bookmark node for the given url (BookmarkNode)
464 """ 477 """
465 bm = None 478 bm = None
466 for node in startNode.children(): 479 for node in startNode.children():
467 if node.type() == BookmarkNode.Folder: 480 if node.type() == BookmarkNode.Folder:
468 bm = self.__searchBookmark(url, node) 481 bm = self.__searchBookmark(url, node)
469 elif ( 482 elif node.type() == BookmarkNode.Bookmark and node.url == url:
470 node.type() == BookmarkNode.Bookmark and
471 node.url == url
472 ):
473 bm = node 483 bm = node
474 if bm is not None: 484 if bm is not None:
475 return bm 485 return bm
476 return None 486 return None
477 487
478 def bookmarksForUrl(self, url, start=StartRoot): 488 def bookmarksForUrl(self, url, start=StartRoot):
479 """ 489 """
480 Public method to get a list of bookmark nodes for a given URL. 490 Public method to get a list of bookmark nodes for a given URL.
481 491
482 @param url URL of the bookmarks to search for (QUrl or string) 492 @param url URL of the bookmarks to search for (QUrl or string)
483 @param start indicator for the start of the search 493 @param start indicator for the start of the search
484 (StartRoot, StartMenu, StartToolBar) 494 (StartRoot, StartMenu, StartToolBar)
485 @return list of bookmark nodes for the given url (list of BookmarkNode) 495 @return list of bookmark nodes for the given url (list of BookmarkNode)
486 """ 496 """
490 startNode = self.__toolbar 500 startNode = self.__toolbar
491 else: 501 else:
492 startNode = self.__bookmarkRootNode 502 startNode = self.__bookmarkRootNode
493 if startNode is None: 503 if startNode is None:
494 return [] 504 return []
495 505
496 if isinstance(url, QUrl): 506 if isinstance(url, QUrl):
497 url = url.toString() 507 url = url.toString()
498 508
499 return self.__searchBookmarks(url, startNode) 509 return self.__searchBookmarks(url, startNode)
500 510
501 def __searchBookmarks(self, url, startNode): 511 def __searchBookmarks(self, url, startNode):
502 """ 512 """
503 Private method get a list of bookmark nodes for a given URL. 513 Private method get a list of bookmark nodes for a given URL.
504 514
505 @param url URL of the bookmarks to search for (string) 515 @param url URL of the bookmarks to search for (string)
506 @param startNode reference to the node to start searching 516 @param startNode reference to the node to start searching
507 (BookmarkNode) 517 (BookmarkNode)
508 @return list of bookmark nodes for the given url (list of BookmarkNode) 518 @return list of bookmark nodes for the given url (list of BookmarkNode)
509 """ 519 """
510 bm = [] 520 bm = []
511 for node in startNode.children(): 521 for node in startNode.children():
512 if node.type() == BookmarkNode.Folder: 522 if node.type() == BookmarkNode.Folder:
513 bm.extend(self.__searchBookmarks(url, node)) 523 bm.extend(self.__searchBookmarks(url, node))
514 elif ( 524 elif node.type() == BookmarkNode.Bookmark and node.url == url:
515 node.type() == BookmarkNode.Bookmark and
516 node.url == url
517 ):
518 bm.append(node) 525 bm.append(node)
519 return bm 526 return bm
520 527
521 528
522 class RemoveBookmarksCommand(QUndoCommand): 529 class RemoveBookmarksCommand(QUndoCommand):
523 """ 530 """
524 Class implementing the Remove undo command. 531 Class implementing the Remove undo command.
525 """ 532 """
533
526 def __init__(self, bookmarksManager, parent, row): 534 def __init__(self, bookmarksManager, parent, row):
527 """ 535 """
528 Constructor 536 Constructor
529 537
530 @param bookmarksManager reference to the bookmarks manager 538 @param bookmarksManager reference to the bookmarks manager
531 (BookmarksManager) 539 (BookmarksManager)
532 @param parent reference to the parent node (BookmarkNode) 540 @param parent reference to the parent node (BookmarkNode)
533 @param row row number of bookmark (integer) 541 @param row row number of bookmark (integer)
534 """ 542 """
535 super().__init__( 543 super().__init__(
536 QCoreApplication.translate("BookmarksManager", "Remove Bookmark")) 544 QCoreApplication.translate("BookmarksManager", "Remove Bookmark")
537 545 )
546
538 self._row = row 547 self._row = row
539 self._bookmarksManager = bookmarksManager 548 self._bookmarksManager = bookmarksManager
540 try: 549 try:
541 self._node = parent.children()[row] 550 self._node = parent.children()[row]
542 except IndexError: 551 except IndexError:
543 self._node = BookmarkNode() 552 self._node = BookmarkNode()
544 self._parent = parent 553 self._parent = parent
545 554
546 def undo(self): 555 def undo(self):
547 """ 556 """
548 Public slot to perform the undo action. 557 Public slot to perform the undo action.
549 """ 558 """
550 self._parent.add(self._node, self._row) 559 self._parent.add(self._node, self._row)
551 self._bookmarksManager.entryAdded.emit(self._node) 560 self._bookmarksManager.entryAdded.emit(self._node)
552 561
553 def redo(self): 562 def redo(self):
554 """ 563 """
555 Public slot to perform the redo action. 564 Public slot to perform the redo action.
556 """ 565 """
557 self._parent.remove(self._node) 566 self._parent.remove(self._node)
558 self._bookmarksManager.entryRemoved.emit( 567 self._bookmarksManager.entryRemoved.emit(self._parent, self._row, self._node)
559 self._parent, self._row, self._node)
560 568
561 569
562 class InsertBookmarksCommand(RemoveBookmarksCommand): 570 class InsertBookmarksCommand(RemoveBookmarksCommand):
563 """ 571 """
564 Class implementing the Insert undo command. 572 Class implementing the Insert undo command.
565 """ 573 """
574
566 def __init__(self, bookmarksManager, parent, node, row): 575 def __init__(self, bookmarksManager, parent, node, row):
567 """ 576 """
568 Constructor 577 Constructor
569 578
570 @param bookmarksManager reference to the bookmarks manager 579 @param bookmarksManager reference to the bookmarks manager
571 (BookmarksManager) 580 (BookmarksManager)
572 @param parent reference to the parent node (BookmarkNode) 581 @param parent reference to the parent node (BookmarkNode)
573 @param node reference to the node to be inserted (BookmarkNode) 582 @param node reference to the node to be inserted (BookmarkNode)
574 @param row row number of bookmark (integer) 583 @param row row number of bookmark (integer)
575 """ 584 """
576 RemoveBookmarksCommand.__init__(self, bookmarksManager, parent, row) 585 RemoveBookmarksCommand.__init__(self, bookmarksManager, parent, row)
577 self.setText(QCoreApplication.translate( 586 self.setText(QCoreApplication.translate("BookmarksManager", "Insert Bookmark"))
578 "BookmarksManager", "Insert Bookmark"))
579 self._node = node 587 self._node = node
580 588
581 def undo(self): 589 def undo(self):
582 """ 590 """
583 Public slot to perform the undo action. 591 Public slot to perform the undo action.
584 """ 592 """
585 RemoveBookmarksCommand.redo(self) 593 RemoveBookmarksCommand.redo(self)
586 594
587 def redo(self): 595 def redo(self):
588 """ 596 """
589 Public slot to perform the redo action. 597 Public slot to perform the redo action.
590 """ 598 """
591 RemoveBookmarksCommand.undo(self) 599 RemoveBookmarksCommand.undo(self)
593 601
594 class ChangeBookmarkCommand(QUndoCommand): 602 class ChangeBookmarkCommand(QUndoCommand):
595 """ 603 """
596 Class implementing the Insert undo command. 604 Class implementing the Insert undo command.
597 """ 605 """
606
598 def __init__(self, bookmarksManager, node, newValue, title): 607 def __init__(self, bookmarksManager, node, newValue, title):
599 """ 608 """
600 Constructor 609 Constructor
601 610
602 @param bookmarksManager reference to the bookmarks manager 611 @param bookmarksManager reference to the bookmarks manager
603 (BookmarksManager) 612 (BookmarksManager)
604 @param node reference to the node to be changed (BookmarkNode) 613 @param node reference to the node to be changed (BookmarkNode)
605 @param newValue new value to be set (string) 614 @param newValue new value to be set (string)
606 @param title flag indicating a change of the title (True) or 615 @param title flag indicating a change of the title (True) or
607 the URL (False) (boolean) 616 the URL (False) (boolean)
608 """ 617 """
609 super().__init__() 618 super().__init__()
610 619
611 self._bookmarksManager = bookmarksManager 620 self._bookmarksManager = bookmarksManager
612 self._title = title 621 self._title = title
613 self._newValue = newValue 622 self._newValue = newValue
614 self._node = node 623 self._node = node
615 624
616 if self._title: 625 if self._title:
617 self._oldValue = self._node.title 626 self._oldValue = self._node.title
618 self.setText(QCoreApplication.translate( 627 self.setText(QCoreApplication.translate("BookmarksManager", "Name Change"))
619 "BookmarksManager", "Name Change"))
620 else: 628 else:
621 self._oldValue = self._node.url 629 self._oldValue = self._node.url
622 self.setText(QCoreApplication.translate( 630 self.setText(
623 "BookmarksManager", "Address Change")) 631 QCoreApplication.translate("BookmarksManager", "Address Change")
624 632 )
633
625 def undo(self): 634 def undo(self):
626 """ 635 """
627 Public slot to perform the undo action. 636 Public slot to perform the undo action.
628 """ 637 """
629 if self._title: 638 if self._title:
630 self._node.title = self._oldValue 639 self._node.title = self._oldValue
631 else: 640 else:
632 self._node.url = self._oldValue 641 self._node.url = self._oldValue
633 self._bookmarksManager.entryChanged.emit(self._node) 642 self._bookmarksManager.entryChanged.emit(self._node)
634 643
635 def redo(self): 644 def redo(self):
636 """ 645 """
637 Public slot to perform the redo action. 646 Public slot to perform the redo action.
638 """ 647 """
639 if self._title: 648 if self._title:

eric ide

mercurial