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