12 |
12 |
13 import sys |
13 import sys |
14 import os |
14 import os |
15 import zipfile |
15 import zipfile |
16 |
16 |
17 from PyQt4.QtCore import pyqtSignal, pyqtSlot, Qt, QFile, QIODevice, QUrl, QProcess |
17 from PyQt4.QtCore import pyqtSignal, pyqtSlot, Qt, QFile, QIODevice, QUrl, \ |
18 from PyQt4.QtGui import QWidget, QDialogButtonBox, QAbstractButton, QTreeWidgetItem, \ |
18 QProcess |
19 QDialog, QVBoxLayout |
19 from PyQt4.QtGui import QWidget, QDialogButtonBox, QAbstractButton, \ |
20 from PyQt4.QtNetwork import QNetworkAccessManager, QNetworkRequest, QNetworkReply |
20 QTreeWidgetItem, QDialog, QVBoxLayout |
|
21 from PyQt4.QtNetwork import QNetworkAccessManager, QNetworkRequest, \ |
|
22 QNetworkReply |
21 |
23 |
22 from .Ui_PluginRepositoryDialog import Ui_PluginRepositoryDialog |
24 from .Ui_PluginRepositoryDialog import Ui_PluginRepositoryDialog |
23 |
25 |
24 from E5Gui import E5MessageBox |
26 from E5Gui import E5MessageBox |
25 from E5Gui.E5MainWindow import E5MainWindow |
27 from E5Gui.E5MainWindow import E5MainWindow |
47 |
49 |
48 class PluginRepositoryWidget(QWidget, Ui_PluginRepositoryDialog): |
50 class PluginRepositoryWidget(QWidget, Ui_PluginRepositoryDialog): |
49 """ |
51 """ |
50 Class implementing a dialog showing the available plugins. |
52 Class implementing a dialog showing the available plugins. |
51 |
53 |
52 @signal closeAndInstall() emitted when the Close & Install button is pressed |
54 @signal closeAndInstall() emitted when the Close & Install button is |
|
55 pressed |
53 """ |
56 """ |
54 closeAndInstall = pyqtSignal() |
57 closeAndInstall = pyqtSignal() |
55 |
58 |
56 def __init__(self, parent=None, external=False): |
59 def __init__(self, parent=None, external=False): |
57 """ |
60 """ |
58 Constructor |
61 Constructor |
59 |
62 |
60 @param parent parent of this dialog (QWidget) |
63 @param parent parent of this dialog (QWidget) |
|
64 @param external flag indicating an instatiation as a main |
|
65 window (boolean) |
61 """ |
66 """ |
62 super(PluginRepositoryWidget, self).__init__(parent) |
67 super(PluginRepositoryWidget, self).__init__(parent) |
63 self.setupUi(self) |
68 self.setupUi(self) |
64 |
69 |
65 self.__updateButton = \ |
70 self.__updateButton = self.buttonBox.addButton( |
66 self.buttonBox.addButton(self.trUtf8("Update"), QDialogButtonBox.ActionRole) |
71 self.trUtf8("Update"), QDialogButtonBox.ActionRole) |
67 self.__downloadButton = \ |
72 self.__downloadButton = self.buttonBox.addButton( |
68 self.buttonBox.addButton(self.trUtf8("Download"), QDialogButtonBox.ActionRole) |
73 self.trUtf8("Download"), QDialogButtonBox.ActionRole) |
69 self.__downloadButton.setEnabled(False) |
74 self.__downloadButton.setEnabled(False) |
70 self.__downloadInstallButton = \ |
75 self.__downloadInstallButton = \ |
71 self.buttonBox.addButton(self.trUtf8("Download && Install"), |
76 self.buttonBox.addButton(self.trUtf8("Download && Install"), |
72 QDialogButtonBox.ActionRole) |
77 QDialogButtonBox.ActionRole) |
73 self.__downloadInstallButton.setEnabled(False) |
78 self.__downloadInstallButton.setEnabled(False) |
74 self.__downloadCancelButton = \ |
79 self.__downloadCancelButton = self.buttonBox.addButton( |
75 self.buttonBox.addButton(self.trUtf8("Cancel"), QDialogButtonBox.ActionRole) |
80 self.trUtf8("Cancel"), QDialogButtonBox.ActionRole) |
76 self.__installButton = \ |
81 self.__installButton = \ |
77 self.buttonBox.addButton(self.trUtf8("Close && Install"), |
82 self.buttonBox.addButton(self.trUtf8("Close && Install"), |
78 QDialogButtonBox.ActionRole) |
83 QDialogButtonBox.ActionRole) |
79 self.__downloadCancelButton.setEnabled(False) |
84 self.__downloadCancelButton.setEnabled(False) |
80 self.__installButton.setEnabled(False) |
85 self.__installButton.setEnabled(False) |
81 |
86 |
82 self.repositoryUrlEdit.setText(Preferences.getUI("PluginRepositoryUrl5")) |
87 self.repositoryUrlEdit.setText( |
83 |
88 Preferences.getUI("PluginRepositoryUrl5")) |
84 self.repositoryList.headerItem().setText(self.repositoryList.columnCount(), "") |
89 |
|
90 self.repositoryList.headerItem().setText( |
|
91 self.repositoryList.columnCount(), "") |
85 self.repositoryList.header().setSortIndicator(0, Qt.AscendingOrder) |
92 self.repositoryList.header().setSortIndicator(0, Qt.AscendingOrder) |
86 |
93 |
87 self.pluginRepositoryFile = \ |
94 self.pluginRepositoryFile = \ |
88 os.path.join(Utilities.getConfigDir(), "PluginRepository") |
95 os.path.join(Utilities.getConfigDir(), "PluginRepository") |
89 |
96 |
239 self.__pluginsToDownload = [] |
248 self.__pluginsToDownload = [] |
240 self.__downloadButton.setEnabled(False) |
249 self.__downloadButton.setEnabled(False) |
241 self.__downloadInstallButton.setEnabled(False) |
250 self.__downloadInstallButton.setEnabled(False) |
242 self.__installButton.setEnabled(False) |
251 self.__installButton.setEnabled(False) |
243 for itm in self.repositoryList.selectedItems(): |
252 for itm in self.repositoryList.selectedItems(): |
244 if itm not in [self.__stableItem, self.__unstableItem, self.__unknownItem]: |
253 if itm not in [self.__stableItem, self.__unstableItem, |
|
254 self.__unknownItem]: |
245 url = itm.data(0, urlRole) |
255 url = itm.data(0, urlRole) |
246 filename = os.path.join( |
256 filename = os.path.join( |
247 Preferences.getPluginManager("DownloadPath"), |
257 Preferences.getPluginManager("DownloadPath"), |
248 itm.data(0, filenameRole)) |
258 itm.data(0, filenameRole)) |
249 self.__pluginsToDownload.append((url, filename)) |
259 self.__pluginsToDownload.append((url, filename)) |
311 url = Preferences.getUI("PluginRepositoryUrl5") |
322 url = Preferences.getUI("PluginRepositoryUrl5") |
312 if url != self.repositoryUrlEdit.text(): |
323 if url != self.repositoryUrlEdit.text(): |
313 self.repositoryUrlEdit.setText(url) |
324 self.repositoryUrlEdit.setText(url) |
314 E5MessageBox.warning(self, |
325 E5MessageBox.warning(self, |
315 self.trUtf8("Plugins Repository URL Changed"), |
326 self.trUtf8("Plugins Repository URL Changed"), |
316 self.trUtf8("""The URL of the Plugins Repository has""" |
327 self.trUtf8( |
317 """ changed. Select the "Update" button to get""" |
328 """The URL of the Plugins Repository has""" |
318 """ the new repository file.""")) |
329 """ changed. Select the "Update" button to get""" |
|
330 """ the new repository file.""")) |
319 else: |
331 else: |
320 E5MessageBox.critical(self, |
332 E5MessageBox.critical(self, |
321 self.trUtf8("Read plugins repository file"), |
333 self.trUtf8("Read plugins repository file"), |
322 self.trUtf8("<p>The plugins repository file <b>{0}</b> " |
334 self.trUtf8("<p>The plugins repository file <b>{0}</b> " |
323 "could not be read. Select Update</p>")\ |
335 "could not be read. Select Update</p>")\ |
324 .format(self.pluginRepositoryFile)) |
336 .format(self.pluginRepositoryFile)) |
325 else: |
337 else: |
326 self.__repositoryMissing = True |
338 self.__repositoryMissing = True |
327 QTreeWidgetItem(self.repositoryList, |
339 QTreeWidgetItem(self.repositoryList, |
328 ["", |
340 ["", self.trUtf8( |
329 self.trUtf8("No plugin repository file available.\nSelect Update.") |
341 "No plugin repository file available.\nSelect Update.") |
330 ]) |
342 ]) |
331 self.repositoryList.resizeColumnToContents(1) |
343 self.repositoryList.resizeColumnToContents(1) |
332 |
344 |
333 def __downloadFile(self, url, filename, doneMethod=None): |
345 def __downloadFile(self, url, filename, doneMethod=None): |
334 """ |
346 """ |
376 ok = False |
388 ok = False |
377 if not self.__downloadCancelled: |
389 if not self.__downloadCancelled: |
378 E5MessageBox.warning(self, |
390 E5MessageBox.warning(self, |
379 self.trUtf8("Error downloading file"), |
391 self.trUtf8("Error downloading file"), |
380 self.trUtf8( |
392 self.trUtf8( |
381 """<p>Could not download the requested file from {0}.</p>""" |
393 """<p>Could not download the requested file""" |
382 """<p>Error: {1}</p>""" |
394 """ from {0}.</p><p>Error: {1}</p>""" |
383 ).format(self.__downloadURL, reply.errorString()) |
395 ).format(self.__downloadURL, reply.errorString()) |
384 ) |
396 ) |
385 self.downloadProgress.setValue(0) |
397 self.downloadProgress.setValue(0) |
386 self.__downloadURL = None |
398 self.__downloadURL = None |
387 self.__downloadIODevice.remove() |
399 self.__downloadIODevice.remove() |
389 if self.repositoryList.topLevelItemCount(): |
401 if self.repositoryList.topLevelItemCount(): |
390 if self.repositoryList.currentItem() is None: |
402 if self.repositoryList.currentItem() is None: |
391 self.repositoryList.setCurrentItem( |
403 self.repositoryList.setCurrentItem( |
392 self.repositoryList.topLevelItem(0)) |
404 self.repositoryList.topLevelItem(0)) |
393 else: |
405 else: |
394 self.__downloadButton.setEnabled(len(self.__selectedItems())) |
406 self.__downloadButton.setEnabled( |
395 self.__downloadInstallButton.setEnabled(len(self.__selectedItems())) |
407 len(self.__selectedItems())) |
|
408 self.__downloadInstallButton.setEnabled( |
|
409 len(self.__selectedItems())) |
396 return |
410 return |
397 |
411 |
398 self.__downloadIODevice.open(QIODevice.WriteOnly) |
412 self.__downloadIODevice.open(QIODevice.WriteOnly) |
399 self.__downloadIODevice.write(reply.readAll()) |
413 self.__downloadIODevice.write(reply.readAll()) |
400 self.__downloadIODevice.close() |
414 self.__downloadIODevice.close() |
426 """ |
440 """ |
427 if total: |
441 if total: |
428 self.downloadProgress.setMaximum(total) |
442 self.downloadProgress.setMaximum(total) |
429 self.downloadProgress.setValue(done) |
443 self.downloadProgress.setValue(done) |
430 |
444 |
431 def addEntry(self, name, short, description, url, author, version, filename, status): |
445 def addEntry(self, name, short, description, url, author, version, |
|
446 filename, status): |
432 """ |
447 """ |
433 Public method to add an entry to the list. |
448 Public method to add an entry to the list. |
434 |
449 |
435 @param name data for the name field (string) |
450 @param name data for the name field (string) |
436 @param short data for the short field (string) |
451 @param short data for the short field (string) |
442 @param status status of the plugin (string [stable, unstable, unknown]) |
457 @param status status of the plugin (string [stable, unstable, unknown]) |
443 """ |
458 """ |
444 if status == "stable": |
459 if status == "stable": |
445 if self.__stableItem is None: |
460 if self.__stableItem is None: |
446 self.__stableItem = \ |
461 self.__stableItem = \ |
447 QTreeWidgetItem(self.repositoryList, [self.trUtf8("Stable")]) |
462 QTreeWidgetItem(self.repositoryList, |
|
463 [self.trUtf8("Stable")]) |
448 self.__stableItem.setExpanded(True) |
464 self.__stableItem.setExpanded(True) |
449 parent = self.__stableItem |
465 parent = self.__stableItem |
450 elif status == "unstable": |
466 elif status == "unstable": |
451 if self.__unstableItem is None: |
467 if self.__unstableItem is None: |
452 self.__unstableItem = \ |
468 self.__unstableItem = \ |
453 QTreeWidgetItem(self.repositoryList, [self.trUtf8("Unstable")]) |
469 QTreeWidgetItem(self.repositoryList, |
|
470 [self.trUtf8("Unstable")]) |
454 self.__unstableItem.setExpanded(True) |
471 self.__unstableItem.setExpanded(True) |
455 parent = self.__unstableItem |
472 parent = self.__unstableItem |
456 else: |
473 else: |
457 if self.__unknownItem is None: |
474 if self.__unknownItem is None: |
458 self.__unknownItem = \ |
475 self.__unknownItem = \ |
459 QTreeWidgetItem(self.repositoryList, [self.trUtf8("Unknown")]) |
476 QTreeWidgetItem(self.repositoryList, |
|
477 [self.trUtf8("Unknown")]) |
460 self.__unknownItem.setExpanded(True) |
478 self.__unknownItem.setExpanded(True) |
461 parent = self.__unknownItem |
479 parent = self.__unknownItem |
462 itm = QTreeWidgetItem(parent, [name, version, short]) |
480 itm = QTreeWidgetItem(parent, [name, version, short]) |
463 |
481 |
464 itm.setData(0, urlRole, url) |
482 itm.setData(0, urlRole, url) |
583 self.cw = PluginRepositoryWidget(self, external=True) |
602 self.cw = PluginRepositoryWidget(self, external=True) |
584 size = self.cw.size() |
603 size = self.cw.size() |
585 self.setCentralWidget(self.cw) |
604 self.setCentralWidget(self.cw) |
586 self.resize(size) |
605 self.resize(size) |
587 |
606 |
588 self.setStyle(Preferences.getUI("Style"), Preferences.getUI("StyleSheet")) |
607 self.setStyle(Preferences.getUI("Style"), |
|
608 Preferences.getUI("StyleSheet")) |
589 |
609 |
590 self.cw.buttonBox.accepted[()].connect(self.close) |
610 self.cw.buttonBox.accepted[()].connect(self.close) |
591 self.cw.buttonBox.rejected[()].connect(self.close) |
611 self.cw.buttonBox.rejected[()].connect(self.close) |
592 self.cw.closeAndInstall.connect(self.__startPluginInstall) |
612 self.cw.closeAndInstall.connect(self.__startPluginInstall) |
593 |
613 |
600 |
620 |
601 args = [] |
621 args = [] |
602 args.append(applPath) |
622 args.append(applPath) |
603 args += self.cw.getDownloadedPlugins() |
623 args += self.cw.getDownloadedPlugins() |
604 |
624 |
605 if not os.path.isfile(applPath) or not proc.startDetached(sys.executable, args): |
625 if not os.path.isfile(applPath) or \ |
|
626 not proc.startDetached(sys.executable, args): |
606 E5MessageBox.critical(self, |
627 E5MessageBox.critical(self, |
607 self.trUtf8('Process Generation Error'), |
628 self.trUtf8('Process Generation Error'), |
608 self.trUtf8( |
629 self.trUtf8( |
609 '<p>Could not start the process.<br>' |
630 '<p>Could not start the process.<br>' |
610 'Ensure that it is available as <b>{0}</b>.</p>' |
631 'Ensure that it is available as <b>{0}</b>.</p>' |