[Plugin Manager] remove the old plugin_installer plugin
Before Width: | Height: | Size: 4.8 KiB |
@ -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)
|
||||
|
@ -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})
|
@ -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.
|
@ -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)
|
@ -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()
|
@ -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)
|
@ -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()
|
@ -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
|
Before Width: | Height: | Size: 9.5 KiB |
Before Width: | Height: | Size: 214 B |
Before Width: | Height: | Size: 4.8 KiB |
Before Width: | Height: | Size: 785 B |
@ -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><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
|
||||
<html><head><meta name="qrichtext" content="1" /><style type="text/css">
|
||||
p, li { white-space: pre-wrap; }
|
||||
</style></head><body style=" font-family:'DejaVu Sans'; font-size:9pt; font-weight:400; font-style:normal;">
|
||||
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">Note:</span> 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.</p></body></html></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><!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0//EN" "http://www.w3.org/TR/REC-html40/strict.dtd">
|
||||
<html><head><meta name="qrichtext" content="1" /><style type="text/css">
|
||||
p, li { white-space: pre-wrap; }
|
||||
</style></head><body style=" font-family:'DejaVu Sans'; font-size:9pt; font-weight:400; font-style:normal;">
|
||||
<p style=" margin-top:0px; margin-bottom:0px; margin-left:0px; margin-right:0px; -qt-block-indent:0; text-indent:0px;"><span style=" font-weight:600;">Note:</span> 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.</p></body></html></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>
|
@ -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>
|
@ -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>
|
@ -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>
|
@ -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 <a href="http://lists.osgeo.org/mailman/listinfo/qgis-user">QGIS users group</a> and try to solve the problem. If not, you can just uninstall it. Here is the error message below:</string>
|
||||
</property>
|
||||
<property name="wordWrap" >
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="openExternalLinks" >
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0" >
|
||||
<widget class="QTextBrowser" name="textBrowser" >
|
||||
<property name="minimumSize" >
|
||||
<size>
|
||||
<width>0</width>
|
||||
<height>0</height>
|
||||
</size>
|
||||
</property>
|
||||
<property name="focusPolicy" >
|
||||
<enum>Qt::NoFocus</enum>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="0" >
|
||||
<spacer>
|
||||
<property name="orientation" >
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeType" >
|
||||
<enum>QSizePolicy::Fixed</enum>
|
||||
</property>
|
||||
<property name="sizeHint" >
|
||||
<size>
|
||||
<width>503</width>
|
||||
<height>10</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="4" column="0" >
|
||||
<widget class="QLabel" name="label1" >
|
||||
<property name="frameShape" >
|
||||
<enum>QFrame::NoFrame</enum>
|
||||
</property>
|
||||
<property name="frameShadow" >
|
||||
<enum>QFrame::Plain</enum>
|
||||
</property>
|
||||
<property name="text" >
|
||||
<string>Do you want to uninstall this plugin now? If you're unsure, probably you would like to do this.</string>
|
||||
</property>
|
||||
<property name="wordWrap" >
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="0" >
|
||||
<widget class="QDialogButtonBox" name="buttonBox" >
|
||||
<property name="standardButtons" >
|
||||
<set>QDialogButtonBox::No|QDialogButtonBox::NoButton|QDialogButtonBox::Yes</set>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="0" column="0" >
|
||||
<spacer>
|
||||
<property name="orientation" >
|
||||
<enum>Qt::Vertical</enum>
|
||||
</property>
|
||||
<property name="sizeType" >
|
||||
<enum>QSizePolicy::Fixed</enum>
|
||||
</property>
|
||||
<property name="sizeHint" >
|
||||
<size>
|
||||
<width>10</width>
|
||||
<height>10</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<tabstops>
|
||||
<tabstop>textBrowser</tabstop>
|
||||
</tabstops>
|
||||
<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>
|
@ -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>
|
Before Width: | Height: | Size: 917 B |
Before Width: | Height: | Size: 482 B |
Before Width: | Height: | Size: 910 B |
@ -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>
|
@ -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
|
@ -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
|
@ -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() );
|
||||
|
@ -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
|
||||
{
|
||||
|