| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,50 @@ | ||
| /** | ||
| * \class QgsPluginManagerInterface | ||
| * \brief Abstract base class to make QgsPluginManager available to plugins. | ||
| */ | ||
| class QgsPluginManagerInterface : QObject | ||
| { | ||
| %TypeHeaderCode | ||
| #include <qgspluginmanagerinterface.h> | ||
| %End | ||
|
|
||
| public: | ||
|
|
||
| //! Constructor | ||
| QgsPluginManagerInterface(); | ||
|
|
||
| //! Virtual destructor | ||
| ~QgsPluginManagerInterface(); | ||
|
|
||
| //! remove metadata of all python plugins from the registry (c++ plugins stay) | ||
| virtual void clearPythonPluginMetadata() = 0; | ||
|
|
||
| //! add a single plugin to the metadata registry | ||
| virtual void addPluginMetadata( QMap<QString,QString> metadata ) = 0; | ||
|
|
||
| //! refresh listView model and textView content | ||
| virtual void reloadModel() = 0; | ||
|
|
||
| //! get given plugin metadata | ||
| virtual QMap<QString, QString> * pluginMetadata( QString key ) = 0; | ||
|
|
||
| //! clear the repository listWidget | ||
| virtual void clearRepositoryList() = 0; | ||
|
|
||
| //! add repository to the repository listWidget | ||
| virtual void addToRepositoryList( QMap<QString,QString> repository ) = 0; | ||
|
|
||
| signals: | ||
|
|
||
| //! emitted when the Python Plugin Installer should show the fetching repositories window | ||
| void fetchingStillInProgress( ); | ||
|
|
||
| public slots: | ||
|
|
||
| //! show the Plugin Manager window when remote repositories are fetched. | ||
| //! Display a progress dialog when fetching. | ||
| virtual void showPluginManagerWhenReady( ) = 0; | ||
|
|
||
| //! promptly show the Plugin Manager window and optionally open tab tabIndex: | ||
| virtual void showPluginManager( int tabIndex = -1 ) = 0; | ||
| }; |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,26 @@ | ||
| SET (QGIS_PLUGININSTALLER_DIR ${QGIS_DATA_DIR}/python/pyplugin_installer) | ||
| SET (PYTHON_OUTPUT_DIRECTORY ${QGIS_OUTPUT_DIRECTORY}/python) | ||
|
|
||
| SET(PY_PLUGININSTALLER_FILES | ||
| __init__.py | ||
| installer.py | ||
| installer_data.py | ||
| installer_gui.py | ||
| unzip.py | ||
| version_compare.py | ||
| ) | ||
|
|
||
| # FILE(GLOB UI_FILES *.ui) | ||
| # PYQT4_WRAP_UI(PYUI_FILES ${UI_FILES}) | ||
|
|
||
| PYQT4_WRAP_UI(PYUI_FILES | ||
| qgsplugininstallerfetchingbase.ui | ||
| qgsplugininstallerinstallingbase.ui | ||
| qgsplugininstallerpluginerrorbase.ui | ||
| qgsplugininstallerrepositorybase.ui | ||
| qgsplugininstalleroldreposbase.ui | ||
| ) | ||
|
|
||
| ADD_CUSTOM_TARGET(pyplugin_installer ALL DEPENDS ${PYUI_FILES}) | ||
|
|
||
| INSTALL(FILES ${PY_PLUGININSTALLER_FILES} ${PYUI_FILES} DESTINATION "${QGIS_PLUGININSTALLER_DIR}") |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,40 @@ | ||
| # -*- coding: utf-8 -*- | ||
|
|
||
| """ | ||
| *************************************************************************** | ||
| __init__.py | ||
| --------------------- | ||
| Date : May 2013 | ||
| Copyright : (C) 2013 by Borys Jurgiel | ||
| Email : info at borysjurgiel dot pl | ||
| This module is based on former plugin_installer plugin: | ||
| Copyright (C) 2007-2008 Matthew Perry | ||
| Copyright (C) 2008-2013 Borys Jurgiel | ||
| /*************************************************************************** | ||
| * * | ||
| * This program is free software; you can redistribute it and/or modify * | ||
| * it under the terms of the GNU General Public License as published by * | ||
| * the Free Software Foundation; either version 2 of the License, or * | ||
| * (at your option) any later version. * | ||
| * * | ||
| ***************************************************************************/ | ||
| """ | ||
|
|
||
| __author__ = 'Borys Jurgiel' | ||
| __date__ = 'May 2013' | ||
| __copyright__ = '(C) 2013, Borys Jurgiel' | ||
| # This will get replaced with a git SHA1 when you do a git archive | ||
| __revision__ = '$Format:%H$' | ||
|
|
||
|
|
||
| # import functions for easier access | ||
| import installer | ||
| from installer import initPluginInstaller | ||
|
|
||
|
|
||
| def instance(): | ||
| if not installer.pluginInstaller: | ||
| installer.initPluginInstaller() | ||
| return installer.pluginInstaller |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,220 @@ | ||
| # -*- coding:utf-8 -*- | ||
| """ | ||
| /*************************************************************************** | ||
| Plugin Installer module | ||
| ------------------- | ||
| Date : May 2013 | ||
| Copyright : (C) 2013 by Borys Jurgiel | ||
| Email : info at borysjurgiel dot pl | ||
| This module is based on former plugin_installer plugin: | ||
| Copyright (C) 2007-2008 Matthew Perry | ||
| Copyright (C) 2008-2013 Borys Jurgiel | ||
| ***************************************************************************/ | ||
| /*************************************************************************** | ||
| * * | ||
| * This program is free software; you can redistribute it and/or modify * | ||
| * it under the terms of the GNU General Public License as published by * | ||
| * the Free Software Foundation; either version 2 of the License, or * | ||
| * (at your option) any later version. * | ||
| * * | ||
| ***************************************************************************/ | ||
| """ | ||
|
|
||
| import sys | ||
| import time | ||
|
|
||
| from PyQt4.QtCore import * | ||
| from PyQt4.QtGui import * | ||
|
|
||
| from qgis.core import QgsApplication, QgsContextHelp | ||
|
|
||
| from ui_qgsplugininstallerfetchingbase import Ui_QgsPluginInstallerFetchingDialogBase | ||
| from ui_qgsplugininstallerinstallingbase import Ui_QgsPluginInstallerInstallingDialogBase | ||
| from ui_qgsplugininstallerrepositorybase import Ui_QgsPluginInstallerRepositoryDetailsDialogBase | ||
| from ui_qgsplugininstallerpluginerrorbase import Ui_QgsPluginInstallerPluginErrorDialogBase | ||
|
|
||
| from installer_data import * | ||
| from unzip import unzip | ||
|
|
||
|
|
||
|
|
||
|
|
||
| # --- class QgsPluginInstallerFetchingDialog --------------------------------------------------------------- # | ||
| class QgsPluginInstallerFetchingDialog(QDialog, Ui_QgsPluginInstallerFetchingDialogBase): | ||
| # ----------------------------------------- # | ||
| def __init__(self, parent): | ||
| QDialog.__init__(self, parent) | ||
| self.setupUi(self) | ||
| self.progressBar.setRange(0,len(repositories.allEnabled())*100) | ||
| self.itemProgress = {} | ||
| self.item = {} | ||
| for key in repositories.allEnabled(): | ||
| self.item[key] = QTreeWidgetItem(self.treeWidget) | ||
| self.item[key].setText(0,key) | ||
| if repositories.all()[key]["state"] > 1: | ||
| self.itemProgress[key] = 100 | ||
| self.displayState(key,0) | ||
| else: | ||
| self.itemProgress[key] = 0 | ||
| self.displayState(key,2) | ||
| self.treeWidget.resizeColumnToContents(0) | ||
| QObject.connect(repositories, SIGNAL("repositoryFetched(QString)"), self.repositoryFetched) | ||
| QObject.connect(repositories, SIGNAL("anythingChanged(QString, int, int)"), self.displayState) | ||
|
|
||
|
|
||
| # ----------------------------------------- # | ||
| def displayState(self,key,state,state2=None): | ||
| messages=[self.tr("Success"),self.tr("Resolving host name..."),self.tr("Connecting..."),self.tr("Host connected. Sending request..."),self.tr("Downloading data..."),self.tr("Idle"),self.tr("Closing connection..."),self.tr("Error")] | ||
| message = messages[state] | ||
| if state2: | ||
| message += " (%s%%)" % state2 | ||
| self.item[key].setText(1,message) | ||
|
|
||
| if state == 4 and state2: | ||
| self.itemProgress[key] = state2 | ||
| totalProgress = sum(self.itemProgress.values()) | ||
| self.progressBar.setValue(totalProgress) | ||
|
|
||
|
|
||
| # ----------------------------------------- # | ||
| def repositoryFetched(self, repoName): | ||
| self.itemProgress[repoName] = 100 | ||
| if repositories.all()[repoName]["state"] == 2: | ||
| self.displayState(repoName,0) | ||
| else: | ||
| self.displayState(repoName,7) | ||
| if not repositories.fetchingInProgress(): | ||
| self.close() | ||
| # --- /class QgsPluginInstallerFetchingDialog -------------------------------------------------------------- # | ||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
| # --- class QgsPluginInstallerRepositoryDialog ------------------------------------------------------------- # | ||
| class QgsPluginInstallerRepositoryDialog(QDialog, Ui_QgsPluginInstallerRepositoryDetailsDialogBase): | ||
| # ----------------------------------------- # | ||
| def __init__(self, parent=None): | ||
| QDialog.__init__(self, parent) | ||
| self.setupUi(self) | ||
| self.editURL.setText("http://") | ||
| self.connect(self.editName, SIGNAL("textChanged(const QString &)"), self.textChanged) | ||
| self.connect(self.editURL, SIGNAL("textChanged(const QString &)"), self.textChanged) | ||
| self.textChanged(None) | ||
|
|
||
| # ----------------------------------------- # | ||
| def textChanged(self, string): | ||
| enable = (self.editName.text().count() > 0 and self.editURL.text().count() > 0) | ||
| self.buttonBox.button(QDialogButtonBox.Ok).setEnabled(enable) | ||
| # --- /class QgsPluginInstallerRepositoryDialog ------------------------------------------------------------ # | ||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
| # --- class QgsPluginInstallerInstallingDialog --------------------------------------------------------------- # | ||
| class QgsPluginInstallerInstallingDialog(QDialog, Ui_QgsPluginInstallerInstallingDialogBase): | ||
| # ----------------------------------------- # | ||
| def __init__(self, parent, plugin): | ||
| QDialog.__init__(self, parent) | ||
| self.setupUi(self) | ||
| self.plugin = plugin | ||
| self.mResult = QString() | ||
| self.progressBar.setRange(0,0) | ||
| self.progressBar.setFormat(QString("%p%")) | ||
| self.labelName.setText(QString(plugin["name"])) | ||
| self.connect(self.buttonBox, SIGNAL("clicked(QAbstractButton*)"), self.abort) | ||
|
|
||
| url = QUrl(plugin["download_url"]) | ||
| path = QString(url.toPercentEncoding(url.path(), "!$&'()*+,;=:/@")) | ||
| fileName = plugin["filename"] | ||
| tmpDir = QDir.tempPath() | ||
| tmpPath = QDir.cleanPath(tmpDir+"/"+fileName) | ||
| self.file = QFile(tmpPath) | ||
| port = url.port() | ||
| if port < 0: | ||
| port = 80 | ||
| self.http = QPHttp(url.host(), port) | ||
| self.connect(self.http, SIGNAL("stateChanged ( int )"), self.stateChanged) | ||
| self.connect(self.http, SIGNAL("dataReadProgress ( int , int )"), self.readProgress) | ||
| self.connect(self.http, SIGNAL("requestFinished (int, bool)"), self.requestFinished) | ||
| self.httpGetId = self.http.get(path, self.file) | ||
|
|
||
|
|
||
| # ----------------------------------------- # | ||
| def result(self): | ||
| return self.mResult | ||
|
|
||
|
|
||
| # ----------------------------------------- # | ||
| def stateChanged(self, state): | ||
| messages=[self.tr("Installing..."),self.tr("Resolving host name..."),self.tr("Connecting..."),self.tr("Host connected. Sending request..."),self.tr("Downloading data..."),self.tr("Idle"),self.tr("Closing connection..."),self.tr("Error")] | ||
| self.labelState.setText(messages[state]) | ||
|
|
||
|
|
||
| # ----------------------------------------- # | ||
| def readProgress(self, done, total): | ||
| self.progressBar.setMaximum(total) | ||
| self.progressBar.setValue(done) | ||
|
|
||
|
|
||
| # ----------------------------------------- # | ||
| def requestFinished(self, requestId, state): | ||
| if requestId != self.httpGetId: | ||
| return | ||
| self.buttonBox.setEnabled(False) | ||
| if state: | ||
| self.mResult = self.http.errorString() | ||
| self.reject() | ||
| return | ||
| self.file.close() | ||
| pluginDir = QFileInfo(QgsApplication.qgisUserDbFilePath()).path() + "/python/plugins" | ||
| tmpPath = self.file.fileName() | ||
| # make sure that the parent directory exists | ||
| if not QDir(pluginDir).exists(): | ||
| QDir().mkpath(pluginDir) | ||
| # if the target directory already exists as a link, remove the link without resolving: | ||
| QFile(pluginDir+QString(QDir.separator())+self.plugin["id"]).remove() | ||
| try: | ||
| unzip(unicode(tmpPath), unicode(pluginDir)) # test extract. If fails, then exception will be raised and no removing occurs | ||
| # removing old plugin files if exist | ||
| removeDir(QDir.cleanPath(pluginDir+"/"+self.plugin["id"])) # remove old plugin if exists | ||
| unzip(unicode(tmpPath), unicode(pluginDir)) # final extract. | ||
| except: | ||
| self.mResult = self.tr("Failed to unzip the plugin package. Probably it's broken or missing from the repository. You may also want to make sure that you have write permission to the plugin directory:") + "\n" + pluginDir | ||
| self.reject() | ||
| return | ||
| try: | ||
| # cleaning: removing the temporary zip file | ||
| QFile(tmpPath).remove() | ||
| except: | ||
| pass | ||
| self.close() | ||
|
|
||
|
|
||
| # ----------------------------------------- # | ||
| def abort(self): | ||
| self.http.abort() | ||
| self.mResult = self.tr("Aborted by user") | ||
| self.reject() | ||
| # --- /class QgsPluginInstallerInstallingDialog ------------------------------------------------------------- # | ||
|
|
||
|
|
||
|
|
||
|
|
||
|
|
||
| # --- class QgsPluginInstallerPluginErrorDialog -------------------------------------------------------------- # | ||
| class QgsPluginInstallerPluginErrorDialog(QDialog, Ui_QgsPluginInstallerPluginErrorDialogBase): | ||
| # ----------------------------------------- # | ||
| def __init__(self, parent, errorMessage): | ||
| QDialog.__init__(self, parent) | ||
| self.setupUi(self) | ||
| if not errorMessage: | ||
| errorMessage = self.tr("no error message received") | ||
| self.textBrowser.setText(errorMessage) | ||
| # --- /class QgsPluginInstallerPluginErrorDialog ------------------------------------------------------------- # | ||
|
|
||
|
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,194 @@ | ||
| <ui version="4.0" > | ||
| <author>Borys Jurgiel</author> | ||
| <class>QgsPluginInstallerFetchingDialogBase</class> | ||
| <widget class="QDialog" name="QgsPluginInstallerFetchingDialogBase" > | ||
| <property name="geometry" > | ||
| <rect> | ||
| <x>0</x> | ||
| <y>0</y> | ||
| <width>521</width> | ||
| <height>332</height> | ||
| </rect> | ||
| </property> | ||
| <property name="windowTitle" > | ||
| <string>Fetching repositories</string> | ||
| </property> | ||
| <layout class="QGridLayout" > | ||
| <item row="1" column="0" > | ||
| <spacer> | ||
| <property name="orientation" > | ||
| <enum>Qt::Vertical</enum> | ||
| </property> | ||
| <property name="sizeType" > | ||
| <enum>QSizePolicy::Fixed</enum> | ||
| </property> | ||
| <property name="sizeHint" > | ||
| <size> | ||
| <width>249</width> | ||
| <height>10</height> | ||
| </size> | ||
| </property> | ||
| </spacer> | ||
| </item> | ||
| <item row="2" column="0" > | ||
| <widget class="QLabel" name="label1" > | ||
| <property name="text" > | ||
| <string>Overall progress:</string> | ||
| </property> | ||
| </widget> | ||
| </item> | ||
| <item row="3" column="0" > | ||
| <widget class="QProgressBar" name="progressBar" > | ||
| <property name="value" > | ||
| <number>24</number> | ||
| </property> | ||
| <property name="alignment" > | ||
| <set>Qt::AlignHCenter</set> | ||
| </property> | ||
| <property name="textDirection" > | ||
| <enum>QProgressBar::TopToBottom</enum> | ||
| </property> | ||
| <property name="format" > | ||
| <string/> | ||
| </property> | ||
| </widget> | ||
| </item> | ||
| <item row="4" column="0" > | ||
| <spacer> | ||
| <property name="orientation" > | ||
| <enum>Qt::Vertical</enum> | ||
| </property> | ||
| <property name="sizeType" > | ||
| <enum>QSizePolicy::Fixed</enum> | ||
| </property> | ||
| <property name="sizeHint" > | ||
| <size> | ||
| <width>248</width> | ||
| <height>10</height> | ||
| </size> | ||
| </property> | ||
| </spacer> | ||
| </item> | ||
| <item row="5" column="0" > | ||
| <layout class="QHBoxLayout" > | ||
| <item> | ||
| <spacer> | ||
| <property name="orientation" > | ||
| <enum>Qt::Horizontal</enum> | ||
| </property> | ||
| <property name="sizeType" > | ||
| <enum>QSizePolicy::MinimumExpanding</enum> | ||
| </property> | ||
| <property name="sizeHint" > | ||
| <size> | ||
| <width>140</width> | ||
| <height>27</height> | ||
| </size> | ||
| </property> | ||
| </spacer> | ||
| </item> | ||
| <item> | ||
| <widget class="QPushButton" name="buttonSkip" > | ||
| <property name="sizePolicy" > | ||
| <sizepolicy vsizetype="Fixed" hsizetype="Fixed" > | ||
| <horstretch>0</horstretch> | ||
| <verstretch>0</verstretch> | ||
| </sizepolicy> | ||
| </property> | ||
| <property name="minimumSize" > | ||
| <size> | ||
| <width>180</width> | ||
| <height>0</height> | ||
| </size> | ||
| </property> | ||
| <property name="focusPolicy" > | ||
| <enum>Qt::NoFocus</enum> | ||
| </property> | ||
| <property name="text" > | ||
| <string>Abort fetching</string> | ||
| </property> | ||
| <property name="autoDefault" > | ||
| <bool>false</bool> | ||
| </property> | ||
| <property name="default" > | ||
| <bool>false</bool> | ||
| </property> | ||
| <property name="flat" > | ||
| <bool>false</bool> | ||
| </property> | ||
| </widget> | ||
| </item> | ||
| <item> | ||
| <spacer> | ||
| <property name="orientation" > | ||
| <enum>Qt::Horizontal</enum> | ||
| </property> | ||
| <property name="sizeType" > | ||
| <enum>QSizePolicy::MinimumExpanding</enum> | ||
| </property> | ||
| <property name="sizeHint" > | ||
| <size> | ||
| <width>140</width> | ||
| <height>27</height> | ||
| </size> | ||
| </property> | ||
| </spacer> | ||
| </item> | ||
| </layout> | ||
| </item> | ||
| <item row="0" column="0" > | ||
| <widget class="QTreeWidget" name="treeWidget" > | ||
| <property name="enabled" > | ||
| <bool>true</bool> | ||
| </property> | ||
| <property name="horizontalScrollBarPolicy" > | ||
| <enum>Qt::ScrollBarAsNeeded</enum> | ||
| </property> | ||
| <property name="showDropIndicator" stdset="0" > | ||
| <bool>false</bool> | ||
| </property> | ||
| <property name="selectionMode" > | ||
| <enum>QAbstractItemView::NoSelection</enum> | ||
| </property> | ||
| <property name="horizontalScrollMode" > | ||
| <enum>QAbstractItemView::ScrollPerItem</enum> | ||
| </property> | ||
| <property name="rootIsDecorated" > | ||
| <bool>false</bool> | ||
| </property> | ||
| <property name="itemsExpandable" > | ||
| <bool>false</bool> | ||
| </property> | ||
| <column> | ||
| <property name="text" > | ||
| <string>Repository</string> | ||
| </property> | ||
| </column> | ||
| <column> | ||
| <property name="text" > | ||
| <string>State</string> | ||
| </property> | ||
| </column> | ||
| </widget> | ||
| </item> | ||
| </layout> | ||
| </widget> | ||
| <connections> | ||
| <connection> | ||
| <sender>buttonSkip</sender> | ||
| <signal>clicked()</signal> | ||
| <receiver>QgsPluginInstallerFetchingDialogBase</receiver> | ||
| <slot>reject()</slot> | ||
| <hints> | ||
| <hint type="sourcelabel" > | ||
| <x>350</x> | ||
| <y>321</y> | ||
| </hint> | ||
| <hint type="destinationlabel" > | ||
| <x>250</x> | ||
| <y>76</y> | ||
| </hint> | ||
| </hints> | ||
| </connection> | ||
| </connections> | ||
| </ui> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,118 @@ | ||
| <ui version="4.0" > | ||
| <author>Borys Jurgiel</author> | ||
| <class>QgsPluginInstallerInstallingDialogBase</class> | ||
| <widget class="QDialog" name="QgsPluginInstallerInstallingDialogBase" > | ||
| <property name="geometry" > | ||
| <rect> | ||
| <x>0</x> | ||
| <y>0</y> | ||
| <width>520</width> | ||
| <height>175</height> | ||
| </rect> | ||
| </property> | ||
| <property name="windowTitle" > | ||
| <string>QGIS Python Plugin Installer</string> | ||
| </property> | ||
| <layout class="QGridLayout" > | ||
| <item row="0" column="0" > | ||
| <spacer> | ||
| <property name="orientation" > | ||
| <enum>Qt::Vertical</enum> | ||
| </property> | ||
| <property name="sizeType" > | ||
| <enum>QSizePolicy::MinimumExpanding</enum> | ||
| </property> | ||
| <property name="sizeHint" > | ||
| <size> | ||
| <width>502</width> | ||
| <height>16</height> | ||
| </size> | ||
| </property> | ||
| </spacer> | ||
| </item> | ||
| <item row="1" column="0" > | ||
| <layout class="QHBoxLayout" > | ||
| <item> | ||
| <widget class="QLabel" name="label" > | ||
| <property name="text" > | ||
| <string>Installing plugin:</string> | ||
| </property> | ||
| </widget> | ||
| </item> | ||
| <item> | ||
| <widget class="QLabel" name="labelName" > | ||
| <property name="sizePolicy" > | ||
| <sizepolicy vsizetype="Preferred" hsizetype="Expanding" > | ||
| <horstretch>0</horstretch> | ||
| <verstretch>0</verstretch> | ||
| </sizepolicy> | ||
| </property> | ||
| <property name="text" > | ||
| <string/> | ||
| </property> | ||
| </widget> | ||
| </item> | ||
| </layout> | ||
| </item> | ||
| <item row="2" column="0" > | ||
| <widget class="QLabel" name="labelState" > | ||
| <property name="text" > | ||
| <string>Connecting...</string> | ||
| </property> | ||
| </widget> | ||
| </item> | ||
| <item row="3" column="0" > | ||
| <widget class="QProgressBar" name="progressBar" > | ||
| <property name="maximum" > | ||
| <number>100</number> | ||
| </property> | ||
| <property name="value" > | ||
| <number>0</number> | ||
| </property> | ||
| <property name="alignment" > | ||
| <set>Qt::AlignHCenter</set> | ||
| </property> | ||
| <property name="textDirection" > | ||
| <enum>QProgressBar::TopToBottom</enum> | ||
| </property> | ||
| <property name="format" > | ||
| <string/> | ||
| </property> | ||
| </widget> | ||
| </item> | ||
| <item row="4" column="0" > | ||
| <spacer> | ||
| <property name="orientation" > | ||
| <enum>Qt::Vertical</enum> | ||
| </property> | ||
| <property name="sizeType" > | ||
| <enum>QSizePolicy::Fixed</enum> | ||
| </property> | ||
| <property name="sizeHint" > | ||
| <size> | ||
| <width>502</width> | ||
| <height>16</height> | ||
| </size> | ||
| </property> | ||
| </spacer> | ||
| </item> | ||
| <item row="5" column="0" > | ||
| <widget class="QDialogButtonBox" name="buttonBox" > | ||
| <property name="focusPolicy" > | ||
| <enum>Qt::NoFocus</enum> | ||
| </property> | ||
| <property name="contextMenuPolicy" > | ||
| <enum>Qt::NoContextMenu</enum> | ||
| </property> | ||
| <property name="standardButtons" > | ||
| <set>QDialogButtonBox::Abort</set> | ||
| </property> | ||
| <property name="centerButtons" > | ||
| <bool>true</bool> | ||
| </property> | ||
| </widget> | ||
| </item> | ||
| </layout> | ||
| </widget> | ||
| <connections/> | ||
| </ui> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,113 @@ | ||
| <?xml version="1.0" encoding="UTF-8"?> | ||
| <ui version="4.0"> | ||
| <author>Borys Jurgiel</author> | ||
| <class>QgsPluginInstallerOldReposBase</class> | ||
| <widget class="QDialog" name="QgsPluginInstallerOldReposBase"> | ||
| <property name="geometry"> | ||
| <rect> | ||
| <x>0</x> | ||
| <y>0</y> | ||
| <width>601</width> | ||
| <height>182</height> | ||
| </rect> | ||
| </property> | ||
| <property name="minimumSize"> | ||
| <size> | ||
| <width>480</width> | ||
| <height>182</height> | ||
| </size> | ||
| </property> | ||
| <property name="windowTitle"> | ||
| <string>Plugin Installer</string> | ||
| </property> | ||
| <layout class="QGridLayout" name="gridLayout"> | ||
| <item row="0" column="1"> | ||
| <widget class="QLabel" name="label"> | ||
| <property name="sizePolicy"> | ||
| <sizepolicy hsizetype="Expanding" vsizetype="Expanding"> | ||
| <horstretch>0</horstretch> | ||
| <verstretch>0</verstretch> | ||
| </sizepolicy> | ||
| </property> | ||
| <property name="text"> | ||
| <string>The Plugin Installer has detected that your copy of QGIS is configured to use a number of plugin repositories around the world. It was a typical situation in older versions of the program, but from the version 1.5, external plugins are collected in one central Contributed Repository, and all the old repositories are not necessary any more. Do you want to drop them now? If you're unsure what to do, probably you don't need them. However, if you choose to keep them in use, you will be able to remove them manually later.</string> | ||
| </property> | ||
| <property name="wordWrap"> | ||
| <bool>true</bool> | ||
| </property> | ||
| <property name="openExternalLinks"> | ||
| <bool>true</bool> | ||
| </property> | ||
| </widget> | ||
| </item> | ||
| <item row="1" column="1" colspan="2"> | ||
| <layout class="QHBoxLayout" name="horizontalLayout"> | ||
| <item> | ||
| <widget class="QPushButton" name="butOldReposRemove"> | ||
| <property name="text"> | ||
| <string>Remove</string> | ||
| </property> | ||
| </widget> | ||
| </item> | ||
| <item> | ||
| <widget class="QPushButton" name="butOldReposDisable"> | ||
| <property name="text"> | ||
| <string>Disable</string> | ||
| </property> | ||
| </widget> | ||
| </item> | ||
| <item> | ||
| <widget class="QPushButton" name="butOldReposKeep"> | ||
| <property name="text"> | ||
| <string>Keep</string> | ||
| </property> | ||
| </widget> | ||
| </item> | ||
| <item> | ||
| <widget class="QPushButton" name="butOldReposAsk"> | ||
| <property name="text"> | ||
| <string>Ask me later</string> | ||
| </property> | ||
| <property name="default"> | ||
| <bool>true</bool> | ||
| </property> | ||
| </widget> | ||
| </item> | ||
| </layout> | ||
| </item> | ||
| <item row="0" column="3"> | ||
| <spacer name="horizontalSpacer_2"> | ||
| <property name="orientation"> | ||
| <enum>Qt::Horizontal</enum> | ||
| </property> | ||
| <property name="sizeType"> | ||
| <enum>QSizePolicy::Fixed</enum> | ||
| </property> | ||
| <property name="sizeHint" stdset="0"> | ||
| <size> | ||
| <width>20</width> | ||
| <height>20</height> | ||
| </size> | ||
| </property> | ||
| </spacer> | ||
| </item> | ||
| <item row="0" column="0"> | ||
| <spacer name="horizontalSpacer"> | ||
| <property name="orientation"> | ||
| <enum>Qt::Horizontal</enum> | ||
| </property> | ||
| <property name="sizeType"> | ||
| <enum>QSizePolicy::Fixed</enum> | ||
| </property> | ||
| <property name="sizeHint" stdset="0"> | ||
| <size> | ||
| <width>20</width> | ||
| <height>20</height> | ||
| </size> | ||
| </property> | ||
| </spacer> | ||
| </item> | ||
| </layout> | ||
| </widget> | ||
| <connections/> | ||
| </ui> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,149 @@ | ||
| <ui version="4.0" > | ||
| <author>Borys Jurgiel</author> | ||
| <class>QgsPluginInstallerPluginErrorDialogBase</class> | ||
| <widget class="QDialog" name="QgsPluginInstallerPluginErrorDialogBase" > | ||
| <property name="geometry" > | ||
| <rect> | ||
| <x>0</x> | ||
| <y>0</y> | ||
| <width>521</width> | ||
| <height>383</height> | ||
| </rect> | ||
| </property> | ||
| <property name="minimumSize" > | ||
| <size> | ||
| <width>480</width> | ||
| <height>300</height> | ||
| </size> | ||
| </property> | ||
| <property name="windowTitle" > | ||
| <string>Error loading plugin</string> | ||
| </property> | ||
| <layout class="QGridLayout" > | ||
| <item row="1" column="0" > | ||
| <widget class="QLabel" name="label" > | ||
| <property name="sizePolicy" > | ||
| <sizepolicy vsizetype="Preferred" hsizetype="Expanding" > | ||
| <horstretch>0</horstretch> | ||
| <verstretch>0</verstretch> | ||
| </sizepolicy> | ||
| </property> | ||
| <property name="text" > | ||
| <string>The plugin seems to be invalid or have unfulfilled dependencies. It has been installed, but can't be loaded. If you really need this plugin, you can contact its author or <a href="http://lists.osgeo.org/mailman/listinfo/qgis-user">QGIS users group</a> and try to solve the problem. If not, you can just uninstall it. Here is the error message below:</string> | ||
| </property> | ||
| <property name="wordWrap" > | ||
| <bool>true</bool> | ||
| </property> | ||
| <property name="openExternalLinks" > | ||
| <bool>true</bool> | ||
| </property> | ||
| </widget> | ||
| </item> | ||
| <item row="2" column="0" > | ||
| <widget class="QTextBrowser" name="textBrowser" > | ||
| <property name="minimumSize" > | ||
| <size> | ||
| <width>0</width> | ||
| <height>0</height> | ||
| </size> | ||
| </property> | ||
| <property name="focusPolicy" > | ||
| <enum>Qt::NoFocus</enum> | ||
| </property> | ||
| </widget> | ||
| </item> | ||
| <item row="3" column="0" > | ||
| <spacer> | ||
| <property name="orientation" > | ||
| <enum>Qt::Vertical</enum> | ||
| </property> | ||
| <property name="sizeType" > | ||
| <enum>QSizePolicy::Fixed</enum> | ||
| </property> | ||
| <property name="sizeHint" > | ||
| <size> | ||
| <width>503</width> | ||
| <height>10</height> | ||
| </size> | ||
| </property> | ||
| </spacer> | ||
| </item> | ||
| <item row="4" column="0" > | ||
| <widget class="QLabel" name="label1" > | ||
| <property name="frameShape" > | ||
| <enum>QFrame::NoFrame</enum> | ||
| </property> | ||
| <property name="frameShadow" > | ||
| <enum>QFrame::Plain</enum> | ||
| </property> | ||
| <property name="text" > | ||
| <string>Do you want to uninstall this plugin now? If you're unsure, probably you would like to do this.</string> | ||
| </property> | ||
| <property name="wordWrap" > | ||
| <bool>true</bool> | ||
| </property> | ||
| </widget> | ||
| </item> | ||
| <item row="6" column="0" > | ||
| <widget class="QDialogButtonBox" name="buttonBox" > | ||
| <property name="standardButtons" > | ||
| <set>QDialogButtonBox::No|QDialogButtonBox::NoButton|QDialogButtonBox::Yes</set> | ||
| </property> | ||
| </widget> | ||
| </item> | ||
| <item row="0" column="0" > | ||
| <spacer> | ||
| <property name="orientation" > | ||
| <enum>Qt::Vertical</enum> | ||
| </property> | ||
| <property name="sizeType" > | ||
| <enum>QSizePolicy::Fixed</enum> | ||
| </property> | ||
| <property name="sizeHint" > | ||
| <size> | ||
| <width>10</width> | ||
| <height>10</height> | ||
| </size> | ||
| </property> | ||
| </spacer> | ||
| </item> | ||
| </layout> | ||
| </widget> | ||
| <tabstops> | ||
| <tabstop>textBrowser</tabstop> | ||
| </tabstops> | ||
| <connections> | ||
| <connection> | ||
| <sender>buttonBox</sender> | ||
| <signal>rejected()</signal> | ||
| <receiver>QgsPluginInstallerPluginErrorDialogBase</receiver> | ||
| <slot>reject()</slot> | ||
| <hints> | ||
| <hint type="sourcelabel" > | ||
| <x>266</x> | ||
| <y>428</y> | ||
| </hint> | ||
| <hint type="destinationlabel" > | ||
| <x>266</x> | ||
| <y>226</y> | ||
| </hint> | ||
| </hints> | ||
| </connection> | ||
| <connection> | ||
| <sender>buttonBox</sender> | ||
| <signal>accepted()</signal> | ||
| <receiver>QgsPluginInstallerPluginErrorDialogBase</receiver> | ||
| <slot>accept()</slot> | ||
| <hints> | ||
| <hint type="sourcelabel" > | ||
| <x>266</x> | ||
| <y>428</y> | ||
| </hint> | ||
| <hint type="destinationlabel" > | ||
| <x>266</x> | ||
| <y>226</y> | ||
| </hint> | ||
| </hints> | ||
| </connection> | ||
| </connections> | ||
| </ui> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,237 @@ | ||
| <ui version="4.0" > | ||
| <author>Borys Jurgiel</author> | ||
| <class>QgsPluginInstallerRepositoryDetailsDialogBase</class> | ||
| <widget class="QDialog" name="QgsPluginInstallerRepositoryDetailsDialogBase" > | ||
| <property name="geometry" > | ||
| <rect> | ||
| <x>0</x> | ||
| <y>0</y> | ||
| <width>522</width> | ||
| <height>191</height> | ||
| </rect> | ||
| </property> | ||
| <property name="sizePolicy" > | ||
| <sizepolicy vsizetype="Preferred" hsizetype="Preferred" > | ||
| <horstretch>0</horstretch> | ||
| <verstretch>0</verstretch> | ||
| </sizepolicy> | ||
| </property> | ||
| <property name="windowTitle" > | ||
| <string>Repository details</string> | ||
| </property> | ||
| <property name="statusTip" > | ||
| <string/> | ||
| </property> | ||
| <property name="whatsThis" > | ||
| <string/> | ||
| </property> | ||
| <layout class="QGridLayout" > | ||
| <item row="0" column="0" > | ||
| <widget class="QLabel" name="label" > | ||
| <property name="sizePolicy" > | ||
| <sizepolicy vsizetype="Preferred" hsizetype="Fixed" > | ||
| <horstretch>0</horstretch> | ||
| <verstretch>0</verstretch> | ||
| </sizepolicy> | ||
| </property> | ||
| <property name="text" > | ||
| <string>Name:</string> | ||
| </property> | ||
| </widget> | ||
| </item> | ||
| <item row="0" column="1" > | ||
| <spacer> | ||
| <property name="orientation" > | ||
| <enum>Qt::Horizontal</enum> | ||
| </property> | ||
| <property name="sizeType" > | ||
| <enum>QSizePolicy::Fixed</enum> | ||
| </property> | ||
| <property name="sizeHint" > | ||
| <size> | ||
| <width>16</width> | ||
| <height>27</height> | ||
| </size> | ||
| </property> | ||
| </spacer> | ||
| </item> | ||
| <item row="0" column="2" colspan="2" > | ||
| <widget class="QLineEdit" name="editName" > | ||
| <property name="toolTip" > | ||
| <string>Enter a name for the repository</string> | ||
| </property> | ||
| <property name="whatsThis" > | ||
| <string>Enter a name for the repository</string> | ||
| </property> | ||
| </widget> | ||
| </item> | ||
| <item row="1" column="0" > | ||
| <widget class="QLabel" name="label_2" > | ||
| <property name="text" > | ||
| <string>URL:</string> | ||
| </property> | ||
| </widget> | ||
| </item> | ||
| <item row="1" column="2" colspan="2" > | ||
| <widget class="QLineEdit" name="editURL" > | ||
| <property name="toolTip" > | ||
| <string>Enter the repository URL, beginning with "http://"</string> | ||
| </property> | ||
| <property name="whatsThis" > | ||
| <string>Enter the repository URL, beginning with "http://"</string> | ||
| </property> | ||
| <property name="text" > | ||
| <string/> | ||
| </property> | ||
| </widget> | ||
| </item> | ||
| <item row="2" column="2" > | ||
| <widget class="QCheckBox" name="checkBoxEnabled" > | ||
| <property name="enabled" > | ||
| <bool>true</bool> | ||
| </property> | ||
| <property name="sizePolicy" > | ||
| <sizepolicy vsizetype="Fixed" hsizetype="Fixed" > | ||
| <horstretch>0</horstretch> | ||
| <verstretch>0</verstretch> | ||
| </sizepolicy> | ||
| </property> | ||
| <property name="toolTip" > | ||
| <string>Enable or disable the repository (disabled repositories will be omitted)</string> | ||
| </property> | ||
| <property name="whatsThis" > | ||
| <string>Enable or disable the repository (disabled repositories will be omitted)</string> | ||
| </property> | ||
| <property name="text" > | ||
| <string>Enabled</string> | ||
| </property> | ||
| <property name="checked" > | ||
| <bool>false</bool> | ||
| </property> | ||
| </widget> | ||
| </item> | ||
| <item row="2" column="3" > | ||
| <spacer> | ||
| <property name="orientation" > | ||
| <enum>Qt::Horizontal</enum> | ||
| </property> | ||
| <property name="sizeType" > | ||
| <enum>QSizePolicy::Fixed</enum> | ||
| </property> | ||
| <property name="sizeHint" > | ||
| <size> | ||
| <width>351</width> | ||
| <height>23</height> | ||
| </size> | ||
| </property> | ||
| </spacer> | ||
| </item> | ||
| <item row="3" column="2" colspan="2" > | ||
| <widget class="QLabel" name="labelInfo" > | ||
| <property name="enabled" > | ||
| <bool>true</bool> | ||
| </property> | ||
| <property name="sizePolicy" > | ||
| <sizepolicy vsizetype="Fixed" hsizetype="Expanding" > | ||
| <horstretch>0</horstretch> | ||
| <verstretch>0</verstretch> | ||
| </sizepolicy> | ||
| </property> | ||
| <property name="palette" > | ||
| <palette> | ||
| <active> | ||
| <colorrole role="WindowText" > | ||
| <brush brushstyle="SolidPattern" > | ||
| <color alpha="255" > | ||
| <red>175</red> | ||
| <green>0</green> | ||
| <blue>0</blue> | ||
| </color> | ||
| </brush> | ||
| </colorrole> | ||
| </active> | ||
| <inactive> | ||
| <colorrole role="WindowText" > | ||
| <brush brushstyle="SolidPattern" > | ||
| <color alpha="255" > | ||
| <red>175</red> | ||
| <green>0</green> | ||
| <blue>0</blue> | ||
| </color> | ||
| </brush> | ||
| </colorrole> | ||
| </inactive> | ||
| <disabled> | ||
| <colorrole role="WindowText" > | ||
| <brush brushstyle="SolidPattern" > | ||
| <color alpha="255" > | ||
| <red>128</red> | ||
| <green>128</green> | ||
| <blue>128</blue> | ||
| </color> | ||
| </brush> | ||
| </colorrole> | ||
| </disabled> | ||
| </palette> | ||
| </property> | ||
| <property name="font" > | ||
| <font> | ||
| <weight>75</weight> | ||
| <bold>true</bold> | ||
| </font> | ||
| </property> | ||
| <property name="frameShape" > | ||
| <enum>QFrame::NoFrame</enum> | ||
| </property> | ||
| <property name="text" > | ||
| <string/> | ||
| </property> | ||
| </widget> | ||
| </item> | ||
| <item row="5" column="0" colspan="4" > | ||
| <widget class="QDialogButtonBox" name="buttonBox" > | ||
| <property name="orientation" > | ||
| <enum>Qt::Horizontal</enum> | ||
| </property> | ||
| <property name="standardButtons" > | ||
| <set>QDialogButtonBox::Cancel|QDialogButtonBox::NoButton|QDialogButtonBox::Ok</set> | ||
| </property> | ||
| </widget> | ||
| </item> | ||
| </layout> | ||
| </widget> | ||
| <connections> | ||
| <connection> | ||
| <sender>buttonBox</sender> | ||
| <signal>accepted()</signal> | ||
| <receiver>QgsPluginInstallerRepositoryDetailsDialogBase</receiver> | ||
| <slot>accept()</slot> | ||
| <hints> | ||
| <hint type="sourcelabel" > | ||
| <x>257</x> | ||
| <y>207</y> | ||
| </hint> | ||
| <hint type="destinationlabel" > | ||
| <x>157</x> | ||
| <y>216</y> | ||
| </hint> | ||
| </hints> | ||
| </connection> | ||
| <connection> | ||
| <sender>buttonBox</sender> | ||
| <signal>rejected()</signal> | ||
| <receiver>QgsPluginInstallerRepositoryDetailsDialogBase</receiver> | ||
| <slot>reject()</slot> | ||
| <hints> | ||
| <hint type="sourcelabel" > | ||
| <x>325</x> | ||
| <y>207</y> | ||
| </hint> | ||
| <hint type="destinationlabel" > | ||
| <x>286</x> | ||
| <y>216</y> | ||
| </hint> | ||
| </hints> | ||
| </connection> | ||
| </connections> | ||
| </ui> |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,49 @@ | ||
| # -*- coding:utf-8 -*- | ||
| """ | ||
| /*************************************************************************** | ||
| Plugin Installer module | ||
| unzip function | ||
| ------------------- | ||
| Date : May 2013 | ||
| Copyright : (C) 2013 by Borys Jurgiel | ||
| Email : info at borysjurgiel dot pl | ||
| ***************************************************************************/ | ||
| /*************************************************************************** | ||
| * * | ||
| * This program is free software; you can redistribute it and/or modify * | ||
| * it under the terms of the GNU General Public License as published by * | ||
| * the Free Software Foundation; either version 2 of the License, or * | ||
| * (at your option) any later version. * | ||
| * * | ||
| ***************************************************************************/ | ||
| """ | ||
|
|
||
| import zipfile | ||
| import os | ||
|
|
||
| def unzip(file, targetDir): | ||
| """ Creates directory structure and extracts the zip contents to it. | ||
| file - the zip file to extract | ||
| targetDir - target location | ||
| """ | ||
|
|
||
| # create destination directory if doesn't exist | ||
| if not targetDir.endswith(':') and not os.path.exists(targetDir): | ||
| os.makedirs(targetDir) | ||
|
|
||
| zf = zipfile.ZipFile(file) | ||
| for name in zf.namelist(): | ||
| # create directory if doesn't exist | ||
| localDir = os.path.split(name)[0] | ||
| fullDir = os.path.normpath( os.path.join(targetDir, localDir) ) | ||
| if not os.path.exists(fullDir): | ||
| os.makedirs(fullDir) | ||
| # extract file | ||
| if not name.endswith('/'): | ||
| fullPath = os.path.normpath( os.path.join(targetDir, name) ) | ||
| outfile = open(fullPath, 'wb') | ||
| outfile.write(zf.read(name)) | ||
| outfile.flush() | ||
| outfile.close() |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,145 @@ | ||
| """ | ||
| /*************************************************************************** | ||
| Plugin Installer module | ||
| Plugin version comparision functions | ||
| ------------------- | ||
| Date : 2008-11-24 | ||
| Copyright : (C) 2008 by Borys Jurgiel | ||
| Email : info at borysjurgiel dot pl | ||
| ***************************************************************************/ | ||
| /*************************************************************************** | ||
| * * | ||
| * This program is free software; you can redistribute it and/or modify * | ||
| * it under the terms of the GNU General Public License as published by * | ||
| * the Free Software Foundation; either version 2 of the License, or * | ||
| * (at your option) any later version. * | ||
| * * | ||
| ***************************************************************************/ | ||
| Here is Python function for comparing version numbers. It's case insensitive | ||
| and recognizes all major notations, prefixes (ver. and version), delimiters | ||
| (. - and _) and suffixes (alpha, beta, rc, preview and trunk). | ||
| Usage: compareVersions(version1, version2) | ||
| The function accepts arguments of any type convertable to unicode string | ||
| and returns integer value: | ||
| 0 - the versions are equal | ||
| 1 - version 1 is higher | ||
| 2 - version 2 is higher | ||
| ----------------------------------------------------------------------------- | ||
| HOW DOES IT WORK... | ||
| First, both arguments are converted to uppercase unicode and stripped of | ||
| 'VERSION' or 'VER.' prefix. Then they are chopped into a list of particular | ||
| numeric and alphabetic elements. The dots, dashes and underlines are recognized | ||
| as delimiters. Also numbers and non numbers are separated. See example below: | ||
| 'Ver 0.03-120_rc7foo' is converted to ['0','03','120','RC','7','FOO'] | ||
| Then every pair of elements, from left to right, is compared as string | ||
| or as number to provide the best result (you know, 11>9 but also '03'>'007'). | ||
| The comparing stops when one of elements is greater. If comparing achieves | ||
| the end of the shorter list and the matter is still unresolved, the longer | ||
| list is usually recognized as higher, except following suffixes: | ||
| ALPHA, BETA, RC, PREVIEW and TRUNK which make the version number lower. | ||
| """ | ||
|
|
||
| # ------------------------------------------------------------------------ # | ||
| def normalizeVersion(s): | ||
| """ remove possible prefix from given string and convert to uppercase """ | ||
| prefixes = ['VERSION','VER.','VER','V.','V','REVISION','REV.','REV','R.','R'] | ||
| if not s: | ||
| return unicode() | ||
| s = unicode(s).upper() | ||
| for i in prefixes: | ||
| if s[:len(i)] == i: | ||
| s = s.replace(i,'') | ||
| s = s.strip() | ||
| return s | ||
|
|
||
|
|
||
| # ------------------------------------------------------------------------ # | ||
| def classifyCharacter(c): | ||
| """ return 0 for delimiter, 1 for digit and 2 for alphabetic character """ | ||
| if c in [".","-","_"," "]: | ||
| return 0 | ||
| if c.isdigit(): | ||
| return 1 | ||
| else: | ||
| return 2 | ||
|
|
||
|
|
||
| # ------------------------------------------------------------------------ # | ||
| def chopString(s): | ||
| """ convert string to list of numbers and words """ | ||
| l = [s[0]] | ||
| for i in range(1,len(s)): | ||
| if classifyCharacter(s[i]) == 0: | ||
| pass | ||
| elif classifyCharacter(s[i]) == classifyCharacter(s[i-1]): | ||
| l[len(l)-1] += s[i] | ||
| else: | ||
| l += [s[i]] | ||
| return l | ||
|
|
||
|
|
||
| # ------------------------------------------------------------------------ # | ||
| def compareElements(s1,s2): | ||
| """ compare two particular elements """ | ||
| # check if the matter is easy solvable: | ||
| if s1 == s2: | ||
| return 0 | ||
| # try to compare as numeric values (but only if the first character is not 0): | ||
| if s1 and s2 and s1.isnumeric() and s2.isnumeric() and s1[0] != '0' and s2[0] != '0': | ||
| if float(s1) == float(s2): | ||
| return 0 | ||
| elif float(s1) > float(s2): | ||
| return 1 | ||
| else: | ||
| return 2 | ||
| # if the strings aren't numeric or start from 0, compare them as a strings: | ||
| # but first, set ALPHA < BETA < PREVIEW < RC < TRUNK < [NOTHING] < [ANYTHING_ELSE] | ||
| if not s1 in ['ALPHA','BETA','PREVIEW','RC','TRUNK']: | ||
| s1 = 'Z' + s1 | ||
| if not s2 in ['ALPHA','BETA','PREVIEW','RC','TRUNK']: | ||
| s2 = 'Z' + s2 | ||
| # the final test: | ||
| if s1 > s2: | ||
| return 1 | ||
| else: | ||
| return 2 | ||
|
|
||
|
|
||
| # ------------------------------------------------------------------------ # | ||
| def compareVersions(a,b): | ||
| """ Compare two version numbers. Return 0 if a==b or error, 1 if a<b and 2 if b>a """ | ||
| if not a or not b: | ||
| return 0 | ||
| a = normalizeVersion(a) | ||
| b = normalizeVersion(b) | ||
| if a == b: | ||
| return 0 | ||
| # convert the strings to the lists | ||
| v1 = chopString(a) | ||
| v2 = chopString(b) | ||
| # set the shorter string as a base | ||
| l = len(v1) | ||
| if l > len(v2): | ||
| l = len(v2) | ||
| # try to determine within the common length | ||
| for i in range(l): | ||
| if compareElements(v1[i],v2[i]): | ||
| return compareElements(v1[i],v2[i]) | ||
| # if the lists are identical till the end of the shorther string, try to compare the odd tail | ||
| #with the simple space (because the 'alpha', 'beta', 'preview' and 'rc' are LESS then nothing) | ||
| if len(v1) > l: | ||
| return compareElements(v1[l],u' ') | ||
| if len(v2) > l: | ||
| return compareElements(u' ',v2[l]) | ||
| # if everything else fails... | ||
| if a > b: | ||
| return 1 | ||
| else: | ||
| return 2 |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,29 @@ | ||
| PLUGIN METADATA TAGS | ||
| ======================================================= | ||
| id the key, usually library base name | ||
| name | ||
| description | ||
| icon path to installed or available icon | ||
| category will be removed? | ||
| tags comma separated, spaces allowed | ||
| changelog may be multiline | ||
| author_name | ||
| author_email | ||
| homepage url | ||
| tracker url | ||
| code_repository url | ||
| version_installed | ||
| library cpp: path to the installed library | Python: module name | ||
| pythonic is plugin pythonic or cpp? | ||
| readonly is core plugin? | ||
| status not installed | installed | upgradeable | orphan | new | newer * | ||
| error NULL | broken | incompatible | dependent | ||
| error_details | ||
| experimental choosen version status | ||
| version_available | ||
| zip_repository the remote repository id | ||
| download_url | ||
| filename the zip file name | ||
| downloads number of dowloads | ||
| average_vote | ||
| rating_votes number of votes |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,102 @@ | ||
| /*************************************************************************** | ||
| qgsapppluginmanagerinterface.cpp | ||
| -------------------------------------- | ||
| Date : 15-May-2013 | ||
| Copyright : (C) 2013 by Borys Jurgiel | ||
| Email : info at borysjurgiel dot pl | ||
| ****************************************************************************/ | ||
| /*************************************************************************** | ||
| * * | ||
| * This program is free software; you can redistribute it and/or modify * | ||
| * it under the terms of the GNU General Public License as published by * | ||
| * the Free Software Foundation; either version 2 of the License, or * | ||
| * (at your option) any later version. * | ||
| * * | ||
| ***************************************************************************/ | ||
|
|
||
| #include "qgsapppluginmanagerinterface.h" | ||
| #include <qgslogger.h> | ||
|
|
||
|
|
||
| QgsAppPluginManagerInterface::QgsAppPluginManagerInterface( QgsPluginManager * pluginManager ) | ||
| : mPluginManager( pluginManager ) | ||
| { | ||
| } | ||
|
|
||
|
|
||
| QgsAppPluginManagerInterface::~QgsAppPluginManagerInterface() | ||
| { | ||
| } | ||
|
|
||
|
|
||
| //! show the Plugin Manager window when remote repositories are fetched. | ||
| //! Display a progress dialog when fetching. | ||
| void QgsAppPluginManagerInterface::showPluginManagerWhenReady( ) | ||
| { | ||
| } | ||
|
|
||
|
|
||
| //! promptly show the Plugin Manager window and optionally open tab tabIndex: | ||
| void QgsAppPluginManagerInterface::showPluginManager( int tabIndex ) | ||
| { | ||
| mPluginManager->getCppPluginDescriptions(); | ||
| mPluginManager->reloadModelData(); | ||
|
|
||
| //! switch to tab, if specified ( -1 means not specified ) | ||
| if ( tabIndex > -1 ) | ||
| { | ||
| mPluginManager->selectTabItem( tabIndex ); | ||
| } | ||
|
|
||
| mPluginManager->exec(); | ||
| } | ||
|
|
||
|
|
||
| //! remove metadata of all python plugins from the registry (c++ plugins stay) | ||
| void QgsAppPluginManagerInterface::clearPythonPluginMetadata() | ||
| { | ||
| mPluginManager->clearPythonPluginMetadata(); | ||
| } | ||
|
|
||
|
|
||
| //! add a single plugin to the metadata registry | ||
| void QgsAppPluginManagerInterface::addPluginMetadata( QMap<QString,QString> metadata ) | ||
| { | ||
| if ( metadata.isEmpty() || !metadata.contains("id") ) | ||
| { | ||
| QgsDebugMsg( "Warning: incomplete metadata" ); | ||
| return; | ||
| } | ||
| mPluginManager->addPluginMetadata( metadata.value("id"), metadata ); | ||
| } | ||
|
|
||
|
|
||
| //! refresh listView model and textView content | ||
| void QgsAppPluginManagerInterface::reloadModel() | ||
| { | ||
| mPluginManager->reloadModelData(); | ||
| } | ||
|
|
||
|
|
||
|
|
||
|
|
||
| //! get given plugin metadata | ||
| QMap<QString,QString> * QgsAppPluginManagerInterface::pluginMetadata( QString key ) | ||
| { | ||
| return mPluginManager->pluginMetadata( key ); | ||
| } | ||
|
|
||
|
|
||
| //! clear the repository listWidget | ||
| void QgsAppPluginManagerInterface::clearRepositoryList() | ||
| { | ||
| mPluginManager->clearRepositoryList(); | ||
| } | ||
|
|
||
|
|
||
| //! add repository to the repository listWidget | ||
| void QgsAppPluginManagerInterface::addToRepositoryList( QMap<QString,QString> repository ) | ||
| { | ||
| mPluginManager->addToRepositoryList( repository ); | ||
| } | ||
|
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,72 @@ | ||
| /*************************************************************************** | ||
| qgsapppluginmanagerinterface.h | ||
| -------------------------------------- | ||
| Date : 15-May-2013 | ||
| Copyright : (C) 2013 by Borys Jurgiel | ||
| Email : info at borysjurgiel dot pl | ||
| ****************************************************************************/ | ||
| /*************************************************************************** | ||
| * * | ||
| * This program is free software; you can redistribute it and/or modify * | ||
| * it under the terms of the GNU General Public License as published by * | ||
| * the Free Software Foundation; either version 2 of the License, or * | ||
| * (at your option) any later version. * | ||
| * * | ||
| ***************************************************************************/ | ||
|
|
||
| #ifndef QGSPLUGINMANAGERAPPIFACE_H | ||
| #define QGSPLUGINMANAGERAPPIFACE_H | ||
|
|
||
| #include "qgspluginmanagerinterface.h" | ||
| #include "qgspluginmanager.h" | ||
|
|
||
| /** \ingroup gui | ||
| * QgsPluginManagerInterface | ||
| * Abstract base class to make QgsPluginManager available to plugins. | ||
| */ | ||
| class QgsAppPluginManagerInterface : public QgsPluginManagerInterface | ||
| { | ||
| Q_OBJECT | ||
|
|
||
| public: | ||
|
|
||
| //! Constructor | ||
| explicit QgsAppPluginManagerInterface( QgsPluginManager * pluginManager ); | ||
|
|
||
| //! Destructor | ||
| ~QgsAppPluginManagerInterface(); | ||
|
|
||
| //! remove metadata of all python plugins from the registry (c++ plugins stay) | ||
| void clearPythonPluginMetadata(); | ||
|
|
||
| //! add a single plugin to the metadata registry | ||
| void addPluginMetadata( QMap<QString,QString> metadata ); | ||
|
|
||
| //! refresh listView model and textView content | ||
| void reloadModel(); | ||
|
|
||
| //! get given plugin metadata | ||
| QMap<QString, QString> * pluginMetadata( QString key ); | ||
|
|
||
| //! clear the repository listWidget | ||
| void clearRepositoryList(); | ||
|
|
||
| //! add repository to the repository listWidget | ||
| void addToRepositoryList( QMap<QString,QString> repository ); | ||
|
|
||
| public slots: | ||
|
|
||
| //! show the Plugin Manager window when remote repositories are fetched. | ||
| //! Display a progress dialog when fetching. | ||
| void showPluginManagerWhenReady( ); | ||
|
|
||
| //! promptly show the Plugin Manager window and optionally open tab tabIndex: | ||
| void showPluginManager( int tabIndex = -1 ); | ||
|
|
||
| private: | ||
|
|
||
| //! Pointer to QgsPluginManager object | ||
| QgsPluginManager *mPluginManager; | ||
| }; | ||
|
|
||
| #endif //QGSPLUGINMANAGERAPPIFACE_H |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,182 @@ | ||
| /*************************************************************************** | ||
| qgspluginmanager.h | ||
| Plugin manager for loading/unloading QGIS plugins | ||
| ------------------- | ||
| begin : 2004-02-12 | ||
| copyright : (C) 2004 by Gary E.Sherman | ||
| email : sherman at mrcc.com | ||
| ***************************************************************************/ | ||
|
|
||
| /*************************************************************************** | ||
| * * | ||
| // * This program is free software; you can redistribute it and/or modify * | ||
| * it under the terms of the GNU General Public License as published by * | ||
| * the Free Software Foundation; either version 2 of the License, or * | ||
| * (at your option) any later version. * | ||
| * * | ||
| ***************************************************************************/ | ||
| #ifndef QGSPLUGINMANAGER_H | ||
| #define QGSPLUGINMANAGER_H | ||
| #include <vector> | ||
| #include <QMap> | ||
| #include <QString> | ||
| #include <QStandardItemModel> | ||
| #include <QStandardItem> | ||
| #include <QHeaderView> | ||
| #include "ui_qgspluginmanagerbase.h" | ||
| #include "qgsoptionsdialogbase.h" | ||
| #include "qgisgui.h" | ||
| #include "qgscontexthelp.h" | ||
| #include "qgspythonutils.h" | ||
| #include "qgspluginsortfilterproxymodel.h" | ||
|
|
||
|
|
||
|
|
||
| /*! | ||
| * \brief Plugin manager for loading/unloading plugins | ||
| @author Gary Sherman | ||
| */ | ||
| class QgsPluginManager : public QgsOptionsDialogBase, private Ui::QgsPluginManagerBase | ||
| { | ||
| Q_OBJECT | ||
| public: | ||
| //! Constructor | ||
| QgsPluginManager( QWidget *parent = 0, Qt::WFlags fl = QgisGui::ModalDialogFlags ); | ||
| //! Destructor | ||
| ~QgsPluginManager(); | ||
|
|
||
| //! Save pointer for python utils - necessary for unloading Python plugins | ||
| void setPythonUtils( QgsPythonUtils* pythonUtils ); | ||
|
|
||
| //! Load selected plugin | ||
| void loadPlugin( QString id ); | ||
| //! Unload unselected plugin | ||
| void unloadPlugin( QString id ); | ||
| //! Get description of C++ plugins (name, etc) | ||
| void getCppPluginDescriptions(); | ||
|
|
||
| //! Repopulate the plugin list model | ||
| void reloadModelData(); | ||
| //! Populate the html browser widget with plugin details | ||
| void showPluginDetails( QStandardItem * item ); | ||
|
|
||
| //! Remove python plugins from the metadata registry (c++ plugins stay) | ||
| void clearPythonPluginMetadata(); | ||
|
|
||
| //! Add a single plugin to the map of plugin metadata | ||
| void addPluginMetadata( QString key, QMap<QString,QString> metadata ); | ||
|
|
||
| //! Get metadata of given plugin | ||
| QMap<QString,QString> * pluginMetadata( QString key ); | ||
|
|
||
| //! Switch to one of vertical tabs by API | ||
| void selectTabItem( int idx ); | ||
|
|
||
| //! Clear the repository listWidget | ||
| void clearRepositoryList(); | ||
|
|
||
| //! Add repository to the repository listWidget | ||
| void addToRepositoryList( QMap<QString,QString> repository ); | ||
|
|
||
| // // //! Set vwPlugins table GUI | ||
| // // void setTable(); | ||
| // // //! Get description of Pythin plugins (does nothing when python is disabled) | ||
| // // void getPythonPluginDescriptions(); | ||
| // // //! Resize columns to contents | ||
| // // void resizeColumnsToContents(); | ||
| // // //! Sort model by column ascending | ||
| // // void sortModel( int ); | ||
| // // //! Check whether plugin installer is available (and tries to load it if it's disabled) | ||
| // // bool checkForPluginInstaller(); | ||
|
|
||
| public slots: | ||
| //! Load selected plugins and close the dialog (called when the "Close" button clicked) | ||
| void reject(); | ||
| //! Update stacket widget (called from the vertical list item) | ||
| void setCurrentTab( int idx ); | ||
| //! Updates current tab tile of according to current filters | ||
| void updateTabTitle(); | ||
| //! Handle plugin selection | ||
| void currentPluginChanged( const QModelIndex & theIndex ); | ||
| //! Load/unload plugin when checkbox state changed | ||
| void pluginItemChanged( QStandardItem * item ); | ||
| //! Display details of inactive item too | ||
| void on_vwPlugins_clicked( const QModelIndex & ); | ||
| //! Disable/enable plugin after double click | ||
| void on_vwPlugins_doubleClicked( const QModelIndex & index ); | ||
| //! Update the filter when user changes the filter expression | ||
| void on_leFilter_textChanged( QString theText ); | ||
| //! Set filter mode to filter by name | ||
| void on_rbFilterNames_toggled( bool checked ); | ||
| //! Set filter mode to filter by description | ||
| void on_rbFilterDescriptions_toggled( bool checked ); | ||
| //! Set filter mode to filter by tags | ||
| void on_rbFilterTags_toggled( bool checked ); | ||
| //! Set filter mode to filter by autor | ||
| void on_rbFilterAuthors_toggled( bool checked ); | ||
| //! Upgrade all upgradeable plugins | ||
| void on_buttonUpgradeAll_clicked( ); | ||
| //! Install selected plugin | ||
| void on_buttonInstall_clicked( ); | ||
| //! Uninstall selected plugin | ||
| void on_buttonUninstall_clicked( ); | ||
|
|
||
| //! Enable/disable buttons according to selected repository | ||
| void on_treeRepositories_itemSelectionChanged( ); | ||
| //! Edit selected repository | ||
| void on_treeRepositories_doubleClicked( QModelIndex ); | ||
| //! Define new repository connection | ||
| void on_buttonAddRep_clicked( ); | ||
| //! Edit selected repository connection | ||
| void on_buttonEditRep_clicked( ); | ||
| //! Delete selected repository connection | ||
| void on_buttonDeleteRep_clicked( ); | ||
| //! Refresh all repositories | ||
| void on_buttonRefreshRepos_clicked( ); | ||
|
|
||
| //! Reload plugin metadata registry after allowing/disallowing experimental plugins | ||
| void on_ckbExperimental_toggled( bool state ); | ||
|
|
||
| //! Open help browser | ||
| void on_buttonBox_helpRequested( ) { QgsContextHelp::run( metaObject()->className() ); } | ||
|
|
||
| // // // //! Select all plugins by setting their checkbox on | ||
| // // // void selectAll(); | ||
| // // // //! Clear all selections by clearing the plugins checkbox | ||
| // // // void clearAll(); | ||
| // // // //! Show the plugin installer | ||
| // // // void showPluginInstaller(); | ||
|
|
||
| // // // //! query the metadata registry about some frequently used state questions | ||
| // // // bool pluginState( QString key, QString question ); | ||
|
|
||
| //! Overwrite QgsOptionsDialogBase method to prevent changing the tab list from the stacked widget | ||
| void optionsStackedWidget_CurrentChanged( int indx ) { Q_UNUSED( indx ) } | ||
|
|
||
| private: | ||
|
|
||
| //! Return true if given plugin is currently present in QgsPluginRegistry | ||
| bool isPluginLoaded( QString key ); | ||
|
|
||
| //! Return true if there are upgradeable plugins in the registry | ||
| bool hasUpgradeablePlugins( ); | ||
|
|
||
| //! Return true if there are new plugins in the registry | ||
| bool hasNewPlugins( ); | ||
|
|
||
| //! Return true if there are invalid plugins in the registry | ||
| bool hasInvalidPlugins( ); | ||
|
|
||
| QStandardItemModel *mModelPlugins; | ||
| QgsPluginSortFilterProxyModel * mModelProxy; | ||
|
|
||
| QgsPythonUtils* mPythonUtils; | ||
|
|
||
| QMap< QString, QMap< QString,QString > > mPlugins; | ||
|
|
||
| QString mCurrentlyDisplayedPlugin; | ||
|
|
||
| QList<int> checkingOnStartIntervals; | ||
| }; | ||
|
|
||
| #endif |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,116 @@ | ||
| /*************************************************************************** | ||
| qgspluginsortfilterproxymodel.cpp | ||
| -------------------------------------- | ||
| Date : 20-May-2013 | ||
| Copyright : (C) 2013 by Borys Jurgiel | ||
| Email : info at borysjurgiel dot pl | ||
| ****************************************************************************/ | ||
| /*************************************************************************** | ||
| * * | ||
| * This program is free software; you can redistribute it and/or modify * | ||
| * it under the terms of the GNU General Public License as published by * | ||
| * the Free Software Foundation; either version 2 of the License, or * | ||
| * (at your option) any later version. * | ||
| * * | ||
| ***************************************************************************/ | ||
|
|
||
| #include "qgspluginsortfilterproxymodel.h" | ||
| #include "qgslogger.h" | ||
|
|
||
| QgsPluginSortFilterProxyModel::QgsPluginSortFilterProxyModel(QObject *parent) | ||
| : QSortFilterProxyModel(parent) | ||
| { | ||
| } | ||
|
|
||
|
|
||
|
|
||
|
|
||
| bool QgsPluginSortFilterProxyModel::filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const | ||
| { | ||
| QModelIndex inx = sourceModel()->index(sourceRow, 0, sourceParent); | ||
|
|
||
| return ( filterByStatus( inx ) && sourceModel()->data( inx, filterRole() ).toString().contains( filterRegExp() ) ); | ||
| } | ||
|
|
||
|
|
||
|
|
||
|
|
||
| void QgsPluginSortFilterProxyModel::setAcceptedStatuses( QStringList statuses) | ||
| { | ||
| mAcceptedStatuses = statuses; | ||
| invalidateFilter(); | ||
| } | ||
|
|
||
|
|
||
|
|
||
|
|
||
| bool QgsPluginSortFilterProxyModel::filterByStatus( QModelIndex &index ) const | ||
| { | ||
| if ( mAcceptedStatuses.contains( "invalid" ) | ||
| && sourceModel()->data(index, PLUGIN_ERROR_ROLE).toString().isEmpty() ) | ||
| { | ||
| // Don't accept if the "invalid" filter is set and the plugin is ok | ||
| return false; | ||
| } | ||
|
|
||
| if ( ! mAcceptedStatuses.isEmpty() | ||
| && ! mAcceptedStatuses.contains( "invalid" ) | ||
| && ! mAcceptedStatuses.contains( sourceModel()->data(index, PLUGIN_STATUS_ROLE).toString() ) ) | ||
| { | ||
| // Don't accept if the status doesn't match | ||
| return false; | ||
| } | ||
|
|
||
| // Otherwise, let the item go. | ||
| return true; | ||
| } | ||
|
|
||
|
|
||
|
|
||
|
|
||
| int QgsPluginSortFilterProxyModel::countWithCurrentStatus( ) | ||
| { | ||
| int result = 0; | ||
| for (int i=0; i < sourceModel()->rowCount(); ++i) | ||
| { | ||
| QModelIndex idx = sourceModel()->index(i, 0); | ||
| if ( filterByStatus( idx ) ) | ||
| { | ||
| result++ ; | ||
| } | ||
| } | ||
| return result; | ||
| } | ||
|
|
||
|
|
||
|
|
||
|
|
||
| void QgsPluginSortFilterProxyModel::sortPluginsByName( ) | ||
| { | ||
| sort( 0, Qt::AscendingOrder ); | ||
| setSortRole( Qt::DisplayRole ); | ||
| } | ||
|
|
||
| void QgsPluginSortFilterProxyModel::sortPluginsByDownloads( ) | ||
| { | ||
| sort( 0, Qt::DescendingOrder ); | ||
| setSortRole( PLUGIN_DOWNLOADS_ROLE ); | ||
| } | ||
|
|
||
| void QgsPluginSortFilterProxyModel::sortPluginsByVote( ) | ||
| { | ||
| sort( 0, Qt::DescendingOrder ); | ||
| setSortRole( PLUGIN_VOTE_ROLE ); | ||
| } | ||
|
|
||
| void QgsPluginSortFilterProxyModel::sortPluginsByStatus( ) | ||
| { | ||
| sort( 0, Qt::DescendingOrder ); | ||
| setSortRole( PLUGIN_STATUS_ROLE ); | ||
| } | ||
|
|
||
| void QgsPluginSortFilterProxyModel::sortPluginsByRepository( ) | ||
| { | ||
| sort( 0, Qt::DescendingOrder ); | ||
| setSortRole( PLUGIN_REPOSITORY_ROLE ); | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,69 @@ | ||
| /*************************************************************************** | ||
| qgspluginsortfilterproxymodel.h | ||
| -------------------------------------- | ||
| Date : 20-May-2013 | ||
| Copyright : (C) 2013 by Borys Jurgiel | ||
| Email : info at borysjurgiel dot pl | ||
| ****************************************************************************/ | ||
| /*************************************************************************** | ||
| * * | ||
| * This program is free software; you can redistribute it and/or modify * | ||
| * it under the terms of the GNU General Public License as published by * | ||
| * the Free Software Foundation; either version 2 of the License, or * | ||
| * (at your option) any later version. * | ||
| * * | ||
| ***************************************************************************/ | ||
|
|
||
| #ifndef QGSPLUGINSORTFILTERPROXYMODEL_H | ||
| #define QGSPLUGINSORTFILTERPROXYMODEL_H | ||
|
|
||
| #include <QSortFilterProxyModel> | ||
| #include <QStringList> | ||
| // #include <QString> | ||
| // #include <QMap> | ||
|
|
||
| const int PLUGIN_BASE_NAME_ROLE = Qt::UserRole + 1; | ||
| const int PLUGIN_DESCRIPTION_ROLE = Qt::UserRole + 2; // for filtering | ||
| const int PLUGIN_AUTHOR_ROLE = Qt::UserRole + 3; // for filtering | ||
| const int PLUGIN_TAGS_ROLE = Qt::UserRole + 4; // for filtering | ||
| const int PLUGIN_ERROR_ROLE = Qt::UserRole + 6; // for filtering | ||
| const int PLUGIN_STATUS_ROLE = Qt::UserRole + 5; // for filtering and sorting | ||
| const int PLUGIN_DOWNLOADS_ROLE = Qt::UserRole + 7; // for sorting | ||
| const int PLUGIN_VOTE_ROLE = Qt::UserRole + 8; // for sorting | ||
| const int PLUGIN_REPOSITORY_ROLE = Qt::UserRole + 9; // for sorting | ||
|
|
||
|
|
||
| /*! | ||
| * \brief Proxy model for filtering and sorting items in Plugin Manager | ||
| */ | ||
| class QgsPluginSortFilterProxyModel : public QSortFilterProxyModel | ||
| { | ||
| Q_OBJECT | ||
|
|
||
| public: | ||
| QgsPluginSortFilterProxyModel(QObject *parent = 0); | ||
|
|
||
| //! (Re)configire the status filter | ||
| void setAcceptedStatuses( QStringList statuses ); | ||
|
|
||
| //! Return number of item with status filter matching (no other filters are considered) | ||
| int countWithCurrentStatus( ); | ||
|
|
||
| public slots: | ||
| void sortPluginsByName( ); | ||
| void sortPluginsByDownloads( ); | ||
| void sortPluginsByVote( ); | ||
| void sortPluginsByStatus( ); | ||
| void sortPluginsByRepository( ); | ||
|
|
||
| protected: | ||
| //! Filter by status: this method is used in both filterAcceptsRow and countWithCurrentStatus. | ||
| bool filterByStatus( QModelIndex &index ) const; | ||
| //! The main filter method | ||
| bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent) const; | ||
|
|
||
| private: | ||
| QStringList mAcceptedStatuses; | ||
| }; | ||
|
|
||
| #endif |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,26 @@ | ||
| /*************************************************************************** | ||
| qgspluginmanagerinterface.cpp | ||
| -------------------------------------- | ||
| Date : 15-May-2013 | ||
| Copyright : (C) 2013 by Borys Jurgiel | ||
| Email : info at borysjurgiel dot pl | ||
| ****************************************************************************/ | ||
| /*************************************************************************** | ||
| * * | ||
| * This program is free software; you can redistribute it and/or modify * | ||
| * it under the terms of the GNU General Public License as published by * | ||
| * the Free Software Foundation; either version 2 of the License, or * | ||
| * (at your option) any later version. * | ||
| * * | ||
| ***************************************************************************/ | ||
|
|
||
| #include "qgspluginmanagerinterface.h" | ||
|
|
||
| QgsPluginManagerInterface::QgsPluginManagerInterface() | ||
| { | ||
| } | ||
|
|
||
| QgsPluginManagerInterface::~QgsPluginManagerInterface() | ||
| { | ||
| } | ||
|
|
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,70 @@ | ||
| /*************************************************************************** | ||
| qgspluginmanagerinterface.h | ||
| -------------------------------------- | ||
| Date : 15-May-2013 | ||
| Copyright : (C) 2013 by Borys Jurgiel | ||
| Email : info at borysjurgiel dot pl | ||
| ****************************************************************************/ | ||
| /*************************************************************************** | ||
| * * | ||
| * This program is free software; you can redistribute it and/or modify * | ||
| * it under the terms of the GNU General Public License as published by * | ||
| * the Free Software Foundation; either version 2 of the License, or * | ||
| * (at your option) any later version. * | ||
| * * | ||
| ***************************************************************************/ | ||
|
|
||
| #ifndef QGSPLUGINMANAGERINTERFACE_H | ||
| #define QGSPLUGINMANAGERINTERFACE_H | ||
|
|
||
| #include <QObject> | ||
| #include <QString> | ||
| #include <QMap> | ||
|
|
||
| class GUI_EXPORT QgsPluginManagerInterface : public QObject | ||
| { | ||
| Q_OBJECT | ||
|
|
||
| public: | ||
|
|
||
| //! Constructor | ||
| QgsPluginManagerInterface(); | ||
|
|
||
| //! Virtual destructor | ||
| virtual ~QgsPluginManagerInterface(); | ||
|
|
||
| //! remove metadata of all python plugins from the registry (c++ plugins stay) | ||
| virtual void clearPythonPluginMetadata() = 0; | ||
|
|
||
| //! add a single plugin to the metadata registry | ||
| virtual void addPluginMetadata( QMap<QString,QString> metadata ) = 0; | ||
|
|
||
| //! refresh listView model and textView content | ||
| virtual void reloadModel() = 0; | ||
|
|
||
| //! get given plugin metadata | ||
| virtual QMap<QString, QString> * pluginMetadata( QString key ) = 0; | ||
|
|
||
| //! clear the repository listWidget | ||
| virtual void clearRepositoryList() = 0; | ||
|
|
||
| //! add repository to the repository listWidget | ||
| virtual void addToRepositoryList( QMap<QString,QString> repository ) = 0; | ||
|
|
||
| signals: | ||
|
|
||
| //! emitted when the Python Plugin Installer should show the fetching repositories window | ||
| void fetchingStillInProgress( ); | ||
|
|
||
| public slots: | ||
|
|
||
| //! show the Plugin Manager window when remote repositories are fetched. | ||
| //! Display a progress dialog when fetching. | ||
| virtual void showPluginManagerWhenReady( ) = 0; | ||
|
|
||
| //! promptly show the Plugin Manager window and optionally open tab tabIndex: | ||
| virtual void showPluginManager( int tabIndex = -1 ) = 0; | ||
|
|
||
| }; | ||
|
|
||
| #endif |