eric7/HelpViewer/HelpBookmarksWidget.py

branch
eric7
changeset 8902
ba9b8c6e4928
parent 8900
9c153ce17d74
equal deleted inserted replaced
8901:adc47f306e51 8902:ba9b8c6e4928
1 # -*- coding: utf-8 -*- 1 # -*- coding: utf-8 -*-
2 2
3 # Copyright (c) 2022 Detlev Offenbach <detlev@die-offenbachs.de> 3 # Copyright (c) 2022 Detlev Offenbach <detlev@die-offenbachs.de>
4 # 4 #
5 5
6 """
7 Module implementing a widget showing the list of bookmarks.
8 """
9
6 import contextlib 10 import contextlib
11 import datetime
7 import json 12 import json
13 import os
8 14
9 from PyQt6.QtCore import pyqtSignal, pyqtSlot, Qt, QPoint, QUrl 15 from PyQt6.QtCore import pyqtSignal, pyqtSlot, Qt, QPoint, QUrl
10 from PyQt6.QtGui import QClipboard, QGuiApplication 16 from PyQt6.QtGui import QClipboard, QGuiApplication
11 from PyQt6.QtWidgets import ( 17 from PyQt6.QtWidgets import (
12 QAbstractItemView, QApplication, QDialog, QListWidget, QListWidgetItem, QMenu 18 QAbstractItemView, QApplication, QDialog, QListWidget, QListWidgetItem,
19 QMenu
13 ) 20 )
14 21
22 from EricWidgets import EricFileDialog, EricMessageBox
23
15 import Preferences 24 import Preferences
16 25
17 from .HelpBookmarkPropertiesDialog import HelpBookmarkPropertiesDialog 26 from .HelpBookmarkPropertiesDialog import HelpBookmarkPropertiesDialog
27
18 28
19 class HelpBookmarksWidget(QListWidget): 29 class HelpBookmarksWidget(QListWidget):
20 """ 30 """
21 Class implementing a widget showing the list of bookmarks. 31 Class implementing a widget showing the list of bookmarks.
22 32
92 openBookmarks = menu.addAction(self.tr("Open All Bookmarks")) 102 openBookmarks = menu.addAction(self.tr("Open All Bookmarks"))
93 menu.addSeparator() 103 menu.addSeparator()
94 newBookmark = menu.addAction(self.tr("New Bookmark")) 104 newBookmark = menu.addAction(self.tr("New Bookmark"))
95 addBookmark = menu.addAction(self.tr("Bookmark Page")) 105 addBookmark = menu.addAction(self.tr("Bookmark Page"))
96 menu.addSeparator() 106 menu.addSeparator()
97 deleteBookmarks = menu.addAction(self.tr("Delete All Bookmark")) 107 deleteBookmarks = menu.addAction(self.tr("Delete All Bookmarks"))
108 menu.addSeparator()
109 exportBookmarks = menu.addAction(self.tr("Export All Bookmarks"))
110 importBookmarks = menu.addAction(self.tr("Import Bookmarks"))
98 111
99 act = menu.exec(self.mapToGlobal(point)) 112 act = menu.exec(self.mapToGlobal(point))
100 if act == openBookmarks: 113 if act == openBookmarks:
101 self.__openBookmarks(selected=False) 114 self.__openBookmarks(selected=False)
102 elif act == newBookmark: 115 elif act == newBookmark:
105 self.__bookmarkCurrentPage() 118 self.__bookmarkCurrentPage()
106 elif act == deleteBookmarks: 119 elif act == deleteBookmarks:
107 self.__deleteBookmarks([ 120 self.__deleteBookmarks([
108 self.item(row) for row in range(self.count()) 121 self.item(row) for row in range(self.count())
109 ]) 122 ])
123 elif act == exportBookmarks:
124 self.__exportBookmarks(selected=False)
125 elif act == importBookmarks:
126 self.__importBookmarks()
110 127
111 @pyqtSlot(QPoint) 128 @pyqtSlot(QPoint)
112 def __showBookmarkContextMenu(self, point): 129 def __showBookmarkContextMenu(self, point):
113 """ 130 """
114 Private slot to show the context menu for a bookmark. 131 Private slot to show the context menu for a bookmark.
138 addBookmark = menu.addAction(self.tr("Bookmark Page")) 155 addBookmark = menu.addAction(self.tr("Bookmark Page"))
139 menu.addSeparator() 156 menu.addSeparator()
140 editBookmark = menu.addAction(self.tr("Edit Bookmark")) 157 editBookmark = menu.addAction(self.tr("Edit Bookmark"))
141 menu.addSeparator() 158 menu.addSeparator()
142 deleteBookmark = menu.addAction(self.tr("Delete Bookmark")) 159 deleteBookmark = menu.addAction(self.tr("Delete Bookmark"))
160 menu.addSeparator()
161 exportBookmarks = menu.addAction(self.tr("Export All Bookmarks"))
162 importBookmarks = menu.addAction(self.tr("Import Bookmarks"))
143 163
144 act = menu.exec(self.mapToGlobal(point)) 164 act = menu.exec(self.mapToGlobal(point))
145 if act == curPage: 165 if act == curPage:
146 self.openUrl.emit(url) 166 self.openUrl.emit(url)
147 elif act == newPage: 167 elif act == newPage:
160 self.__bookmarkCurrentPage() 180 self.__bookmarkCurrentPage()
161 elif act == editBookmark: 181 elif act == editBookmark:
162 self.__editBookmark(itm) 182 self.__editBookmark(itm)
163 elif act == deleteBookmark: 183 elif act == deleteBookmark:
164 self.__deleteBookmarks([itm]) 184 self.__deleteBookmarks([itm])
185 elif act == exportBookmarks:
186 self.__exportBookmarks(selected=False)
187 elif act == importBookmarks:
188 self.__importBookmarks()
165 189
166 @pyqtSlot(QPoint) 190 @pyqtSlot(QPoint)
167 def __showBookmarksContextMenu(self, point): 191 def __showBookmarksContextMenu(self, point):
168 """ 192 """
169 Private slot to show the context menu for multiple bookmark. 193 Private slot to show the context menu for multiple bookmark.
173 """ 197 """
174 menu = QMenu() 198 menu = QMenu()
175 openBookmarks = menu.addAction(self.tr("Open Selected Bookmarks")) 199 openBookmarks = menu.addAction(self.tr("Open Selected Bookmarks"))
176 menu.addSeparator() 200 menu.addSeparator()
177 deleteBookmarks = menu.addAction(self.tr("Delete Selected Bookmarks")) 201 deleteBookmarks = menu.addAction(self.tr("Delete Selected Bookmarks"))
202 menu.addSeparator()
203 exportBookmarks = menu.addAction(self.tr("Export Selected Bookmarks"))
204 exportAllBookmarks = menu.addAction(self.tr("Export All Bookmarks"))
205 importBookmarks = menu.addAction(self.tr("Import Bookmarks"))
178 206
179 act = menu.exec(self.mapToGlobal(point)) 207 act = menu.exec(self.mapToGlobal(point))
180 if act == openBookmarks: 208 if act == openBookmarks:
181 self.__openBookmarks(selected=True) 209 self.__openBookmarks(selected=True)
182 elif act == deleteBookmarks: 210 elif act == deleteBookmarks:
183 self.__deleteBookmarks(self.selectedItems()) 211 self.__deleteBookmarks(self.selectedItems())
212 elif act == exportBookmarks:
213 self.__exportBookmarks(selected=True)
214 elif act == exportAllBookmarks:
215 self.__exportBookmarks(selected=False)
216 elif act == importBookmarks:
217 self.__importBookmarks()
184 218
185 @pyqtSlot(str, str) 219 @pyqtSlot(str, str)
186 def __addBookmark(self, title, url): 220 def __addBookmark(self, title, url):
187 """ 221 """
188 Private slot to add a bookmark entry. 222 Private slot to add a bookmark entry.
356 "title": itm.text(), 390 "title": itm.text(),
357 "url": itm.data(self.UrlRole).toString(), 391 "url": itm.data(self.UrlRole).toString(),
358 }) 392 })
359 Preferences.setHelp("Bookmarks", json.dumps(bookmarks)) 393 Preferences.setHelp("Bookmarks", json.dumps(bookmarks))
360 394
361 def __exportBookmarks(self): 395 @pyqtSlot()
362 """ 396 def __exportBookmarks(self, selected=False):
363 Private method to export the bookmarks into a JSON file. 397 """
364 """ 398 Private slot to export the bookmarks into a JSON file.
365 # TODO: not yet implemented 399
366 400 @param selected flag indicating to export the selected bookmarks
401 (defaults to False)
402 @type bool (optional)
403 """
404 filename, selectedFilter = EricFileDialog.getSaveFileNameAndFilter(
405 self,
406 self.tr("Export Bookmarks"),
407 "",
408 self.tr("eric Bookmarks Files (*.json);;All Files (*)"),
409 None,
410 EricFileDialog.DontConfirmOverwrite
411 )
412 if filename:
413 ext = os.path.splitext(filename)[1]
414 if not ext:
415 ex = selectedFilter.split("(*")[1].split(")")[0]
416 if ex:
417 filename += ex
418
419 if os.path.exists(filename):
420 ok = EricMessageBox.yesNo(
421 self,
422 self.tr("Export Bookmarks"),
423 self.tr("""The file <b>{0}</b> already exists. Do you"""
424 """ want to overwrite it?""").format(filename))
425 if not ok:
426 return
427
428 bookmarksDict = {
429 "creator": "eric7",
430 "version": 1,
431 "created": datetime.datetime.now().isoformat(
432 sep=" ", timespec="seconds"),
433 "bookmarks": []
434 }
435 bookmarkItems = (
436 self.selectedItems()
437 if selected else
438 [self.item(row) for row in range(self.count())]
439 )
440 for bookmarkItem in bookmarkItems:
441 bookmarksDict["bookmarks"].append({
442 "type": "url",
443 "title": bookmarkItem.text(),
444 "url": bookmarkItem.data(self.UrlRole).toString(),
445 })
446
447 jsonStr = json.dumps(bookmarksDict, indent=2, sort_keys=True)
448 try:
449 with open(filename, "w") as f:
450 f.write(jsonStr)
451 except OSError as err:
452 EricMessageBox.critical(
453 self,
454 self.tr("Export Bookmarks"),
455 self.tr("""<p>The bookmarks could not be exported"""
456 """ to <b>{0}</b>.</p><p>Reason: {1}</p>""")
457 .format(filename, str(err)))
458
459 @pyqtSlot()
367 def __importBookmarks(self): 460 def __importBookmarks(self):
368 """ 461 """
369 Private method to import bookmarks from a JSON file. 462 Private slot to import bookmarks from a JSON file.
370 """ 463 """
371 # TODO: not yet implemented 464 from .HelpBookmarksImportDialog import HelpBookmarksImportDialog
372 # 1. read file 465
373 # 2. check, if exported from eric and compatible format version 466 dlg = HelpBookmarksImportDialog(self)
374 # 3. process each entry 467 if dlg.exec() == QDialog.DialogCode.Accepted:
468 replace, filename = dlg.getData()
469
470 try:
471 with open(filename, "r") as f:
472 jsonStr = f.read()
473 bookmarks = json.loads(jsonStr)
474 except (OSError, json.JSONDecodeError) as err:
475 EricMessageBox.critical(
476 self,
477 self.tr("Import Bookmarks"),
478 self.tr(
479 "<p>The bookmarks file <b>{0}</b> could not be "
480 "read.</p><p>Reason: {1}</p>"
481 ).format(filename, str(err))
482 )
483 return
484
485 if not isinstance(bookmarks, dict):
486 EricMessageBox.critical(
487 self,
488 self.tr("Import Bookmarks"),
489 self.tr(
490 "The bookmarks file <b>{0}</b> has invalid contents."
491 ).format(filename)
492 )
493 return
494
495 try:
496 if bookmarks["creator"] != "eric7":
497 EricMessageBox.critical(
498 self,
499 self.tr("Import Bookmarks"),
500 self.tr(
501 "The bookmarks file <b>{0}</b> was not created"
502 " with 'eric7'."
503 ).format(filename)
504 )
505 return
506
507 if bookmarks["version"] != 1:
508 EricMessageBox.critical(
509 self,
510 self.tr("Import Bookmarks"),
511 self.tr(
512 "The bookmarks file <b>{0}</b> has an unsupported"
513 " format version."
514 ).format(filename)
515 )
516 return
517
518 if replace:
519 self.clear()
520
521 for bookmark in bookmarks["bookmarks"]:
522 if bookmark["type"] == "url":
523 self.__addBookmark(bookmark["title"], bookmark["url"])
524 self.sortItems()
525 self.__saveBookmarks()
526
527 except KeyError:
528 EricMessageBox.critical(
529 self,
530 self.tr("Import Bookmarks"),
531 self.tr(
532 "The bookmarks file <b>{0}</b> has invalid contents."
533 ).format(filename)
534 )

eric ide

mercurial