[Plugin Manager] remove the old plugin_installer plugin

This commit is contained in:
Borys Jurgiel 2013-05-27 17:24:50 +02:00 committed by Nathan Woodrow
parent 53d3ea91de
commit fa9d79fab3
27 changed files with 116 additions and 3835 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.8 KiB

View File

@ -73,7 +73,6 @@ MACRO (PLUGIN_INSTALL plugin subdir )
ENDMACRO (PLUGIN_INSTALL)
ADD_SUBDIRECTORY(plugin_installer)
ADD_SUBDIRECTORY(mapserver_export)
ADD_SUBDIRECTORY(fTools)
ADD_SUBDIRECTORY(GdalTools)

View File

@ -1,29 +0,0 @@
SET(INSTALLER_FILES
metadata.txt
__init__.py
installer_data.py
installer_gui.py
installer_plugin.py
plugin_installer.png
qgis-icon.png
repoConnected.png
repoDisabled.png
repoUnavailable.png
pluginExperimental.png
pluginStable.png
unzip.py
version_compare.py
)
PYQT4_WRAP_UI(PYUI_FILES
qgsplugininstallerbase.ui
qgsplugininstallerfetchingbase.ui
qgsplugininstallerinstallingbase.ui
qgsplugininstallerpluginerrorbase.ui
qgsplugininstallerrepositorybase.ui
qgsplugininstalleroldreposbase.ui
)
PYQT4_ADD_RESOURCES(PYRC_FILES resources.qrc)
PLUGIN_INSTALL(plugin_installer . ${PYUI_FILES} ${PYRC_FILES} ${INSTALLER_FILES})

View File

@ -1,21 +0,0 @@
Copyright (c) 2007 Matthew T. Perry
Copyright (c) 2008-2009 Borys Jurgiel
Permission is hereby granted, free of charge, to any person obtaining a copy of
this software and associated documentation files (the "Software"), to deal in
the Software without restriction, including without limitation the rights to
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is furnished to do
so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

View File

@ -1,17 +0,0 @@
# -*- coding: utf-8 -*-
"""
Copyright (C) 2007-2008 Matthew Perry
Copyright (C) 2008-2010 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. *
* *
***************************************************************************/
"""
def classFactory(iface):
from installer_plugin import InstallerPlugin
return InstallerPlugin(iface)

View File

@ -1,737 +0,0 @@
# -*- coding: utf-8 -*-
"""
Copyright (C) 2007-2008 Matthew Perry
Copyright (C) 2008-2010 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. *
* *
***************************************************************************/
"""
from PyQt4.QtCore import *
from PyQt4.QtXml import QDomDocument
from PyQt4.QtNetwork import *
from qgis.core import *
from unzip import unzip
from version_compare import compareVersions, normalizeVersion
import sys
"""
Data structure:
mRepositories = dict of dicts: {repoName : {"url" QString,
"enabled" bool,
"valid" bool,
"QPHttp" QPHttp,
"Relay" Relay, # Relay object for transmitting signals from QPHttp with adding the repoName information
"xmlData" QBuffer,
"state" int, (0 - disabled, 1-loading, 2-loaded ok, 3-error (to be retried), 4-rejected)
"error" QString}}
mPlugins = dict of dicts {id : {"name" QString,
"version_avail" QString,
"version_inst" QString,
"desc_repo" QString,
"desc_local" QString,
"author" QString,
"status" QString, ("not installed", "installed", "upgradeable", "orphan", "new", "newer")
"error" QString, ("", "broken", "incompatible", "dependent")
"error_details" QString,
"homepage" QString,
"url" QString,
"experimental" bool
"filename" QString,
"repository" QString,
"localdir" QString,
"read-only" boolean}}
"""
QGIS_VER = QGis.QGIS_VERSION
QGIS_14 = (QGIS_VER[2] > "3")
QGIS_15 = (QGIS_VER[2] > "4")
def setIface(qgisIface):
global iface
iface = qgisIface
reposGroup = "/Qgis/plugin-repos"
settingsGroup = "/Qgis/plugin-installer"
seenPluginGroup = "/Qgis/plugin-seen"
# Repositories: (name, url, possible depreciated url)
officialRepo = ("QGIS Official Repository", "http://plugins.qgis.org/plugins/plugins.xml","http://plugins.qgis.org/plugins")
depreciatedRepos = [
("Old QGIS Official Repository", "http://pyqgis.org/repo/official"),
("Old QGIS Contributed Repository","http://pyqgis.org/repo/contributed"),
("Aaron Racicot's Repository", "http://qgisplugins.z-pulley.com"),
("Barry Rowlingson's Repository", "http://www.maths.lancs.ac.uk/~rowlings/Qgis/Plugins/plugins.xml"),
("Bob Bruce's Repository", "http://www.mappinggeek.ca/QGISPythonPlugins/Bobs-QGIS-plugins.xml"),
("Borys Jurgiel's Repository", "http://bwj.aster.net.pl/qgis/plugins.xml"),
("Borys Jurgiel's Repository 2", "http://bwj.aster.net.pl/qgis-oldapi/plugins.xml"),
("Carson Farmer's Repository", "http://www.ftools.ca/cfarmerQgisRepo.xml"),
("Carson Farmer's Repository 2", "http://www.ftools.ca/cfarmerQgisRepo_0.xx.xml"),
("CatAIS Repository", "http://www.catais.org/qgis/plugins.xml"),
("Faunalia Repository", "http://www.faunalia.it/qgis/plugins.xml"),
("Faunalia Repository 2", "http://faunalia.it/qgis/plugins.xml"),
("GIS-Lab Repository", "http://gis-lab.info/programs/qgis/qgis-repo.xml"),
("Kappasys Repository", "http://www.kappasys.org/qgis/plugins.xml"),
("Martin Dobias' Sandbox", "http://mapserver.sk/~wonder/qgis/plugins-sandbox.xml"),
("Marco Hugentobler's Repository", "http://karlinapp.ethz.ch/python_plugins/python_plugins.xml"),
("Sourcepole Repository", "http://build.sourcepole.ch/qgis/plugins.xml"),
("Volkan Kepoglu's Repository", "http://ggit.metu.edu.tr/~volkan/plugins.xml")
]
# --- class History ----------------------------------------------------------------------- #
class History(dict):
""" Dictionary for keeping changes made duging the session - will be used to complete the (un/re)loading """
# ----------------------------------------- #
def markChange(self, plugin, change):
""" mark the status change: A-added, D-deleted, R-reinstalled """
if change == "A" and self.get(plugin) == "D": # installation right after uninstallation
self.__setitem__(plugin, "R")
elif change == "A": # any other installation
self.__setitem__(plugin, "A")
elif change == "D" and self.get(plugin) == "A": # uninstallation right after installation
self.pop(plugin)
elif change == "D": # any other uninstallation
self.__setitem__(plugin, "D")
elif change == "R" and self.get(plugin) == "A": # reinstallation right after installation
self.__setitem__(plugin, "A")
elif change == "R": # any other reinstallation
self.__setitem__(plugin, "R")
# ----------------------------------------- #
def toList(self, change):
""" return a list of plugins matching the given change """
result = []
for i in self.items():
if i[1] == change:
result += [i[0]]
return result
# --- /class History ---------------------------------------------------------------------- #
# --- class QPHttp ----------------------------------------------------------------------- #
# --- It's a temporary workaround for broken proxy handling in Qt ------------------------- #
class QPHttp(QHttp):
def __init__(self,*args):
QHttp.__init__(self,*args)
settings = QSettings()
settings.beginGroup("proxy")
if settings.value("/proxyEnabled").toBool():
self.proxy=QNetworkProxy()
proxyType = settings.value( "/proxyType", QVariant(0)).toString()
if len(args)>0 and settings.value("/proxyExcludedUrls").toString().contains(args[0]):
proxyType = "NoProxy"
if proxyType in ["1","Socks5Proxy"]: self.proxy.setType(QNetworkProxy.Socks5Proxy)
elif proxyType in ["2","NoProxy"]: self.proxy.setType(QNetworkProxy.NoProxy)
elif proxyType in ["3","HttpProxy"]: self.proxy.setType(QNetworkProxy.HttpProxy)
elif proxyType in ["4","HttpCachingProxy"] and QT_VERSION >= 0X040400: self.proxy.setType(QNetworkProxy.HttpCachingProxy)
elif proxyType in ["5","FtpCachingProxy"] and QT_VERSION >= 0X040400: self.proxy.setType(QNetworkProxy.FtpCachingProxy)
else: self.proxy.setType(QNetworkProxy.DefaultProxy)
self.proxy.setHostName(settings.value("/proxyHost").toString())
self.proxy.setPort(settings.value("/proxyPort").toUInt()[0])
self.proxy.setUser(settings.value("/proxyUser").toString())
self.proxy.setPassword(settings.value("/proxyPassword").toString())
self.setProxy(self.proxy)
settings.endGroup()
return None
# --- /class QPHttp ---------------------------------------------------------------------- #
# --- class Relay ----------------------------------------------------------------------- #
class Relay(QObject):
""" Relay object for transmitting signals from QPHttp with adding the repoName information """
# ----------------------------------------- #
def __init__(self, key):
QObject.__init__(self)
self.key = key
def stateChanged(self, state):
self.emit(SIGNAL("anythingChanged(QString, int, int)"), self.key, state, 0)
# ----------------------------------------- #
def dataReadProgress(self, done, total):
state = 4
if total:
progress = int(float(done)/float(total)*100)
else:
progress = 0
self.emit(SIGNAL("anythingChanged(QString, int, int)"), self.key, state, progress)
# --- /class Relay ---------------------------------------------------------------------- #
# --- class Repositories ----------------------------------------------------------------- #
class Repositories(QObject):
""" A dict-like class for handling repositories data """
# ----------------------------------------- #
def __init__(self):
QObject.__init__(self)
self.mRepositories = {}
self.httpId = {} # {httpId : repoName}
## depreciated in qgis 1.8 until we use 3rd party repos again
## ----------------------------------------- #
#def addKnownRepos(self):
#""" add known 3rd party repositories to QSettings """
#presentURLs = []
#for i in self.all().values():
#presentURLs += [QString(i["url"])]
#settings = QSettings()
#settings.beginGroup(reposGroup)
## add the official repository
#if presentURLs.count(officialRepo[1]) == 0:
#settings.setValue(officialRepo[0]+"/url", QVariant(officialRepo[1]))
#settings.setValue(officialRepo[0]+"/enabled", QVariant(True))
## add author repositories
#for i in authorRepos:
#if i[1] and presentURLs.count(i[1]) == 0:
#repoName = QString(i[0])
#if self.all().has_key(repoName):
#repoName = repoName + " (original)"
#settings.setValue(repoName+"/url", QVariant(i[1]))
#settings.setValue(repoName+"/enabled", QVariant(True))
# ----------------------------------------- #
def all(self):
""" return dict of all repositories """
return self.mRepositories
# ----------------------------------------- #
def allEnabled(self):
""" return dict of all enabled and valid repositories """
repos = {}
for i in self.mRepositories:
if self.mRepositories[i]["enabled"] and self.mRepositories[i]["valid"]:
repos[i] = self.mRepositories[i]
return repos
# ----------------------------------------- #
def allUnavailable(self):
""" return dict of all unavailable repositories """
repos = {}
for i in self.mRepositories:
if self.mRepositories[i]["enabled"] and self.mRepositories[i]["valid"] and self.mRepositories[i]["state"] == 3:
repos[i] = self.mRepositories[i]
return repos
# ----------------------------------------- #
def setRepositoryData(self, reposName, key, value):
""" write data to the mRepositories dict """
self.mRepositories[reposName][key] = value
# ----------------------------------------- #
def remove(self, reposName):
""" remove given item from the mRepositories dict """
del self.mRepositories[reposName]
# ----------------------------------------- #
def rename(self, oldName, newName):
""" rename repository key """
if oldName == newName:
return
self.mRepositories[newName] = self.mRepositories[oldName]
del self.mRepositories[oldName]
# ----------------------------------------- #
def checkingOnStart(self):
""" return true if checking for news and updates is enabled """
settings = QSettings()
return settings.value(settingsGroup+"/checkOnStart", QVariant(False)).toBool()
# ----------------------------------------- #
def setCheckingOnStart(self, state):
""" set state of checking for news and updates """
settings = QSettings()
settings.setValue(settingsGroup+"/checkOnStart", QVariant(state))
# ----------------------------------------- #
def checkingOnStartInterval(self):
""" return checking for news and updates interval """
settings = QSettings()
(i, ok) = settings.value(settingsGroup+"/checkOnStartInterval").toInt()
if i < 0 or not ok:
i = 1
# allowed values: 0,1,3,7,14,30 days
interval = 0
for j in [1,3,7,14,30]:
if i >= j:
interval = j
return interval
# ----------------------------------------- #
def setCheckingOnStartInterval(self, interval):
""" set checking for news and updates interval """
settings = QSettings()
settings.setValue(settingsGroup+"/checkOnStartInterval", QVariant(interval))
# ----------------------------------------- #
def saveCheckingOnStartLastDate(self):
""" set today's date as the day of last checking """
settings = QSettings()
settings.setValue(settingsGroup+"/checkOnStartLastDate", QVariant(QDate.currentDate()))
# ----------------------------------------- #
def timeForChecking(self):
""" determine whether it's the time for checking for news and updates now """
if self.checkingOnStartInterval() == 0:
return True
settings = QSettings()
interval = settings.value(settingsGroup+"/checkOnStartLastDate").toDate().daysTo(QDate.currentDate())
if interval >= self.checkingOnStartInterval():
return True
else:
return False
# ----------------------------------------- #
def load(self):
""" populate the mRepositories dict"""
self.mRepositories = {}
settings = QSettings()
settings.beginGroup(reposGroup)
# first, update repositories in QSettings if needed
officialRepoPresent = False
for key in settings.childGroups():
url = settings.value(key+"/url", QVariant()).toString()
if url == officialRepo[1]:
officialRepoPresent = True
if url == officialRepo[2]:
settings.setValue(key+"/url", QVariant(officialRepo[1])) # correct a depreciated url
officialRepoPresent = True
if not officialRepoPresent:
settings.setValue(officialRepo[0]+"/url", QVariant(officialRepo[1]))
for key in settings.childGroups():
self.mRepositories[key] = {}
self.mRepositories[key]["url"] = settings.value(key+"/url", QVariant()).toString()
self.mRepositories[key]["enabled"] = settings.value(key+"/enabled", QVariant(True)).toBool()
self.mRepositories[key]["valid"] = settings.value(key+"/valid", QVariant(True)).toBool()
self.mRepositories[key]["QPHttp"] = QPHttp()
self.mRepositories[key]["Relay"] = Relay(key)
self.mRepositories[key]["xmlData"] = QBuffer()
self.mRepositories[key]["state"] = 0
self.mRepositories[key]["error"] = QString()
settings.endGroup()
# ----------------------------------------- #
def requestFetching(self,key):
""" start fetching the repository given by key """
self.mRepositories[key]["state"] = 1
url = QUrl(self.mRepositories[key]["url"])
path = QString(url.toPercentEncoding(url.path(), "!$&'()*+,;=:@/"))
v=str(QGis.QGIS_VERSION_INT)
path += "?qgis=%s" % ('.'.join([str(int(s)) for s in [v[0], v[1:3], v[3:5]]]))
port = url.port()
if port < 0:
port = 80
self.mRepositories[key]["QPHttp"] = QPHttp(url.host(), port)
self.connect(self.mRepositories[key]["QPHttp"], SIGNAL("requestFinished (int, bool)"), self.xmlDownloaded)
self.connect(self.mRepositories[key]["QPHttp"], SIGNAL("stateChanged ( int )"), self.mRepositories[key]["Relay"].stateChanged)
self.connect(self.mRepositories[key]["QPHttp"], SIGNAL("dataReadProgress ( int , int )"), self.mRepositories[key]["Relay"].dataReadProgress)
self.connect(self.mRepositories[key]["Relay"], SIGNAL("anythingChanged(QString, int, int)"), self, SIGNAL("anythingChanged (QString, int, int)"))
i = self.mRepositories[key]["QPHttp"].get(path, self.mRepositories[key]["xmlData"])
self.httpId[i] = key
# ----------------------------------------- #
def fetchingInProgress(self):
""" return true if fetching repositories is still in progress """
for key in self.mRepositories:
if self.mRepositories[key]["state"] == 1:
return True
return False
# ----------------------------------------- #
def killConnection(self, key):
""" kill the fetching on demand """
if self.mRepositories[key]["QPHttp"].state():
self.mRepositories[key]["QPHttp"].abort()
# ----------------------------------------- #
def xmlDownloaded(self,nr,state):
""" populate the plugins object with the fetched data """
if not self.httpId.has_key(nr):
return
reposName = self.httpId[nr]
if state: # fetching failed
self.mRepositories[reposName]["state"] = 3
self.mRepositories[reposName]["error"] = self.mRepositories[reposName]["QPHttp"].errorString()
else:
repoData = self.mRepositories[reposName]["xmlData"]
reposXML = QDomDocument()
reposXML.setContent(repoData.data())
pluginNodes = reposXML.elementsByTagName("pyqgis_plugin")
if pluginNodes.size():
for i in range(pluginNodes.size()):
fileName = pluginNodes.item(i).firstChildElement("file_name").text().simplified()
if not fileName:
fileName = QFileInfo(pluginNodes.item(i).firstChildElement("download_url").text().trimmed().split("?")[0]).fileName()
name = fileName.section(".", 0, 0)
name = unicode(name)
experimental = False
if pluginNodes.item(i).firstChildElement("experimental").text().simplified().toUpper() in ["TRUE","YES"]:
experimental = True
plugin = {
"name" : pluginNodes.item(i).toElement().attribute("name"),
"version_avail" : pluginNodes.item(i).toElement().attribute("version"),
"desc_repo" : pluginNodes.item(i).firstChildElement("description").text().simplified(),
"desc_local" : "",
"author" : pluginNodes.item(i).firstChildElement("author_name").text().simplified(),
"homepage" : pluginNodes.item(i).firstChildElement("homepage").text().simplified(),
"url" : pluginNodes.item(i).firstChildElement("download_url").text().simplified(),
"experimental" : experimental,
"filename" : fileName,
"status" : "not installed",
"error" : "",
"error_details" : "",
"version_inst" : "",
"repository" : reposName,
"localdir" : name,
"read-only" : False}
qgisMinimumVersion = pluginNodes.item(i).firstChildElement("qgis_minimum_version").text().simplified()
if not qgisMinimumVersion: qgisMinimumVersion = "1"
qgisMaximumVersion = pluginNodes.item(i).firstChildElement("qgis_maximum_version").text().simplified()
if not qgisMaximumVersion: qgisMaximumVersion = qgisMinimumVersion[0] + ".99"
#if compatible, add the plugin to the list
if not pluginNodes.item(i).firstChildElement("disabled").text().simplified().toUpper() in ["TRUE","YES"]:
if compareVersions(QGIS_VER, qgisMinimumVersion) < 2 and compareVersions(qgisMaximumVersion, QGIS_VER) < 2:
#add the plugin to the cache
plugins.addFromRepository(plugin)
# set state=2, even if the repo is empty
self.mRepositories[reposName]["state"] = 2
self.emit(SIGNAL("repositoryFetched(QString)"), reposName )
# is the checking done?
if not self.fetchingInProgress():
plugins.rebuild()
self.saveCheckingOnStartLastDate()
self.emit(SIGNAL("checkingDone()"))
# --- /class Repositories ---------------------------------------------------------------- #
# --- class Plugins ---------------------------------------------------------------------- #
class Plugins(QObject):
""" A dict-like class for handling plugins data """
# ----------------------------------------- #
def __init__(self):
QObject.__init__(self)
self.mPlugins = {} # the dict of plugins (dicts)
self.repoCache = {} # the dict of lists of plugins (dicts)
self.localCache = {} # the dict of plugins (dicts)
self.obsoletePlugins = [] # the list of outdated 'user' plugins masking newer 'system' ones
# ----------------------------------------- #
def all(self):
""" return all plugins """
return self.mPlugins
# ----------------------------------------- #
def keyByUrl(self, name):
""" return plugin key by given url """
plugins = [i for i in self.mPlugins if self.mPlugins[i]["url"] == name]
if plugins:
return plugins[0]
return None
# ----------------------------------------- #
def addInstalled(self, plugin):
""" add given plugin to the localCache """
key = plugin["localdir"]
self.localCache[key] = plugin
# ----------------------------------------- #
def addFromRepository(self, plugin):
""" add given plugin to the repoCache """
repo = plugin["repository"]
try:
self.repoCache[repo] += [plugin]
except:
self.repoCache[repo] = [plugin]
# ----------------------------------------- #
def removeInstalledPlugin(self, key):
""" remove given plugin from the localCache """
if self.localCache.has_key(key):
del self.localCache[key]
# ----------------------------------------- #
def removeRepository(self, repo):
""" remove whole repository from the repoCache """
if self.repoCache.has_key(repo):
del self.repoCache[repo]
# ----------------------------------------- #
def getInstalledPlugin(self, key, readOnly, testLoad=False):
""" get the metadata of an installed plugin """
if readOnly:
path = QgsApplication.pkgDataPath()
else:
path = QgsApplication.qgisSettingsDirPath()
path = QDir.cleanPath(path) + "/python/plugins/" + key
if not QDir(path).exists():
return
nam = ""
ver = ""
desc = ""
auth = ""
homepage = ""
error = ""
errorDetails = ""
try:
exec("import %s" % key)
exec("reload (%s)" % key)
try:
exec("nam = %s.name()" % key)
except:
pass
try:
exec("ver = %s.version()" % key)
except:
pass
try:
exec("desc = %s.description()" % key)
except:
pass
try:
exec("auth = %s.author()" % key)
except:
# "authorName" was deprecated in QGis > 1.8,
# you must use "author" instead
try:
exec("auth = %s.authorName()" % key)
except:
pass
try:
exec("homepage = %s.homepage()" % key)
except:
pass
try:
exec("qgisMinimumVersion = %s.qgisMinimumVersion()" % key)
if compareVersions(QGIS_VER, qgisMinimumVersion) == 2:
error = "incompatible"
errorDetails = qgisMinimumVersion
except:
pass
if testLoad:
try:
exec ("%s.classFactory(iface)" % key)
except Exception, error:
error = unicode(error.args[0])
except Exception, error:
error = unicode(error.args[0])
if not nam:
nam = key
if error[:16] == "No module named ":
mona = error.replace("No module named ","")
if mona != key:
error = "dependent"
errorDetails = mona
if not error in ["", "dependent", "incompatible"]:
errorDetails = error
error = "broken"
plugin = {
"name" : nam,
"version_inst" : normalizeVersion(ver),
"version_avail" : "",
"desc_local" : desc,
"desc_repo" : "",
"author" : auth,
"homepage" : homepage,
"url" : path,
"experimental" : False,
"filename" : "",
"status" : "orphan",
"error" : error,
"error_details" : errorDetails,
"repository" : "",
"localdir" : key,
"read-only" : readOnly}
return plugin
# ----------------------------------------- #
def getAllInstalled(self, testLoad=False):
""" Build the localCache """
self.localCache = {}
# first, try to add the read-only plugins...
pluginsPath = unicode(QDir.convertSeparators(QDir.cleanPath(QgsApplication.pkgDataPath() + "/python/plugins")))
# temporarily add the system path as the first element to force loading the read-only plugins, even if masked by user ones.
sys.path = [pluginsPath] + sys.path
try:
pluginDir = QDir(pluginsPath)
pluginDir.setFilter(QDir.AllDirs)
for key in pluginDir.entryList():
key = unicode(key)
if not key in [".",".."]:
self.localCache[key] = self.getInstalledPlugin(key, True)
except:
# return QCoreApplication.translate("QgsPluginInstaller","Couldn't open the system plugin directory")
pass # it's not necessary to stop due to this error
# remove the temporarily added path
sys.path.remove(pluginsPath)
# ...then try to add locally installed ones
try:
pluginDir = QDir.convertSeparators(QDir.cleanPath(QgsApplication.qgisSettingsDirPath() + "/python/plugins"))
pluginDir = QDir(pluginDir)
pluginDir.setFilter(QDir.AllDirs)
except:
return QCoreApplication.translate("QgsPluginInstaller","Couldn't open the local plugin directory")
for key in pluginDir.entryList():
key = unicode(key)
if not key in [".",".."]:
plugin = self.getInstalledPlugin(key, False, testLoad)
if key in self.localCache.keys() and compareVersions(self.localCache[key]["version_inst"],plugin["version_inst"]) == 1:
# An obsolete plugin in the "user" location is masking a newer one in the "system" location!
self.obsoletePlugins += [key]
self.localCache[key] = plugin
# ----------------------------------------- #
def rebuild(self):
""" build or rebuild the mPlugins from the caches """
self.mPlugins = {}
for i in self.localCache.keys():
self.mPlugins[i] = self.localCache[i].copy()
settings = QSettings()
(allowed, ok) = settings.value(settingsGroup+"/allowedPluginType", QVariant(2)).toInt()
for i in self.repoCache.values():
for plugin in i:
key = plugin["localdir"]
# check if the plugin is allowed and if there isn't any better one added already.
if (allowed != 1 or plugin["repository"] == officialRepo[0]) and (allowed == 3 or not plugin["experimental"]) \
and not (self.mPlugins.has_key(key) and self.mPlugins[key]["version_avail"] and compareVersions(self.mPlugins[key]["version_avail"], plugin["version_avail"]) < 2):
# The mPlugins dict contains now locally installed plugins.
# Now, add the available one if not present yet or update it if present already.
if not self.mPlugins.has_key(key):
self.mPlugins[key] = plugin # just add a new plugin
else:
self.mPlugins[key]["version_avail"] = plugin["version_avail"]
self.mPlugins[key]["desc_repo"] = plugin["desc_repo"]
self.mPlugins[key]["filename"] = plugin["filename"]
self.mPlugins[key]["repository"] = plugin["repository"]
self.mPlugins[key]["experimental"] = plugin["experimental"]
# use remote name if local one is not available
if self.mPlugins[key]["name"] == key and plugin["name"]:
self.mPlugins[key]["name"] = plugin["name"]
# those metadata has higher priority for their remote instances:
if plugin["author"]:
self.mPlugins[key]["author"] = plugin["author"]
if plugin["homepage"]:
self.mPlugins[key]["homepage"] = plugin["homepage"]
if plugin["url"]:
self.mPlugins[key]["url"] = plugin["url"]
# set status
#
# installed available status
# ---------------------------------------
# none any "not installed" (will be later checked if is "new")
# any none "orphan"
# same same "installed"
# less greater "upgradeable"
# greater less "newer"
if not self.mPlugins[key]["version_avail"]:
self.mPlugins[key]["status"] = "orphan"
elif self.mPlugins[key]["error"] in ["broken","dependent"]:
self.mPlugins[key]["status"] = "installed"
elif not self.mPlugins[key]["version_inst"]:
self.mPlugins[key]["status"] = "not installed"
elif compareVersions(self.mPlugins[key]["version_avail"],self.mPlugins[key]["version_inst"]) == 0:
self.mPlugins[key]["status"] = "installed"
elif compareVersions(self.mPlugins[key]["version_avail"],self.mPlugins[key]["version_inst"]) == 1:
self.mPlugins[key]["status"] = "upgradeable"
else:
self.mPlugins[key]["status"] = "newer"
self.markNews()
# ----------------------------------------- #
def markNews(self):
""" mark all new plugins as new """
settings = QSettings()
seenPlugins = settings.value(seenPluginGroup, QVariant(QStringList(self.mPlugins.keys()))).toStringList()
if len(seenPlugins) > 0:
for i in self.mPlugins.keys():
if seenPlugins.count(QString(i)) == 0 and self.mPlugins[i]["status"] == "not installed":
self.mPlugins[i]["status"] = "new"
# ----------------------------------------- #
def updateSeenPluginsList(self):
""" update the list of all seen plugins """
settings = QSettings()
seenPlugins = settings.value(seenPluginGroup, QVariant(QStringList(self.mPlugins.keys()))).toStringList()
for i in self.mPlugins.keys():
if seenPlugins.count(QString(i)) == 0:
seenPlugins += [i]
settings.setValue(seenPluginGroup, QVariant(QStringList(seenPlugins)))
# ----------------------------------------- #
def isThereAnythingNew(self):
""" return true if an upgradeable or new plugin detected """
for i in self.mPlugins.values():
if i["status"] in ["upgradeable","new"]:
return True
return False
# --- /class Plugins --------------------------------------------------------------------- #
# public members:
history = History()
repositories = Repositories()
plugins = Plugins()

View File

@ -1,949 +0,0 @@
# -*- coding: utf-8 -*-
"""
Copyright (C) 2007-2008 Matthew Perry
Copyright (C) 2008-2010 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 ui_qgsplugininstallerbase import Ui_QgsPluginInstallerDialogBase
from installer_data import *
try:
from qgis.utils import startPlugin, unloadPlugin, loadPlugin # QGIS >= 1.4
from qgis.utils import reloadPlugin, updateAvailablePlugins # QGIS >= 1.5
except Exception:
pass
# --- common functions ------------------------------------------------------------------- #
def removeDir(path):
result = QString()
if not QFile(path).exists():
result = QCoreApplication.translate("QgsPluginInstaller","Nothing to remove! Plugin directory doesn't exist:")+"\n"+path
elif QFile(path).remove(): # if it is only link, just remove it without resolving.
pass
else:
fltr = QDir.Dirs | QDir.Files | QDir.Hidden
iterator = QDirIterator(path, fltr, QDirIterator.Subdirectories)
while iterator.hasNext():
item = iterator.next()
if QFile(item).remove():
pass
fltr = QDir.Dirs | QDir.Hidden
iterator = QDirIterator(path, fltr, QDirIterator.Subdirectories)
while iterator.hasNext():
item = iterator.next()
if QDir().rmpath(item):
pass
if QFile(path).exists():
result = QCoreApplication.translate("QgsPluginInstaller","Failed to remove the directory:")+"\n"+path+"\n"+QCoreApplication.translate("QgsPluginInstaller","Check permissions or remove it manually")
# restore plugin directory if removed by QDir().rmpath()
pluginDir = QFileInfo(QgsApplication.qgisUserDbFilePath()).path() + "/python/plugins"
if not QDir(pluginDir).exists():
QDir().mkpath(pluginDir)
return result
# --- /common functions ------------------------------------------------------------------ #
# --- 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["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["localdir"]).remove()
try:
un = unzip()
un.extract(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["localdir"])) # remove old plugin if exists
un.extract(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 ------------------------------------------------------------- #
# --- class QgsPluginInstallerDialog ------------------------------------------------------------------------- #
class QgsPluginInstallerDialog(QDialog, Ui_QgsPluginInstallerDialogBase):
# ----------------------------------------- #
def __init__(self, parent):
QDialog.__init__(self, parent)
self.setupUi(self)
self.reposGroup = "/Qgis/plugin-repos"
self.connect(self.lineFilter, SIGNAL("textChanged (QString)"), self.filterChanged)
self.connect(self.comboFilter1, SIGNAL("currentIndexChanged (int)"), self.filterChanged)
self.connect(self.comboFilter2, SIGNAL("currentIndexChanged (int)"), self.filterChanged)
# grab clicks on trees
self.connect(self.treePlugins, SIGNAL("itemSelectionChanged()"), self.pluginTreeClicked)
self.connect(self.treeRepositories, SIGNAL("itemSelectionChanged()"), self.repositoryTreeClicked)
# buttons
self.connect(self.buttonUpgradeAll, SIGNAL("clicked()"), self.upgradeAllClicked)
self.connect(self.buttonInstall, SIGNAL("clicked()"), self.installPluginClicked)
self.connect(self.buttonUninstall, SIGNAL("clicked()"), self.uninstallPluginClicked)
self.buttonInstall.setEnabled(False)
self.buttonUninstall.setEnabled(False)
self.buttonHelp.setEnabled(QGIS_14)
self.connect(self.buttonHelp, SIGNAL("clicked()"), self.runHelp)
# repositories handling
self.connect(self.treeRepositories, SIGNAL("doubleClicked(QModelIndex)"), self.editRepository)
#self.connect(self.buttonFetchRepositories, SIGNAL("clicked()"), self.addKnownRepositories)
self.connect(self.buttonAddRep, SIGNAL("clicked()"), self.addRepository)
self.connect(self.buttonEditRep, SIGNAL("clicked()"), self.editRepository)
self.connect(self.buttonDeleteRep, SIGNAL("clicked()"), self.deleteRepository)
self.buttonEditRep.setEnabled(False)
self.buttonDeleteRep.setEnabled(False)
# configuration widgets
self.connect(self.checkUpdates, SIGNAL("toggled (bool)"), self.changeCheckingPolicy)
self.connect(self.comboInterval, SIGNAL("currentIndexChanged (int)"), self.changeCheckingInterval)
self.connect(self.radioPluginType0, SIGNAL("toggled (bool)"), self.changePluginPolicy)
self.connect(self.radioPluginType1, SIGNAL("toggled (bool)"), self.changePluginPolicy)
self.connect(self.radioPluginType2, SIGNAL("toggled (bool)"), self.changePluginPolicy)
# increase default icon size
self.treePlugins.setIconSize(QSize(22, 22))
if repositories.checkingOnStart():
self.checkUpdates.setChecked(Qt.Checked)
else:
self.checkUpdates.setChecked(Qt.Unchecked)
interval = repositories.checkingOnStartInterval()
intervals = [0,1,3,7,14,30] # days
if intervals.count(interval):
index = intervals.index(interval)
else:
index = 1
self.comboInterval.setCurrentIndex(index)
self.populateMostWidgets()
self.pluginDir.setText( self.tr( "The plugins will be installed to %1" ).arg( QFileInfo(QgsApplication.qgisUserDbFilePath()).path() + "python/plugins" ) )
# ----------------------------------------- #
def getAllAvailablePlugins(self):
""" fetch plugins from all repositories """
repositories.load()
plugins.getAllInstalled()
for key in repositories.allEnabled():
repositories.requestFetching(key)
if repositories.fetchingInProgress():
self.fetchDlg = QgsPluginInstallerFetchingDialog(self)
self.fetchDlg.exec_()
del self.fetchDlg
for key in repositories.all():
repositories.killConnection(key)
# display error messages for every unavailable reposioty, unless Shift pressed nor all repositories are unavailable
keepQuiet = QgsApplication.keyboardModifiers() == Qt.KeyboardModifiers(Qt.ShiftModifier)
if repositories.allUnavailable() and repositories.allUnavailable() != repositories.allEnabled():
for key in repositories.allUnavailable():
if not keepQuiet:
QMessageBox.warning(self, self.tr("QGIS Python Plugin Installer"), self.tr("Error reading repository:") + " " + key + "\n" + repositories.all()[key]["error"])
if QgsApplication.keyboardModifiers() == Qt.KeyboardModifiers(Qt.ShiftModifier):
keepQuiet = True
# ----------------------------------------- #
def populateMostWidgets(self):
self.comboFilter1.clear()
self.comboFilter1.addItem(self.tr("all repositories"))
self.treeRepositories.clear()
for key in repositories.all():
a = QTreeWidgetItem(self.treeRepositories)
a.setText(1,key)
a.setText(2,repositories.all()[key]["url"])
if repositories.all()[key]["enabled"] and repositories.all()[key]["valid"]:
if repositories.all()[key]["state"] == 2:
a.setText(0,self.tr("connected"))
a.setIcon(0,QIcon(":/plugins/installer/repoConnected.png"))
a.setToolTip(0,self.tr("This repository is connected"))
self.comboFilter1.addItem(key)
else:
a.setText(0,self.tr("unavailable"))
a.setIcon(0,QIcon(":/plugins/installer/repoUnavailable.png"))
a.setToolTip(0,self.tr("This repository is enabled, but unavailable"))
self.comboFilter1.addItem(key)
else:
a.setText(0,self.tr("disabled"))
a.setIcon(0,QIcon(":/plugins/installer/repoDisabled.png"))
if repositories.all()[key]["valid"]:
a.setToolTip(0,self.tr("This repository is disabled"))
else:
a.setToolTip(0,self.tr("This repository is blocked due to incompatibility with your QGIS version"))
for i in [0,1,2]:
a.setForeground(i,QBrush(QColor(Qt.gray)))
for i in [0,1,2]:
self.treeRepositories.resizeColumnToContents(i)
self.comboFilter1.addItem(self.tr("orphans"))
# fill the status filter comboBox
self.comboFilter2.clear()
self.comboFilter2.addItem(self.tr("any status"))
self.comboFilter2.addItem(self.tr("not installed", "plural"))
self.comboFilter2.addItem(self.tr("installed", "plural"))
if plugins.isThereAnythingNew():
self.comboFilter2.addItem(self.tr("upgradeable and news"))
settings = QSettings()
(i, ok) = settings.value(settingsGroup+"/allowedPluginType", QVariant(1)).toInt()
if i == 1:
self.radioPluginType0.setChecked(Qt.Checked)
elif i == 2:
self.radioPluginType1.setChecked(Qt.Checked)
else:
self.radioPluginType2.setChecked(Qt.Checked)
# ----------------------------------------- #
def filterChanged(self,i):
""" one of the filter widgets has been changed """
self.populatePluginTree()
# ----------------------------------------- #
def filterCheck(self,plugin):
""" the filter for the pluginsTree """
if self.comboFilter1.currentIndex() != 0 and self.comboFilter1.currentText() != self.tr("orphans"):
if self.comboFilter1.currentText() != plugin["repository"]:
return False
elif self.comboFilter1.currentText() == self.tr("orphans"):
if plugin["status"] != "orphan":
return False
if self.comboFilter2.currentIndex() == 1 and not plugin["status"] in ["not installed","new"]:
return False
if self.comboFilter2.currentIndex() == 2 and not plugin["status"] in ["installed","upgradeable","newer","orphan"]:
return False
if self.comboFilter2.currentIndex() == 3 and not plugin["status"] in ["upgradeable","new"]:
return False
if self.lineFilter.text() == "":
return True
else:
for i in ["name","version_inst","version_avail","desc_repo","desc_local","author","status","repository"]:
item = QString(plugin[i])
if item != None:
if item.contains(self.lineFilter.text(), Qt.CaseInsensitive):
return True
return False
# ----------------------------------------- #
def populatePluginTree(self):
""" fill up the pluginTree """
statusTips={"not installed" : self.tr("This plugin is not installed"),
"installed" : self.tr("This plugin is installed"),
"upgradeable" : self.tr("This plugin is installed, but there is an updated version available"),
"orphan" : self.tr("This plugin is installed, but I can't find it in any enabled repository"),
"new" : self.tr("This plugin is not installed and is seen for the first time"),
"newer" : self.tr("This plugin is installed and is newer than its version available in a repository"),
"incompatible" : self.tr("This plugin is incompatible with your QGIS version and probably won't work."),
"dependent" : self.tr("The required Python module is not installed.\nFor more information, please visit its homepage and QGIS wiki."),
"broken" : self.tr("This plugin seems to be broken.\nIt has been installed but can't be loaded.\nHere is the error message:")}
statuses ={"not installed" : self.tr("not installed", "singular"),
"installed" : self.tr("installed", "singular"),
"upgradeable" : self.tr("upgradeable", "singular"),
"orphan" : self.tr("installed", "singular"),
"new" : self.tr("new!", "singular"),
"newer" : self.tr("installed", "singular"),
"incompatible" : self.tr("invalid", "singular"),
"dependent" : self.tr("invalid", "singular"),
"broken" : self.tr("invalid", "singular")}
orderInvalid = ["incompatible","broken","dependent"]
orderValid = ["upgradeable","new","not installed","installed","orphan","newer"]
def addItem(p):
if self.filterCheck(p):
statusTip = statusTips[p["status"]]
if p["read-only"]:
statusTip = statusTip + "\n" + self.tr("Note that it's an uninstallable core plugin")
installedVersion = p["version_inst"]
if not installedVersion:
installedVersion = "?"
availableVersion = p["version_avail"]
if not availableVersion:
availableVersion = "?"
if p["status"] == "upgradeable":
ver = installedVersion + " -> " + availableVersion
elif p["status"] == "newer":
ver = installedVersion + " (" + availableVersion + ")"
elif p["status"] in ["not installed", "new"]:
ver = availableVersion
else:
ver = installedVersion
if p["status"] in ["upgradeable","newer"] or p["error"]:
verTip = self.tr("installed version") + ": " + installedVersion + "\n" + self.tr("available version") + ": " + availableVersion
elif p["status"] in ["not installed", "new"]:
verTip = self.tr("available version") + ": " + availableVersion
elif p["status"] == "installed":
verTip = self.tr("installed version") + ": " + installedVersion + "\n" + self.tr("That's the newest available version")
elif p["status"] == "orphan":
verTip = self.tr("installed version") + ": " + installedVersion + "\n" + self.tr("There is no version available for download")
else:
verTip = ""
if p["error"] == "broken":
desc = self.tr("This plugin is broken")
descTip = statusTips[p["error"]] + "\n" + p["error_details"]
statusTip = descTip
elif p["error"] == "incompatible":
desc = self.tr("This plugin requires a newer version of QGIS") + " (" + self.tr("at least")+ " " + p["error_details"] + ")"
descTip = statusTips[p["error"]]
statusTip = descTip
elif p["error"] == "dependent":
desc = self.tr("This plugin requires a missing module") + " (" + p["error_details"] + ")"
descTip = statusTips[p["error"]]
statusTip = descTip
else:
desc = p["desc_local"]
descTip = p["desc_repo"]
if not desc:
desc = descTip
if not p["repository"]:
repository = self.tr("only locally available")
else:
repository = p["repository"]
a = QgsPluginTreeItem(self.treePlugins)
if p["experimental"]:
a.setIcon(0, QIcon(":/plugins/installer/pluginExperimental.png"))
a.setToolTip(0, self.tr("Experimental plugin. Use at own risk"))
a.setData(0, Qt.UserRole, QVariant(0))
else:
# set empty icon to keep row height same for all plugins
a.setIcon(0, QIcon(":/plugins/installer/pluginStable.png"))
a.setData(0, Qt.UserRole, QVariant(1))
if p["error"]:
a.setText(1,statuses[p["error"]])
else:
a.setText(1,statuses[p["status"]])
a.setToolTip(1,statusTip)
a.setText(2,p["name"])
a.setText(3,ver)
a.setToolTip(3,verTip)
a.setText(4,desc)
# split the tooltip into multiple lines when they are too long
tmp = ""
splitTip = ""
for word in descTip.split(" "):
if len(tmp + word) < 80:
tmp = tmp + " " + word
else:
splitTip += tmp + "\n"
tmp = word
a.setToolTip(4, splitTip+tmp)
a.setText(5,p["author"])
if p["homepage"]:
a.setToolTip(5,p["homepage"])
else:
a.setToolTip(6,"")
a.setText(6,repository)
a.setToolTip(6,p["url"])
# set fonts and colors
for i in [0,1,2,3,4,5,6]:
if p["error"]:
a.setForeground(i,QBrush(QColor(Qt.red)))
if p["status"] in ["new","upgradeable"] or p["error"]:
font = QFont()
font.setWeight(QFont.Bold)
a.setFont(i,font)
# -------- #
if not plugins.all():
return
self.treePlugins.clear()
for i in orderInvalid:
for p in plugins.all().values():
if p["error"] == i:
addItem(p)
n = 0 # displayed plugins count
self.upgradeablePlugins = [] # list of plugins able to update
for i in orderValid:
for p in plugins.all().values():
if p["status"] == i and not p["error"]:
addItem(p)
if p["status"] == "upgradeable": self.upgradeablePlugins += [p["localdir"]]
n +=1
self.setWindowTitle(self.tr("QGIS Python Plugin Installer") + self.tr(" - %d plugins available" % len(plugins.all())))
self.buttonUpgradeAll.setEnabled( len(self.upgradeablePlugins) )
# initially, keep insert order
self.treePlugins.sortItems(100,Qt.AscendingOrder)
# resize the columns
for i in [0,1,2,3,4,5]:
self.treePlugins.resizeColumnToContents(i)
for i in [0,1,2,4,5]:
if self.treePlugins.columnWidth(i) > 260:
self.treePlugins.setColumnWidth(i, 260)
if self.treePlugins.columnWidth(3) > 560:
self.treePlugins.setColumnWidth(3, 560)
# ----------------------------------------- #
def pluginTreeClicked(self):
""" the pluginsTree has been clicked """
buttons={"not installed":(True,False,self.tr("Install plugin")),
"installed":(True,True,self.tr("Reinstall plugin")),
"upgradeable":(True,True,self.tr("Upgrade plugin")),
"orphan":(False,True,self.tr("Install/upgrade plugin")),
"new":(True,False,self.tr("Install plugin")),
"newer":(True,True,self.tr("Downgrade plugin"))}
self.buttonInstall.setEnabled(False)
self.buttonInstall.setText(self.tr("Install/upgrade plugin"))
self.buttonUninstall.setEnabled(False)
if not self.treePlugins.selectedItems():
return
item = self.treePlugins.currentItem()
if not item:
return
key = plugins.keyByUrl(item.toolTip(6))
if not key:
return
plugin = plugins.all()[key]
if not plugin:
return
self.buttonInstall.setEnabled(buttons[plugin["status"]][0])
self.buttonUninstall.setEnabled(buttons[plugin["status"]][1])
self.buttonInstall.setText(buttons[plugin["status"]][2])
if plugin["read-only"]:
self.buttonUninstall.setEnabled(False)
# ----------------------------------------- #
def upgradeAllClicked(self):
for key in self.upgradeablePlugins:
self.installPlugin(key, quiet=True)
# ----------------------------------------- #
def installPluginClicked(self):
if not self.treePlugins.currentItem():
return
key = plugins.keyByUrl(self.treePlugins.currentItem().toolTip(6))
self.installPlugin(key)
# ----------------------------------------- #
def uninstallPluginClicked(self):
if not self.treePlugins.currentItem():
return
key = plugins.keyByUrl(self.treePlugins.currentItem().toolTip(6))
self.uninstallPlugin(key)
# ----------------------------------------- #
def installPlugin(self, key, quiet=False):
""" install currently selected plugin """
infoString = ('','')
plugin = plugins.all()[key]
previousStatus = plugin["status"]
if not plugin:
return
if plugin["status"] == "newer" and not plugin["error"]: # ask for confirmation if user downgrades an usable plugin
if QMessageBox.warning(self, self.tr("QGIS Python Plugin Installer"), self.tr("Are you sure you want to downgrade the plugin to the latest available version? The installed one is newer!"), QMessageBox.Yes, QMessageBox.No) == QMessageBox.No:
return
dlg = QgsPluginInstallerInstallingDialog(self,plugin)
dlg.exec_()
if dlg.result():
infoString = (self.tr("Plugin installation failed"), dlg.result())
elif not QDir(QDir.cleanPath(QgsApplication.qgisSettingsDirPath() + "/python/plugins/" + key)).exists():
infoString = (self.tr("Plugin has disappeared"), self.tr("The plugin seems to have been installed but I don't know where. Probably the plugin package contained a wrong named directory.\nPlease search the list of installed plugins. I'm nearly sure you'll find the plugin there, but I just can't determine which of them it is. It also means that I won't be able to determine if this plugin is installed and inform you about available updates. However the plugin may work. Please contact the plugin author and submit this issue."))
QApplication.setOverrideCursor(Qt.WaitCursor)
plugins.getAllInstalled()
plugins.rebuild()
QApplication.restoreOverrideCursor()
else:
if QGIS_14:
if QGIS_15: # update the list of plugins in plugin handling routines
updateAvailablePlugins()
# try to load the plugin
loadPlugin(plugin["localdir"])
else: # QGIS < 1.4
try:
exec ("sys.path_importer_cache.clear()")
exec ("import %s" % plugin["localdir"])
exec ("reload (%s)" % plugin["localdir"])
except:
pass
plugins.getAllInstalled(testLoad=True)
plugins.rebuild()
plugin = plugins.all()[key]
if not plugin["error"]:
if previousStatus in ["not installed", "new"]:
if QGIS_14: # plugins can be started in python from QGIS >= 1.4
infoString = (self.tr("Plugin installed successfully"), self.tr("Plugin installed successfully"))
settings = QSettings()
settings.setValue("/PythonPlugins/"+plugin["localdir"], QVariant(True))
startPlugin(plugin["localdir"])
else: infoString = (self.tr("Plugin installed successfully"), self.tr("Python plugin installed.\nNow you need to enable it in Plugin Manager."))
else:
if QGIS_15: # plugins can be reloaded on the fly in QGIS >= 1.5
settings = QSettings()
if key != 'plugin_installer' and settings.value("/PythonPlugins/"+key).toBool(): # plugin will be reloaded on the fly only if currently loaded
infoString = (self.tr("Plugin reinstalled successfully"), self.tr("Plugin reinstalled successfully"))
reloadPlugin(key)
else:
infoString = (self.tr("Plugin reinstalled successfully"), self.tr("Python plugin reinstalled.\nYou need to restart QGIS in order to reload it."))
else: infoString = (self.tr("Plugin reinstalled successfully"), self.tr("Python plugin reinstalled.\nYou need to restart QGIS in order to reload it."))
if quiet:
infoString = (None, None)
else:
if plugin["error"] == "incompatible":
message = self.tr("The plugin is designed for a newer version of QGIS. The minimum required version is:")
message += " <b>" + plugin["error_details"] + "</b>"
elif plugin["error"] == "dependent":
message = self.tr("The plugin depends on some components missing on your system. You need to install the following Python module in order to enable it:")
message += "<b> " + plugin["error_details"] + "</b>"
else:
message = self.tr("The plugin is broken. Python said:")
message += "<br><b>" + plugin["error_details"] + "</b>"
dlg = QgsPluginInstallerPluginErrorDialog(self,message)
dlg.exec_()
if dlg.result():
# revert installation
plugins.getAllInstalled()
plugins.rebuild()
pluginDir = QFileInfo(QgsApplication.qgisUserDbFilePath()).path() + "/python/plugins/" + plugin["localdir"]
removeDir(pluginDir)
if QDir(pluginDir).exists():
infoString = (self.tr("Plugin uninstall failed"), result)
try:
exec ("sys.path_importer_cache.clear()")
exec ("import %s" % plugin["localdir"])
exec ("reload (%s)" % plugin["localdir"])
except:
pass
else:
try:
exec ("del sys.modules[%s]" % plugin["localdir"])
except:
pass
plugins.getAllInstalled()
plugins.rebuild()
if plugins.all().has_key(key) and not plugins.all()[key]["status"] in ["not installed", "new"]:
if previousStatus in ["not installed", "new"]:
history.markChange(key,'A')
else:
history.markChange(key,'R')
self.populatePluginTree()
if infoString[0]:
QMessageBox.information(self, infoString[0], infoString[1])
# ----------------------------------------- #
def uninstallPlugin(self,key):
""" uninstall currently selected plugin """
plugin = plugins.all()[key]
if not plugin:
return
warning = self.tr("Are you sure you want to uninstall the following plugin?") + "\n(" + plugin["name"] + ")"
if plugin["status"] == "orphan" and not plugin["error"]:
warning += "\n\n"+self.tr("Warning: this plugin isn't available in any accessible repository!")
if QMessageBox.warning(self, self.tr("QGIS Python Plugin Installer"), warning , QMessageBox.Yes, QMessageBox.No) == QMessageBox.No:
return
# unload the plugin if it's not plugin_installer itself (otherwise, do it after removing its directory):
if key != "plugin_installer":
try:
unloadPlugin(key)
except:
pass
pluginDir = QFileInfo(QgsApplication.qgisUserDbFilePath()).path() + "/python/plugins/" + plugin["localdir"]
result = removeDir(pluginDir)
if result:
QMessageBox.warning(self, self.tr("Plugin uninstall failed"), result)
else:
# if the uninstalled plugin is the installer itself, reload it and quit
if key == "plugin_installer":
if QGIS_15:
try:
QMessageBox.information(self, self.tr("QGIS Python Plugin Installer"), self.tr("Plugin Installer update uninstalled. Plugin Installer will now close and revert to its primary version. You can find it in the Plugins menu and continue operation."))
reloadPlugin(key)
return
except:
pass
else:
QMessageBox.information(self, self.tr("QGIS Python Plugin Installer"), self.tr("Plugin Installer update uninstalled. Please restart QGIS in order to load its primary version."))
# safe remove
try:
unloadPlugin(plugin["localdir"])
except:
pass
try:
exec ("plugins[%s].unload()" % plugin["localdir"])
exec ("del plugins[%s]" % plugin["localdir"])
except:
pass
try:
exec ("del sys.modules[%s]" % plugin["localdir"])
except:
pass
plugins.getAllInstalled()
plugins.rebuild()
self.populatePluginTree()
if QGIS_14: QMessageBox.information(self, self.tr("Plugin uninstalled successfully"), self.tr("Plugin uninstalled successfully"))
else: QMessageBox.information(self, self.tr("Plugin uninstalled successfully"), self.tr("Python plugin uninstalled. Note that you may need to restart QGIS in order to remove it completely."))
history.markChange(key,'D')
# ----------------------------------------- #
def repositoryTreeClicked(self):
""" the repositoryTree has been clicked """
if self.treeRepositories.selectedItems():
self.buttonEditRep.setEnabled(True)
self.buttonDeleteRep.setEnabled(True)
else:
self.buttonEditRep.setEnabled(False)
self.buttonDeleteRep.setEnabled(False)
# ----------------------------------------- #
def changeCheckingPolicy(self,policy):
""" the Checking On Start checkbox has been clicked """
if policy:
repositories.setCheckingOnStart(True)
else:
repositories.setCheckingOnStart(False)
# ----------------------------------------- #
def changeCheckingInterval(self,interval):
""" the Checking on start interval combobox has been clicked """
intervals = [0,1,3,7,14,30]
repositories.setCheckingOnStartInterval(intervals[interval])
# ----------------------------------------- #
def changePluginPolicy(self, state):
""" one of the plugin type radiobuttons has been clicked """
if not state: # radio button released
return
if self.radioPluginType0.isChecked():
i = 1
elif self.radioPluginType1.isChecked():
i = 2
else:
i = 3
settings = QSettings()
settings.setValue(settingsGroup+"/allowedPluginType", QVariant(i))
plugins.rebuild()
self.populatePluginTree()
## depreciated in qgis 1.8 until we use 3rd party repos again
# ----------------------------------------- #
#def addKnownRepositories(self):
#""" update list of known repositories - in the future it will be replaced with an online fetching """
#message = self.tr("You are about to add several plugin repositories that are neither authorized nor supported by the QGIS team. Plugin authors generally make efforts to ensure that their work is useful and safe, however, we can assume no responsibility for them.")
#if QMessageBox.question(self, self.tr("QGIS Python Plugin Installer"), message, QMessageBox.Ok, QMessageBox.Abort) == QMessageBox.Ok:
#repositories.addKnownRepos()
## refresh lists and populate widgets
#QApplication.setOverrideCursor(Qt.WaitCursor)
#self.getAllAvailablePlugins()
#plugins.rebuild()
#self.populateMostWidgets()
#self.populatePluginTree()
#QApplication.restoreOverrideCursor()
# ----------------------------------------- #
def addRepository(self):
""" add repository button has been clicked """
dlg = QgsPluginInstallerRepositoryDialog(self)
dlg.checkBoxEnabled.setCheckState(Qt.Checked)
if not dlg.exec_():
return
for i in repositories.all().values():
if dlg.editURL.text().trimmed() == i["url"]:
QMessageBox.warning(self, self.tr("QGIS Python Plugin Installer"), self.tr("Unable to add another repository with the same URL!"))
return
settings = QSettings()
settings.beginGroup(self.reposGroup)
reposName = dlg.editName.text()
reposURL = dlg.editURL.text().trimmed()
if repositories.all().has_key(reposName):
reposName = reposName + "(2)"
# add to settings
settings.setValue(reposName+"/url", QVariant(reposURL))
settings.setValue(reposName+"/enabled", QVariant(bool(dlg.checkBoxEnabled.checkState())))
# refresh lists and populate widgets
QApplication.setOverrideCursor(Qt.WaitCursor)
plugins.removeRepository(reposName)
self.getAllAvailablePlugins()
plugins.rebuild()
self.populateMostWidgets()
self.populatePluginTree()
QApplication.restoreOverrideCursor()
# ----------------------------------------- #
def editRepository(self):
""" edit repository button has been clicked """
checkState={False:Qt.Unchecked,True:Qt.Checked}
current = self.treeRepositories.currentItem()
if current == None:
return
reposName = current.text(1)
dlg = QgsPluginInstallerRepositoryDialog(self)
dlg.editName.setText(reposName)
dlg.editURL.setText(repositories.all()[reposName]["url"])
dlg.checkBoxEnabled.setCheckState(checkState[repositories.all()[reposName]["enabled"]])
if repositories.all()[reposName]["valid"]:
dlg.checkBoxEnabled.setEnabled(True)
dlg.labelInfo.setText("")
else:
dlg.checkBoxEnabled.setEnabled(False)
dlg.labelInfo.setText(self.tr("This repository is blocked due to incompatibility with your QGIS version"))
dlg.labelInfo.setFrameShape(QFrame.Box)
if not dlg.exec_():
return # nothing to do if cancelled
for i in repositories.all().values():
if dlg.editURL.text().trimmed() == i["url"] and dlg.editURL.text().trimmed() != repositories.all()[reposName]["url"]:
QMessageBox.warning(self, self.tr("QGIS Python Plugin Installer"), self.tr("Unable to add another repository with the same URL!"))
return
# delete old repo from QSettings and create new one
settings = QSettings()
settings.beginGroup(self.reposGroup)
settings.remove(reposName)
newName = dlg.editName.text()
if repositories.all().has_key(newName) and newName != reposName:
newName = newName + "(2)"
settings.setValue(newName+"/url", QVariant(dlg.editURL.text().trimmed()))
settings.setValue(newName+"/enabled", QVariant(bool(dlg.checkBoxEnabled.checkState())))
if dlg.editURL.text().trimmed() == repositories.all()[reposName]["url"] and dlg.checkBoxEnabled.checkState() == checkState[repositories.all()[reposName]["enabled"]]:
repositories.rename(reposName, newName)
self.populateMostWidgets()
return # nothing else to do if only repository name was changed
# refresh lists and populate widgets
QApplication.setOverrideCursor(Qt.WaitCursor)
plugins.removeRepository(reposName)
self.getAllAvailablePlugins()
plugins.rebuild()
self.populateMostWidgets()
self.populatePluginTree()
QApplication.restoreOverrideCursor()
# ----------------------------------------- #
def deleteRepository(self):
""" delete repository button has been clicked """
current = self.treeRepositories.currentItem()
if current == None:
return
warning = self.tr("Are you sure you want to remove the following repository?") + "\n" + current.text(1)
if QMessageBox.warning(self, self.tr("QGIS Python Plugin Installer"), warning , QMessageBox.Yes, QMessageBox.No) == QMessageBox.No:
return
reposName = current.text(1)
# delete from the settings, refresh data and repopulate all the widgets
settings = QSettings()
settings.beginGroup(self.reposGroup)
settings.remove(reposName)
repositories.remove(reposName)
plugins.removeRepository(reposName)
plugins.rebuild()
self.populateMostWidgets()
self.populatePluginTree()
# ----------------------------------------- #
def runHelp(self):
""" open the context help browser """
QgsContextHelp.run("QgsPluginInstallerDialog")
# ----------------------------------------- #
def reject(self):
""" update the list of seen plugins before exit (both 'done' and 'x' buttons emit 'reject' signal) """
plugins.updateSeenPluginsList()
QDialog.reject(self)
# --- /class QgsPluginInstallerDialog ------------------------------------------------------------------------ #
class QgsPluginTreeItem(QTreeWidgetItem):
def __init__(self, parent=None):
QTreeWidgetItem.__init__(self, parent)
def __lt__(self, otherItem):
column = self.treeWidget().sortColumn()
if column == 0:
return self.data(column, Qt.UserRole).toInt()[0] < otherItem.data(column, Qt.UserRole).toInt()[0]
else:
return self.text(column) < otherItem.text(column)

View File

@ -1,192 +0,0 @@
# -*- coding: utf-8 -*-
"""
Copyright (C) 2007-2008 Matthew Perry
Copyright (C) 2008-2010 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. *
* *
***************************************************************************/
"""
from PyQt4.QtCore import *
from PyQt4.QtGui import *
from qgis.core import *
from installer_gui import *
from installer_data import *
import resources_rc
class InstallerPlugin():
# ----------------------------------------- #
def __init__(self, iface):
self.iface = iface
setIface(self.iface) #pass self.iface to installer_data module (needed for plugin loading & testing)
self.mainWindow = self.iface.mainWindow
self.guiDlg = None
# ----------------------------------------- #
def setCurrentTheme(self, theThemeName):
""" Set icons to the current theme """
self.action.setIcon(self.getThemeIcon("plugin_installer.png"))
# ----------------------------------------- #
def getThemeIcon(self, theName):
""" get the icon from the best available theme """
myCurThemePath = QgsApplication.activeThemePath() + "/plugins/" + theName;
myDefThemePath = QgsApplication.defaultThemePath() + "/plugins/" + theName;
myQrcPath = ":/plugins/installer/" + theName;
if QFile.exists(myCurThemePath):
return QIcon(myCurThemePath)
elif QFile.exists(myDefThemePath):
return QIcon(myDefThemePath)
elif QFile.exists(myQrcPath):
return QIcon(myQrcPath)
else:
return QIcon()
# ----------------------------------------- #
def initGui(self):
""" create action that will start plugin window and then add it to menu """
self.action = QAction(self.getThemeIcon("plugin_installer.png"), QCoreApplication.translate("QgsPluginInstaller","Fetch Python Plugins..."), self.mainWindow())
self.action.setWhatsThis(QCoreApplication.translate("QgsPluginInstaller","Install more plugins from remote repositories"))
self.action.setStatusTip(QCoreApplication.translate("QgsPluginInstaller","Install more plugins from remote repositories"))
nextAction = self.iface.actionManagePlugins()
self.iface.pluginMenu().insertAction(nextAction,self.action)
QObject.connect(self.action, SIGNAL("triggered()"), self.run)
QObject.connect(self.iface, SIGNAL("currentThemeChanged ( QString )"), self.setCurrentTheme)
self.statusLabel = None
repositories.load()
plugins.getAllInstalled()
if repositories.checkingOnStart() and repositories.timeForChecking() and repositories.allEnabled():
self.statusLabel = QLabel(QCoreApplication.translate("QgsPluginInstaller","Looking for new plugins..."), self.mainWindow().statusBar())
self.mainWindow().statusBar().insertPermanentWidget(0,self.statusLabel)
QObject.connect(self.statusLabel, SIGNAL("linkActivated (QString)"), self.preRun)
QObject.connect(repositories, SIGNAL("checkingDone()"), self.checkingDone)
for key in repositories.allEnabled():
repositories.requestFetching(key)
else:
for key in repositories.allEnabled():
repositories.setRepositoryData(key,"state",3)
for i in plugins.obsoletePlugins:
if i == "plugin_installer":
# uninstall the installer itself
QMessageBox.warning(self.mainWindow(), QCoreApplication.translate("QgsPluginInstaller","QGIS Plugin Installer update"), QCoreApplication.translate("QgsPluginInstaller","The Plugin Installer has been updated. Please restart QGIS prior to using it"))
removeDir( QFileInfo(QgsApplication.qgisUserDbFilePath()).path() + "/python/plugins/" + plugins.localCache[i]["localdir"] )
return
else:
QMessageBox.warning(self.mainWindow(), QCoreApplication.translate("QgsPluginInstaller","QGIS Plugin Conflict:")+" "+plugins.localCache[i]["name"], "<b>"+ plugins.localCache[i]["name"] + "</b><br/><br/>" + QCoreApplication.translate("QgsPluginInstaller","The Plugin Installer has detected an obsolete plugin which masks a newer version shipped with this QGIS version. This is likely due to files associated with a previous installation of QGIS. Please use the Plugin Installer to remove that older plugin in order to unmask the newer version shipped with this copy of QGIS."))
# ----------------------------------------- #
def checkingDone(self):
""" display the notify label if any updates or news available """
if not self.statusLabel:
return
# look for news in the repositories
plugins.markNews()
status = ""
# first check for news
for key in plugins.all():
if plugins.all()[key]["status"] == "new":
status = QCoreApplication.translate("QgsPluginInstaller","There is a new plugin available")
# then check for updates (and eventually overwrite status)
for key in plugins.all():
if plugins.all()[key]["status"] == "upgradeable":
status = QCoreApplication.translate("QgsPluginInstaller","There is a plugin update available")
# finally set the notify label
if status:
self.statusLabel.setText(u' <a href="#">%s</a> ' % status)
else:
self.mainWindow().statusBar().removeWidget(self.statusLabel)
self.statusLabel = None
# ----------------------------------------- #
def unload(self):
""" remove the menu item and notify label """
# kill pending http requests
for key in repositories.all():
repositories.killConnection(key)
self.iface.pluginMenu().removeAction(self.action)
if self.statusLabel:
self.mainWindow().statusBar().removeWidget(self.statusLabel)
if self.guiDlg:
self.guiDlg.close()
# ----------------------------------------- #
def preRun(self, * params):
""" stupid method to get rid of the string value """
self.run()
# ----------------------------------------- #
def run(self, parent = None):
""" create and show a configuration dialog """
QApplication.setOverrideCursor(Qt.WaitCursor)
if self.statusLabel:
self.mainWindow().statusBar().removeWidget(self.statusLabel)
self.statusLabel = None
if not parent:
parent = self.mainWindow()
for key in repositories.all():
if repositories.all()[key]["state"] == 3: # if state = 3 (error), try to fetch once again
repositories.requestFetching(key)
if repositories.fetchingInProgress():
self.fetchDlg = QgsPluginInstallerFetchingDialog(parent)
self.fetchDlg.exec_()
del self.fetchDlg
for key in repositories.all():
repositories.killConnection(key)
QApplication.restoreOverrideCursor()
# display error messages for every unavailable reposioty, unless Shift pressed nor all repositories are unavailable
keepQuiet = QgsApplication.keyboardModifiers() == Qt.KeyboardModifiers(Qt.ShiftModifier)
if repositories.allUnavailable() and repositories.allUnavailable() != repositories.allEnabled():
for key in repositories.allUnavailable():
if not keepQuiet:
QMessageBox.warning(parent, QCoreApplication.translate("QgsPluginInstaller","QGIS Python Plugin Installer"), QCoreApplication.translate("QgsPluginInstaller","Error reading repository:") + QString(' %s\n%s' % (key,repositories.all()[key]["error"])))
if QgsApplication.keyboardModifiers() == Qt.KeyboardModifiers(Qt.ShiftModifier):
keepQuiet = True
self.guiDlg = QgsPluginInstallerDialog(parent)
self.guiDlg.show()
# ----------------------------------------- #
def newlyInstalledPlugins(self):
""" return the list of newly installed plugins for further loading """
return history.toList("A")
# ----------------------------------------- #
def newlyUninstalledPlugins(self):
""" return the list of newly uninstalled plugins for further unloading """
return history.toList("D")
# ----------------------------------------- #
def newlyReinstalledPlugins(self):
""" return the list of newly reinstalled plugins for further reloading """
return history.toList("R")
# ----------------------------------------- #
def resetNewlyProcessedPlugins(self):
""" clear the dict of newly processed plugins """
history.clear()

View File

@ -1,13 +0,0 @@
[general]
name=Plugin Installer
description=Downloads and installs QGIS python plugins
category=Plugins
version=1.3
qgisMinimumVersion=1.9
author=Borys Jurgiel
email=qgis@borysjurgiel.pl
icon=plugin_installer.png
class_name=InstallerPlugin

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 214 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 785 B

View File

@ -1,694 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<author>Matthew Perry, Borys Jurgiel</author>
<class>QgsPluginInstallerDialogBase</class>
<widget class="QDialog" name="QgsPluginInstallerDialogBase">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>799</width>
<height>409</height>
</rect>
</property>
<property name="windowTitle">
<string>QGIS Python Plugin Installer</string>
</property>
<property name="windowIcon">
<iconset resource="resources.qrc">
<normaloff>:/plugins/installer/qgis-icon.png</normaloff>:/plugins/installer/qgis-icon.png</iconset>
</property>
<property name="whatsThis">
<string>QGIS Python Plugin Installer</string>
</property>
<layout class="QGridLayout">
<item row="1" column="0">
<layout class="QHBoxLayout">
<item>
<widget class="QPushButton" name="buttonHelp">
<property name="text">
<string>Help</string>
</property>
</widget>
</item>
<item>
<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>
<widget class="QLabel" name="pluginDir">
<property name="whatsThis">
<string/>
</property>
<property name="text">
<string></string>
</property>
</widget>
</item>
<item>
<spacer name="horizontalSpacer">
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="buttonClose">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="toolTip">
<string>Close the Installer window</string>
</property>
<property name="whatsThis">
<string>Close the Installer window</string>
</property>
<property name="text">
<string>Close</string>
</property>
</widget>
</item>
</layout>
</item>
<item row="0" column="0">
<widget class="QTabWidget" name="tabWidget">
<property name="toolTip">
<string/>
</property>
<property name="whatsThis">
<string/>
</property>
<property name="currentIndex">
<number>0</number>
</property>
<widget class="QWidget" name="tab">
<attribute name="title">
<string>Plugins</string>
</attribute>
<attribute name="toolTip">
<string>List of available and installed plugins</string>
</attribute>
<layout class="QVBoxLayout">
<item>
<layout class="QHBoxLayout">
<item>
<widget class="QLabel" name="label_5">
<property name="enabled">
<bool>true</bool>
</property>
<property name="text">
<string>Filter:</string>
</property>
<property name="buddy">
<cstring>lineFilter</cstring>
</property>
</widget>
</item>
<item>
<widget class="QgsFilterLineEdit" name="lineFilter">
<property name="enabled">
<bool>true</bool>
</property>
<property name="toolTip">
<string>Display only plugins containing this word in their metadata</string>
</property>
<property name="whatsThis">
<string>Display only plugins containing this word in their metadata</string>
</property>
</widget>
</item>
<item>
<widget class="QComboBox" name="comboFilter1">
<property name="enabled">
<bool>true</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="toolTip">
<string>Display only plugins from given repository</string>
</property>
<property name="statusTip">
<string/>
</property>
<property name="whatsThis">
<string>Display only plugins from given repository</string>
</property>
<item>
<property name="text">
<string>all repositories</string>
</property>
</item>
</widget>
</item>
<item>
<widget class="QComboBox" name="comboFilter2">
<property name="enabled">
<bool>true</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="toolTip">
<string>Display only plugins with matching status</string>
</property>
<property name="whatsThis">
<string>Display only plugins with matching status</string>
</property>
</widget>
</item>
</layout>
</item>
<item>
<widget class="QTreeWidget" name="treePlugins">
<property name="alternatingRowColors">
<bool>true</bool>
</property>
<property name="rootIsDecorated">
<bool>false</bool>
</property>
<property name="itemsExpandable">
<bool>false</bool>
</property>
<property name="sortingEnabled">
<bool>true</bool>
</property>
<property name="allColumnsShowFocus">
<bool>true</bool>
</property>
<column>
<property name="text">
<string>State</string>
</property>
</column>
<column>
<property name="text">
<string>Status</string>
</property>
</column>
<column>
<property name="text">
<string>Name</string>
</property>
</column>
<column>
<property name="text">
<string>Version</string>
</property>
</column>
<column>
<property name="text">
<string>Description</string>
</property>
</column>
<column>
<property name="text">
<string>Author</string>
</property>
</column>
<column>
<property name="text">
<string>Repository</string>
</property>
</column>
</widget>
</item>
<item>
<layout class="QHBoxLayout">
<item>
<widget class="QPushButton" name="buttonUpgradeAll">
<property name="text">
<string>Upgrade all</string>
</property>
</widget>
</item>
<item>
<spacer>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item>
<widget class="QPushButton" name="buttonInstall">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>160</width>
<height>0</height>
</size>
</property>
<property name="toolTip">
<string>Install, reinstall or upgrade the selected plugin</string>
</property>
<property name="whatsThis">
<string>Install, reinstall or upgrade the selected plugin</string>
</property>
<property name="text">
<string>Install/upgrade plugin</string>
</property>
</widget>
</item>
<item>
<widget class="QPushButton" name="buttonUninstall">
<property name="enabled">
<bool>true</bool>
</property>
<property name="toolTip">
<string>Uninstall the selected plugin</string>
</property>
<property name="whatsThis">
<string>Uninstall the selected plugin</string>
</property>
<property name="text">
<string>Uninstall plugin</string>
</property>
</widget>
</item>
</layout>
</item>
</layout>
</widget>
<widget class="QWidget" name="tab_2">
<attribute name="title">
<string>Repositories</string>
</attribute>
<attribute name="toolTip">
<string>List of plugin repositories</string>
</attribute>
<layout class="QGridLayout">
<item row="0" column="0" colspan="7">
<widget class="QTreeWidget" name="treeRepositories">
<property name="rootIsDecorated">
<bool>false</bool>
</property>
<property name="itemsExpandable">
<bool>false</bool>
</property>
<column>
<property name="text">
<string>Status</string>
</property>
</column>
<column>
<property name="text">
<string>Name</string>
</property>
</column>
<column>
<property name="text">
<string>URL</string>
</property>
</column>
</widget>
</item>
<item row="1" column="3">
<spacer>
<property name="orientation">
<enum>Qt::Horizontal</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>40</width>
<height>20</height>
</size>
</property>
</spacer>
</item>
<item row="1" column="4">
<widget class="QPushButton" name="buttonAddRep">
<property name="toolTip">
<string>Add a new plugin repository</string>
</property>
<property name="whatsThis">
<string>Add a new plugin repository</string>
</property>
<property name="text">
<string>Add...</string>
</property>
</widget>
</item>
<item row="1" column="5">
<widget class="QPushButton" name="buttonEditRep">
<property name="toolTip">
<string>Edit the selected repository</string>
</property>
<property name="whatsThis">
<string>Edit the selected repository</string>
</property>
<property name="text">
<string>Edit...</string>
</property>
</widget>
</item>
<item row="1" column="6">
<widget class="QPushButton" name="buttonDeleteRep">
<property name="toolTip">
<string>Remove the selected repository</string>
</property>
<property name="whatsThis">
<string>Remove the selected repository</string>
</property>
<property name="text">
<string>Delete</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QPushButton" name="buttonAddContributedRepository">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>0</width>
<height>16777215</height>
</size>
</property>
<property name="toolTip">
<string>Add the contributed repository to the list</string>
</property>
<property name="whatsThis">
<string>Add the contributed repository to the list</string>
</property>
<property name="text">
<string>Add the contributed repository</string>
</property>
</widget>
</item>
<item row="1" column="2">
<widget class="QPushButton" name="buttonDeleteDepreciatedRepos">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="maximumSize">
<size>
<width>0</width>
<height>16777215</height>
</size>
</property>
<property name="toolTip">
<string>Remove depreciated repositories from the list</string>
</property>
<property name="whatsThis">
<string>Remove depreciated repositories from the list</string>
</property>
<property name="text">
<string>Delete depreciated repositories</string>
</property>
</widget>
</item>
</layout>
</widget>
<widget class="QWidget" name="tab_3">
<attribute name="title">
<string>Options</string>
</attribute>
<attribute name="toolTip">
<string>Configuration of the plugin installer</string>
</attribute>
<layout class="QVBoxLayout" name="verticalLayout">
<item>
<widget class="QGroupBox" name="checkUpdates">
<property name="enabled">
<bool>true</bool>
</property>
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="title">
<string>Check for updates on startup</string>
</property>
<property name="checkable">
<bool>true</bool>
</property>
<property name="checked">
<bool>false</bool>
</property>
<layout class="QGridLayout" name="gridLayout">
<item row="0" column="0">
<widget class="QComboBox" name="comboInterval">
<item>
<property name="text">
<string>every time QGIS starts</string>
</property>
</item>
<item>
<property name="text">
<string>once a day</string>
</property>
</item>
<item>
<property name="text">
<string>every 3 days</string>
</property>
</item>
<item>
<property name="text">
<string>every week</string>
</property>
</item>
<item>
<property name="text">
<string>every 2 weeks</string>
</property>
</item>
<item>
<property name="text">
<string>every month</string>
</property>
</item>
</widget>
</item>
<item row="2" column="0">
<spacer name="verticalSpacer_3">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>10</height>
</size>
</property>
</spacer>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="text">
<string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'DejaVu Sans'; font-size:9pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;Note:&lt;/span&gt; If this function is enabled, QGIS will inform you whenever a new plugin or plugin update is available. Otherwise, fetching repositories will be performed during opening of the Plugin Installer window.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
</item>
<item>
<widget class="QGroupBox" name="groupBox_2">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>1</verstretch>
</sizepolicy>
</property>
<property name="title">
<string>Allowed plugins</string>
</property>
<layout class="QGridLayout" name="gridLayout_2">
<item row="0" column="0">
<widget class="QRadioButton" name="radioPluginType0">
<property name="enabled">
<bool>true</bool>
</property>
<property name="text">
<string>Only show plugins from the official repository</string>
</property>
<property name="checked">
<bool>true</bool>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QRadioButton" name="radioPluginType1">
<property name="enabled">
<bool>true</bool>
</property>
<property name="text">
<string>Show all plugins except those marked as experimental</string>
</property>
<property name="checked">
<bool>false</bool>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QRadioButton" name="radioPluginType2">
<property name="enabled">
<bool>true</bool>
</property>
<property name="text">
<string>Show all plugins, even those marked as experimental</string>
</property>
</widget>
</item>
<item row="3" column="0">
<widget class="QLabel" name="label_2">
<property name="sizePolicy">
<sizepolicy hsizetype="Preferred" vsizetype="MinimumExpanding">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>0</width>
<height>75</height>
</size>
</property>
<property name="text">
<string>&lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.0//EN&quot; &quot;http://www.w3.org/TR/REC-html40/strict.dtd&quot;&gt;
&lt;html&gt;&lt;head&gt;&lt;meta name=&quot;qrichtext&quot; content=&quot;1&quot; /&gt;&lt;style type=&quot;text/css&quot;&gt;
p, li { white-space: pre-wrap; }
&lt;/style&gt;&lt;/head&gt;&lt;body style=&quot; font-family:'DejaVu Sans'; font-size:9pt; font-weight:400; font-style:normal;&quot;&gt;
&lt;p style=&quot; margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;&quot;&gt;&lt;span style=&quot; font-weight:600;&quot;&gt;Note:&lt;/span&gt; Experimental plugins are generally unsuitable for production use. These plugins are in early stages of development, and should be considered 'incomplete' or 'proof of concept' tools. QGIS does not recommend installing these plugins unless you intend to use them for testing purposes.&lt;/p&gt;&lt;/body&gt;&lt;/html&gt;</string>
</property>
<property name="textFormat">
<enum>Qt::RichText</enum>
</property>
<property name="alignment">
<set>Qt::AlignLeading|Qt::AlignLeft|Qt::AlignTop</set>
</property>
<property name="wordWrap">
<bool>true</bool>
</property>
</widget>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
</widget>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>QgsFilterLineEdit</class>
<extends>QLineEdit</extends>
<header>qgis.gui</header>
</customwidget>
</customwidgets>
<tabstops>
<tabstop>tabWidget</tabstop>
<tabstop>lineFilter</tabstop>
<tabstop>comboFilter1</tabstop>
<tabstop>comboFilter2</tabstop>
<tabstop>treePlugins</tabstop>
<tabstop>buttonInstall</tabstop>
<tabstop>buttonUninstall</tabstop>
<tabstop>buttonClose</tabstop>
<tabstop>buttonHelp</tabstop>
<tabstop>treeRepositories</tabstop>
<tabstop>buttonAddContributedRepository</tabstop>
<tabstop>buttonDeleteDepreciatedRepos</tabstop>
<tabstop>buttonAddRep</tabstop>
<tabstop>buttonEditRep</tabstop>
<tabstop>buttonDeleteRep</tabstop>
<tabstop>checkUpdates</tabstop>
<tabstop>comboInterval</tabstop>
<tabstop>radioPluginType0</tabstop>
<tabstop>radioPluginType1</tabstop>
<tabstop>radioPluginType2</tabstop>
</tabstops>
<resources>
<include location="resources.qrc"/>
</resources>
<connections>
<connection>
<sender>buttonClose</sender>
<signal>released()</signal>
<receiver>QgsPluginInstallerDialogBase</receiver>
<slot>close()</slot>
<hints>
<hint type="sourcelabel">
<x>790</x>
<y>372</y>
</hint>
<hint type="destinationlabel">
<x>380</x>
<y>235</y>
</hint>
</hints>
</connection>
</connections>
</ui>

View File

@ -1,200 +0,0 @@
<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>
<property name="windowIcon" >
<iconset resource="resources.qrc" >:/plugins/installer/qgis-icon.png</iconset>
</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>
<resources>
<include location="resources.qrc" />
</resources>
<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>

View File

@ -1,124 +0,0 @@
<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>
<property name="windowIcon" >
<iconset resource="resources.qrc" >:/plugins/installer/qgis-icon.png</iconset>
</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>
<resources>
<include location="resources.qrc" />
</resources>
<connections/>
</ui>

View File

@ -1,120 +0,0 @@
<?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>
<property name="windowIcon">
<iconset resource="resources.qrc">
<normaloff>:/plugins/installer/qgis-icon.png</normaloff>:/plugins/installer/qgis-icon.png</iconset>
</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>
<resources>
<include location="resources.qrc"/>
</resources>
<connections/>
</ui>

View File

@ -1,155 +0,0 @@
<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>
<property name="windowIcon" >
<iconset resource="resources.qrc" >:/plugins/installer/qgis-icon.png</iconset>
</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 &lt;a href="http://lists.osgeo.org/mailman/listinfo/qgis-user">QGIS users group&lt;/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>
<resources>
<include location="resources.qrc" />
</resources>
<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>

View File

@ -1,243 +0,0 @@
<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="windowIcon" >
<iconset resource="resources.qrc" >:/plugins/installer/qgis-icon.png</iconset>
</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>
<resources>
<include location="resources.qrc" />
</resources>
<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>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 917 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 482 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 910 B

View File

@ -1,11 +0,0 @@
<RCC>
<qresource prefix="/plugins/installer">
<file>plugin_installer.png</file>
<file>qgis-icon.png</file>
<file>repoDisabled.png</file>
<file>repoUnavailable.png</file>
<file>repoConnected.png</file>
<file>pluginExperimental.png</file>
<file>pluginStable.png</file>
</qresource>
</RCC>

View File

@ -1,89 +0,0 @@
""" unzip.py
Version: 1.1
By Doug Tolton (http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/252508)
"""
import zipfile
import os
class unzip:
""" unzip.py
Version: 1.1
Extract a zipfile to the directory provided
It first creates the directory structure to house the files
then it extracts the files to it.
import unzip
un = unzip.unzip()
un.extract(r'c:\testfile.zip', 'c:\testoutput')
By Doug Tolton (http://aspn.activestate.com/ASPN/Cookbook/Python/Recipe/252508)
"""
def __init__(self, verbose = True, percent = 10):
self.verbose = verbose
self.percent = percent
def extract(self, file, dir):
if not dir.endswith(':') and not os.path.exists(dir):
os.makedirs(dir)
zf = zipfile.ZipFile(file)
# create directory structure to house files
#print "Creating plugin structure:"
self._createstructure(file, dir)
num_files = len(zf.namelist())
percent = self.percent
divisions = 100 / percent
perc = int(num_files / divisions)
# extract files to directory structure
for i, name in enumerate(zf.namelist()):
if self.verbose == True:
pass
#print "Extracting %s" % name
elif perc > 0 and (i % perc) == 0 and i > 0:
complete = int (i / perc) * percent
#print "%s%% complete" % complete
if not name.endswith('/'):
outfile = open(os.path.join(dir, name), 'wb')
outfile.write(zf.read(name))
outfile.flush()
outfile.close()
def _createstructure(self, file, dir):
self._makedirs(self._listdirs(file), dir)
def _makedirs(self, directories, basedir):
""" Create any directories that don't currently exist """
#print "Processing directories contained in the zip file: %s" % directories
for dir in directories:
curdir = os.path.join(basedir, dir)
# normalize the path
curdir = os.path.normpath(curdir)
#print "Checking to see if we should create %s" % curdir
if not os.path.exists(curdir):
# use makedirs to create parent directories as well
#print "Creating %s" % curdir
os.makedirs(curdir)
def _listdirs(self, file):
""" Grabs all the directories in the zip structure
This is necessary to create the structure before trying
to extract the file to it. """
zf = zipfile.ZipFile(file)
dirs = []
for name in zf.namelist():
(path, filename) = os.path.split(name)
if path not in dirs:
dirs.append(path)
dirs.sort()
return dirs

View File

@ -1,140 +0,0 @@
"""
This is a Python module to compare 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 IT WORKS...
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.
/***************************************************************************
* *
* Copyright (C) 2008-11-24 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. *
* *
***************************************************************************/
"""
# ------------------------------------------------------------------------ #
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

View File

@ -100,7 +100,7 @@ QgisPlugin *QgsPluginRegistry::plugin( QString key )
{
QMap<QString, QgsPluginMetadata>::iterator it = mPlugins.find( key );
if ( it == mPlugins.end() )
return 0;
return NULL;
// note: not used by python plugins
@ -109,7 +109,12 @@ QgisPlugin *QgsPluginRegistry::plugin( QString key )
bool QgsPluginRegistry::isPythonPlugin( QString key )
{
return mPythonUtils && mPythonUtils->isEnabled() && mPythonUtils->isPluginLoaded( key );
if ( mPythonUtils && mPythonUtils->isEnabled() )
{
if ( mPythonUtils->isPluginLoaded( key ) )
return true;
}
return false;
}
void QgsPluginRegistry::addPlugin( QString key, QgsPluginMetadata metadata )
@ -267,20 +272,30 @@ void QgsPluginRegistry::loadPythonPlugin( QString packageName )
void QgsPluginRegistry::loadCppPlugin( QString theFullPathName )
{
// first check to see if its already loaded
QSettings settings;
QString baseName = QFileInfo( theFullPathName ).baseName();
// first check to see if its already loaded
if ( isLoaded( baseName ) )
{
// plugin is loaded
// QMessageBox::warning(this, "Already Loaded", description + " is already loaded");
return;
}
QLibrary myLib( theFullPathName );
if ( !myLib.load() )
QString myError; //we will only show detailed diagnostics if something went wrong
myError += QObject::tr( "Library name is %1\n" ).arg( myLib.fileName() );
bool loaded = myLib.load();
if ( !loaded )
{
QgsMessageLog::logMessage( QObject::tr( "Failed to load %1 (Reason: %2)" ).arg( myLib.fileName() ).arg( myLib.errorString() ), QObject::tr( "Plugins" ) );
return;
}
QString myError( QObject::tr( "Library name is %1\n" ).arg( myLib.fileName() ) );
myError += QObject::tr( "Attempting to resolve the classFactory function\n" );
type_t *pType = ( type_t * ) cast_to_fptr( myLib.resolve( "type" ) );
@ -294,57 +309,59 @@ void QgsPluginRegistry::loadCppPlugin( QString theFullPathName )
{
// UI only -- doesn't use mapcanvas
create_ui *cf = ( create_ui * ) cast_to_fptr( myLib.resolve( "classFactory" ) );
if ( !cf )
if ( cf )
{
QgsMessageLog::logMessage( QObject::tr( "Unable to find the class factory for %1." ).arg( theFullPathName ), QObject::tr( "Plugins" ) );
break;
}
QgisPlugin *pl = cf( mQgisInterface );
if ( pl )
{
pl->initGui();
// add it to the plugin registry
addPlugin( baseName, QgsPluginMetadata( myLib.fileName(), pName(), pl ) );
//add it to the qsettings file [ts]
settings.setValue( "/Plugins/" + baseName, true );
QgsMessageLog::logMessage( QObject::tr( "Loaded %1 (Path: %2)" ).arg( pName() ).arg( myLib.fileName() ), QObject::tr( "Plugins" ), QgsMessageLog::INFO );
QSettings settings;
QgisPlugin *pl = cf( mQgisInterface );
if ( !pl )
{
// something went wrong
QMessageBox::warning( mQgisInterface->mainWindow(), QObject::tr( "Error Loading Plugin" ),
QObject::tr( "There was an error loading a plugin."
"The following diagnostic information may help the QGIS developers resolve the issue:\n%1." )
.arg( myError ) );
//disable it to the qsettings file [ts]
settings.setValue( "/Plugins/" + baseName, false );
break;
}
pl->initGui();
// add it to the plugin registry
addPlugin( baseName, QgsPluginMetadata( myLib.fileName(), pName(), pl ) );
//add it to the qsettings file [ts]
settings.setValue( "/Plugins/" + baseName, true );
QgsMessageLog::logMessage( QObject::tr( "Loaded %1 (Path: %2)" ).arg( pName() ).arg( myLib.fileName() ), QObject::tr( "Plugins" ), QgsMessageLog::INFO );
QObject *o = dynamic_cast<QObject *>( pl );
if ( !o )
break;
QgsDebugMsg( QString( "plugin object name: %1" ).arg( o->objectName() ) );
if ( o->objectName().isEmpty() )
{
QObject *o = dynamic_cast<QObject *>( pl );
if ( o )
{
QgsDebugMsg( QString( "plugin object name: %1" ).arg( o->objectName() ) );
if ( o->objectName().isEmpty() )
{
#ifndef WIN32
baseName = baseName.mid( 3 );
baseName = baseName.mid( 3 );
#endif
QgsDebugMsg( QString( "object name to %1" ).arg( baseName ) );
o->setObjectName( QString( "qgis_plugin_%1" ).arg( baseName ) );
QgsDebugMsg( QString( "plugin object name now: %1" ).arg( o->objectName() ) );
}
QgsDebugMsg( QString( "object name to %1" ).arg( baseName ) );
o->setObjectName( QString( "qgis_plugin_%1" ).arg( baseName ) );
QgsDebugMsg( QString( "plugin object name now: %1" ).arg( o->objectName() ) );
}
if ( !o->parent() )
{
QgsDebugMsg( QString( "setting plugin parent" ) );
o->setParent( QgisApp::instance() );
if ( !o->parent() )
{
QgsDebugMsg( QString( "setting plugin parent" ) );
o->setParent( QgisApp::instance() );
}
else
{
QgsDebugMsg( QString( "plugin parent already set" ) );
}
}
}
else
{
// something went wrong
QMessageBox::warning( mQgisInterface->mainWindow(), QObject::tr( "Error Loading Plugin" ),
QObject::tr( "There was an error loading a plugin."
"The following diagnostic information may help the QGIS developers resolve the issue:\n%1." )
.arg( myError ) );
//disable it to the qsettings file [ts]
settings.setValue( "/Plugins/" + baseName, false );
}
}
else
{
QgsDebugMsg( QString( "plugin parent already set" ) );
QgsMessageLog::logMessage( QObject::tr( "Unable to find the class factory for %1." ).arg( theFullPathName ), QObject::tr( "Plugins" ) );
}
}
break;
default:
@ -434,65 +451,63 @@ void QgsPluginRegistry::restoreSessionPlugins( QString thePluginDirString )
}
}
if ( !mPythonUtils || !mPythonUtils->isEnabled() )
return;
// check for python plugins system-wide
QStringList pluginList = mPythonUtils->pluginList();
QgsDebugMsg( "Loading python plugins" );
QStringList corePlugins = QStringList();
corePlugins << "plugin_installer";
corePlugins << "fTools";
corePlugins << "GdalTools";
corePlugins << "db_manager";
// make the required core plugins enabled by default:
for ( int i = 0; i < corePlugins.size(); i++ )
if ( mPythonUtils && mPythonUtils->isEnabled() )
{
if ( !mySettings.contains( "/PythonPlugins/" + corePlugins[i] ) )
// check for python plugins system-wide
QStringList pluginList = mPythonUtils->pluginList();
QgsDebugMsg( "Loading python plugins" );
QStringList corePlugins = QStringList();
corePlugins << "fTools";
corePlugins << "GdalTools";
corePlugins << "db_manager";
// make the required core plugins enabled by default:
for ( int i = 0; i < corePlugins.size(); i++ )
{
mySettings.setValue( "/PythonPlugins/" + corePlugins[i], true );
if ( !mySettings.contains( "/PythonPlugins/" + corePlugins[i] ) )
{
mySettings.setValue( "/PythonPlugins/" + corePlugins[i], true );
}
}
}
for ( int i = 0; i < pluginList.size(); i++ )
{
QString packageName = pluginList[i];
for ( int i = 0; i < pluginList.size(); i++ )
{
QString packageName = pluginList[i];
// TODO: apply better solution for #5879
// start - temporary fix for issue #5879
// TODO: apply better solution for #5879
// start - temporary fix for issue #5879
if ( QgsApplication::isRunningFromBuildDir() )
{
if ( corePlugins.contains( packageName ) )
{
QgsApplication::setPkgDataPath( QString( "" ) );
}
else
{
QgsApplication::setPkgDataPath( QgsApplication::buildSourcePath() );
}
}
// end - temporary fix for issue #5879, more below
if ( checkPythonPlugin( packageName ) )
{
// check if the plugin was active on last session
if ( mySettings.value( "/PythonPlugins/" + packageName ).toBool() )
{
loadPythonPlugin( packageName );
}
}
}
// start - temporary fix for issue #5879, more above
if ( QgsApplication::isRunningFromBuildDir() )
{
if ( corePlugins.contains( packageName ) )
{
QgsApplication::setPkgDataPath( QString( "" ) );
}
else
{
QgsApplication::setPkgDataPath( QgsApplication::buildSourcePath() );
}
}
// end - temporary fix for issue #5879, more below
if ( checkPythonPlugin( packageName ) )
{
// check if the plugin was active on last session
if ( mySettings.value( "/PythonPlugins/" + packageName ).toBool() )
{
loadPythonPlugin( packageName );
}
QgsApplication::setPkgDataPath( QgsApplication::buildSourcePath() );
}
// end - temporary fix for issue #5879
}
// start - temporary fix for issue #5879, more above
if ( QgsApplication::isRunningFromBuildDir() )
{
QgsApplication::setPkgDataPath( QgsApplication::buildSourcePath() );
}
// end - temporary fix for issue #5879
QgsDebugMsg( "Plugin loading completed" );
}
@ -500,7 +515,8 @@ void QgsPluginRegistry::restoreSessionPlugins( QString thePluginDirString )
bool QgsPluginRegistry::checkCppPlugin( QString pluginFullPath )
{
QLibrary myLib( pluginFullPath );
if ( !myLib.load() )
bool loaded = myLib.load();
if ( ! loaded )
{
QgsMessageLog::logMessage( QObject::tr( "Failed to load %1 (Reason: %2)" ).arg( myLib.fileName() ).arg( myLib.errorString() ), QObject::tr( "Plugins" ) );
return false;
@ -511,7 +527,7 @@ bool QgsPluginRegistry::checkCppPlugin( QString pluginFullPath )
category_t * myCategory = ( category_t * ) cast_to_fptr( myLib.resolve( "category" ) );
version_t * myVersion = ( version_t * ) cast_to_fptr( myLib.resolve( "version" ) );
if ( myName && myDescription && myVersion && myCategory )
if ( myName && myDescription && myVersion && myCategory )
return true;
QgsDebugMsg( "Failed to get name, description, category or type for " + myLib.fileName() );

View File

@ -34,7 +34,7 @@ class QString;
*
* plugin key is:
* - C++ plugins: base name of plugin library, e.g. libgrassplugin
* - Python plugins: module name (directory) of plugin, e.g. plugin_installer
* - Python plugins: module name (directory) of plugin, e.g. db_manager
*/
class QgsPluginRegistry
{