src/eric7/HelpViewer/HelpBookmarksWidget.py

branch
eric7
changeset 9221
bf71ee032bb4
parent 9209
b99e7fd55fd3
child 9413
80c06d472826
equal deleted inserted replaced
9220:e9e7eca7efee 9221:bf71ee032bb4
13 import os 13 import os
14 14
15 from PyQt6.QtCore import pyqtSignal, pyqtSlot, Qt, QPoint, QUrl 15 from PyQt6.QtCore import pyqtSignal, pyqtSlot, Qt, QPoint, QUrl
16 from PyQt6.QtGui import QClipboard, QGuiApplication 16 from PyQt6.QtGui import QClipboard, QGuiApplication
17 from PyQt6.QtWidgets import ( 17 from PyQt6.QtWidgets import (
18 QAbstractItemView, QApplication, QDialog, QListWidget, QListWidgetItem, 18 QAbstractItemView,
19 QMenu 19 QApplication,
20 QDialog,
21 QListWidget,
22 QListWidgetItem,
23 QMenu,
20 ) 24 )
21 25
22 from EricWidgets import EricFileDialog, EricMessageBox 26 from EricWidgets import EricFileDialog, EricMessageBox
23 27
24 import Preferences 28 import Preferences
27 31
28 32
29 class HelpBookmarksWidget(QListWidget): 33 class HelpBookmarksWidget(QListWidget):
30 """ 34 """
31 Class implementing a widget showing the list of bookmarks. 35 Class implementing a widget showing the list of bookmarks.
32 36
33 @signal escapePressed() emitted when the ESC key was pressed 37 @signal escapePressed() emitted when the ESC key was pressed
34 @signal openUrl(QUrl, str) emitted to open an entry in the current tab 38 @signal openUrl(QUrl, str) emitted to open an entry in the current tab
35 @signal newTab(QUrl, str) emitted to open an entry in a new tab 39 @signal newTab(QUrl, str) emitted to open an entry in a new tab
36 @signal newBackgroundTab(QUrl, str) emitted to open an entry in a 40 @signal newBackgroundTab(QUrl, str) emitted to open an entry in a
37 new background tab 41 new background tab
38 """ 42 """
43
39 escapePressed = pyqtSignal() 44 escapePressed = pyqtSignal()
40 openUrl = pyqtSignal(QUrl) 45 openUrl = pyqtSignal(QUrl)
41 newTab = pyqtSignal(QUrl) 46 newTab = pyqtSignal(QUrl)
42 newBackgroundTab = pyqtSignal(QUrl) 47 newBackgroundTab = pyqtSignal(QUrl)
43 48
44 UrlRole = Qt.ItemDataRole.UserRole + 1 49 UrlRole = Qt.ItemDataRole.UserRole + 1
45 50
46 def __init__(self, parent=None): 51 def __init__(self, parent=None):
47 """ 52 """
48 Constructor 53 Constructor
49 54
50 @param parent reference to the parent widget (defaults to None) 55 @param parent reference to the parent widget (defaults to None)
51 @type QWidget (optional) 56 @type QWidget (optional)
52 """ 57 """
53 super().__init__(parent) 58 super().__init__(parent)
54 self.setObjectName("HelpBookmarksWidget") 59 self.setObjectName("HelpBookmarksWidget")
55 60
56 self.__helpViewer = parent 61 self.__helpViewer = parent
57 62
58 self.setAlternatingRowColors(True) 63 self.setAlternatingRowColors(True)
59 self.setSelectionMode( 64 self.setSelectionMode(QAbstractItemView.SelectionMode.ExtendedSelection)
60 QAbstractItemView.SelectionMode.ExtendedSelection)
61 self.setSortingEnabled(True) 65 self.setSortingEnabled(True)
62 66
63 self.setContextMenuPolicy( 67 self.setContextMenuPolicy(Qt.ContextMenuPolicy.CustomContextMenu)
64 Qt.ContextMenuPolicy.CustomContextMenu) 68 self.customContextMenuRequested.connect(self.__showContextMenu)
65 self.customContextMenuRequested.connect( 69
66 self.__showContextMenu)
67
68 self.__bookmarks = [] 70 self.__bookmarks = []
69 self.__loadBookmarks() 71 self.__loadBookmarks()
70 72
71 self.itemDoubleClicked.connect(self.__bookmarkActivated) 73 self.itemDoubleClicked.connect(self.__bookmarkActivated)
72 74
73 @pyqtSlot(QPoint) 75 @pyqtSlot(QPoint)
74 def __showContextMenu(self, point): 76 def __showContextMenu(self, point):
75 """ 77 """
76 Private slot to handle the customContextMenuRequested signal of 78 Private slot to handle the customContextMenuRequested signal of
77 the viewlist. 79 the viewlist.
78 80
79 @param point position to open the menu at 81 @param point position to open the menu at
80 @type QPoint 82 @type QPoint
81 """ 83 """
82 selectedItemsCount = len(self.selectedItems()) 84 selectedItemsCount = len(self.selectedItems())
83 if selectedItemsCount == 0: 85 if selectedItemsCount == 0:
87 # single bookmark menu 89 # single bookmark menu
88 self.__showBookmarkContextMenu(point) 90 self.__showBookmarkContextMenu(point)
89 else: 91 else:
90 # multiple selected bookmarks 92 # multiple selected bookmarks
91 self.__showBookmarksContextMenu(point) 93 self.__showBookmarksContextMenu(point)
92 94
93 @pyqtSlot(QPoint) 95 @pyqtSlot(QPoint)
94 def __showBackgroundMenu(self, point): 96 def __showBackgroundMenu(self, point):
95 """ 97 """
96 Private slot to show the background menu (i.e. no selection). 98 Private slot to show the background menu (i.e. no selection).
97 99
98 @param point position to open the menu at 100 @param point position to open the menu at
99 @type QPoint 101 @type QPoint
100 """ 102 """
101 menu = QMenu() 103 menu = QMenu()
102 openBookmarks = menu.addAction(self.tr("Open All Bookmarks")) 104 openBookmarks = menu.addAction(self.tr("Open All Bookmarks"))
106 menu.addSeparator() 108 menu.addSeparator()
107 deleteBookmarks = menu.addAction(self.tr("Delete All Bookmarks")) 109 deleteBookmarks = menu.addAction(self.tr("Delete All Bookmarks"))
108 menu.addSeparator() 110 menu.addSeparator()
109 exportBookmarks = menu.addAction(self.tr("Export All Bookmarks")) 111 exportBookmarks = menu.addAction(self.tr("Export All Bookmarks"))
110 importBookmarks = menu.addAction(self.tr("Import Bookmarks")) 112 importBookmarks = menu.addAction(self.tr("Import Bookmarks"))
111 113
112 act = menu.exec(self.mapToGlobal(point)) 114 act = menu.exec(self.mapToGlobal(point))
113 if act == openBookmarks: 115 if act == openBookmarks:
114 self.__openBookmarks(selected=False) 116 self.__openBookmarks(selected=False)
115 elif act == newBookmark: 117 elif act == newBookmark:
116 self.__newBookmark() 118 self.__newBookmark()
117 elif act == addBookmark: 119 elif act == addBookmark:
118 self.__bookmarkCurrentPage() 120 self.__bookmarkCurrentPage()
119 elif act == deleteBookmarks: 121 elif act == deleteBookmarks:
120 self.__deleteBookmarks([ 122 self.__deleteBookmarks([self.item(row) for row in range(self.count())])
121 self.item(row) for row in range(self.count())
122 ])
123 elif act == exportBookmarks: 123 elif act == exportBookmarks:
124 self.__exportBookmarks(selected=False) 124 self.__exportBookmarks(selected=False)
125 elif act == importBookmarks: 125 elif act == importBookmarks:
126 self.__importBookmarks() 126 self.__importBookmarks()
127 127
128 @pyqtSlot(QPoint) 128 @pyqtSlot(QPoint)
129 def __showBookmarkContextMenu(self, point): 129 def __showBookmarkContextMenu(self, point):
130 """ 130 """
131 Private slot to show the context menu for a bookmark. 131 Private slot to show the context menu for a bookmark.
132 132
133 @param point position to open the menu at 133 @param point position to open the menu at
134 @type QPoint 134 @type QPoint
135 """ 135 """
136 itm = self.selectedItems()[0] 136 itm = self.selectedItems()[0]
137 url = itm.data(self.UrlRole) 137 url = itm.data(self.UrlRole)
138 validUrl = ( 138 validUrl = url is not None and not url.isEmpty() and url.isValid()
139 url is not None and not url.isEmpty() and url.isValid() 139
140 )
141
142 menu = QMenu() 140 menu = QMenu()
143 curPage = menu.addAction(self.tr("Open Link")) 141 curPage = menu.addAction(self.tr("Open Link"))
144 curPage.setEnabled(validUrl) 142 curPage.setEnabled(validUrl)
145 newPage = menu.addAction(self.tr("Open Link in New Page")) 143 newPage = menu.addAction(self.tr("Open Link in New Page"))
146 newPage.setEnabled(validUrl) 144 newPage.setEnabled(validUrl)
147 newBackgroundPage = menu.addAction( 145 newBackgroundPage = menu.addAction(self.tr("Open Link in Background Page"))
148 self.tr("Open Link in Background Page"))
149 newBackgroundPage.setEnabled(validUrl) 146 newBackgroundPage.setEnabled(validUrl)
150 menu.addSeparator() 147 menu.addSeparator()
151 copyUrl = menu.addAction(self.tr("Copy URL to Clipboard")) 148 copyUrl = menu.addAction(self.tr("Copy URL to Clipboard"))
152 copyUrl.setEnabled(validUrl) 149 copyUrl.setEnabled(validUrl)
153 menu.addSeparator() 150 menu.addSeparator()
158 menu.addSeparator() 155 menu.addSeparator()
159 deleteBookmark = menu.addAction(self.tr("Delete Bookmark")) 156 deleteBookmark = menu.addAction(self.tr("Delete Bookmark"))
160 menu.addSeparator() 157 menu.addSeparator()
161 exportBookmarks = menu.addAction(self.tr("Export All Bookmarks")) 158 exportBookmarks = menu.addAction(self.tr("Export All Bookmarks"))
162 importBookmarks = menu.addAction(self.tr("Import Bookmarks")) 159 importBookmarks = menu.addAction(self.tr("Import Bookmarks"))
163 160
164 act = menu.exec(self.mapToGlobal(point)) 161 act = menu.exec(self.mapToGlobal(point))
165 if act == curPage: 162 if act == curPage:
166 self.openUrl.emit(url) 163 self.openUrl.emit(url)
167 elif act == newPage: 164 elif act == newPage:
168 self.newTab.emit(url) 165 self.newTab.emit(url)
169 elif act == newBackgroundPage: 166 elif act == newBackgroundPage:
170 self.newBackgroundTab.emit(url) 167 self.newBackgroundTab.emit(url)
171 elif act == copyUrl: 168 elif act == copyUrl:
172 # copy the URL to both clipboard areas 169 # copy the URL to both clipboard areas
173 QGuiApplication.clipboard().setText( 170 QGuiApplication.clipboard().setText(
174 url.toString(), QClipboard.Mode.Clipboard) 171 url.toString(), QClipboard.Mode.Clipboard
172 )
175 QGuiApplication.clipboard().setText( 173 QGuiApplication.clipboard().setText(
176 url.toString(), QClipboard.Mode.Selection) 174 url.toString(), QClipboard.Mode.Selection
175 )
177 elif act == newBookmark: 176 elif act == newBookmark:
178 self.__newBookmark() 177 self.__newBookmark()
179 elif act == addBookmark: 178 elif act == addBookmark:
180 self.__bookmarkCurrentPage() 179 self.__bookmarkCurrentPage()
181 elif act == editBookmark: 180 elif act == editBookmark:
184 self.__deleteBookmarks([itm]) 183 self.__deleteBookmarks([itm])
185 elif act == exportBookmarks: 184 elif act == exportBookmarks:
186 self.__exportBookmarks(selected=False) 185 self.__exportBookmarks(selected=False)
187 elif act == importBookmarks: 186 elif act == importBookmarks:
188 self.__importBookmarks() 187 self.__importBookmarks()
189 188
190 @pyqtSlot(QPoint) 189 @pyqtSlot(QPoint)
191 def __showBookmarksContextMenu(self, point): 190 def __showBookmarksContextMenu(self, point):
192 """ 191 """
193 Private slot to show the context menu for multiple bookmark. 192 Private slot to show the context menu for multiple bookmark.
194 193
195 @param point position to open the menu at 194 @param point position to open the menu at
196 @type QPoint 195 @type QPoint
197 """ 196 """
198 menu = QMenu() 197 menu = QMenu()
199 openBookmarks = menu.addAction(self.tr("Open Selected Bookmarks")) 198 openBookmarks = menu.addAction(self.tr("Open Selected Bookmarks"))
201 deleteBookmarks = menu.addAction(self.tr("Delete Selected Bookmarks")) 200 deleteBookmarks = menu.addAction(self.tr("Delete Selected Bookmarks"))
202 menu.addSeparator() 201 menu.addSeparator()
203 exportBookmarks = menu.addAction(self.tr("Export Selected Bookmarks")) 202 exportBookmarks = menu.addAction(self.tr("Export Selected Bookmarks"))
204 exportAllBookmarks = menu.addAction(self.tr("Export All Bookmarks")) 203 exportAllBookmarks = menu.addAction(self.tr("Export All Bookmarks"))
205 importBookmarks = menu.addAction(self.tr("Import Bookmarks")) 204 importBookmarks = menu.addAction(self.tr("Import Bookmarks"))
206 205
207 act = menu.exec(self.mapToGlobal(point)) 206 act = menu.exec(self.mapToGlobal(point))
208 if act == openBookmarks: 207 if act == openBookmarks:
209 self.__openBookmarks(selected=True) 208 self.__openBookmarks(selected=True)
210 elif act == deleteBookmarks: 209 elif act == deleteBookmarks:
211 self.__deleteBookmarks(self.selectedItems()) 210 self.__deleteBookmarks(self.selectedItems())
213 self.__exportBookmarks(selected=True) 212 self.__exportBookmarks(selected=True)
214 elif act == exportAllBookmarks: 213 elif act == exportAllBookmarks:
215 self.__exportBookmarks(selected=False) 214 self.__exportBookmarks(selected=False)
216 elif act == importBookmarks: 215 elif act == importBookmarks:
217 self.__importBookmarks() 216 self.__importBookmarks()
218 217
219 @pyqtSlot(str, str) 218 @pyqtSlot(str, str)
220 def __addBookmark(self, title, url): 219 def __addBookmark(self, title, url):
221 """ 220 """
222 Private slot to add a bookmark entry. 221 Private slot to add a bookmark entry.
223 222
224 @param title title for the bookmark 223 @param title title for the bookmark
225 @type str 224 @type str
226 @param url URL for the bookmark 225 @param url URL for the bookmark
227 @type str 226 @type str
228 """ 227 """
229 url = url.strip() 228 url = url.strip()
230 229
231 itm = QListWidgetItem(title, self) 230 itm = QListWidgetItem(title, self)
232 itm.setData(self.UrlRole, QUrl(url)) 231 itm.setData(self.UrlRole, QUrl(url))
233 itm.setToolTip(url) 232 itm.setToolTip(url)
234 233
235 @pyqtSlot(str, QUrl) 234 @pyqtSlot(str, QUrl)
236 def addBookmark(self, title, url): 235 def addBookmark(self, title, url):
237 """ 236 """
238 Public slot to add a bookmark with given data. 237 Public slot to add a bookmark with given data.
239 238
240 @param title title for the bookmark 239 @param title title for the bookmark
241 @type str 240 @type str
242 @param url URL for the bookmark 241 @param url URL for the bookmark
243 @type QUrl 242 @type QUrl
244 """ 243 """
246 if dlg.exec() == QDialog.DialogCode.Accepted: 245 if dlg.exec() == QDialog.DialogCode.Accepted:
247 title, url = dlg.getData() 246 title, url = dlg.getData()
248 self.__addBookmark(title, url) 247 self.__addBookmark(title, url)
249 self.sortItems() 248 self.sortItems()
250 self.__saveBookmarks() 249 self.__saveBookmarks()
251 250
252 @pyqtSlot() 251 @pyqtSlot()
253 def __bookmarkCurrentPage(self): 252 def __bookmarkCurrentPage(self):
254 """ 253 """
255 Private slot to bookmark the current page. 254 Private slot to bookmark the current page.
256 """ 255 """
257 currentViewer = self.__helpViewer.currentViewer() 256 currentViewer = self.__helpViewer.currentViewer()
258 title = currentViewer.pageTitle() 257 title = currentViewer.pageTitle()
259 url = currentViewer.link() 258 url = currentViewer.link()
260 self.addBookmark(title, url) 259 self.addBookmark(title, url)
261 260
262 @pyqtSlot() 261 @pyqtSlot()
263 def __newBookmark(self): 262 def __newBookmark(self):
264 """ 263 """
265 Private slot to create a new bookmark. 264 Private slot to create a new bookmark.
266 """ 265 """
268 if dlg.exec() == QDialog.DialogCode.Accepted: 267 if dlg.exec() == QDialog.DialogCode.Accepted:
269 title, url = dlg.getData() 268 title, url = dlg.getData()
270 self.__addBookmark(title, url) 269 self.__addBookmark(title, url)
271 self.sortItems() 270 self.sortItems()
272 self.__saveBookmarks() 271 self.__saveBookmarks()
273 272
274 @pyqtSlot() 273 @pyqtSlot()
275 def __editBookmark(self, itm): 274 def __editBookmark(self, itm):
276 """ 275 """
277 Private slot to edit a bookmark. 276 Private slot to edit a bookmark.
278 277
279 @param itm reference to the bookmark item to be edited 278 @param itm reference to the bookmark item to be edited
280 @type QListWidgetItem 279 @type QListWidgetItem
281 """ 280 """
282 dlg = HelpBookmarkPropertiesDialog( 281 dlg = HelpBookmarkPropertiesDialog(
283 itm.text(), itm.data(self.UrlRole).toString(), self) 282 itm.text(), itm.data(self.UrlRole).toString(), self
283 )
284 if dlg.exec() == QDialog.DialogCode.Accepted: 284 if dlg.exec() == QDialog.DialogCode.Accepted:
285 title, url = dlg.getData() 285 title, url = dlg.getData()
286 itm.setText(title) 286 itm.setText(title)
287 itm.setData(self.UrlRole, QUrl(url)) 287 itm.setData(self.UrlRole, QUrl(url))
288 itm.setToolTip(url) 288 itm.setToolTip(url)
289 self.sortItems() 289 self.sortItems()
290 self.__saveBookmarks() 290 self.__saveBookmarks()
291 291
292 @pyqtSlot(QListWidgetItem) 292 @pyqtSlot(QListWidgetItem)
293 def __bookmarkActivated(self, itm): 293 def __bookmarkActivated(self, itm):
294 """ 294 """
295 Private slot handling the activation of a bookmark. 295 Private slot handling the activation of a bookmark.
296 296
297 @param itm reference to the activated item 297 @param itm reference to the activated item
298 @type QListWidgetItem 298 @type QListWidgetItem
299 """ 299 """
300 url = itm.data(self.UrlRole) 300 url = itm.data(self.UrlRole)
301 if url and not url.isEmpty() and url.isValid(): 301 if url and not url.isEmpty() and url.isValid():
302 buttons = QApplication.mouseButtons() 302 buttons = QApplication.mouseButtons()
303 modifiers = QApplication.keyboardModifiers() 303 modifiers = QApplication.keyboardModifiers()
304 304
305 if buttons & Qt.MouseButton.MiddleButton: 305 if buttons & Qt.MouseButton.MiddleButton:
306 self.newTab.emit(url) 306 self.newTab.emit(url)
307 else: 307 else:
308 if ( 308 if modifiers & (
309 modifiers & ( 309 Qt.KeyboardModifier.ControlModifier
310 Qt.KeyboardModifier.ControlModifier | 310 | Qt.KeyboardModifier.ShiftModifier
311 Qt.KeyboardModifier.ShiftModifier 311 ) == (
312 ) == ( 312 Qt.KeyboardModifier.ControlModifier
313 Qt.KeyboardModifier.ControlModifier | 313 | Qt.KeyboardModifier.ShiftModifier
314 Qt.KeyboardModifier.ShiftModifier
315 )
316 ): 314 ):
317 self.newBackgroundTab.emit(url) 315 self.newBackgroundTab.emit(url)
318 elif modifiers & Qt.KeyboardModifier.ControlModifier: 316 elif modifiers & Qt.KeyboardModifier.ControlModifier:
319 self.newTab.emit(url) 317 self.newTab.emit(url)
320 elif ( 318 elif (
321 modifiers & Qt.KeyboardModifier.ShiftModifier and 319 modifiers & Qt.KeyboardModifier.ShiftModifier
322 not self.__internal 320 and not self.__internal
323 ): 321 ):
324 self.newWindow.emit(url) 322 self.newWindow.emit(url)
325 else: 323 else:
326 self.openUrl.emit(url) 324 self.openUrl.emit(url)
327 325
328 def __openBookmarks(self, selected=False): 326 def __openBookmarks(self, selected=False):
329 """ 327 """
330 Private method to open all or selected bookmarks. 328 Private method to open all or selected bookmarks.
331 329
332 @param selected flag indicating to open the selected bookmarks 330 @param selected flag indicating to open the selected bookmarks
333 (defaults to False) 331 (defaults to False)
334 @type bool (optional) 332 @type bool (optional)
335 """ 333 """
336 items = ( 334 items = (
337 self.selectedItems() 335 self.selectedItems()
338 if selected else 336 if selected
339 [self.item(row) for row in range(self.count())] 337 else [self.item(row) for row in range(self.count())]
340 ) 338 )
341 339
342 for itm in items: 340 for itm in items:
343 url = itm.data(self.UrlRole) 341 url = itm.data(self.UrlRole)
344 if url is not None and not url.isEmpty() and url.isValid(): 342 if url is not None and not url.isEmpty() and url.isValid():
345 self.newTab.emit(url) 343 self.newTab.emit(url)
346 344
347 def __deleteBookmarks(self, items): 345 def __deleteBookmarks(self, items):
348 """ 346 """
349 Private method to delete the given bookmark items. 347 Private method to delete the given bookmark items.
350 348
351 @param items list of bookmarks to be deleted 349 @param items list of bookmarks to be deleted
352 @type list of QListWidgetItem 350 @type list of QListWidgetItem
353 """ 351 """
354 from UI.DeleteFilesConfirmationDialog import ( 352 from UI.DeleteFilesConfirmationDialog import DeleteFilesConfirmationDialog
355 DeleteFilesConfirmationDialog 353
356 )
357 dlg = DeleteFilesConfirmationDialog( 354 dlg = DeleteFilesConfirmationDialog(
358 self, 355 self,
359 self.tr("Delete Bookmarks"), 356 self.tr("Delete Bookmarks"),
360 self.tr("Shall these bookmarks really be deleted?"), 357 self.tr("Shall these bookmarks really be deleted?"),
361 [itm.text() for itm in items] 358 [itm.text() for itm in items],
362 ) 359 )
363 if dlg.exec() == QDialog.DialogCode.Accepted: 360 if dlg.exec() == QDialog.DialogCode.Accepted:
364 for itm in items: 361 for itm in items:
365 self.takeItem(self.row(itm)) 362 self.takeItem(self.row(itm))
366 del itm 363 del itm
367 self.__saveBookmarks() 364 self.__saveBookmarks()
368 365
369 def __loadBookmarks(self): 366 def __loadBookmarks(self):
370 """ 367 """
371 Private method to load the defined bookmarks. 368 Private method to load the defined bookmarks.
372 """ 369 """
373 bookmarksStr = Preferences.getHelp("Bookmarks") 370 bookmarksStr = Preferences.getHelp("Bookmarks")
374 with contextlib.suppress(ValueError): 371 with contextlib.suppress(ValueError):
375 bookmarks = json.loads(bookmarksStr) 372 bookmarks = json.loads(bookmarksStr)
376 373
377 self.clear() 374 self.clear()
378 for bookmark in bookmarks: 375 for bookmark in bookmarks:
379 self.__addBookmark(bookmark["title"], bookmark["url"]) 376 self.__addBookmark(bookmark["title"], bookmark["url"])
380 self.sortItems() 377 self.sortItems()
381 378
382 def __saveBookmarks(self): 379 def __saveBookmarks(self):
383 """ 380 """
384 Private method to save the defined bookmarks. 381 Private method to save the defined bookmarks.
385 """ 382 """
386 bookmarks = [] 383 bookmarks = []
387 for row in range(self.count()): 384 for row in range(self.count()):
388 itm = self.item(row) 385 itm = self.item(row)
389 bookmarks.append({ 386 bookmarks.append(
390 "title": itm.text(), 387 {
391 "url": itm.data(self.UrlRole).toString(), 388 "title": itm.text(),
392 }) 389 "url": itm.data(self.UrlRole).toString(),
390 }
391 )
393 Preferences.setHelp("Bookmarks", json.dumps(bookmarks)) 392 Preferences.setHelp("Bookmarks", json.dumps(bookmarks))
394 393
395 @pyqtSlot() 394 @pyqtSlot()
396 def __exportBookmarks(self, selected=False): 395 def __exportBookmarks(self, selected=False):
397 """ 396 """
398 Private slot to export the bookmarks into a JSON file. 397 Private slot to export the bookmarks into a JSON file.
399 398
400 @param selected flag indicating to export the selected bookmarks 399 @param selected flag indicating to export the selected bookmarks
401 (defaults to False) 400 (defaults to False)
402 @type bool (optional) 401 @type bool (optional)
403 """ 402 """
404 filename, selectedFilter = EricFileDialog.getSaveFileNameAndFilter( 403 filename, selectedFilter = EricFileDialog.getSaveFileNameAndFilter(
405 self, 404 self,
406 self.tr("Export Bookmarks"), 405 self.tr("Export Bookmarks"),
407 "", 406 "",
408 self.tr("eric Bookmarks Files (*.json);;All Files (*)"), 407 self.tr("eric Bookmarks Files (*.json);;All Files (*)"),
409 None, 408 None,
410 EricFileDialog.DontConfirmOverwrite 409 EricFileDialog.DontConfirmOverwrite,
411 ) 410 )
412 if filename: 411 if filename:
413 ext = os.path.splitext(filename)[1] 412 ext = os.path.splitext(filename)[1]
414 if not ext: 413 if not ext:
415 ex = selectedFilter.split("(*")[1].split(")")[0] 414 ex = selectedFilter.split("(*")[1].split(")")[0]
416 if ex: 415 if ex:
417 filename += ex 416 filename += ex
418 417
419 if os.path.exists(filename): 418 if os.path.exists(filename):
420 ok = EricMessageBox.yesNo( 419 ok = EricMessageBox.yesNo(
421 self, 420 self,
422 self.tr("Export Bookmarks"), 421 self.tr("Export Bookmarks"),
423 self.tr("""The file <b>{0}</b> already exists. Do you""" 422 self.tr(
424 """ want to overwrite it?""").format(filename)) 423 """The file <b>{0}</b> already exists. Do you"""
424 """ want to overwrite it?"""
425 ).format(filename),
426 )
425 if not ok: 427 if not ok:
426 return 428 return
427 429
428 bookmarksDict = { 430 bookmarksDict = {
429 "creator": "eric7", 431 "creator": "eric7",
430 "version": 1, 432 "version": 1,
431 "created": datetime.datetime.now().isoformat( 433 "created": datetime.datetime.now().isoformat(
432 sep=" ", timespec="seconds"), 434 sep=" ", timespec="seconds"
433 "bookmarks": [] 435 ),
436 "bookmarks": [],
434 } 437 }
435 bookmarkItems = ( 438 bookmarkItems = (
436 self.selectedItems() 439 self.selectedItems()
437 if selected else 440 if selected
438 [self.item(row) for row in range(self.count())] 441 else [self.item(row) for row in range(self.count())]
439 ) 442 )
440 for bookmarkItem in bookmarkItems: 443 for bookmarkItem in bookmarkItems:
441 bookmarksDict["bookmarks"].append({ 444 bookmarksDict["bookmarks"].append(
442 "type": "url", 445 {
443 "title": bookmarkItem.text(), 446 "type": "url",
444 "url": bookmarkItem.data(self.UrlRole).toString(), 447 "title": bookmarkItem.text(),
445 }) 448 "url": bookmarkItem.data(self.UrlRole).toString(),
446 449 }
450 )
451
447 jsonStr = json.dumps(bookmarksDict, indent=2, sort_keys=True) 452 jsonStr = json.dumps(bookmarksDict, indent=2, sort_keys=True)
448 try: 453 try:
449 with open(filename, "w") as f: 454 with open(filename, "w") as f:
450 f.write(jsonStr) 455 f.write(jsonStr)
451 except OSError as err: 456 except OSError as err:
452 EricMessageBox.critical( 457 EricMessageBox.critical(
453 self, 458 self,
454 self.tr("Export Bookmarks"), 459 self.tr("Export Bookmarks"),
455 self.tr("""<p>The bookmarks could not be exported""" 460 self.tr(
456 """ to <b>{0}</b>.</p><p>Reason: {1}</p>""") 461 """<p>The bookmarks could not be exported"""
457 .format(filename, str(err))) 462 """ to <b>{0}</b>.</p><p>Reason: {1}</p>"""
458 463 ).format(filename, str(err)),
464 )
465
459 @pyqtSlot() 466 @pyqtSlot()
460 def __importBookmarks(self): 467 def __importBookmarks(self):
461 """ 468 """
462 Private slot to import bookmarks from a JSON file. 469 Private slot to import bookmarks from a JSON file.
463 """ 470 """
464 from .HelpBookmarksImportDialog import HelpBookmarksImportDialog 471 from .HelpBookmarksImportDialog import HelpBookmarksImportDialog
465 472
466 dlg = HelpBookmarksImportDialog(self) 473 dlg = HelpBookmarksImportDialog(self)
467 if dlg.exec() == QDialog.DialogCode.Accepted: 474 if dlg.exec() == QDialog.DialogCode.Accepted:
468 replace, filename = dlg.getData() 475 replace, filename = dlg.getData()
469 476
470 try: 477 try:
471 with open(filename, "r") as f: 478 with open(filename, "r") as f:
472 jsonStr = f.read() 479 jsonStr = f.read()
473 bookmarks = json.loads(jsonStr) 480 bookmarks = json.loads(jsonStr)
474 except (OSError, json.JSONDecodeError) as err: 481 except (OSError, json.JSONDecodeError) as err:
476 self, 483 self,
477 self.tr("Import Bookmarks"), 484 self.tr("Import Bookmarks"),
478 self.tr( 485 self.tr(
479 "<p>The bookmarks file <b>{0}</b> could not be " 486 "<p>The bookmarks file <b>{0}</b> could not be "
480 "read.</p><p>Reason: {1}</p>" 487 "read.</p><p>Reason: {1}</p>"
481 ).format(filename, str(err)) 488 ).format(filename, str(err)),
482 ) 489 )
483 return 490 return
484 491
485 if not isinstance(bookmarks, dict): 492 if not isinstance(bookmarks, dict):
486 EricMessageBox.critical( 493 EricMessageBox.critical(
487 self, 494 self,
488 self.tr("Import Bookmarks"), 495 self.tr("Import Bookmarks"),
489 self.tr( 496 self.tr(
490 "The bookmarks file <b>{0}</b> has invalid contents." 497 "The bookmarks file <b>{0}</b> has invalid contents."
491 ).format(filename) 498 ).format(filename),
492 ) 499 )
493 return 500 return
494 501
495 try: 502 try:
496 if bookmarks["creator"] != "eric7": 503 if bookmarks["creator"] != "eric7":
497 EricMessageBox.critical( 504 EricMessageBox.critical(
498 self, 505 self,
499 self.tr("Import Bookmarks"), 506 self.tr("Import Bookmarks"),
500 self.tr( 507 self.tr(
501 "The bookmarks file <b>{0}</b> was not created" 508 "The bookmarks file <b>{0}</b> was not created"
502 " with 'eric7'." 509 " with 'eric7'."
503 ).format(filename) 510 ).format(filename),
504 ) 511 )
505 return 512 return
506 513
507 if bookmarks["version"] != 1: 514 if bookmarks["version"] != 1:
508 EricMessageBox.critical( 515 EricMessageBox.critical(
509 self, 516 self,
510 self.tr("Import Bookmarks"), 517 self.tr("Import Bookmarks"),
511 self.tr( 518 self.tr(
512 "The bookmarks file <b>{0}</b> has an unsupported" 519 "The bookmarks file <b>{0}</b> has an unsupported"
513 " format version." 520 " format version."
514 ).format(filename) 521 ).format(filename),
515 ) 522 )
516 return 523 return
517 524
518 if replace: 525 if replace:
519 self.clear() 526 self.clear()
520 527
521 for bookmark in bookmarks["bookmarks"]: 528 for bookmark in bookmarks["bookmarks"]:
522 if bookmark["type"] == "url": 529 if bookmark["type"] == "url":
523 self.__addBookmark(bookmark["title"], bookmark["url"]) 530 self.__addBookmark(bookmark["title"], bookmark["url"])
524 self.sortItems() 531 self.sortItems()
525 self.__saveBookmarks() 532 self.__saveBookmarks()
526 533
527 except KeyError: 534 except KeyError:
528 EricMessageBox.critical( 535 EricMessageBox.critical(
529 self, 536 self,
530 self.tr("Import Bookmarks"), 537 self.tr("Import Bookmarks"),
531 self.tr( 538 self.tr(
532 "The bookmarks file <b>{0}</b> has invalid contents." 539 "The bookmarks file <b>{0}</b> has invalid contents."
533 ).format(filename) 540 ).format(filename),
534 ) 541 )

eric ide

mercurial