PluginManager/PluginRepositoryDialog.py

changeset 2992
dbdf27746da5
parent 2960
9453efa25fd5
child 3020
542e97d4ecb3
child 3057
10516539f238
equal deleted inserted replaced
2991:226481ff40d1 2992:dbdf27746da5
10 10
11 import sys 11 import sys
12 import os 12 import os
13 import zipfile 13 import zipfile
14 14
15 from PyQt4.QtCore import pyqtSignal, pyqtSlot, Qt, QFile, QIODevice, QUrl, QProcess 15 from PyQt4.QtCore import pyqtSignal, pyqtSlot, Qt, QFile, QIODevice, QUrl, \
16 from PyQt4.QtGui import QWidget, QDialogButtonBox, QAbstractButton, QTreeWidgetItem, \ 16 QProcess
17 QDialog, QVBoxLayout 17 from PyQt4.QtGui import QWidget, QDialogButtonBox, QAbstractButton, \
18 from PyQt4.QtNetwork import QNetworkAccessManager, QNetworkRequest, QNetworkReply 18 QTreeWidgetItem, QDialog, QVBoxLayout
19 from PyQt4.QtNetwork import QNetworkAccessManager, QNetworkRequest, \
20 QNetworkReply
19 21
20 from .Ui_PluginRepositoryDialog import Ui_PluginRepositoryDialog 22 from .Ui_PluginRepositoryDialog import Ui_PluginRepositoryDialog
21 23
22 from E5Gui import E5MessageBox 24 from E5Gui import E5MessageBox
23 from E5Gui.E5MainWindow import E5MainWindow 25 from E5Gui.E5MainWindow import E5MainWindow
45 47
46 class PluginRepositoryWidget(QWidget, Ui_PluginRepositoryDialog): 48 class PluginRepositoryWidget(QWidget, Ui_PluginRepositoryDialog):
47 """ 49 """
48 Class implementing a dialog showing the available plugins. 50 Class implementing a dialog showing the available plugins.
49 51
50 @signal closeAndInstall() emitted when the Close & Install button is pressed 52 @signal closeAndInstall() emitted when the Close & Install button is
53 pressed
51 """ 54 """
52 closeAndInstall = pyqtSignal() 55 closeAndInstall = pyqtSignal()
53 56
54 def __init__(self, parent=None, external=False): 57 def __init__(self, parent=None, external=False):
55 """ 58 """
60 window (boolean) 63 window (boolean)
61 """ 64 """
62 super().__init__(parent) 65 super().__init__(parent)
63 self.setupUi(self) 66 self.setupUi(self)
64 67
65 self.__updateButton = \ 68 self.__updateButton = self.buttonBox.addButton(
66 self.buttonBox.addButton(self.trUtf8("Update"), QDialogButtonBox.ActionRole) 69 self.trUtf8("Update"), QDialogButtonBox.ActionRole)
67 self.__downloadButton = \ 70 self.__downloadButton = self.buttonBox.addButton(
68 self.buttonBox.addButton(self.trUtf8("Download"), QDialogButtonBox.ActionRole) 71 self.trUtf8("Download"), QDialogButtonBox.ActionRole)
69 self.__downloadButton.setEnabled(False) 72 self.__downloadButton.setEnabled(False)
70 self.__downloadInstallButton = \ 73 self.__downloadInstallButton = \
71 self.buttonBox.addButton(self.trUtf8("Download && Install"), 74 self.buttonBox.addButton(self.trUtf8("Download && Install"),
72 QDialogButtonBox.ActionRole) 75 QDialogButtonBox.ActionRole)
73 self.__downloadInstallButton.setEnabled(False) 76 self.__downloadInstallButton.setEnabled(False)
74 self.__downloadCancelButton = \ 77 self.__downloadCancelButton = self.buttonBox.addButton(
75 self.buttonBox.addButton(self.trUtf8("Cancel"), QDialogButtonBox.ActionRole) 78 self.trUtf8("Cancel"), QDialogButtonBox.ActionRole)
76 self.__installButton = \ 79 self.__installButton = \
77 self.buttonBox.addButton(self.trUtf8("Close && Install"), 80 self.buttonBox.addButton(self.trUtf8("Close && Install"),
78 QDialogButtonBox.ActionRole) 81 QDialogButtonBox.ActionRole)
79 self.__downloadCancelButton.setEnabled(False) 82 self.__downloadCancelButton.setEnabled(False)
80 self.__installButton.setEnabled(False) 83 self.__installButton.setEnabled(False)
81 84
82 self.repositoryUrlEdit.setText(Preferences.getUI("PluginRepositoryUrl5")) 85 self.repositoryUrlEdit.setText(
83 86 Preferences.getUI("PluginRepositoryUrl5"))
84 self.repositoryList.headerItem().setText(self.repositoryList.columnCount(), "") 87
88 self.repositoryList.headerItem().setText(
89 self.repositoryList.columnCount(), "")
85 self.repositoryList.header().setSortIndicator(0, Qt.AscendingOrder) 90 self.repositoryList.header().setSortIndicator(0, Qt.AscendingOrder)
86 91
87 self.pluginRepositoryFile = \ 92 self.pluginRepositoryFile = \
88 os.path.join(Utilities.getConfigDir(), "PluginRepository") 93 os.path.join(Utilities.getConfigDir(), "PluginRepository")
89 94
241 self.__pluginsToDownload = [] 246 self.__pluginsToDownload = []
242 self.__downloadButton.setEnabled(False) 247 self.__downloadButton.setEnabled(False)
243 self.__downloadInstallButton.setEnabled(False) 248 self.__downloadInstallButton.setEnabled(False)
244 self.__installButton.setEnabled(False) 249 self.__installButton.setEnabled(False)
245 for itm in self.repositoryList.selectedItems(): 250 for itm in self.repositoryList.selectedItems():
246 if itm not in [self.__stableItem, self.__unstableItem, self.__unknownItem]: 251 if itm not in [self.__stableItem, self.__unstableItem,
252 self.__unknownItem]:
247 url = itm.data(0, urlRole) 253 url = itm.data(0, urlRole)
248 filename = os.path.join( 254 filename = os.path.join(
249 Preferences.getPluginManager("DownloadPath"), 255 Preferences.getPluginManager("DownloadPath"),
250 itm.data(0, filenameRole)) 256 itm.data(0, filenameRole))
251 self.__pluginsToDownload.append((url, filename)) 257 self.__pluginsToDownload.append((url, filename))
282 288
283 def __resortRepositoryList(self): 289 def __resortRepositoryList(self):
284 """ 290 """
285 Private method to resort the tree. 291 Private method to resort the tree.
286 """ 292 """
287 self.repositoryList.sortItems(self.repositoryList.sortColumn(), 293 self.repositoryList.sortItems(
288 self.repositoryList.header().sortIndicatorOrder()) 294 self.repositoryList.sortColumn(),
295 self.repositoryList.header().sortIndicatorOrder())
289 296
290 def __populateList(self): 297 def __populateList(self):
291 """ 298 """
292 Private method to populate the list of available plugins. 299 Private method to populate the list of available plugins.
293 """ 300 """
313 url = Preferences.getUI("PluginRepositoryUrl5") 320 url = Preferences.getUI("PluginRepositoryUrl5")
314 if url != self.repositoryUrlEdit.text(): 321 if url != self.repositoryUrlEdit.text():
315 self.repositoryUrlEdit.setText(url) 322 self.repositoryUrlEdit.setText(url)
316 E5MessageBox.warning(self, 323 E5MessageBox.warning(self,
317 self.trUtf8("Plugins Repository URL Changed"), 324 self.trUtf8("Plugins Repository URL Changed"),
318 self.trUtf8("""The URL of the Plugins Repository has""" 325 self.trUtf8(
319 """ changed. Select the "Update" button to get""" 326 """The URL of the Plugins Repository has"""
320 """ the new repository file.""")) 327 """ changed. Select the "Update" button to get"""
328 """ the new repository file."""))
321 else: 329 else:
322 E5MessageBox.critical(self, 330 E5MessageBox.critical(self,
323 self.trUtf8("Read plugins repository file"), 331 self.trUtf8("Read plugins repository file"),
324 self.trUtf8("<p>The plugins repository file <b>{0}</b> " 332 self.trUtf8("<p>The plugins repository file <b>{0}</b> "
325 "could not be read. Select Update</p>")\ 333 "could not be read. Select Update</p>")\
326 .format(self.pluginRepositoryFile)) 334 .format(self.pluginRepositoryFile))
327 else: 335 else:
328 self.__repositoryMissing = True 336 self.__repositoryMissing = True
329 QTreeWidgetItem(self.repositoryList, 337 QTreeWidgetItem(self.repositoryList,
330 ["", 338 ["", self.trUtf8(
331 self.trUtf8("No plugin repository file available.\nSelect Update.") 339 "No plugin repository file available.\nSelect Update.")
332 ]) 340 ])
333 self.repositoryList.resizeColumnToContents(1) 341 self.repositoryList.resizeColumnToContents(1)
334 342
335 def __downloadFile(self, url, filename, doneMethod=None): 343 def __downloadFile(self, url, filename, doneMethod=None):
336 """ 344 """
378 ok = False 386 ok = False
379 if not self.__downloadCancelled: 387 if not self.__downloadCancelled:
380 E5MessageBox.warning(self, 388 E5MessageBox.warning(self,
381 self.trUtf8("Error downloading file"), 389 self.trUtf8("Error downloading file"),
382 self.trUtf8( 390 self.trUtf8(
383 """<p>Could not download the requested file from {0}.</p>""" 391 """<p>Could not download the requested file"""
384 """<p>Error: {1}</p>""" 392 """ from {0}.</p><p>Error: {1}</p>"""
385 ).format(self.__downloadURL, reply.errorString()) 393 ).format(self.__downloadURL, reply.errorString())
386 ) 394 )
387 self.downloadProgress.setValue(0) 395 self.downloadProgress.setValue(0)
388 self.__downloadURL = None 396 self.__downloadURL = None
389 self.__downloadIODevice.remove() 397 self.__downloadIODevice.remove()
391 if self.repositoryList.topLevelItemCount(): 399 if self.repositoryList.topLevelItemCount():
392 if self.repositoryList.currentItem() is None: 400 if self.repositoryList.currentItem() is None:
393 self.repositoryList.setCurrentItem( 401 self.repositoryList.setCurrentItem(
394 self.repositoryList.topLevelItem(0)) 402 self.repositoryList.topLevelItem(0))
395 else: 403 else:
396 self.__downloadButton.setEnabled(len(self.__selectedItems())) 404 self.__downloadButton.setEnabled(
397 self.__downloadInstallButton.setEnabled(len(self.__selectedItems())) 405 len(self.__selectedItems()))
406 self.__downloadInstallButton.setEnabled(
407 len(self.__selectedItems()))
398 return 408 return
399 409
400 self.__downloadIODevice.open(QIODevice.WriteOnly) 410 self.__downloadIODevice.open(QIODevice.WriteOnly)
401 self.__downloadIODevice.write(reply.readAll()) 411 self.__downloadIODevice.write(reply.readAll())
402 self.__downloadIODevice.close() 412 self.__downloadIODevice.close()
428 """ 438 """
429 if total: 439 if total:
430 self.downloadProgress.setMaximum(total) 440 self.downloadProgress.setMaximum(total)
431 self.downloadProgress.setValue(done) 441 self.downloadProgress.setValue(done)
432 442
433 def addEntry(self, name, short, description, url, author, version, filename, status): 443 def addEntry(self, name, short, description, url, author, version,
444 filename, status):
434 """ 445 """
435 Public method to add an entry to the list. 446 Public method to add an entry to the list.
436 447
437 @param name data for the name field (string) 448 @param name data for the name field (string)
438 @param short data for the short field (string) 449 @param short data for the short field (string)
444 @param status status of the plugin (string [stable, unstable, unknown]) 455 @param status status of the plugin (string [stable, unstable, unknown])
445 """ 456 """
446 if status == "stable": 457 if status == "stable":
447 if self.__stableItem is None: 458 if self.__stableItem is None:
448 self.__stableItem = \ 459 self.__stableItem = \
449 QTreeWidgetItem(self.repositoryList, [self.trUtf8("Stable")]) 460 QTreeWidgetItem(self.repositoryList,
461 [self.trUtf8("Stable")])
450 self.__stableItem.setExpanded(True) 462 self.__stableItem.setExpanded(True)
451 parent = self.__stableItem 463 parent = self.__stableItem
452 elif status == "unstable": 464 elif status == "unstable":
453 if self.__unstableItem is None: 465 if self.__unstableItem is None:
454 self.__unstableItem = \ 466 self.__unstableItem = \
455 QTreeWidgetItem(self.repositoryList, [self.trUtf8("Unstable")]) 467 QTreeWidgetItem(self.repositoryList,
468 [self.trUtf8("Unstable")])
456 self.__unstableItem.setExpanded(True) 469 self.__unstableItem.setExpanded(True)
457 parent = self.__unstableItem 470 parent = self.__unstableItem
458 else: 471 else:
459 if self.__unknownItem is None: 472 if self.__unknownItem is None:
460 self.__unknownItem = \ 473 self.__unknownItem = \
461 QTreeWidgetItem(self.repositoryList, [self.trUtf8("Unknown")]) 474 QTreeWidgetItem(self.repositoryList,
475 [self.trUtf8("Unknown")])
462 self.__unknownItem.setExpanded(True) 476 self.__unknownItem.setExpanded(True)
463 parent = self.__unknownItem 477 parent = self.__unknownItem
464 itm = QTreeWidgetItem(parent, [name, version, short]) 478 itm = QTreeWidgetItem(parent, [name, version, short])
465 479
466 itm.setData(0, urlRole, url) 480 itm.setData(0, urlRole, url)
521 return self.__pluginsDownloaded 535 return self.__pluginsDownloaded
522 536
523 @pyqtSlot(bool) 537 @pyqtSlot(bool)
524 def on_repositoryUrlEditButton_toggled(self, checked): 538 def on_repositoryUrlEditButton_toggled(self, checked):
525 """ 539 """
526 Private slot to set the read only status of the repository URL line edit. 540 Private slot to set the read only status of the repository URL line
541 edit.
527 542
528 @param checked state of the push button (boolean) 543 @param checked state of the push button (boolean)
529 """ 544 """
530 self.repositoryUrlEdit.setReadOnly(not checked) 545 self.repositoryUrlEdit.setReadOnly(not checked)
531 546
585 self.cw = PluginRepositoryWidget(self, external=True) 600 self.cw = PluginRepositoryWidget(self, external=True)
586 size = self.cw.size() 601 size = self.cw.size()
587 self.setCentralWidget(self.cw) 602 self.setCentralWidget(self.cw)
588 self.resize(size) 603 self.resize(size)
589 604
590 self.setStyle(Preferences.getUI("Style"), Preferences.getUI("StyleSheet")) 605 self.setStyle(Preferences.getUI("Style"),
606 Preferences.getUI("StyleSheet"))
591 607
592 self.cw.buttonBox.accepted[()].connect(self.close) 608 self.cw.buttonBox.accepted[()].connect(self.close)
593 self.cw.buttonBox.rejected[()].connect(self.close) 609 self.cw.buttonBox.rejected[()].connect(self.close)
594 self.cw.closeAndInstall.connect(self.__startPluginInstall) 610 self.cw.closeAndInstall.connect(self.__startPluginInstall)
595 611
602 618
603 args = [] 619 args = []
604 args.append(applPath) 620 args.append(applPath)
605 args += self.cw.getDownloadedPlugins() 621 args += self.cw.getDownloadedPlugins()
606 622
607 if not os.path.isfile(applPath) or not proc.startDetached(sys.executable, args): 623 if not os.path.isfile(applPath) or \
624 not proc.startDetached(sys.executable, args):
608 E5MessageBox.critical(self, 625 E5MessageBox.critical(self,
609 self.trUtf8('Process Generation Error'), 626 self.trUtf8('Process Generation Error'),
610 self.trUtf8( 627 self.trUtf8(
611 '<p>Could not start the process.<br>' 628 '<p>Could not start the process.<br>'
612 'Ensure that it is available as <b>{0}</b>.</p>' 629 'Ensure that it is available as <b>{0}</b>.</p>'

eric ide

mercurial