mirror of
https://github.com/qgis/QGIS.git
synced 2025-04-15 00:04:00 -04:00
Merged in Borys's new plugin installer
git-svn-id: http://svn.osgeo.org/qgis/trunk@9293 c8812cc2-4d05-0410-92ff-de0c093fc19c
This commit is contained in:
parent
d049698222
commit
47a02a106f
@ -10,5 +10,22 @@ qgis_plugins.py
|
||||
resources.py
|
||||
repository_ui.py
|
||||
repository_dialog.py
|
||||
qgis-icon.png
|
||||
installingbase.ui
|
||||
fetchingbase.py
|
||||
guibase.py
|
||||
repositorybase.py
|
||||
plugin_installer.png
|
||||
unzip.py
|
||||
installer_gui.py
|
||||
installingbase.py
|
||||
pluginerrorbase.ui
|
||||
installer_data.py
|
||||
repoConnected.png
|
||||
guibase.ui
|
||||
pluginerrorbase.py
|
||||
repositorybase.ui
|
||||
resources_rc.py
|
||||
repoDisabled.png
|
||||
)
|
||||
INSTALL(FILES ${INSTALLER_FILES} DESTINATION ${QGIS_DATA_DIR}/python/plugins/plugin_installer)
|
||||
|
@ -1,4 +1,6 @@
|
||||
Copyright (c) 2007 Matthew T. Perry
|
||||
Copyright (c) 2008 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
|
||||
|
@ -1,5 +1,6 @@
|
||||
"""
|
||||
Copyright (C) 2008 Matthew Perry
|
||||
Copyright (C) 2008 Borys Jurgiel
|
||||
/***************************************************************************
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
@ -10,15 +11,17 @@ Copyright (C) 2008 Matthew Perry
|
||||
***************************************************************************/
|
||||
"""
|
||||
def name():
|
||||
return "Plugin installer"
|
||||
return "Plugin Installer"
|
||||
|
||||
def description():
|
||||
return "Downloads and installs QGIS python plugins"
|
||||
|
||||
def author_name():
|
||||
return "perrygeo, borysiasty"
|
||||
|
||||
def version():
|
||||
return "Version 0.02"
|
||||
return "Version 0.05.6"
|
||||
|
||||
def classFactory(iface):
|
||||
# load TestPlugin class from file testplugin.py
|
||||
from installer_plugin import InstallerPlugin
|
||||
return InstallerPlugin(iface)
|
||||
return InstallerPlugin(iface)
|
85
python/plugins/plugin_installer/fetchingbase.py
Normal file
85
python/plugins/plugin_installer/fetchingbase.py
Normal file
@ -0,0 +1,85 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Form implementation generated from reading ui file 'fetchingbase.ui'
|
||||
#
|
||||
# Created: Sun Sep 7 16:22:19 2008
|
||||
# by: PyQt4 UI code generator 4.3
|
||||
#
|
||||
# WARNING! All changes made in this file will be lost!
|
||||
|
||||
from PyQt4 import QtCore, QtGui
|
||||
|
||||
class Ui_QgsPluginInstallerFetchingDialog(object):
|
||||
def setupUi(self, QgsPluginInstallerFetchingDialog):
|
||||
QgsPluginInstallerFetchingDialog.setObjectName("QgsPluginInstallerFetchingDialog")
|
||||
QgsPluginInstallerFetchingDialog.resize(QtCore.QSize(QtCore.QRect(0,0,521,332).size()).expandedTo(QgsPluginInstallerFetchingDialog.minimumSizeHint()))
|
||||
QgsPluginInstallerFetchingDialog.setWindowIcon(QtGui.QIcon(":/plugins/installer/qgis-icon.png"))
|
||||
|
||||
self.gridlayout = QtGui.QGridLayout(QgsPluginInstallerFetchingDialog)
|
||||
self.gridlayout.setObjectName("gridlayout")
|
||||
|
||||
spacerItem = QtGui.QSpacerItem(249,10,QtGui.QSizePolicy.Minimum,QtGui.QSizePolicy.Fixed)
|
||||
self.gridlayout.addItem(spacerItem,1,0,1,1)
|
||||
|
||||
self.label1 = QtGui.QLabel(QgsPluginInstallerFetchingDialog)
|
||||
self.label1.setObjectName("label1")
|
||||
self.gridlayout.addWidget(self.label1,2,0,1,1)
|
||||
|
||||
self.progressBar = QtGui.QProgressBar(QgsPluginInstallerFetchingDialog)
|
||||
self.progressBar.setProperty("value",QtCore.QVariant(24))
|
||||
self.progressBar.setAlignment(QtCore.Qt.AlignHCenter)
|
||||
self.progressBar.setTextDirection(QtGui.QProgressBar.TopToBottom)
|
||||
self.progressBar.setObjectName("progressBar")
|
||||
self.gridlayout.addWidget(self.progressBar,3,0,1,1)
|
||||
|
||||
spacerItem1 = QtGui.QSpacerItem(248,10,QtGui.QSizePolicy.Minimum,QtGui.QSizePolicy.Fixed)
|
||||
self.gridlayout.addItem(spacerItem1,4,0,1,1)
|
||||
|
||||
self.hboxlayout = QtGui.QHBoxLayout()
|
||||
self.hboxlayout.setObjectName("hboxlayout")
|
||||
|
||||
spacerItem2 = QtGui.QSpacerItem(140,27,QtGui.QSizePolicy.MinimumExpanding,QtGui.QSizePolicy.Minimum)
|
||||
self.hboxlayout.addItem(spacerItem2)
|
||||
|
||||
self.buttonSkip = QtGui.QPushButton(QgsPluginInstallerFetchingDialog)
|
||||
|
||||
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Fixed,QtGui.QSizePolicy.Fixed)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.buttonSkip.sizePolicy().hasHeightForWidth())
|
||||
self.buttonSkip.setSizePolicy(sizePolicy)
|
||||
self.buttonSkip.setMinimumSize(QtCore.QSize(180,0))
|
||||
self.buttonSkip.setFocusPolicy(QtCore.Qt.NoFocus)
|
||||
self.buttonSkip.setAutoDefault(False)
|
||||
self.buttonSkip.setDefault(False)
|
||||
self.buttonSkip.setFlat(False)
|
||||
self.buttonSkip.setObjectName("buttonSkip")
|
||||
self.hboxlayout.addWidget(self.buttonSkip)
|
||||
|
||||
spacerItem3 = QtGui.QSpacerItem(140,27,QtGui.QSizePolicy.MinimumExpanding,QtGui.QSizePolicy.Minimum)
|
||||
self.hboxlayout.addItem(spacerItem3)
|
||||
self.gridlayout.addLayout(self.hboxlayout,5,0,1,1)
|
||||
|
||||
self.treeWidget = QtGui.QTreeWidget(QgsPluginInstallerFetchingDialog)
|
||||
self.treeWidget.setEnabled(True)
|
||||
self.treeWidget.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAsNeeded)
|
||||
self.treeWidget.setProperty("showDropIndicator",QtCore.QVariant(False))
|
||||
self.treeWidget.setSelectionMode(QtGui.QAbstractItemView.NoSelection)
|
||||
self.treeWidget.setHorizontalScrollMode(QtGui.QAbstractItemView.ScrollPerItem)
|
||||
self.treeWidget.setRootIsDecorated(False)
|
||||
self.treeWidget.setItemsExpandable(False)
|
||||
self.treeWidget.setObjectName("treeWidget")
|
||||
self.gridlayout.addWidget(self.treeWidget,0,0,1,1)
|
||||
|
||||
self.retranslateUi(QgsPluginInstallerFetchingDialog)
|
||||
QtCore.QObject.connect(self.buttonSkip,QtCore.SIGNAL("clicked()"),QgsPluginInstallerFetchingDialog.reject)
|
||||
QtCore.QMetaObject.connectSlotsByName(QgsPluginInstallerFetchingDialog)
|
||||
|
||||
def retranslateUi(self, QgsPluginInstallerFetchingDialog):
|
||||
QgsPluginInstallerFetchingDialog.setWindowTitle(QtGui.QApplication.translate("QgsPluginInstallerFetchingDialog", "Fetching repositories", None, QtGui.QApplication.UnicodeUTF8))
|
||||
self.label1.setText(QtGui.QApplication.translate("QgsPluginInstallerFetchingDialog", "Overall progress:", None, QtGui.QApplication.UnicodeUTF8))
|
||||
self.buttonSkip.setText(QtGui.QApplication.translate("QgsPluginInstallerFetchingDialog", "Abort fetching", None, QtGui.QApplication.UnicodeUTF8))
|
||||
self.treeWidget.headerItem().setText(0,QtGui.QApplication.translate("QgsPluginInstallerFetchingDialog", "Repository", None, QtGui.QApplication.UnicodeUTF8))
|
||||
self.treeWidget.headerItem().setText(1,QtGui.QApplication.translate("QgsPluginInstallerFetchingDialog", "State", None, QtGui.QApplication.UnicodeUTF8))
|
||||
|
||||
import resources_rc
|
226
python/plugins/plugin_installer/guibase.py
Normal file
226
python/plugins/plugin_installer/guibase.py
Normal file
@ -0,0 +1,226 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Form implementation generated from reading ui file 'guibase.ui'
|
||||
#
|
||||
# Created: Sun Sep 7 21:28:01 2008
|
||||
# by: PyQt4 UI code generator 4.3
|
||||
#
|
||||
# WARNING! All changes made in this file will be lost!
|
||||
|
||||
from PyQt4 import QtCore, QtGui
|
||||
|
||||
class Ui_QgsPluginInstallerDialog(object):
|
||||
def setupUi(self, QgsPluginInstallerDialog):
|
||||
QgsPluginInstallerDialog.setObjectName("QgsPluginInstallerDialog")
|
||||
QgsPluginInstallerDialog.resize(QtCore.QSize(QtCore.QRect(0,0,769,395).size()).expandedTo(QgsPluginInstallerDialog.minimumSizeHint()))
|
||||
QgsPluginInstallerDialog.setWindowIcon(QtGui.QIcon(":/plugins/installer/qgis-icon.png"))
|
||||
|
||||
self.gridlayout = QtGui.QGridLayout(QgsPluginInstallerDialog)
|
||||
self.gridlayout.setObjectName("gridlayout")
|
||||
|
||||
self.tabWidget = QtGui.QTabWidget(QgsPluginInstallerDialog)
|
||||
self.tabWidget.setObjectName("tabWidget")
|
||||
|
||||
self.tab = QtGui.QWidget()
|
||||
self.tab.setObjectName("tab")
|
||||
|
||||
self.vboxlayout = QtGui.QVBoxLayout(self.tab)
|
||||
self.vboxlayout.setObjectName("vboxlayout")
|
||||
|
||||
self.hboxlayout = QtGui.QHBoxLayout()
|
||||
self.hboxlayout.setObjectName("hboxlayout")
|
||||
|
||||
self.label_5 = QtGui.QLabel(self.tab)
|
||||
self.label_5.setEnabled(True)
|
||||
self.label_5.setObjectName("label_5")
|
||||
self.hboxlayout.addWidget(self.label_5)
|
||||
|
||||
self.lineFilter = QtGui.QLineEdit(self.tab)
|
||||
self.lineFilter.setEnabled(True)
|
||||
self.lineFilter.setObjectName("lineFilter")
|
||||
self.hboxlayout.addWidget(self.lineFilter)
|
||||
|
||||
self.comboFilter1 = QtGui.QComboBox(self.tab)
|
||||
self.comboFilter1.setEnabled(True)
|
||||
|
||||
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding,QtGui.QSizePolicy.Fixed)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.comboFilter1.sizePolicy().hasHeightForWidth())
|
||||
self.comboFilter1.setSizePolicy(sizePolicy)
|
||||
self.comboFilter1.setObjectName("comboFilter1")
|
||||
self.hboxlayout.addWidget(self.comboFilter1)
|
||||
|
||||
self.comboFilter2 = QtGui.QComboBox(self.tab)
|
||||
self.comboFilter2.setEnabled(True)
|
||||
|
||||
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Preferred,QtGui.QSizePolicy.Fixed)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.comboFilter2.sizePolicy().hasHeightForWidth())
|
||||
self.comboFilter2.setSizePolicy(sizePolicy)
|
||||
self.comboFilter2.setObjectName("comboFilter2")
|
||||
self.hboxlayout.addWidget(self.comboFilter2)
|
||||
self.vboxlayout.addLayout(self.hboxlayout)
|
||||
|
||||
self.treePlugins = QtGui.QTreeWidget(self.tab)
|
||||
self.treePlugins.setAlternatingRowColors(True)
|
||||
self.treePlugins.setRootIsDecorated(False)
|
||||
self.treePlugins.setItemsExpandable(False)
|
||||
self.treePlugins.setSortingEnabled(True)
|
||||
self.treePlugins.setAllColumnsShowFocus(True)
|
||||
self.treePlugins.setObjectName("treePlugins")
|
||||
self.vboxlayout.addWidget(self.treePlugins)
|
||||
|
||||
self.hboxlayout1 = QtGui.QHBoxLayout()
|
||||
self.hboxlayout1.setObjectName("hboxlayout1")
|
||||
|
||||
spacerItem = QtGui.QSpacerItem(40,20,QtGui.QSizePolicy.Expanding,QtGui.QSizePolicy.Minimum)
|
||||
self.hboxlayout1.addItem(spacerItem)
|
||||
|
||||
self.buttonInstall = QtGui.QPushButton(self.tab)
|
||||
|
||||
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Fixed,QtGui.QSizePolicy.Fixed)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.buttonInstall.sizePolicy().hasHeightForWidth())
|
||||
self.buttonInstall.setSizePolicy(sizePolicy)
|
||||
self.buttonInstall.setMinimumSize(QtCore.QSize(160,0))
|
||||
self.buttonInstall.setObjectName("buttonInstall")
|
||||
self.hboxlayout1.addWidget(self.buttonInstall)
|
||||
|
||||
self.buttonUninstall = QtGui.QPushButton(self.tab)
|
||||
self.buttonUninstall.setEnabled(True)
|
||||
self.buttonUninstall.setObjectName("buttonUninstall")
|
||||
self.hboxlayout1.addWidget(self.buttonUninstall)
|
||||
self.vboxlayout.addLayout(self.hboxlayout1)
|
||||
self.tabWidget.addTab(self.tab,"")
|
||||
|
||||
self.tab_2 = QtGui.QWidget()
|
||||
self.tab_2.setObjectName("tab_2")
|
||||
|
||||
self.gridlayout1 = QtGui.QGridLayout(self.tab_2)
|
||||
self.gridlayout1.setObjectName("gridlayout1")
|
||||
|
||||
self.treeRepositories = QtGui.QTreeWidget(self.tab_2)
|
||||
self.treeRepositories.setRootIsDecorated(False)
|
||||
self.treeRepositories.setItemsExpandable(False)
|
||||
self.treeRepositories.setObjectName("treeRepositories")
|
||||
self.gridlayout1.addWidget(self.treeRepositories,0,0,1,7)
|
||||
|
||||
self.checkUpdates = QtGui.QCheckBox(self.tab_2)
|
||||
self.checkUpdates.setObjectName("checkUpdates")
|
||||
self.gridlayout1.addWidget(self.checkUpdates,1,0,1,1)
|
||||
|
||||
spacerItem1 = QtGui.QSpacerItem(30,20,QtGui.QSizePolicy.Preferred,QtGui.QSizePolicy.Minimum)
|
||||
self.gridlayout1.addItem(spacerItem1,1,1,1,1)
|
||||
|
||||
self.buttonFetchRepositories = QtGui.QPushButton(self.tab_2)
|
||||
self.buttonFetchRepositories.setEnabled(True)
|
||||
self.buttonFetchRepositories.setObjectName("buttonFetchRepositories")
|
||||
self.gridlayout1.addWidget(self.buttonFetchRepositories,1,2,1,1)
|
||||
|
||||
spacerItem2 = QtGui.QSpacerItem(40,20,QtGui.QSizePolicy.Expanding,QtGui.QSizePolicy.Minimum)
|
||||
self.gridlayout1.addItem(spacerItem2,1,3,1,1)
|
||||
|
||||
self.buttonAddRep = QtGui.QPushButton(self.tab_2)
|
||||
self.buttonAddRep.setObjectName("buttonAddRep")
|
||||
self.gridlayout1.addWidget(self.buttonAddRep,1,4,1,1)
|
||||
|
||||
self.buttonEditRep = QtGui.QPushButton(self.tab_2)
|
||||
self.buttonEditRep.setObjectName("buttonEditRep")
|
||||
self.gridlayout1.addWidget(self.buttonEditRep,1,5,1,1)
|
||||
|
||||
self.buttonDeleteRep = QtGui.QPushButton(self.tab_2)
|
||||
self.buttonDeleteRep.setObjectName("buttonDeleteRep")
|
||||
self.gridlayout1.addWidget(self.buttonDeleteRep,1,6,1,1)
|
||||
self.tabWidget.addTab(self.tab_2,"")
|
||||
self.gridlayout.addWidget(self.tabWidget,0,0,1,1)
|
||||
|
||||
self.hboxlayout2 = QtGui.QHBoxLayout()
|
||||
self.hboxlayout2.setObjectName("hboxlayout2")
|
||||
|
||||
self.label_3 = QtGui.QLabel(QgsPluginInstallerDialog)
|
||||
self.label_3.setObjectName("label_3")
|
||||
self.hboxlayout2.addWidget(self.label_3)
|
||||
|
||||
self.buttonClose = QtGui.QPushButton(QgsPluginInstallerDialog)
|
||||
|
||||
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Fixed,QtGui.QSizePolicy.Fixed)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.buttonClose.sizePolicy().hasHeightForWidth())
|
||||
self.buttonClose.setSizePolicy(sizePolicy)
|
||||
self.buttonClose.setObjectName("buttonClose")
|
||||
self.hboxlayout2.addWidget(self.buttonClose)
|
||||
self.gridlayout.addLayout(self.hboxlayout2,1,0,1,1)
|
||||
|
||||
self.retranslateUi(QgsPluginInstallerDialog)
|
||||
self.tabWidget.setCurrentIndex(0)
|
||||
QtCore.QObject.connect(self.buttonClose,QtCore.SIGNAL("released()"),QgsPluginInstallerDialog.close)
|
||||
QtCore.QMetaObject.connectSlotsByName(QgsPluginInstallerDialog)
|
||||
QgsPluginInstallerDialog.setTabOrder(self.tabWidget,self.lineFilter)
|
||||
QgsPluginInstallerDialog.setTabOrder(self.lineFilter,self.comboFilter1)
|
||||
QgsPluginInstallerDialog.setTabOrder(self.comboFilter1,self.comboFilter2)
|
||||
QgsPluginInstallerDialog.setTabOrder(self.comboFilter2,self.treePlugins)
|
||||
QgsPluginInstallerDialog.setTabOrder(self.treePlugins,self.buttonInstall)
|
||||
QgsPluginInstallerDialog.setTabOrder(self.buttonInstall,self.buttonUninstall)
|
||||
QgsPluginInstallerDialog.setTabOrder(self.buttonUninstall,self.buttonClose)
|
||||
QgsPluginInstallerDialog.setTabOrder(self.buttonClose,self.treeRepositories)
|
||||
QgsPluginInstallerDialog.setTabOrder(self.treeRepositories,self.buttonFetchRepositories)
|
||||
QgsPluginInstallerDialog.setTabOrder(self.buttonFetchRepositories,self.checkUpdates)
|
||||
QgsPluginInstallerDialog.setTabOrder(self.checkUpdates,self.buttonAddRep)
|
||||
QgsPluginInstallerDialog.setTabOrder(self.buttonAddRep,self.buttonEditRep)
|
||||
QgsPluginInstallerDialog.setTabOrder(self.buttonEditRep,self.buttonDeleteRep)
|
||||
|
||||
def retranslateUi(self, QgsPluginInstallerDialog):
|
||||
QgsPluginInstallerDialog.setWindowTitle(QtGui.QApplication.translate("QgsPluginInstallerDialog", "QGIS Python Plugin Installer", None, QtGui.QApplication.UnicodeUTF8))
|
||||
QgsPluginInstallerDialog.setWhatsThis(QtGui.QApplication.translate("QgsPluginInstallerDialog", "QGIS Plugin Installer", None, QtGui.QApplication.UnicodeUTF8))
|
||||
self.label_5.setText(QtGui.QApplication.translate("QgsPluginInstallerDialog", "Filter:", None, QtGui.QApplication.UnicodeUTF8))
|
||||
self.lineFilter.setToolTip(QtGui.QApplication.translate("QgsPluginInstallerDialog", "Display only plugins containing this word in their metadata", None, QtGui.QApplication.UnicodeUTF8))
|
||||
self.lineFilter.setWhatsThis(QtGui.QApplication.translate("QgsPluginInstallerDialog", "Display only plugins containing this word in their metadata", None, QtGui.QApplication.UnicodeUTF8))
|
||||
self.comboFilter1.setToolTip(QtGui.QApplication.translate("QgsPluginInstallerDialog", "Display only plugins from given repository", None, QtGui.QApplication.UnicodeUTF8))
|
||||
self.comboFilter1.setWhatsThis(QtGui.QApplication.translate("QgsPluginInstallerDialog", "Display only plugins from given repository", None, QtGui.QApplication.UnicodeUTF8))
|
||||
self.comboFilter1.addItem(QtGui.QApplication.translate("QgsPluginInstallerDialog", "all repositories", None, QtGui.QApplication.UnicodeUTF8))
|
||||
self.comboFilter2.setToolTip(QtGui.QApplication.translate("QgsPluginInstallerDialog", "Display only plugins with matching status", None, QtGui.QApplication.UnicodeUTF8))
|
||||
self.comboFilter2.setWhatsThis(QtGui.QApplication.translate("QgsPluginInstallerDialog", "Display only plugins with matching status", None, QtGui.QApplication.UnicodeUTF8))
|
||||
self.treePlugins.headerItem().setText(0,QtGui.QApplication.translate("QgsPluginInstallerDialog", "Status", None, QtGui.QApplication.UnicodeUTF8))
|
||||
self.treePlugins.headerItem().setText(1,QtGui.QApplication.translate("QgsPluginInstallerDialog", "Name", None, QtGui.QApplication.UnicodeUTF8))
|
||||
self.treePlugins.headerItem().setText(2,QtGui.QApplication.translate("QgsPluginInstallerDialog", "Version", None, QtGui.QApplication.UnicodeUTF8))
|
||||
self.treePlugins.headerItem().setText(3,QtGui.QApplication.translate("QgsPluginInstallerDialog", "Description", None, QtGui.QApplication.UnicodeUTF8))
|
||||
self.treePlugins.headerItem().setText(4,QtGui.QApplication.translate("QgsPluginInstallerDialog", "Author", None, QtGui.QApplication.UnicodeUTF8))
|
||||
self.treePlugins.headerItem().setText(5,QtGui.QApplication.translate("QgsPluginInstallerDialog", "Repository", None, QtGui.QApplication.UnicodeUTF8))
|
||||
self.buttonInstall.setToolTip(QtGui.QApplication.translate("QgsPluginInstallerDialog", "Install, reinstall or upgrade the selected plugin", None, QtGui.QApplication.UnicodeUTF8))
|
||||
self.buttonInstall.setWhatsThis(QtGui.QApplication.translate("QgsPluginInstallerDialog", "Install, reinstall or upgrade the selected plugin", None, QtGui.QApplication.UnicodeUTF8))
|
||||
self.buttonInstall.setText(QtGui.QApplication.translate("QgsPluginInstallerDialog", "Install/upgrade plugin", None, QtGui.QApplication.UnicodeUTF8))
|
||||
self.buttonUninstall.setToolTip(QtGui.QApplication.translate("QgsPluginInstallerDialog", "Uninstall the selected plugin", None, QtGui.QApplication.UnicodeUTF8))
|
||||
self.buttonUninstall.setWhatsThis(QtGui.QApplication.translate("QgsPluginInstallerDialog", "Uninstall the selected plugin", None, QtGui.QApplication.UnicodeUTF8))
|
||||
self.buttonUninstall.setText(QtGui.QApplication.translate("QgsPluginInstallerDialog", "Uninstall plugin", None, QtGui.QApplication.UnicodeUTF8))
|
||||
self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab), QtGui.QApplication.translate("QgsPluginInstallerDialog", "Plugins", None, QtGui.QApplication.UnicodeUTF8))
|
||||
self.tabWidget.setTabToolTip(self.tabWidget.indexOf(self.tab),QtGui.QApplication.translate("QgsPluginInstallerDialog", "List of available and installed plugins", None, QtGui.QApplication.UnicodeUTF8))
|
||||
self.treeRepositories.headerItem().setText(0,QtGui.QApplication.translate("QgsPluginInstallerDialog", "Status", None, QtGui.QApplication.UnicodeUTF8))
|
||||
self.treeRepositories.headerItem().setText(1,QtGui.QApplication.translate("QgsPluginInstallerDialog", "Name", None, QtGui.QApplication.UnicodeUTF8))
|
||||
self.treeRepositories.headerItem().setText(2,QtGui.QApplication.translate("QgsPluginInstallerDialog", "URL", None, QtGui.QApplication.UnicodeUTF8))
|
||||
self.checkUpdates.setToolTip(QtGui.QApplication.translate("QgsPluginInstallerDialog", "Allow the Installer to look for updates and news in enabled repositories on QGIS startup", None, QtGui.QApplication.UnicodeUTF8))
|
||||
self.checkUpdates.setWhatsThis(QtGui.QApplication.translate("QgsPluginInstallerDialog", "Allow the Installer to look for updates and news in enabled repositories on QGIS startup", None, QtGui.QApplication.UnicodeUTF8))
|
||||
self.checkUpdates.setText(QtGui.QApplication.translate("QgsPluginInstallerDialog", "Check for updates on startup", None, QtGui.QApplication.UnicodeUTF8))
|
||||
self.buttonFetchRepositories.setToolTip(QtGui.QApplication.translate("QgsPluginInstallerDialog", "Add third party plugin repositories to the list", None, QtGui.QApplication.UnicodeUTF8))
|
||||
self.buttonFetchRepositories.setWhatsThis(QtGui.QApplication.translate("QgsPluginInstallerDialog", "Add third party plugin repositories to the list", None, QtGui.QApplication.UnicodeUTF8))
|
||||
self.buttonFetchRepositories.setText(QtGui.QApplication.translate("QgsPluginInstallerDialog", "Add 3rd party repositories", None, QtGui.QApplication.UnicodeUTF8))
|
||||
self.buttonAddRep.setToolTip(QtGui.QApplication.translate("QgsPluginInstallerDialog", "Add a new plugin repository", None, QtGui.QApplication.UnicodeUTF8))
|
||||
self.buttonAddRep.setWhatsThis(QtGui.QApplication.translate("QgsPluginInstallerDialog", "Add a new plugin repository", None, QtGui.QApplication.UnicodeUTF8))
|
||||
self.buttonAddRep.setText(QtGui.QApplication.translate("QgsPluginInstallerDialog", "Add...", None, QtGui.QApplication.UnicodeUTF8))
|
||||
self.buttonEditRep.setToolTip(QtGui.QApplication.translate("QgsPluginInstallerDialog", "Edit the selected repository", None, QtGui.QApplication.UnicodeUTF8))
|
||||
self.buttonEditRep.setWhatsThis(QtGui.QApplication.translate("QgsPluginInstallerDialog", "Edit the selected repository", None, QtGui.QApplication.UnicodeUTF8))
|
||||
self.buttonEditRep.setText(QtGui.QApplication.translate("QgsPluginInstallerDialog", "Edit...", None, QtGui.QApplication.UnicodeUTF8))
|
||||
self.buttonDeleteRep.setToolTip(QtGui.QApplication.translate("QgsPluginInstallerDialog", "Remove the selected repository", None, QtGui.QApplication.UnicodeUTF8))
|
||||
self.buttonDeleteRep.setWhatsThis(QtGui.QApplication.translate("QgsPluginInstallerDialog", "Remove the selected repository", None, QtGui.QApplication.UnicodeUTF8))
|
||||
self.buttonDeleteRep.setText(QtGui.QApplication.translate("QgsPluginInstallerDialog", "Delete", None, QtGui.QApplication.UnicodeUTF8))
|
||||
self.tabWidget.setTabText(self.tabWidget.indexOf(self.tab_2), QtGui.QApplication.translate("QgsPluginInstallerDialog", "Repositories", None, QtGui.QApplication.UnicodeUTF8))
|
||||
self.tabWidget.setTabToolTip(self.tabWidget.indexOf(self.tab_2),QtGui.QApplication.translate("QgsPluginInstallerDialog", "List of plugin repositories", None, QtGui.QApplication.UnicodeUTF8))
|
||||
self.label_3.setText(QtGui.QApplication.translate("QgsPluginInstallerDialog", "The plugins will be installed to ~/.qgis/python/plugins", None, QtGui.QApplication.UnicodeUTF8))
|
||||
self.buttonClose.setToolTip(QtGui.QApplication.translate("QgsPluginInstallerDialog", "Close the Installer window", None, QtGui.QApplication.UnicodeUTF8))
|
||||
self.buttonClose.setWhatsThis(QtGui.QApplication.translate("QgsPluginInstallerDialog", "Close the Installer window", None, QtGui.QApplication.UnicodeUTF8))
|
||||
self.buttonClose.setText(QtGui.QApplication.translate("QgsPluginInstallerDialog", "Close", None, QtGui.QApplication.UnicodeUTF8))
|
||||
|
||||
import resources_rc
|
433
python/plugins/plugin_installer/guibase.ui
Normal file
433
python/plugins/plugin_installer/guibase.ui
Normal file
@ -0,0 +1,433 @@
|
||||
<ui version="4.0" >
|
||||
<author>Matthew Perry, Borys Jurgiel</author>
|
||||
<class>QgsPluginInstallerDialog</class>
|
||||
<widget class="QDialog" name="QgsPluginInstallerDialog" >
|
||||
<property name="geometry" >
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>769</width>
|
||||
<height>395</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>
|
||||
<property name="whatsThis" >
|
||||
<string>QGIS Plugin Installer</string>
|
||||
</property>
|
||||
<layout class="QGridLayout" >
|
||||
<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>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" 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 vsizetype="Fixed" hsizetype="Expanding" >
|
||||
<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 vsizetype="Fixed" hsizetype="Preferred" >
|
||||
<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>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>
|
||||
<spacer>
|
||||
<property name="orientation" >
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" >
|
||||
<size>
|
||||
<width>40</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="buttonInstall" >
|
||||
<property name="sizePolicy" >
|
||||
<sizepolicy vsizetype="Fixed" hsizetype="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="0" >
|
||||
<widget class="QCheckBox" name="checkUpdates" >
|
||||
<property name="toolTip" >
|
||||
<string>Allow the Installer to look for updates and news in enabled repositories on QGIS startup</string>
|
||||
</property>
|
||||
<property name="statusTip" >
|
||||
<string/>
|
||||
</property>
|
||||
<property name="whatsThis" >
|
||||
<string>Allow the Installer to look for updates and news in enabled repositories on QGIS startup</string>
|
||||
</property>
|
||||
<property name="text" >
|
||||
<string>Check for updates on startup</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1" >
|
||||
<spacer>
|
||||
<property name="orientation" >
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeType" >
|
||||
<enum>QSizePolicy::Preferred</enum>
|
||||
</property>
|
||||
<property name="sizeHint" >
|
||||
<size>
|
||||
<width>30</width>
|
||||
<height>20</height>
|
||||
</size>
|
||||
</property>
|
||||
</spacer>
|
||||
</item>
|
||||
<item row="1" column="2" >
|
||||
<widget class="QPushButton" name="buttonFetchRepositories" >
|
||||
<property name="enabled" >
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="toolTip" >
|
||||
<string>Add third party plugin repositories to the list</string>
|
||||
</property>
|
||||
<property name="whatsThis" >
|
||||
<string>Add third party plugin repositories to the list</string>
|
||||
</property>
|
||||
<property name="text" >
|
||||
<string>Add 3rd party repositories</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="3" >
|
||||
<spacer>
|
||||
<property name="orientation" >
|
||||
<enum>Qt::Horizontal</enum>
|
||||
</property>
|
||||
<property name="sizeHint" >
|
||||
<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>
|
||||
</layout>
|
||||
</widget>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0" >
|
||||
<layout class="QHBoxLayout" >
|
||||
<item>
|
||||
<widget class="QLabel" name="label_3" >
|
||||
<property name="whatsThis" >
|
||||
<string/>
|
||||
</property>
|
||||
<property name="text" >
|
||||
<string>The plugins will be installed to ~/.qgis/python/plugins</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="buttonClose" >
|
||||
<property name="sizePolicy" >
|
||||
<sizepolicy vsizetype="Fixed" hsizetype="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>
|
||||
</layout>
|
||||
</widget>
|
||||
<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>treeRepositories</tabstop>
|
||||
<tabstop>buttonFetchRepositories</tabstop>
|
||||
<tabstop>checkUpdates</tabstop>
|
||||
<tabstop>buttonAddRep</tabstop>
|
||||
<tabstop>buttonEditRep</tabstop>
|
||||
<tabstop>buttonDeleteRep</tabstop>
|
||||
</tabstops>
|
||||
<resources>
|
||||
<include location="resources.qrc" />
|
||||
</resources>
|
||||
<connections>
|
||||
<connection>
|
||||
<sender>buttonClose</sender>
|
||||
<signal>released()</signal>
|
||||
<receiver>QgsPluginInstallerDialog</receiver>
|
||||
<slot>close()</slot>
|
||||
<hints>
|
||||
<hint type="sourcelabel" >
|
||||
<x>710</x>
|
||||
<y>447</y>
|
||||
</hint>
|
||||
<hint type="destinationlabel" >
|
||||
<x>380</x>
|
||||
<y>235</y>
|
||||
</hint>
|
||||
</hints>
|
||||
</connection>
|
||||
</connections>
|
||||
</ui>
|
584
python/plugins/plugin_installer/installer_data.py
Normal file
584
python/plugins/plugin_installer/installer_data.py
Normal file
@ -0,0 +1,584 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
qgis_plugins.py
|
||||
Copyright (C) 2007-2008 Matthew Perry
|
||||
Copyright (C) 2008 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 QHttp, QNetworkProxy
|
||||
from qgis.core import *
|
||||
from unzip import unzip
|
||||
|
||||
|
||||
|
||||
"""
|
||||
Data structure:
|
||||
mRepositories = dict of dicts: {repoName : {"url" string,
|
||||
"enabled" bool,
|
||||
"valid" bool,
|
||||
"QHttp" QHttp,
|
||||
"Relay" Relay, # Relay object for transmitting signals from QHttp with adding the repoName information
|
||||
"xmlData" QDomDocument,
|
||||
"state" int, (0 - disabled, 1-loading, 2-loaded ok, 3-error (to be retried), 4-rejected)
|
||||
"error" QString}}
|
||||
mPlugins = dict of dicts {id : {"name" string,
|
||||
"version_avail" string,
|
||||
"version_inst" string,
|
||||
"desc_repo" string,
|
||||
"desc_local" string,
|
||||
"author" string,
|
||||
"status" string, ("not installed", "installed", "upgradeable", "orphan", "new", "newer", "invalid")
|
||||
"homepage" string,
|
||||
"url" string,
|
||||
"filename" string,
|
||||
"repository" string,
|
||||
"localdir" string,
|
||||
"read-only" boolean}}
|
||||
"""
|
||||
|
||||
|
||||
reposGroup = "/Qgis/plugin-repos"
|
||||
settingsGroup = "/Qgis/plugin-installer"
|
||||
seenPluginGroup = "/Qgis/plugin-seen"
|
||||
|
||||
# knownRepos: (name, url for QGIS 0.x, url for QGIS 1.x, possible depreciated url, another possible depreciated url)
|
||||
knownRepos = [("Official QGIS Repository","http://spatialserver.net/cgi-bin/pyqgis_plugin.rb","http://spatialserver.net/cgi-bin/pyqgis_plugin.rb","",""),
|
||||
("Carson Farmer's Repository","http://www.ftools.ca/cfarmerQgisRepo.xml","","http://www.geog.uvic.ca/spar/carson/cfarmerQgisRepo.xml",""),
|
||||
("Barry Rowlingson's Repository","http://www.maths.lancs.ac.uk/~rowlings/Qgis/Plugins/plugins.xml","","",""),
|
||||
("Borys Jurgiel's Repository","http://bwj.aster.net.pl/qgis-oldapi/plugins.xml","http://bwj.aster.net.pl/qgis/plugins.xml","",""),
|
||||
("Faunalia Repository","http://faunalia.it/qgis/plugins.xml","","","")]
|
||||
|
||||
|
||||
|
||||
# --- class Relay ----------------------------------------------------------------------- #
|
||||
class Relay(QObject):
|
||||
""" Relay object for transmitting signals from QHttp 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):
|
||||
# ----------------------------------------- #
|
||||
def __init__(self):
|
||||
QObject.__init__(self)
|
||||
self.mRepositories = {}
|
||||
self.httpId = {} # {httpId : repoName}
|
||||
self.QGISver = int(str(QGis.qgisVersion)[0])
|
||||
|
||||
|
||||
# ----------------------------------------- #
|
||||
def addKnownRepos(self):
|
||||
presentURLs = []
|
||||
for i in self.all().values():
|
||||
presentURLs += [str(i["url"])]
|
||||
for i in knownRepos:
|
||||
if i[self.QGISver+1] and presentURLs.count(i[self.QGISver+1]) == 0:
|
||||
settings = QSettings()
|
||||
settings.beginGroup(reposGroup)
|
||||
repoName = QString(i[0])
|
||||
if self.all().has_key(repoName):
|
||||
repoName = repoName + "(2)"
|
||||
# add to settings
|
||||
settings.setValue(repoName+"/url", QVariant(i[self.QGISver+1]))
|
||||
settings.setValue(repoName+"/enabled", QVariant(True))
|
||||
|
||||
|
||||
# ----------------------------------------- #
|
||||
def all(self):
|
||||
return self.mRepositories
|
||||
|
||||
|
||||
# ----------------------------------------- #
|
||||
def allEnabled(self):
|
||||
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):
|
||||
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):
|
||||
self.mRepositories[reposName][key] = value
|
||||
|
||||
|
||||
# ----------------------------------------- #
|
||||
def rename(self,oldName, newName):
|
||||
if oldName == newName:
|
||||
return
|
||||
self.mRepositories[newName] = self.mRepositories[oldName]
|
||||
del self.mRepositories[oldName]
|
||||
|
||||
|
||||
# ----------------------------------------- #
|
||||
def checkingOnStart(self):
|
||||
settings = QSettings()
|
||||
return settings.value(settingsGroup+"/checkOnStart", QVariant(True)).toBool()
|
||||
|
||||
|
||||
# ----------------------------------------- #
|
||||
def setCheckingOnStart(self, state):
|
||||
settings = QSettings()
|
||||
settings.setValue(settingsGroup+"/checkOnStart", QVariant(state))
|
||||
|
||||
|
||||
# ----------------------------------------- #
|
||||
def load(self):
|
||||
""" populate the mRepositories dict"""
|
||||
self.mRepositories = {}
|
||||
settings = QSettings()
|
||||
settings.beginGroup(reposGroup)
|
||||
# first, update the QSettings repositories if needed
|
||||
if len(settings.childGroups()) == 0: # add the default repository when there isn't any
|
||||
settings.setValue(self.knownRepos[0][0]+"/url", QVariant(self.knownRepos[0][self.QGISver+1]))
|
||||
else: # else update invalid urls
|
||||
for key in settings.childGroups():
|
||||
url = settings.value(key+"/url", QVariant()).toString()
|
||||
allOk = True
|
||||
for repo in knownRepos:
|
||||
if repo[3] == url or repo[4] == url or (repo[self.QGISver+1] != url and repo[int(not self.QGISver)+1] == url):
|
||||
if repo[self.QGISver+1]: #update the URL
|
||||
settings.setValue(key+"/url", QVariant(repo[self.QGISver+1]))
|
||||
settings.setValue(key+"/valid", QVariant(True))
|
||||
allOk = False
|
||||
else: # mark as invalid
|
||||
settings.setValue(key+"/valid", QVariant(False))
|
||||
allOk = False
|
||||
if allOk: # marking as valid if no problem.
|
||||
settings.setValue(key+"/valid", QVariant(True))
|
||||
|
||||
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]["QHttp"] = QHttp()
|
||||
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):
|
||||
self.mRepositories[key]["state"] = 1
|
||||
url = QUrl(self.mRepositories[key]["url"])
|
||||
path = QString(url.toPercentEncoding(url.path(), "!$&'()*+,;=:@/"))
|
||||
self.mRepositories[key]["QHttp"] = QHttp(url.host())
|
||||
self.connect(self.mRepositories[key]["QHttp"], SIGNAL("requestFinished (int, bool)"), self.xmlDownloaded)
|
||||
self.connect(self.mRepositories[key]["QHttp"], SIGNAL("stateChanged ( int )"), self.mRepositories[key]["Relay"].stateChanged)
|
||||
self.connect(self.mRepositories[key]["QHttp"], 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]["QHttp"].get(path, self.mRepositories[key]["xmlData"])
|
||||
self.httpId[i] = key
|
||||
|
||||
|
||||
# ----------------------------------------- #
|
||||
def fetchingInProgress(self):
|
||||
for key in self.mRepositories:
|
||||
if self.mRepositories[key]["state"] == 1:
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
# ----------------------------------------- #
|
||||
def killConnection(self, key):
|
||||
if self.mRepositories[key]["QHttp"].state():
|
||||
self.mRepositories[key]["QHttp"].abort()
|
||||
|
||||
|
||||
# ----------------------------------------- #
|
||||
def xmlDownloaded(self,nr,state):
|
||||
#print reposName, nr, state
|
||||
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]["QHttp"].errorString()
|
||||
#print "Repository fetching failed! " , reposName , str(self.mRepositories[reposName]["error"])
|
||||
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()):
|
||||
name = QFileInfo(pluginNodes.item(i).firstChildElement("download_url").text().trimmed()).fileName()
|
||||
name = str(name[0:len(name)-4])
|
||||
plugin = {}
|
||||
plugin[name] = {
|
||||
"name" : pluginNodes.item(i).toElement().attribute("name"),
|
||||
"version_avail" : pluginNodes.item(i).toElement().attribute("version"),
|
||||
"desc_repo" : pluginNodes.item(i).firstChildElement("description").text().trimmed(),
|
||||
"desc_local" : "",
|
||||
"author" : pluginNodes.item(i).firstChildElement("author_name").text().trimmed(),
|
||||
"homepage" : pluginNodes.item(i).firstChildElement("homepage").text().trimmed(),
|
||||
"url" : pluginNodes.item(i).firstChildElement("download_url").text().trimmed(),
|
||||
"filename" : pluginNodes.item(i).firstChildElement("file_name").text().trimmed(),
|
||||
"status" : "not installed",
|
||||
"version_inst" : "",
|
||||
"repository" : reposName,
|
||||
"localdir" : name,
|
||||
"read-only" : False}
|
||||
plugins.addPlugin(plugin)
|
||||
|
||||
plugins.workarounds()
|
||||
self.mRepositories[reposName]["state"] = 2
|
||||
else:
|
||||
#print "Repository parsing error"
|
||||
self.mRepositories[reposName]["state"] = 3
|
||||
self.mRepositories[reposName]["error"] = QCoreApplication.translate("QgsPluginInstaller","Couldn't parse output from the repository")
|
||||
|
||||
self.emit(SIGNAL("repositoryFetched(QString)"), reposName )
|
||||
|
||||
# is the checking done?
|
||||
if not self.fetchingInProgress():
|
||||
plugins.getAllInstalled()
|
||||
self.emit(SIGNAL("checkingDone()"))
|
||||
# --- /class Repositories ---------------------------------------------------------------- #
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# --- class Plugins ---------------------------------------------------------------------- #
|
||||
class Plugins(QObject):
|
||||
# ----------------------------------------- #
|
||||
def __init__(self):
|
||||
QObject.__init__(self)
|
||||
self.mPlugins = {}
|
||||
|
||||
|
||||
# ----------------------------------------- #
|
||||
def all(self):
|
||||
return self.mPlugins
|
||||
|
||||
|
||||
# ----------------------------------------- #
|
||||
def firstByName(self, name):
|
||||
plugins = [i for i in self.mPlugins if self.mPlugins[i]["name"] == name]
|
||||
if plugins:
|
||||
return plugins[0]
|
||||
return None
|
||||
|
||||
|
||||
# ----------------------------------------- #
|
||||
def setPluginData(self, pluginName, key, value):
|
||||
self.mPlugins[pluginName][key] = value
|
||||
|
||||
|
||||
# ----------------------------------------- #
|
||||
def clear(self):
|
||||
""" clear the plugins dict"""
|
||||
self.mPlugins = {}
|
||||
|
||||
|
||||
# ----------------------------------------- #
|
||||
def normalizeVersion(self,ver):
|
||||
if not ver:
|
||||
return QString()
|
||||
if ver.toUpper().left(7) == "VERSION":
|
||||
ver.remove(0,7)
|
||||
elif ver.toUpper().left(4) == "VER.":
|
||||
ver.remove(0,4)
|
||||
if ver[0] == " ":
|
||||
ver.remove(0,1)
|
||||
return ver
|
||||
|
||||
|
||||
# ----------------------------------------- #
|
||||
def compareVersions(self,a,b):
|
||||
# -------- #
|
||||
def classify(s):
|
||||
if s in [".","-","_"," "]:
|
||||
return 0
|
||||
try:
|
||||
float(s)
|
||||
return 1
|
||||
except:
|
||||
return 2
|
||||
# -------- #
|
||||
def chop(s):
|
||||
s2 = [s[0]]
|
||||
for i in range(1,len(s)):
|
||||
if classify(s[i]) == 0:
|
||||
pass
|
||||
elif classify(s[i]) == classify(s[i-1]):
|
||||
s2[len(s2)-1] += s[i]
|
||||
else:
|
||||
s2 += [s[i]]
|
||||
return s2
|
||||
# -------- #
|
||||
def compare(s1,s2):
|
||||
# check if the matter is easy solvable:
|
||||
if s1 == s2:
|
||||
return 0
|
||||
# try to compare as numeric values:
|
||||
try:
|
||||
if s1[0] == '0' or s2[0] == '0':
|
||||
s1 = '0.' + s1
|
||||
s2 = '0.' + s2
|
||||
if float(s1) == float(s2):
|
||||
return 0
|
||||
elif float(s1) > float(s2):
|
||||
return 1
|
||||
else:
|
||||
return 2
|
||||
except:
|
||||
pass
|
||||
# set ALPHA < BETA < RC < FINAL < ANYTHING_ELSE
|
||||
if s1 == 'FINAL':
|
||||
s1 = 'Z' + s1
|
||||
elif not s1 in ['ALPHA','BETA','RC']:
|
||||
s1 = 'ZZ' + s1
|
||||
if s2 == 'FINAL':
|
||||
s2 = 'Z' + s2
|
||||
elif not s2 in ['ALPHA','BETA','RC']:
|
||||
s2 = 'ZZ' + s2
|
||||
# the real test:
|
||||
if s1 > s2:
|
||||
return 1
|
||||
else:
|
||||
return 2
|
||||
# -------- #
|
||||
if not a or not b:
|
||||
return 0
|
||||
a = unicode(a).upper()
|
||||
b = unicode(b).upper()
|
||||
if a == b:
|
||||
return 0
|
||||
|
||||
v1 = chop(a)
|
||||
v2 = chop(b)
|
||||
l = len(v1)
|
||||
if l > len(v2):
|
||||
l = len(v2)
|
||||
|
||||
for i in range(l):
|
||||
if compare(v1[i],v2[i]):
|
||||
return compare(v1[i],v2[i])
|
||||
|
||||
if len(v1) > l:
|
||||
return compare(v1[l],u'')
|
||||
if len(v2) > l:
|
||||
return compare(u'',v2[l])
|
||||
# if everything else fails...
|
||||
if unicode(a) > unicode(b):
|
||||
return 1
|
||||
else:
|
||||
return 2
|
||||
|
||||
|
||||
# ----------------------------------------- #
|
||||
def addPlugin(self, plugins):
|
||||
key = plugins.keys()[0]
|
||||
plugin = plugins[key]
|
||||
plugin["version_avail"] = self.normalizeVersion(QString(plugin["version_avail"]))
|
||||
plugin["version_inst"] = self.normalizeVersion(QString(plugin["version_inst"]))
|
||||
if not self.mPlugins.has_key(key) or self.compareVersions(self.mPlugins[key]["version_avail"],plugin["version_avail"]) == 2:
|
||||
self.mPlugins[key] = plugin # add the plugin if not present yet or if is newer than existing one
|
||||
|
||||
|
||||
# ----------------------------------------- #
|
||||
def updatePlugin(self, key, readOnly):
|
||||
try:
|
||||
exec("import "+ key)
|
||||
try:
|
||||
exec("nam = %s.name()" % key)
|
||||
except:
|
||||
nam = ""
|
||||
try:
|
||||
exec("ver = %s.version()" % key)
|
||||
except:
|
||||
ver = ""
|
||||
try:
|
||||
exec("desc = %s.description()" % key)
|
||||
except:
|
||||
desc = ""
|
||||
try:
|
||||
exec("auth = %s.author_name()" % key)
|
||||
except:
|
||||
auth = ""
|
||||
try:
|
||||
exec("homepage = %s.homepage()" % key)
|
||||
except:
|
||||
homepage = ""
|
||||
stat = ""
|
||||
except:
|
||||
nam = key
|
||||
stat = "invalid"
|
||||
ver = ""
|
||||
desc = ""
|
||||
auth = ""
|
||||
homepage = ""
|
||||
normVer = self.normalizeVersion(QString(ver))
|
||||
plugin = {
|
||||
"name" : nam,
|
||||
"version_inst" : normVer,
|
||||
"version_avail" : "",
|
||||
"desc_local" : desc,
|
||||
"desc_repo" : "",
|
||||
"author" : auth,
|
||||
"homepage" : homepage,
|
||||
"url" : "",
|
||||
"filename" : "",
|
||||
"status" : stat,
|
||||
"repository" : "",
|
||||
"localdir" : key,
|
||||
"read-only" : readOnly}
|
||||
if not self.mPlugins.has_key(key):
|
||||
self.mPlugins[key] = plugin # just add a new plugin
|
||||
else:
|
||||
self.mPlugins[key]["localdir"] = plugin["localdir"]
|
||||
self.mPlugins[key]["read-only"] = plugin["read-only"]
|
||||
if plugin["status"] == "invalid":
|
||||
self.mPlugins[key]["status"] = plugin["status"]
|
||||
else:
|
||||
self.mPlugins[key]["name"] = plugin["name"] # local name has higher priority, except invalid plugins
|
||||
self.mPlugins[key]["version_inst"] = plugin["version_inst"]
|
||||
self.mPlugins[key]["desc_local"] = plugin["desc_local"]
|
||||
if plugin["author"]:
|
||||
self.mPlugins[key]["author"] = plugin["author"] #local author name has higher priority, if exists
|
||||
if plugin["homepage"]:
|
||||
self.mPlugins[key]["homepage"] = plugin["homepage"] # local homepage adress has higher priority, if exists
|
||||
# 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"
|
||||
# *marked as invalid* "invalid"
|
||||
if self.mPlugins[key]["status"] == "invalid":
|
||||
pass
|
||||
elif not self.mPlugins[key]["version_inst"]:
|
||||
self.mPlugins[key]["status"] = "not installed"
|
||||
elif not self.mPlugins[key]["version_avail"]:
|
||||
self.mPlugins[key]["status"] = "orphan"
|
||||
elif self.compareVersions(self.mPlugins[key]["version_avail"],self.mPlugins[key]["version_inst"]) == 0:
|
||||
self.mPlugins[key]["status"] = "installed"
|
||||
elif self.compareVersions(self.mPlugins[key]["version_avail"],self.mPlugins[key]["version_inst"]) == 1:
|
||||
self.mPlugins[key]["status"] = "upgradeable"
|
||||
else:
|
||||
self.mPlugins[key]["status"] = "newer"
|
||||
|
||||
|
||||
# ----------------------------------------- #
|
||||
def getAllInstalled(self):
|
||||
""" update the mPlugins dict with alredy installed plugins """
|
||||
#print "getting list of installed plugins"
|
||||
# first, try to add the read-only plugins...
|
||||
try:
|
||||
pluginDir = QDir.cleanPath(unicode(QgsApplication.pkgDataPath(),'utf-8') + "/python/plugins")
|
||||
pluginDir = QDir(pluginDir)
|
||||
pluginDir.setFilter(QDir.AllDirs)
|
||||
except:
|
||||
return QCoreApplication.translate("QgsPluginInstaller","Couldn't open the system plugin directory")
|
||||
for key in pluginDir.entryList():
|
||||
key = str(key)
|
||||
if not key in [".",".."]:
|
||||
self.updatePlugin(key, True)
|
||||
# ...then try to add locally installed ones
|
||||
try:
|
||||
pluginDir = QDir.cleanPath(unicode(QgsApplication.qgisSettingsDirPath(),'utf-8') + "/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 = str(key)
|
||||
if not key in [".",".."]:
|
||||
self.updatePlugin(key, False)
|
||||
|
||||
|
||||
# ----------------------------------------- #
|
||||
def markNews(self):
|
||||
""" mark all new plugins as new """
|
||||
#print "marking the new plugins"
|
||||
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 """
|
||||
#print "updating the list of 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):
|
||||
for i in self.mPlugins.values():
|
||||
if i["status"] in ["upgradeable","new"]:
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
# ----------------------------------------- #
|
||||
def workarounds(self):
|
||||
if self.mPlugins.has_key("postgps") and self.mPlugins["postgps"]["version_avail"] == "0.2":
|
||||
self.mPlugins["postgps"]["version_avail"] = "0.01"
|
||||
if self.mPlugins.has_key("select") and self.mPlugins["select"]["version_avail"] == "0.1":
|
||||
self.mPlugins["select"]["version_avail"] = "0.2"
|
||||
|
||||
# --- /class Plugins --------------------------------------------------------------------- #
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# public members:
|
||||
repositories = Repositories()
|
||||
plugins = Plugins()
|
709
python/plugins/plugin_installer/installer_gui.py
Normal file
709
python/plugins/plugin_installer/installer_gui.py
Normal file
@ -0,0 +1,709 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
Copyright (C) 2008 Matthew Perry
|
||||
Copyright (C) 2008 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 QgsApplication, QgsContextHelp
|
||||
import sys
|
||||
from fetchingbase import Ui_QgsPluginInstallerFetchingDialog
|
||||
from installingbase import Ui_QgsPluginInstallerInstallingDialog
|
||||
from repositorybase import Ui_QgsPluginInstallerRepositoryDetailsDialog
|
||||
from pluginerrorbase import Ui_QgsPluginInstallerPluginErrorDialog
|
||||
from guibase import Ui_QgsPluginInstallerDialog
|
||||
from installer_data import *
|
||||
|
||||
|
||||
# --- common functions ------------------------------------------------------------------- #
|
||||
def removeDir(path):
|
||||
result = QString()
|
||||
if not QFile(path).exists():
|
||||
result = QCoreApplication.translate("QgsPluginInstaller","Plugin directory doesn't exist: ") + path
|
||||
elif QFile(path).remove(): # if it's only link, just remove it without resolving.
|
||||
#print " Link removing successfull: %s" % path
|
||||
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():
|
||||
#print " File removing successfull: %s" % item
|
||||
pass
|
||||
fltr = QDir.Dirs | QDir.Hidden
|
||||
iterator = QDirIterator(path, fltr, QDirIterator.Subdirectories)
|
||||
while iterator.hasNext():
|
||||
item = iterator.next()
|
||||
if QDir(item).rmpath("."):
|
||||
#print " Directory removing successfull: %s" % item
|
||||
pass
|
||||
if QFile(path).exists():
|
||||
result = QCoreApplication.translate("QgsPluginInstaller","Failed to remove directory")+" "+path+" \n"+QCoreApplication.translate("QgsPluginInstaller","Check permissions or remove it manually")
|
||||
return result
|
||||
# --- /common functions ------------------------------------------------------------------ #
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# --- class QgsPluginInstallerFetchingDialog --------------------------------------------------------------- #
|
||||
class QgsPluginInstallerFetchingDialog(QDialog, Ui_QgsPluginInstallerFetchingDialog):
|
||||
# ----------------------------------------- #
|
||||
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("Done"),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_QgsPluginInstallerRepositoryDetailsDialog):
|
||||
# ----------------------------------------- #
|
||||
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_QgsPluginInstallerInstallingDialog):
|
||||
# ----------------------------------------- #
|
||||
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"]
|
||||
#print "Retrieving from %s" % path
|
||||
tmpDir = QDir.tempPath()
|
||||
tmpPath = QDir.cleanPath(tmpDir+"/"+fileName)
|
||||
self.file = QFile(tmpPath)
|
||||
self.http = QHttp(url.host())
|
||||
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 = unicode(QFileInfo(QgsApplication.qgisUserDbFilePath()).path()+"/python/plugins")
|
||||
tmpPath = unicode(self.file.fileName())
|
||||
|
||||
# make sure that the parent directory exists
|
||||
if not QDir(pluginDir).exists():
|
||||
QDir(pluginDir).mkpath(".")
|
||||
|
||||
#print "Extracting to plugin directory (%s)" % pluginDir
|
||||
#try:
|
||||
|
||||
|
||||
un = unzip()
|
||||
un.extract(tmpPath, pluginDir) # test extract. If fails, then exception will be raised and no removing occurs
|
||||
#print "Removing old plugin files if exist"
|
||||
removeDir(QDir.cleanPath(pluginDir+"/"+self.plugin["localdir"])) # remove old plugin if exists
|
||||
un.extract(tmpPath, pluginDir) # final extract.
|
||||
|
||||
|
||||
#except:
|
||||
#self.mResult = self.tr("Failed to unzip file to ") + pluginDir + "\n" + self.tr("check permissions")
|
||||
#self.reject()
|
||||
#return
|
||||
|
||||
try:
|
||||
#print "Cleaning: removing the zip file (%s)" % tmpPath
|
||||
QFile(tmpPath).remove()
|
||||
except:
|
||||
pass
|
||||
|
||||
self.close()
|
||||
|
||||
|
||||
# ----------------------------------------- #
|
||||
def abort(self):
|
||||
self.http.abort()
|
||||
self.mResult = self.tr("Aborted by user")
|
||||
self.reject()
|
||||
# --- /class QgsPluginInstallerPluginErrorDialog ------------------------------------------------------------- #
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# --- class QgsPluginInstallerPluginErrorDialog -------------------------------------------------------------- #
|
||||
class QgsPluginInstallerPluginErrorDialog(QDialog, Ui_QgsPluginInstallerPluginErrorDialog):
|
||||
# ----------------------------------------- #
|
||||
def __init__(self, parent, errorMessage):
|
||||
QDialog.__init__(self, parent)
|
||||
self.setupUi(self)
|
||||
if not errorMessage:
|
||||
errorMessage = self.tr("No error message received. Try to restart QGIS and ensure the plugin isn't installed under different name. If it is, contact the plugin author and submit this issue, please.")
|
||||
self.textBrowser.setText(errorMessage)
|
||||
# --- /class QgsPluginInstallerPluginErrorDialog ------------------------------------------------------------- #
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
# --- class QgsPluginInstallerDialog ------------------------------------------------------------------------- #
|
||||
class QgsPluginInstallerDialog(QDialog, Ui_QgsPluginInstallerDialog):
|
||||
# ----------------------------------------- #
|
||||
def __init__(self, parent, fl):
|
||||
QDialog.__init__(self, parent, fl)
|
||||
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 the click on the treePlugins
|
||||
self.connect(self.treePlugins, SIGNAL("itemSelectionChanged()"), self.treeClicked)
|
||||
# buttons
|
||||
self.connect(self.buttonInstall, SIGNAL("clicked()"), self.installPlugin)
|
||||
self.connect(self.buttonUninstall, SIGNAL("clicked()"), self.uninstallPlugin)
|
||||
self.buttonInstall.setEnabled(False)
|
||||
self.buttonUninstall.setEnabled(False)
|
||||
# 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)
|
||||
# checkingOnStart checkbox
|
||||
self.connect(self.checkUpdates, SIGNAL("stateChanged (int)"), self.ChangeCheckingPolicy)
|
||||
if repositories.checkingOnStart():
|
||||
self.checkUpdates.setCheckState(Qt.Checked)
|
||||
else:
|
||||
self.checkUpdates.setCheckState(Qt.Unchecked)
|
||||
|
||||
self.populateMostWidgets()
|
||||
|
||||
|
||||
# ----------------------------------------- #
|
||||
def getAllAvailablePlugins(self):
|
||||
""" repopulate the mPlugins dict """
|
||||
repositories.load()
|
||||
plugins.clear()
|
||||
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, except the case if all repositories are unavailable!
|
||||
if repositories.allUnavailable() and repositories.allUnavailable() != repositories.allEnabled():
|
||||
for key in repositories.allUnavailable():
|
||||
QMessageBox.warning(self, self.tr("QGIS Python Plugin Installer"), self.tr("Error reading repository: ") + key + "\n" + repositories.all()[key]["error"])
|
||||
|
||||
|
||||
# ----------------------------------------- #
|
||||
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"))
|
||||
a.setDisabled(True)
|
||||
for i in [0,1,2]:
|
||||
self.treeRepositories.resizeColumnToContents(i)
|
||||
self.comboFilter1.addItem(self.tr("orphans"))
|
||||
# filling the status filter comboBox
|
||||
self.comboFilter2.clear()
|
||||
self.comboFilter2.addItem(self.tr("any status"))
|
||||
self.comboFilter2.addItem(self.tr("not installed"))
|
||||
self.comboFilter2.addItem(self.tr("installed"))
|
||||
if plugins.isThereAnythingNew():
|
||||
self.comboFilter2.addItem(self.tr("upgradeable and news"))
|
||||
|
||||
|
||||
# ----------------------------------------- #
|
||||
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","invalid"]:
|
||||
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 = str(plugin[i]).upper()
|
||||
if item != None:
|
||||
if item.find(self.lineFilter.text().toUpper()) > -1:
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
# ----------------------------------------- #
|
||||
def populatePluginTree(self):
|
||||
""" fill up the pluginTree """
|
||||
descrip={"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 first time"),
|
||||
"newer" : self.tr("This plugin is installed and is newer than its version available in a repository"),
|
||||
"invalid" : self.tr("This plugin seems to be invalid or have unfulfilled dependencies\nIt has been installed, but can't be loaded")}
|
||||
status ={"not installed" : self.tr("not installed"),
|
||||
"installed" : self.tr("installed"),
|
||||
"upgradeable" : self.tr("upgradeable"),
|
||||
"orphan" : self.tr("installed"),
|
||||
"new" : self.tr("new!"),
|
||||
"newer" : self.tr("installed"),
|
||||
"invalid" : self.tr("invalid")}
|
||||
order = ["invalid","upgradeable","new","not installed","installed","orphan","newer"]
|
||||
def addItem(p):
|
||||
if self.filterCheck(p):
|
||||
statusTip = descrip[p["status"]]
|
||||
if p["read-only"]:
|
||||
statusTip += "\n" + self.tr("Note that it's installed in the read-only location and you can't uninstall it")
|
||||
if p["status"] == "upgradeable":
|
||||
ver = p["version_inst"] + " -> " + p["version_avail"]
|
||||
elif p["status"] == "newer":
|
||||
ver = p["version_inst"] + " (" + p["version_avail"] + ")"
|
||||
elif p["status"] in ["not installed", "new", "invalid"]:
|
||||
ver = p["version_avail"]
|
||||
else:
|
||||
ver = p["version_inst"]
|
||||
if p["status"] in ["upgradeable","newer"]:
|
||||
vd = self.tr("installed version") + ": " + p["version_inst"] + "\n" + self.tr("available version") + ": " + p["version_avail"]
|
||||
elif p["status"] in ["not installed", "new"]:
|
||||
vd = self.tr("available version") + ": " + p["version_avail"]
|
||||
elif p["status"] == "installed":
|
||||
vd = self.tr("installed version") + ": " + p["version_inst"] + "\n" + self.tr("That's the newest available version.")
|
||||
elif p["status"] == "orphan":
|
||||
vd = self.tr("installed version") + ": " + p["version_inst"] + "\n" + self.tr("There is no version available for download.")
|
||||
else:
|
||||
vd = ""
|
||||
if p["status"] == "invalid":
|
||||
p["desc_local"] = self.tr("This plugin seems to be invalid or have unfulfilled dependencies")
|
||||
p["desc_repo"] = self.tr("This plugin seems to be invalid or have unfulfilled dependencies\nIt has been installed, but can't be loaded")
|
||||
if p["status"] == "orphan":
|
||||
if p["read-only"]:
|
||||
url = unicode(QgsApplication.pkgDataPath(),'utf-8') + "/python/plugins/" + p["localdir"]
|
||||
else:
|
||||
url = unicode(QgsApplication.qgisSettingsDirPath(),'utf-8') + "/python/plugins/" + p["localdir"]
|
||||
repository = self.tr("only locally available")
|
||||
else:
|
||||
url = p["url"]
|
||||
repository = p["repository"]
|
||||
if not p["desc_local"]:
|
||||
p["desc_local"] = p["desc_repo"]
|
||||
a = QTreeWidgetItem(self.treePlugins)
|
||||
a.setText(0,status[p["status"]])
|
||||
a.setToolTip(0,statusTip)
|
||||
a.setText(1,p["name"])
|
||||
a.setText(2,ver)
|
||||
a.setToolTip(2,vd)
|
||||
a.setText(3,p["desc_local"])
|
||||
a.setToolTip(3, p["desc_repo"])
|
||||
a.setText(4,p["author"])
|
||||
if p["homepage"]:
|
||||
a.setToolTip(4,p["homepage"])
|
||||
else:
|
||||
a.setToolTip(4,"")
|
||||
a.setText(5,repository)
|
||||
a.setToolTip(5,url)
|
||||
# set fonts and colours
|
||||
for i in [0,1,2,3,4,5]:
|
||||
if p["status"] == "invalid":
|
||||
a.setForeground(i,QBrush(QColor(Qt.red)))
|
||||
if p["status"] in ["new","upgradeable","invalid"]:
|
||||
font = QFont()
|
||||
font.setWeight(QFont.Bold)
|
||||
a.setFont(i,font)
|
||||
# -------- #
|
||||
if not plugins.all():
|
||||
return
|
||||
self.treePlugins.clear()
|
||||
for i in order:
|
||||
for p in plugins.all().values():
|
||||
if p["status"] == i:
|
||||
addItem(p)
|
||||
# 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)
|
||||
# initially, keep order of inserting
|
||||
self.treePlugins.sortItems(100,Qt.AscendingOrder)
|
||||
|
||||
|
||||
# ----------------------------------------- #
|
||||
def treeClicked(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")),
|
||||
"invalid":(False,True,self.tr("Reinstall plugin"))}
|
||||
self.buttonInstall.setEnabled(False)
|
||||
self.buttonInstall.setText(self.tr("Install/upgrade plugin"))
|
||||
self.buttonUninstall.setEnabled(False)
|
||||
item = self.treePlugins.currentItem()
|
||||
if not item:
|
||||
return
|
||||
key = plugins.firstByName(item.text(1))
|
||||
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 installPlugin(self):
|
||||
""" install currently selected plugin """
|
||||
if not self.treePlugins.currentItem():
|
||||
return
|
||||
key = plugins.firstByName(self.treePlugins.currentItem().text(1))
|
||||
plugin = plugins.all()[key]
|
||||
if not plugin:
|
||||
return
|
||||
|
||||
dlg = QgsPluginInstallerInstallingDialog(self,plugin)
|
||||
dlg.exec_()
|
||||
|
||||
if dlg.result():
|
||||
infoString = (self.tr("Plugin installation failed"), dlg.result())
|
||||
else:
|
||||
try:
|
||||
exec ("sys.path_importer_cache.clear()")
|
||||
exec ("del sys.modules[%s]" % plugin["localdir"]) # remove old version if exist
|
||||
except:
|
||||
pass
|
||||
try:
|
||||
exec ("import %s" % plugin["localdir"])
|
||||
exec ("reload (%s)" % plugin["localdir"])
|
||||
if plugin["status"] == "not installed" or plugin["status"] == "new":
|
||||
infoString = (self.tr("Plugin installed successfully"), self.tr("Python plugin installed.\nYou have to enable it in the Plugin Manager."))
|
||||
else:
|
||||
infoString = (self.tr("Plugin installed successfully"),self.tr("Python plugin reinstalled.\nYou have to restart Quantum GIS to reload it."))
|
||||
except Exception, error:
|
||||
dlg = QgsPluginInstallerPluginErrorDialog(self,error.message)
|
||||
dlg.exec_()
|
||||
if dlg.result():
|
||||
pluginDir = unicode(QFileInfo(QgsApplication.qgisUserDbFilePath()).path()+"/python/plugins/"+ str(plugin["localdir"]))
|
||||
result = removeDir(pluginDir)
|
||||
if result:
|
||||
QMessageBox.warning(self, self.tr("Plugin uninstall failed"), result)
|
||||
plugins.updatePlugin(key, False)
|
||||
self.populateMostWidgets()
|
||||
self.populatePluginTree()
|
||||
return
|
||||
plugins.updatePlugin(key, False)
|
||||
self.populateMostWidgets()
|
||||
self.populatePluginTree()
|
||||
QMessageBox.information(self, infoString[0], infoString[1])
|
||||
|
||||
|
||||
# ----------------------------------------- #
|
||||
def uninstallPlugin(self):
|
||||
""" uninstall currently selected plugin """
|
||||
if not self.treePlugins.currentItem():
|
||||
return
|
||||
key = plugins.firstByName(self.treePlugins.currentItem().text(1))
|
||||
plugin = plugins.all()[key]
|
||||
if not plugin:
|
||||
return
|
||||
|
||||
warning = self.tr("Are you sure you want to uninstall the plugin ") + plugin["name"] + "?"
|
||||
if plugin["status"] == "orphan":
|
||||
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
|
||||
pluginDir = unicode(QFileInfo(QgsApplication.qgisUserDbFilePath()).path()+"/python/plugins/"+ str(plugin["localdir"]))
|
||||
#print "Uninstalling plugin", plugin["name"], pluginDir
|
||||
result = removeDir(pluginDir)
|
||||
if result:
|
||||
QApplication.restoreOverrideCursor()
|
||||
QMessageBox.warning(self, self.tr("Plugin uninstall failed"), result)
|
||||
else:
|
||||
try:
|
||||
exec ("del sys.modules[%s]" % plugin["localdir"])
|
||||
except:
|
||||
pass
|
||||
plugins.setPluginData(key, "status", "not installed")
|
||||
plugins.setPluginData(key, "version_inst", "")
|
||||
plugins.setPluginData(key, "desc_local", "")
|
||||
self.populatePluginTree()
|
||||
QApplication.restoreOverrideCursor()
|
||||
QMessageBox.information(self, self.tr("QGIS Python Plugin Installer"), self.tr("Plugin uninstalled successfully"))
|
||||
|
||||
|
||||
# ----------------------------------------- #
|
||||
def ChangeCheckingPolicy(self,policy):
|
||||
if policy == Qt.Checked:
|
||||
repositories.setCheckingOnStart(True)
|
||||
else:
|
||||
repositories.setCheckingOnStart(False)
|
||||
|
||||
|
||||
# ----------------------------------------- #
|
||||
def addKnownRepositories(self):
|
||||
""" update list of known repositories - in the future it will be replaced with an online fetching """
|
||||
#print "add known repositories"
|
||||
message = "You are going to add some plugin repositories not authotized nor supported by the QGIS team, however provided by folks associated with us.\n"
|
||||
message += "Plugin authors generally make efforts to make their works useful and safe, but we can't assume any responsibility for them. FEEL WARNED!"
|
||||
if QMessageBox.question(self, self.tr("QGIS Python Plugin Installer"), self.tr(message), QMessageBox.Ok, QMessageBox.Abort) == QMessageBox.Ok:
|
||||
repositories.addKnownRepos()
|
||||
# refresh lists and populate widgets
|
||||
QApplication.setOverrideCursor(Qt.WaitCursor)
|
||||
self.getAllAvailablePlugins()
|
||||
self.populateMostWidgets()
|
||||
self.populatePluginTree()
|
||||
QApplication.restoreOverrideCursor()
|
||||
|
||||
|
||||
# ----------------------------------------- #
|
||||
def addRepository(self):
|
||||
""" add repository button has been clicked """
|
||||
#print "add"
|
||||
dlg = QgsPluginInstallerRepositoryDialog(self)
|
||||
dlg.checkBoxEnabled.setCheckState(Qt.Checked)
|
||||
if not dlg.exec_():
|
||||
return
|
||||
for i in repositories.all().values():
|
||||
if dlg.editURL.text() == 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()
|
||||
if repositories.all().has_key(reposName):
|
||||
reposName = reposName + "(2)"
|
||||
#print "name: "+reposName
|
||||
#print "url: "+reposURL
|
||||
# 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)
|
||||
self.getAllAvailablePlugins()
|
||||
self.populateMostWidgets()
|
||||
self.populatePluginTree()
|
||||
QApplication.restoreOverrideCursor()
|
||||
|
||||
|
||||
# ----------------------------------------- #
|
||||
def editRepository(self):
|
||||
""" edit repository button has been clicked """
|
||||
#print "edit"
|
||||
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() == i["url"] and dlg.editURL.text() != 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()))
|
||||
settings.setValue(newName+"/enabled", QVariant(bool(dlg.checkBoxEnabled.checkState())))
|
||||
if dlg.editURL.text() == 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)
|
||||
self.getAllAvailablePlugins()
|
||||
self.populateMostWidgets()
|
||||
self.populatePluginTree()
|
||||
QApplication.restoreOverrideCursor()
|
||||
|
||||
|
||||
# ----------------------------------------- #
|
||||
def deleteRepository(self):
|
||||
""" delete repository button has been clicked """
|
||||
#print "delete"
|
||||
current = self.treeRepositories.currentItem()
|
||||
if current == None:
|
||||
return
|
||||
warning = self.tr("Are you sure you want to remove the 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)
|
||||
settings = QSettings()
|
||||
settings.beginGroup(self.reposGroup)
|
||||
# delete from settings
|
||||
settings.remove(reposName)
|
||||
# refresh lists and populate widgets
|
||||
QApplication.setOverrideCursor(Qt.WaitCursor)
|
||||
self.getAllAvailablePlugins()
|
||||
self.populateMostWidgets()
|
||||
self.populatePluginTree()
|
||||
QApplication.restoreOverrideCursor()
|
||||
|
||||
|
||||
# ----------------------------------------- #
|
||||
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 ------------------------------------------------------------------------ #
|
@ -1,5 +1,8 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
Copyright (C) 2008 Matthew Perry
|
||||
Copyright (C) 2008 Borys Jurgiel
|
||||
|
||||
/***************************************************************************
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
@ -12,36 +15,108 @@ Copyright (C) 2008 Matthew Perry
|
||||
from PyQt4.QtCore import *
|
||||
from PyQt4.QtGui import *
|
||||
from qgis.core import *
|
||||
from dialog import InstallerPluginGui
|
||||
import resources
|
||||
from installer_gui import *
|
||||
from installer_data import *
|
||||
import resources_rc
|
||||
|
||||
|
||||
|
||||
class InstallerPlugin:
|
||||
|
||||
# ----------------------------------------- #
|
||||
def __init__(self, iface):
|
||||
# save reference to the QGIS interface
|
||||
self.iface = iface
|
||||
if str(QGis.qgisVersion)[0] == "0": # old plugin API
|
||||
self.mainWindow = self.iface.getMainWindow
|
||||
else: # new plugin API
|
||||
self.mainWindow = self.iface.mainWindow
|
||||
|
||||
# ----------------------------------------- #
|
||||
def initGui(self):
|
||||
# create action that will start plugin configuration
|
||||
self.action = QAction(QIcon(":/plugins/installer/icon.xpm"), "Install plugins", self.iface.mainWindow())
|
||||
self.action.setWhatsThis("Plugin Installer")
|
||||
""" create action that will start plugin window and then add it to menu """
|
||||
self.action = QAction(QIcon(":/plugins/installer/PluginInstaller.png"), QCoreApplication.translate("QgsPluginInstaller","Plugin Installer..."), 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"))
|
||||
if str(QGis.qgisVersion)[0] == "0":
|
||||
nextAction = self.mainWindow().menuBar().actions()[4].menu().actions()[1]
|
||||
self.mainWindow().menuBar().actions()[4].menu().insertAction(nextAction,self.action)
|
||||
else:
|
||||
nextAction = self.iface.actionPluginSeparator1()
|
||||
self.iface.pluginMenu().insertAction(nextAction,self.action)
|
||||
QObject.connect(self.action, SIGNAL("activated()"), self.run)
|
||||
self.statusLabel = None
|
||||
|
||||
repositories.load()
|
||||
plugins.clear()
|
||||
if repositories.checkingOnStart():
|
||||
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.run)
|
||||
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)
|
||||
|
||||
|
||||
# ----------------------------------------- #
|
||||
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
|
||||
|
||||
# add toolbar button and menu item
|
||||
self.iface.addToolBarIcon(self.action)
|
||||
self.iface.addPluginToMenu("&Plugin Installer", self.action)
|
||||
|
||||
# ----------------------------------------- #
|
||||
def unload(self):
|
||||
# remove the plugin menu item and icon
|
||||
self.iface.removePluginMenu("&Plugin Installer",self.action)
|
||||
self.iface.removeToolBarIcon(self.action)
|
||||
""" remove the menu item and notify label """
|
||||
self.mainWindow().menuBar().actions()[4].menu().removeAction(self.action)
|
||||
if self.statusLabel:
|
||||
self.mainWindow().statusBar().removeWidget(self.statusLabel)
|
||||
|
||||
|
||||
# ----------------------------------------- #
|
||||
def run(self):
|
||||
# create and show a configuration dialog
|
||||
def run(self, * params):
|
||||
""" create and show a configuration dialog """
|
||||
QApplication.setOverrideCursor(Qt.WaitCursor)
|
||||
if self.statusLabel:
|
||||
self.mainWindow().statusBar().removeWidget(self.statusLabel)
|
||||
self.statusLabel = None
|
||||
|
||||
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(self.mainWindow())
|
||||
self.fetchDlg.exec_()
|
||||
del self.fetchDlg
|
||||
for key in repositories.all():
|
||||
repositories.killConnection(key)
|
||||
|
||||
QApplication.restoreOverrideCursor()
|
||||
|
||||
# display error messages for every unavailable reposioty, except the case if all repositories are unavailable!
|
||||
if repositories.allUnavailable() and repositories.allUnavailable() != repositories.allEnabled():
|
||||
for key in repositories.allUnavailable():
|
||||
QMessageBox.warning(self.mainWindow(), QCoreApplication.translate("QgsPluginInstaller","QGIS Python Plugin Installer"), QCoreApplication.translate("QgsPluginInstaller","Error reading repository:") + u' %s\n%s' % (key,repositories.all()[key]["error"]))
|
||||
|
||||
flags = Qt.WindowTitleHint | Qt.WindowSystemMenuHint | Qt.WindowMaximizeButtonHint
|
||||
self.gui = InstallerPluginGui(self.iface.mainWindow(),flags)
|
||||
self.gui.show()
|
||||
self.guiDlg = QgsPluginInstallerDialog(self.mainWindow(),flags)
|
||||
self.guiDlg.show()
|
||||
|
73
python/plugins/plugin_installer/installingbase.py
Normal file
73
python/plugins/plugin_installer/installingbase.py
Normal file
@ -0,0 +1,73 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Form implementation generated from reading ui file 'installingbase.ui'
|
||||
#
|
||||
# Created: Sun Sep 7 16:22:38 2008
|
||||
# by: PyQt4 UI code generator 4.3
|
||||
#
|
||||
# WARNING! All changes made in this file will be lost!
|
||||
|
||||
from PyQt4 import QtCore, QtGui
|
||||
|
||||
class Ui_QgsPluginInstallerInstallingDialog(object):
|
||||
def setupUi(self, QgsPluginInstallerInstallingDialog):
|
||||
QgsPluginInstallerInstallingDialog.setObjectName("QgsPluginInstallerInstallingDialog")
|
||||
QgsPluginInstallerInstallingDialog.resize(QtCore.QSize(QtCore.QRect(0,0,520,175).size()).expandedTo(QgsPluginInstallerInstallingDialog.minimumSizeHint()))
|
||||
QgsPluginInstallerInstallingDialog.setWindowIcon(QtGui.QIcon(":/plugins/installer/qgis-icon.png"))
|
||||
|
||||
self.gridlayout = QtGui.QGridLayout(QgsPluginInstallerInstallingDialog)
|
||||
self.gridlayout.setObjectName("gridlayout")
|
||||
|
||||
spacerItem = QtGui.QSpacerItem(502,16,QtGui.QSizePolicy.Minimum,QtGui.QSizePolicy.MinimumExpanding)
|
||||
self.gridlayout.addItem(spacerItem,0,0,1,1)
|
||||
|
||||
self.hboxlayout = QtGui.QHBoxLayout()
|
||||
self.hboxlayout.setObjectName("hboxlayout")
|
||||
|
||||
self.label = QtGui.QLabel(QgsPluginInstallerInstallingDialog)
|
||||
self.label.setObjectName("label")
|
||||
self.hboxlayout.addWidget(self.label)
|
||||
|
||||
self.labelName = QtGui.QLabel(QgsPluginInstallerInstallingDialog)
|
||||
|
||||
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding,QtGui.QSizePolicy.Preferred)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.labelName.sizePolicy().hasHeightForWidth())
|
||||
self.labelName.setSizePolicy(sizePolicy)
|
||||
self.labelName.setObjectName("labelName")
|
||||
self.hboxlayout.addWidget(self.labelName)
|
||||
self.gridlayout.addLayout(self.hboxlayout,1,0,1,1)
|
||||
|
||||
self.labelState = QtGui.QLabel(QgsPluginInstallerInstallingDialog)
|
||||
self.labelState.setObjectName("labelState")
|
||||
self.gridlayout.addWidget(self.labelState,2,0,1,1)
|
||||
|
||||
self.progressBar = QtGui.QProgressBar(QgsPluginInstallerInstallingDialog)
|
||||
self.progressBar.setMaximum(100)
|
||||
self.progressBar.setProperty("value",QtCore.QVariant(0))
|
||||
self.progressBar.setAlignment(QtCore.Qt.AlignHCenter)
|
||||
self.progressBar.setTextDirection(QtGui.QProgressBar.TopToBottom)
|
||||
self.progressBar.setObjectName("progressBar")
|
||||
self.gridlayout.addWidget(self.progressBar,3,0,1,1)
|
||||
|
||||
spacerItem1 = QtGui.QSpacerItem(502,16,QtGui.QSizePolicy.Minimum,QtGui.QSizePolicy.Fixed)
|
||||
self.gridlayout.addItem(spacerItem1,4,0,1,1)
|
||||
|
||||
self.buttonBox = QtGui.QDialogButtonBox(QgsPluginInstallerInstallingDialog)
|
||||
self.buttonBox.setFocusPolicy(QtCore.Qt.NoFocus)
|
||||
self.buttonBox.setContextMenuPolicy(QtCore.Qt.NoContextMenu)
|
||||
self.buttonBox.setStandardButtons(QtGui.QDialogButtonBox.Abort)
|
||||
self.buttonBox.setCenterButtons(True)
|
||||
self.buttonBox.setObjectName("buttonBox")
|
||||
self.gridlayout.addWidget(self.buttonBox,5,0,1,1)
|
||||
|
||||
self.retranslateUi(QgsPluginInstallerInstallingDialog)
|
||||
QtCore.QMetaObject.connectSlotsByName(QgsPluginInstallerInstallingDialog)
|
||||
|
||||
def retranslateUi(self, QgsPluginInstallerInstallingDialog):
|
||||
QgsPluginInstallerInstallingDialog.setWindowTitle(QtGui.QApplication.translate("QgsPluginInstallerInstallingDialog", "QGIS Python Plugin Installer", None, QtGui.QApplication.UnicodeUTF8))
|
||||
self.label.setText(QtGui.QApplication.translate("QgsPluginInstallerInstallingDialog", "Installing plugin:", None, QtGui.QApplication.UnicodeUTF8))
|
||||
self.labelState.setText(QtGui.QApplication.translate("QgsPluginInstallerInstallingDialog", "Connecting...", None, QtGui.QApplication.UnicodeUTF8))
|
||||
|
||||
import resources_rc
|
124
python/plugins/plugin_installer/installingbase.ui
Normal file
124
python/plugins/plugin_installer/installingbase.ui
Normal file
@ -0,0 +1,124 @@
|
||||
<ui version="4.0" >
|
||||
<author>Matthew Perry, Borys Jurgiel</author>
|
||||
<class>QgsPluginInstallerInstallingDialog</class>
|
||||
<widget class="QDialog" name="QgsPluginInstallerInstallingDialog" >
|
||||
<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>
|
BIN
python/plugins/plugin_installer/plugin_installer.png
Normal file
BIN
python/plugins/plugin_installer/plugin_installer.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 4.8 KiB |
68
python/plugins/plugin_installer/pluginerrorbase.py
Normal file
68
python/plugins/plugin_installer/pluginerrorbase.py
Normal file
@ -0,0 +1,68 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Form implementation generated from reading ui file 'pluginerrorbase.ui'
|
||||
#
|
||||
# Created: Sun Sep 7 16:22:47 2008
|
||||
# by: PyQt4 UI code generator 4.3
|
||||
#
|
||||
# WARNING! All changes made in this file will be lost!
|
||||
|
||||
from PyQt4 import QtCore, QtGui
|
||||
|
||||
class Ui_QgsPluginInstallerPluginErrorDialog(object):
|
||||
def setupUi(self, QgsPluginInstallerPluginErrorDialog):
|
||||
QgsPluginInstallerPluginErrorDialog.setObjectName("QgsPluginInstallerPluginErrorDialog")
|
||||
QgsPluginInstallerPluginErrorDialog.resize(QtCore.QSize(QtCore.QRect(0,0,521,383).size()).expandedTo(QgsPluginInstallerPluginErrorDialog.minimumSizeHint()))
|
||||
QgsPluginInstallerPluginErrorDialog.setMinimumSize(QtCore.QSize(480,300))
|
||||
QgsPluginInstallerPluginErrorDialog.setWindowIcon(QtGui.QIcon(":/plugins/installer/qgis-icon.png"))
|
||||
|
||||
self.gridlayout = QtGui.QGridLayout(QgsPluginInstallerPluginErrorDialog)
|
||||
self.gridlayout.setObjectName("gridlayout")
|
||||
|
||||
self.label = QtGui.QLabel(QgsPluginInstallerPluginErrorDialog)
|
||||
|
||||
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding,QtGui.QSizePolicy.Preferred)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.label.sizePolicy().hasHeightForWidth())
|
||||
self.label.setSizePolicy(sizePolicy)
|
||||
self.label.setWordWrap(True)
|
||||
self.label.setOpenExternalLinks(True)
|
||||
self.label.setObjectName("label")
|
||||
self.gridlayout.addWidget(self.label,1,0,1,1)
|
||||
|
||||
self.textBrowser = QtGui.QTextBrowser(QgsPluginInstallerPluginErrorDialog)
|
||||
self.textBrowser.setMinimumSize(QtCore.QSize(0,0))
|
||||
self.textBrowser.setFocusPolicy(QtCore.Qt.NoFocus)
|
||||
self.textBrowser.setObjectName("textBrowser")
|
||||
self.gridlayout.addWidget(self.textBrowser,2,0,1,1)
|
||||
|
||||
spacerItem = QtGui.QSpacerItem(503,10,QtGui.QSizePolicy.Minimum,QtGui.QSizePolicy.Fixed)
|
||||
self.gridlayout.addItem(spacerItem,3,0,1,1)
|
||||
|
||||
self.label1 = QtGui.QLabel(QgsPluginInstallerPluginErrorDialog)
|
||||
self.label1.setFrameShape(QtGui.QFrame.NoFrame)
|
||||
self.label1.setFrameShadow(QtGui.QFrame.Plain)
|
||||
self.label1.setWordWrap(True)
|
||||
self.label1.setObjectName("label1")
|
||||
self.gridlayout.addWidget(self.label1,4,0,1,1)
|
||||
|
||||
self.buttonBox = QtGui.QDialogButtonBox(QgsPluginInstallerPluginErrorDialog)
|
||||
self.buttonBox.setStandardButtons(QtGui.QDialogButtonBox.No|QtGui.QDialogButtonBox.NoButton|QtGui.QDialogButtonBox.Yes)
|
||||
self.buttonBox.setObjectName("buttonBox")
|
||||
self.gridlayout.addWidget(self.buttonBox,6,0,1,1)
|
||||
|
||||
spacerItem1 = QtGui.QSpacerItem(10,10,QtGui.QSizePolicy.Minimum,QtGui.QSizePolicy.Fixed)
|
||||
self.gridlayout.addItem(spacerItem1,0,0,1,1)
|
||||
|
||||
self.retranslateUi(QgsPluginInstallerPluginErrorDialog)
|
||||
QtCore.QObject.connect(self.buttonBox,QtCore.SIGNAL("rejected()"),QgsPluginInstallerPluginErrorDialog.reject)
|
||||
QtCore.QObject.connect(self.buttonBox,QtCore.SIGNAL("accepted()"),QgsPluginInstallerPluginErrorDialog.accept)
|
||||
QtCore.QMetaObject.connectSlotsByName(QgsPluginInstallerPluginErrorDialog)
|
||||
|
||||
def retranslateUi(self, QgsPluginInstallerPluginErrorDialog):
|
||||
QgsPluginInstallerPluginErrorDialog.setWindowTitle(QtGui.QApplication.translate("QgsPluginInstallerPluginErrorDialog", "Error loading plugin", None, QtGui.QApplication.UnicodeUTF8))
|
||||
self.label.setText(QtGui.QApplication.translate("QgsPluginInstallerPluginErrorDialog", "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:", None, QtGui.QApplication.UnicodeUTF8))
|
||||
self.label1.setText(QtGui.QApplication.translate("QgsPluginInstallerPluginErrorDialog", "Do you want to uninstall this plugin now? If you\'re unsure, probably you would like to do this.", None, QtGui.QApplication.UnicodeUTF8))
|
||||
|
||||
import resources_rc
|
155
python/plugins/plugin_installer/pluginerrorbase.ui
Normal file
155
python/plugins/plugin_installer/pluginerrorbase.ui
Normal file
@ -0,0 +1,155 @@
|
||||
<ui version="4.0" >
|
||||
<author>Matthew Perry, Borys Jurgiel</author>
|
||||
<class>QgsPluginInstallerPluginErrorDialog</class>
|
||||
<widget class="QDialog" name="QgsPluginInstallerPluginErrorDialog" >
|
||||
<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>QgsPluginInstallerPluginErrorDialog</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>QgsPluginInstallerPluginErrorDialog</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>
|
BIN
python/plugins/plugin_installer/qgis-icon.png
Normal file
BIN
python/plugins/plugin_installer/qgis-icon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 785 B |
BIN
python/plugins/plugin_installer/repoConnected.png
Normal file
BIN
python/plugins/plugin_installer/repoConnected.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 917 B |
BIN
python/plugins/plugin_installer/repoDisabled.png
Normal file
BIN
python/plugins/plugin_installer/repoDisabled.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 482 B |
123
python/plugins/plugin_installer/repositorybase.py
Normal file
123
python/plugins/plugin_installer/repositorybase.py
Normal file
@ -0,0 +1,123 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Form implementation generated from reading ui file 'repositorybase.ui'
|
||||
#
|
||||
# Created: Tue Sep 9 00:09:51 2008
|
||||
# by: PyQt4 UI code generator 4.3
|
||||
#
|
||||
# WARNING! All changes made in this file will be lost!
|
||||
|
||||
from PyQt4 import QtCore, QtGui
|
||||
|
||||
class Ui_QgsPluginInstallerRepositoryDetailsDialog(object):
|
||||
def setupUi(self, QgsPluginInstallerRepositoryDetailsDialog):
|
||||
QgsPluginInstallerRepositoryDetailsDialog.setObjectName("QgsPluginInstallerRepositoryDetailsDialog")
|
||||
QgsPluginInstallerRepositoryDetailsDialog.resize(QtCore.QSize(QtCore.QRect(0,0,522,191).size()).expandedTo(QgsPluginInstallerRepositoryDetailsDialog.minimumSizeHint()))
|
||||
|
||||
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Preferred,QtGui.QSizePolicy.Preferred)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(QgsPluginInstallerRepositoryDetailsDialog.sizePolicy().hasHeightForWidth())
|
||||
QgsPluginInstallerRepositoryDetailsDialog.setSizePolicy(sizePolicy)
|
||||
QgsPluginInstallerRepositoryDetailsDialog.setWindowIcon(QtGui.QIcon(":/plugins/installer/qgis-icon.png"))
|
||||
|
||||
self.gridlayout = QtGui.QGridLayout(QgsPluginInstallerRepositoryDetailsDialog)
|
||||
self.gridlayout.setObjectName("gridlayout")
|
||||
|
||||
self.label = QtGui.QLabel(QgsPluginInstallerRepositoryDetailsDialog)
|
||||
|
||||
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Fixed,QtGui.QSizePolicy.Preferred)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.label.sizePolicy().hasHeightForWidth())
|
||||
self.label.setSizePolicy(sizePolicy)
|
||||
self.label.setObjectName("label")
|
||||
self.gridlayout.addWidget(self.label,0,0,1,1)
|
||||
|
||||
spacerItem = QtGui.QSpacerItem(16,27,QtGui.QSizePolicy.Fixed,QtGui.QSizePolicy.Minimum)
|
||||
self.gridlayout.addItem(spacerItem,0,1,1,1)
|
||||
|
||||
self.editName = QtGui.QLineEdit(QgsPluginInstallerRepositoryDetailsDialog)
|
||||
self.editName.setObjectName("editName")
|
||||
self.gridlayout.addWidget(self.editName,0,2,1,2)
|
||||
|
||||
self.label_2 = QtGui.QLabel(QgsPluginInstallerRepositoryDetailsDialog)
|
||||
self.label_2.setObjectName("label_2")
|
||||
self.gridlayout.addWidget(self.label_2,1,0,1,1)
|
||||
|
||||
self.editURL = QtGui.QLineEdit(QgsPluginInstallerRepositoryDetailsDialog)
|
||||
self.editURL.setObjectName("editURL")
|
||||
self.gridlayout.addWidget(self.editURL,1,2,1,2)
|
||||
|
||||
self.checkBoxEnabled = QtGui.QCheckBox(QgsPluginInstallerRepositoryDetailsDialog)
|
||||
self.checkBoxEnabled.setEnabled(True)
|
||||
|
||||
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Fixed,QtGui.QSizePolicy.Fixed)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.checkBoxEnabled.sizePolicy().hasHeightForWidth())
|
||||
self.checkBoxEnabled.setSizePolicy(sizePolicy)
|
||||
self.checkBoxEnabled.setChecked(False)
|
||||
self.checkBoxEnabled.setObjectName("checkBoxEnabled")
|
||||
self.gridlayout.addWidget(self.checkBoxEnabled,2,2,1,1)
|
||||
|
||||
spacerItem1 = QtGui.QSpacerItem(351,23,QtGui.QSizePolicy.Fixed,QtGui.QSizePolicy.Minimum)
|
||||
self.gridlayout.addItem(spacerItem1,2,3,1,1)
|
||||
|
||||
self.labelInfo = QtGui.QLabel(QgsPluginInstallerRepositoryDetailsDialog)
|
||||
self.labelInfo.setEnabled(True)
|
||||
|
||||
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding,QtGui.QSizePolicy.Fixed)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.labelInfo.sizePolicy().hasHeightForWidth())
|
||||
self.labelInfo.setSizePolicy(sizePolicy)
|
||||
|
||||
palette = QtGui.QPalette()
|
||||
|
||||
brush = QtGui.QBrush(QtGui.QColor(175,0,0))
|
||||
brush.setStyle(QtCore.Qt.SolidPattern)
|
||||
palette.setBrush(QtGui.QPalette.Active,QtGui.QPalette.WindowText,brush)
|
||||
|
||||
brush = QtGui.QBrush(QtGui.QColor(175,0,0))
|
||||
brush.setStyle(QtCore.Qt.SolidPattern)
|
||||
palette.setBrush(QtGui.QPalette.Inactive,QtGui.QPalette.WindowText,brush)
|
||||
|
||||
brush = QtGui.QBrush(QtGui.QColor(128,128,128))
|
||||
brush.setStyle(QtCore.Qt.SolidPattern)
|
||||
palette.setBrush(QtGui.QPalette.Disabled,QtGui.QPalette.WindowText,brush)
|
||||
self.labelInfo.setPalette(palette)
|
||||
|
||||
font = QtGui.QFont()
|
||||
font.setWeight(75)
|
||||
font.setBold(True)
|
||||
self.labelInfo.setFont(font)
|
||||
self.labelInfo.setFrameShape(QtGui.QFrame.NoFrame)
|
||||
self.labelInfo.setObjectName("labelInfo")
|
||||
self.gridlayout.addWidget(self.labelInfo,3,2,1,2)
|
||||
|
||||
self.buttonBox = QtGui.QDialogButtonBox(QgsPluginInstallerRepositoryDetailsDialog)
|
||||
self.buttonBox.setOrientation(QtCore.Qt.Horizontal)
|
||||
self.buttonBox.setStandardButtons(QtGui.QDialogButtonBox.Cancel|QtGui.QDialogButtonBox.NoButton|QtGui.QDialogButtonBox.Ok)
|
||||
self.buttonBox.setObjectName("buttonBox")
|
||||
self.gridlayout.addWidget(self.buttonBox,5,0,1,4)
|
||||
|
||||
self.retranslateUi(QgsPluginInstallerRepositoryDetailsDialog)
|
||||
QtCore.QObject.connect(self.buttonBox,QtCore.SIGNAL("accepted()"),QgsPluginInstallerRepositoryDetailsDialog.accept)
|
||||
QtCore.QObject.connect(self.buttonBox,QtCore.SIGNAL("rejected()"),QgsPluginInstallerRepositoryDetailsDialog.reject)
|
||||
QtCore.QMetaObject.connectSlotsByName(QgsPluginInstallerRepositoryDetailsDialog)
|
||||
|
||||
def retranslateUi(self, QgsPluginInstallerRepositoryDetailsDialog):
|
||||
QgsPluginInstallerRepositoryDetailsDialog.setWindowTitle(QtGui.QApplication.translate("QgsPluginInstallerRepositoryDetailsDialog", "Repository details", None, QtGui.QApplication.UnicodeUTF8))
|
||||
self.label.setText(QtGui.QApplication.translate("QgsPluginInstallerRepositoryDetailsDialog", "Name:", None, QtGui.QApplication.UnicodeUTF8))
|
||||
self.editName.setToolTip(QtGui.QApplication.translate("QgsPluginInstallerRepositoryDetailsDialog", "Enter a name for the repository", None, QtGui.QApplication.UnicodeUTF8))
|
||||
self.editName.setWhatsThis(QtGui.QApplication.translate("QgsPluginInstallerRepositoryDetailsDialog", "Enter a name for the repository", None, QtGui.QApplication.UnicodeUTF8))
|
||||
self.label_2.setText(QtGui.QApplication.translate("QgsPluginInstallerRepositoryDetailsDialog", "URL:", None, QtGui.QApplication.UnicodeUTF8))
|
||||
self.editURL.setToolTip(QtGui.QApplication.translate("QgsPluginInstallerRepositoryDetailsDialog", "Enter the repository URL, beginning with \"http://\"", None, QtGui.QApplication.UnicodeUTF8))
|
||||
self.editURL.setWhatsThis(QtGui.QApplication.translate("QgsPluginInstallerRepositoryDetailsDialog", "Enter the repository URL, beginning with \"http://\"", None, QtGui.QApplication.UnicodeUTF8))
|
||||
self.checkBoxEnabled.setToolTip(QtGui.QApplication.translate("QgsPluginInstallerRepositoryDetailsDialog", "Enable or disable the repository (disabled repositories will be omitted)", None, QtGui.QApplication.UnicodeUTF8))
|
||||
self.checkBoxEnabled.setWhatsThis(QtGui.QApplication.translate("QgsPluginInstallerRepositoryDetailsDialog", "Enable or disable the repository (disabled repositories will be omitted)", None, QtGui.QApplication.UnicodeUTF8))
|
||||
self.checkBoxEnabled.setText(QtGui.QApplication.translate("QgsPluginInstallerRepositoryDetailsDialog", "Enabled", None, QtGui.QApplication.UnicodeUTF8))
|
||||
self.labelInfo.setText(QtGui.QApplication.translate("QgsPluginInstallerRepositoryDetailsDialog", "[place for a warning message]", None, QtGui.QApplication.UnicodeUTF8))
|
||||
|
||||
import resources_rc
|
243
python/plugins/plugin_installer/repositorybase.ui
Normal file
243
python/plugins/plugin_installer/repositorybase.ui
Normal file
@ -0,0 +1,243 @@
|
||||
<ui version="4.0" >
|
||||
<author>Matthew Perry, Borys Jurgiel</author>
|
||||
<class>QgsPluginInstallerRepositoryDetailsDialog</class>
|
||||
<widget class="QDialog" name="QgsPluginInstallerRepositoryDetailsDialog" >
|
||||
<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>[place for a warning message]</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>QgsPluginInstallerRepositoryDetailsDialog</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>QgsPluginInstallerRepositoryDetailsDialog</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>
|
@ -1,5 +1,9 @@
|
||||
<RCC>
|
||||
<qresource prefix="/plugins/installer" >
|
||||
<file>icon.xpm</file>
|
||||
<qresource prefix="/plugins/installer">
|
||||
<file>PluginInstaller.png</file>
|
||||
<file>qgis-icon.png</file>
|
||||
<file>repoDisabled.png</file>
|
||||
<file>repoUnavailable.png</file>
|
||||
<file>repoConnected.png</file>
|
||||
</qresource>
|
||||
</RCC>
|
||||
|
580
python/plugins/plugin_installer/resources_rc.py
Normal file
580
python/plugins/plugin_installer/resources_rc.py
Normal file
@ -0,0 +1,580 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Resource object code
|
||||
#
|
||||
# Created: ?r. wrz 3 18:43:47 2008
|
||||
# by: The Resource Compiler for PyQt (Qt v4.3.2)
|
||||
#
|
||||
# WARNING! All changes made in this file will be lost!
|
||||
|
||||
from PyQt4 import QtCore
|
||||
|
||||
qt_resource_data = "\
|
||||
\x00\x00\x01\xe2\
|
||||
\x89\
|
||||
\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\
|
||||
\x00\x00\x16\x00\x00\x00\x16\x08\x04\x00\x00\x00\x6e\xbd\xa4\xb0\
|
||||
\x00\x00\x00\x01\x73\x52\x47\x42\x00\xae\xce\x1c\xe9\x00\x00\x00\
|
||||
\x02\x62\x4b\x47\x44\x00\xff\x87\x8f\xcc\xbf\x00\x00\x00\x09\x70\
|
||||
\x48\x59\x73\x00\x00\x0b\x13\x00\x00\x0b\x13\x01\x00\x9a\x9c\x18\
|
||||
\x00\x00\x00\x07\x74\x49\x4d\x45\x07\xd8\x07\x0f\x08\x30\x24\x35\
|
||||
\xac\x7b\x3e\x00\x00\x01\x66\x49\x44\x41\x54\x28\xcf\xd5\xd3\x41\
|
||||
\x6b\x13\x41\x00\x40\xe1\x6f\x76\x37\x89\x69\x2c\x26\xdb\xa6\x9a\
|
||||
\x0a\x45\xb1\x07\x05\x7f\x59\x2f\x7a\xf7\xec\x59\xbc\xd8\x3f\x25\
|
||||
\x14\x6f\x05\xa9\x58\xc4\x9a\x36\x34\x69\xac\x69\x9a\x6c\xb2\xeb\
|
||||
\xc1\xa4\x6c\xe2\xd9\x83\x73\x98\x81\xe1\xf1\xe6\x31\xcc\xf0\xff\
|
||||
\x8d\x00\xaf\xdf\x3e\x39\x88\x9a\xcb\xad\xe8\x6e\x0e\x82\xe9\xd5\
|
||||
\xc9\x87\xf7\x6f\x4a\xf0\xbb\xfe\xb3\x56\x2c\x42\x24\x56\x5d\x80\
|
||||
\xb1\x48\x64\xe2\xe3\xe0\x55\xfa\x07\x4e\x20\x6e\xd1\x46\x55\xaa\
|
||||
\xa5\x82\xcc\xb5\x91\x20\x18\xaa\xb6\x56\xce\x2c\x64\x7e\x29\xec\
|
||||
\x79\x2c\x73\xe1\x52\xf0\x50\x6a\x6a\xaa\x28\x35\x27\x30\x37\xd2\
|
||||
\xf0\x52\xc3\x91\x9e\x9a\x8a\xba\x8e\x1d\x53\x5d\xb9\xb9\x35\xf3\
|
||||
\x50\x5d\xea\xc8\xa9\xaa\x3d\x3b\x6e\x7c\xd3\xb3\x2d\xc8\x4a\xe6\
|
||||
\x08\x72\x55\x7b\xfa\x3e\xab\xa0\x63\xdb\x48\xe6\xcc\xcc\x03\xb7\
|
||||
\xf2\x75\xf3\xa6\xa6\x9e\x89\xcc\x4c\x10\x64\xe6\xc6\x6e\x34\xcc\
|
||||
\x4b\xd5\x0b\x73\x8c\x48\x45\x10\x04\x84\x05\x52\x28\xfe\x86\x73\
|
||||
\x23\x6d\x9b\x62\x91\x42\x21\x12\xbb\x67\xc3\xb5\xc8\x6c\x15\x9e\
|
||||
\x2b\x9c\x69\xda\x17\x2b\x5c\xfa\x2e\x48\xec\x4a\x74\xd5\x4a\xcd\
|
||||
\xc9\x32\xe3\x5c\xcf\x73\x75\x5d\x27\x72\x6d\xbb\x1e\xf9\x62\xe2\
|
||||
\x7e\xe9\xea\xee\xe0\xdc\xb1\x17\x9e\xea\xb8\x15\x6c\xa8\xf8\xea\
|
||||
\x54\x6a\xb6\x6e\x9e\x89\x55\x4d\x1d\xdb\xb2\xa5\x2e\x77\xa1\x6b\
|
||||
\x2c\x15\x9b\x97\x9a\x13\x18\x0f\x86\xad\x44\x6c\xe2\x87\x73\x91\
|
||||
\x5c\x90\xa8\x99\xa2\xe7\xe7\x60\x05\xee\x1f\x7e\x3a\xa8\x35\xc3\
|
||||
\xf2\x11\x96\x56\xc6\x57\xfd\xc3\x7f\xff\x53\x7e\x03\x8d\x9d\x7c\
|
||||
\x01\xba\x12\x40\xba\x00\x00\x00\x00\x49\x45\x4e\x44\xae\x42\x60\
|
||||
\x82\
|
||||
\x00\x00\x03\x95\
|
||||
\x89\
|
||||
\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\
|
||||
\x00\x00\x16\x00\x00\x00\x16\x08\x06\x00\x00\x00\xc4\xb4\x6c\x3b\
|
||||
\x00\x00\x00\x01\x73\x52\x47\x42\x00\xae\xce\x1c\xe9\x00\x00\x00\
|
||||
\x09\x70\x48\x59\x73\x00\x00\x0b\x13\x00\x00\x0b\x13\x01\x00\x9a\
|
||||
\x9c\x18\x00\x00\x00\x07\x74\x49\x4d\x45\x07\xd8\x06\x09\x16\x07\
|
||||
\x34\xb6\xaf\x33\x78\x00\x00\x03\x27\x49\x44\x41\x54\x38\xcb\xed\
|
||||
\x95\xcb\x6b\x5d\x55\x14\x87\xbf\xfd\x38\xe7\x3e\xf2\xba\x37\xaf\
|
||||
\xa6\x5e\xd2\xa8\x4d\xa1\x03\x71\x62\x35\x90\xd6\x88\x8a\xa0\x28\
|
||||
\x52\xd0\x2a\xe8\x5f\xd0\x0e\xfc\x07\x1c\x3b\x72\xa6\x62\x11\x54\
|
||||
\x50\x1c\x28\x48\xd1\x42\x55\x0a\xa2\xb1\x26\xb5\xad\x15\x05\xc1\
|
||||
\xb6\x31\x48\xd2\xab\x79\xf5\x36\x37\x8f\x73\xef\x39\xe7\xee\xb3\
|
||||
\x97\x83\x34\x51\x5a\x93\x8e\x1c\x08\xae\xd1\xda\xaf\x8f\xdf\xfe\
|
||||
\xad\xc5\xde\xf0\x7f\xfc\xdb\xa1\x36\x93\xdd\x6f\x94\x5e\xe9\x1f\
|
||||
\xee\x3d\x86\x51\xa5\x5b\x36\x69\x50\xa2\x40\xa9\xbf\x72\x0d\x4a\
|
||||
\x29\x5c\x92\xd5\x17\x2e\x2d\xbe\x39\xf7\x52\xfd\xe5\xbf\x9f\xb1\
|
||||
\x9b\x49\xef\xde\x9e\xa3\x95\x7d\x95\xd2\x40\x7a\x07\x81\x0a\x36\
|
||||
\x26\x35\x04\x26\x20\x0c\x72\x68\xad\xf1\xda\x23\xda\x63\xb5\x45\
|
||||
\x99\x0d\x78\x55\xcf\x96\x44\xe4\xe8\x1c\xdb\x80\xb5\x51\xe5\xee\
|
||||
\xb8\x97\x03\x6d\x23\x00\xe4\x6d\x9e\xbb\xda\x87\xb9\xbb\x38\x4c\
|
||||
\xa7\xee\x04\x60\x55\x56\xb8\x9a\xcc\x70\x35\x9b\xc1\x69\x87\x51\
|
||||
\x06\xf1\xc2\xe5\xdc\xe5\xf2\xcd\xb7\xd4\x9b\x89\x88\x10\xbb\x98\
|
||||
\xf9\x78\x1e\x87\x63\xb4\xe7\x41\x0e\x75\x8e\x41\xa2\x98\x5e\x9e\
|
||||
\x62\x7a\x6d\x9a\xc0\x87\x8c\x14\x47\xb9\x37\xb8\x8f\xb4\x95\x70\
|
||||
\x5d\x6a\x38\xd5\xfa\x47\x8f\xb7\x14\x4b\x26\x2c\xa6\xf3\x54\x82\
|
||||
\x41\x9e\xe9\x3b\x42\xc5\xee\xe1\x93\x5f\x4f\x70\xa1\x79\x16\xdf\
|
||||
\x96\x61\x43\x4b\x39\xe9\xe6\x40\xc7\x08\xa3\xf9\x31\xd2\x56\xc2\
|
||||
\x17\xe9\x49\xe2\x30\xc6\x67\xb2\x03\x58\x84\xda\x5a\x8d\x52\xb9\
|
||||
\xc4\xfe\xfc\x3d\x7c\x7c\xe5\x43\x3e\x6b\x7e\x4a\x7b\x77\x3b\x8f\
|
||||
\x94\x1f\x43\x1c\x7c\x1b\x7f\xcd\x5c\xb3\x8a\x33\x2d\xc6\xda\x1f\
|
||||
\xe5\xe2\xc2\x39\x7e\xb1\x3f\x83\xdc\x0a\xde\xb2\xc2\x67\x42\x21\
|
||||
\x28\x30\xd2\x73\x90\xd9\xb5\x19\x4e\xd4\x3e\x62\xad\x63\x05\xa7\
|
||||
\x1d\x07\xdb\x1e\xe2\xfe\x70\x94\x28\x8a\xb8\xa6\x96\x38\x9d\x9c\
|
||||
\x62\x95\x3a\xc3\xe1\x7e\x1a\x49\x84\x97\x9d\x14\xe3\xc9\x77\xe5\
|
||||
\x18\x2a\xde\xc9\xd4\xc2\x15\xfe\xa0\x8a\xc5\x50\x90\x22\x1a\x8d\
|
||||
\x56\x8a\xc8\xaf\x13\xab\x06\xb1\x34\xf9\x4d\xa6\xd9\x15\xf6\x23\
|
||||
\xeb\x20\xde\x6f\x0f\xf6\xde\x63\x8c\xc1\xa0\xd1\x5a\x43\x1e\x32\
|
||||
\xed\x68\x99\x04\xa5\x36\xda\xdd\x69\x47\x4b\xa7\x1b\xeb\x80\x88\
|
||||
\x42\x79\x8d\xec\x64\x85\x64\x42\x4c\x4c\xd5\xcd\xb2\xb7\x6b\x1f\
|
||||
\x7d\x85\x3e\xb4\xd5\x18\x6d\xc9\xf0\x88\x08\x5a\x6b\x8c\x31\xf4\
|
||||
\x9b\x5d\x0c\x9a\x21\xe6\xe2\x2a\xad\x20\x21\x73\x7e\x07\xb0\x03\
|
||||
\x87\x63\x62\xed\x0c\x7b\x8a\x7b\x38\xdc\xfd\x1c\xa1\xca\xd1\x30\
|
||||
\x11\x3f\xa4\xdf\x71\xbe\x3e\x49\x1c\x34\xc9\xe9\x3c\x4f\x84\x4f\
|
||||
\xd3\xed\x7b\x39\xb7\x3e\x09\xc5\x0d\x51\xdb\x5b\x21\x19\xc6\x18\
|
||||
\x26\x9a\xe3\x4c\xa6\xdf\xf0\x7c\xdf\x8b\xe4\xa2\x90\xcf\xdd\x49\
|
||||
\xde\x6b\xbc\x8d\xe4\x84\x81\xb6\x01\x9e\x0c\x0f\xf3\xb8\x7d\x8a\
|
||||
\x89\x85\x71\x7e\x2c\x7e\x4f\x18\x86\x64\x59\x76\x7b\x8f\x63\xd5\
|
||||
\xe4\xad\xd5\xd7\x50\x5d\x8a\x67\xdb\x5f\xe0\x90\x3c\xcc\xef\xcc\
|
||||
\xa2\xd1\x0c\x9a\x21\x7a\x7d\x3f\x67\x96\xbe\xe2\x83\xf4\x5d\x6c\
|
||||
\x45\xe3\x32\xb9\x4d\xf1\x5a\x82\x35\x86\x20\xb4\x5c\x63\x91\xd7\
|
||||
\xa3\x57\xb9\x60\xcf\xf2\x80\x1d\x65\xc0\xec\x46\x3c\x4c\x25\x97\
|
||||
\x78\x3f\x7a\x87\x9f\x72\x17\xd1\x15\x08\x74\x48\x96\x35\xf1\x6e\
|
||||
\x07\x70\xda\x48\x97\xe3\xeb\x69\xd9\xf4\x5b\xb4\x28\x56\xa8\x73\
|
||||
\x3a\x3b\xc5\x78\xf2\x25\x05\x29\x40\xa6\x48\x6c\x8c\x74\x08\x36\
|
||||
\xb4\x98\x96\x21\xa5\x45\x6d\xa1\x46\xa3\x1e\x2f\x6f\x0b\x5e\x5f\
|
||||
\x8a\x8e\xcf\x9e\xaf\x1e\x0b\x72\x41\x49\xdd\x28\xe9\x66\x9b\x6d\
|
||||
\x3d\x9f\x37\x8d\x6f\x08\xaa\xaf\x2f\x45\xc7\xff\xfb\x3f\xc8\x9f\
|
||||
\xfa\xf1\x66\x0f\xd0\x45\x3e\x19\x00\x00\x00\x00\x49\x45\x4e\x44\
|
||||
\xae\x42\x60\x82\
|
||||
\x00\x00\x03\x8e\
|
||||
\x89\
|
||||
\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\
|
||||
\x00\x00\x16\x00\x00\x00\x16\x08\x06\x00\x00\x00\xc4\xb4\x6c\x3b\
|
||||
\x00\x00\x00\x01\x73\x52\x47\x42\x00\xae\xce\x1c\xe9\x00\x00\x00\
|
||||
\x09\x70\x48\x59\x73\x00\x00\x0b\x13\x00\x00\x0b\x13\x01\x00\x9a\
|
||||
\x9c\x18\x00\x00\x00\x07\x74\x49\x4d\x45\x07\xd8\x06\x09\x16\x09\
|
||||
\x28\x3c\x2d\x42\xb9\x00\x00\x03\x20\x49\x44\x41\x54\x38\xcb\xed\
|
||||
\x95\x5d\x6b\x5c\x45\x18\xc7\x7f\x33\x73\xce\xd9\x5d\x92\x4d\xcf\
|
||||
\x66\xb3\x89\xc9\x26\xd8\x24\x48\x6f\x14\x4c\x43\xb7\x46\xe8\x85\
|
||||
\xa5\x78\x63\xb5\xf8\x31\xda\xaf\xe0\x8d\x5e\xf8\x15\x2c\x88\x50\
|
||||
\x7a\x25\xa2\xa8\x60\xbd\xd2\xd8\xde\xf4\xbd\xdd\x08\x4a\x2a\xac\
|
||||
\x2c\xa1\x49\x76\x93\x34\x27\xbb\x9b\x75\x5f\xce\xd9\x33\x33\x5e\
|
||||
\x6c\xd2\x8a\x64\xe3\x95\x17\x82\x03\x03\xcf\xc0\xcc\xef\x79\x9e\
|
||||
\xff\xf3\x87\x81\xff\xd7\xbf\xbd\xc4\x61\xf0\xd1\x2b\xf3\x1f\xcf\
|
||||
\x8d\x8f\x5f\x51\x52\xf8\x7f\xbf\x24\x01\x2b\x04\x42\x88\x17\x31\
|
||||
\x02\x29\x20\xd4\xba\x5e\xaa\x56\x3f\xf9\xb0\x54\xfe\xe0\xaf\x6f\
|
||||
\x9c\xc3\x60\x36\x97\xbb\x3c\x3f\x33\xe3\xdb\x5c\x0e\xe9\x3a\x07\
|
||||
\x59\x05\xca\x75\xf1\x3c\x0f\x29\x25\xc2\x5a\xa4\x31\x48\xc7\x41\
|
||||
\x1d\x24\x32\xd5\x8a\x6f\x8d\xbd\xcc\x20\xb0\x92\x22\x13\xfb\x3e\
|
||||
\xa3\xaf\x2f\x00\xe0\x26\x12\x9c\x98\x9d\x65\xe4\xe4\x49\x9c\xa1\
|
||||
\x61\x00\xf4\x1f\x4d\x5a\x1b\x9b\x84\x95\x4d\xa4\x8e\x11\x4a\xd1\
|
||||
\xc1\xe2\x3d\xf9\x2d\x73\x54\x97\x00\x18\x0b\x71\xb7\x4b\x7b\x67\
|
||||
\x07\x74\xcc\x64\xe1\x2c\xb9\xc2\x59\x22\x60\xb7\x5c\xa6\xfe\x74\
|
||||
\x0d\xeb\xba\x64\x16\x17\x19\x7e\xed\x55\xa2\x30\x22\xae\xd5\x21\
|
||||
\x8e\x8f\xd4\xd8\x79\x01\x36\x74\x9e\x3d\x23\x39\x35\x45\xfe\xe2\
|
||||
\xbb\x24\xf3\x53\xac\x7e\x7f\x83\xfa\x4a\x91\x94\xb5\xb8\x8e\x4b\
|
||||
\xd2\xf7\xc9\x2e\x2c\xe0\x9f\x29\xd0\x0b\x43\x1a\xcb\xcb\x88\x30\
|
||||
\xc4\x58\x33\x18\x6c\xad\x65\x7f\x6f\x8f\x97\x46\x4e\x90\x3e\x75\
|
||||
\x8a\x5f\xbe\xfd\x86\xe0\xc7\x1f\xc8\xa4\xd3\x4c\x9e\x3b\x47\x6c\
|
||||
\xa1\x7e\xff\x1e\xc1\xf6\x16\x32\x8e\xf1\x97\xde\x64\x6f\xe5\x67\
|
||||
\x28\x95\xb0\xd6\x32\x50\x0a\x6d\x2c\x5e\x2a\xc9\x64\xe1\x0c\x8d\
|
||||
\x8d\x75\xd6\x6f\x7c\x47\xaa\xdd\x42\x68\xcd\x68\xe1\x0d\x46\x16\
|
||||
\x4f\xd3\x6a\xb5\xd0\xb5\x1a\xb5\x5b\x37\x31\xfb\xfb\x0c\xcd\xcf\
|
||||
\x13\xb6\x5b\x47\x82\x9f\x57\x8c\x35\xa4\x93\x29\xd2\xd3\x33\x6c\
|
||||
\x95\xcb\xe8\xad\x2a\x3a\x91\xc0\xa4\x52\x20\x25\x02\x81\x6e\xb7\
|
||||
\xb0\x51\x8f\x5e\xd8\x25\x5a\x7f\x4a\x6a\x34\x4b\x6c\xfb\x45\x0d\
|
||||
\xd6\xd8\x18\x94\x52\x7d\x7f\x4a\x89\x27\x24\x32\x8e\x11\xbd\x1e\
|
||||
\x42\xf4\xed\x2e\xb4\x46\xc4\x3d\x84\xea\x37\x6a\xa5\xe8\xef\x7f\
|
||||
\x92\x82\xb0\x4b\xb7\x5a\x61\x74\x6e\x8e\xa1\xb1\x2c\x4a\x29\xa4\
|
||||
\x72\xc0\x1a\xac\xb5\x48\x21\x51\x4a\xe1\x8d\x8d\x91\xc8\xe7\x69\
|
||||
\x55\xaa\xa8\xa8\x87\x36\xfa\x18\x30\x16\xab\x35\xbb\x0f\x1f\x90\
|
||||
\x9e\xca\x33\xfd\xce\x45\xa4\xe7\x21\x3a\x1d\x9a\xc5\x15\x76\x1e\
|
||||
\x3d\x42\x45\x21\x2a\x91\xc0\x3f\x7f\x01\xe1\x67\x08\x8a\x8f\x49\
|
||||
\x49\x71\xbc\x14\x56\x6b\x94\x52\xd4\xef\xdf\x63\xff\xe1\x03\x5e\
|
||||
\xbe\xf4\x3e\x29\x2f\x41\xe3\xa7\x65\xb6\xbf\xfa\x02\x6d\x2d\xb9\
|
||||
\x89\x09\xfc\x0b\x6f\x33\xf2\xd6\x79\x36\xee\xde\x45\xae\xfe\x8a\
|
||||
\xe7\x79\x68\xad\x07\x83\xb5\xb1\x28\xa5\xb0\x61\xc8\xe6\xf5\x6b\
|
||||
\x4c\x0b\xc1\xc4\x7b\x97\xc8\x2e\x2d\xd1\xab\x56\x11\x42\x90\xc8\
|
||||
\xe7\x11\xa3\x59\x2a\x77\x6e\x13\x7c\xfd\x25\x39\xd7\xc3\xe8\x18\
|
||||
\x63\x8e\xf1\x71\x7c\x30\x3c\xcf\x71\xd0\x41\x40\xe5\xb3\x4f\x19\
|
||||
\x5e\x29\x32\xbc\x70\x1a\x2f\x37\x8e\x06\x76\x4b\xbf\x53\x7b\xfc\
|
||||
\x39\xe6\xc9\x2a\x39\xa9\x50\x9e\x8b\xe9\xc4\x47\x6a\xfc\x1c\xdc\
|
||||
\x8e\xa2\x5a\xbd\xdb\xcd\x8c\x39\x0e\x56\x08\x68\x34\xa8\xdd\xba\
|
||||
\x49\xe3\xce\x6d\x48\x26\xd1\x08\x54\x14\xe2\x01\x49\xc7\x21\x56\
|
||||
\x8a\xb8\x17\xb1\x1d\x04\xd4\x3b\xdd\xda\x40\x70\xd0\x6c\x5e\x2d\
|
||||
\xae\xad\x5d\xf1\x5c\xcf\x3f\x9c\xe8\xa1\xcd\x18\x70\x3e\x28\xa8\
|
||||
\x1e\x34\x9b\x57\xff\xfb\x3f\xc8\x9f\xa2\x63\x68\x95\x98\xd0\x55\
|
||||
\x56\x00\x00\x00\x00\x49\x45\x4e\x44\xae\x42\x60\x82\
|
||||
\x00\x00\x03\x11\
|
||||
\x89\
|
||||
\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\
|
||||
\x00\x00\x10\x00\x00\x00\x10\x08\x06\x00\x00\x00\x1f\xf3\xff\x61\
|
||||
\x00\x00\x00\x06\x62\x4b\x47\x44\x00\xff\x00\xff\x00\xff\xa0\xbd\
|
||||
\xa7\x93\x00\x00\x00\x09\x70\x48\x59\x73\x00\x00\x0b\x12\x00\x00\
|
||||
\x0b\x12\x01\xd2\xdd\x7e\xfc\x00\x00\x00\x07\x74\x49\x4d\x45\x07\
|
||||
\xd4\x0c\x0e\x14\x29\x37\x87\x80\x5f\xe3\x00\x00\x02\x9e\x49\x44\
|
||||
\x41\x54\x78\xda\x95\x92\x5b\x48\x53\x01\x18\xc7\xff\x3b\x3b\xd3\
|
||||
\xb9\xa6\x39\x2f\x9b\x97\xb4\x24\x13\xa7\xb9\x12\xb1\xde\x7a\xb1\
|
||||
\x0c\xc4\x4c\x34\x08\xc5\x34\x8d\x0a\x0c\x34\x7b\x29\x84\x8c\x22\
|
||||
\x33\xd0\x61\x3d\x16\x51\x12\x2a\x09\xf9\x50\xa1\xf8\x30\x12\xba\
|
||||
\x4b\x37\x9b\x28\xa3\x79\x69\xa6\xa6\xe7\xec\xd2\xe6\xe6\x39\x67\
|
||||
\x3b\x97\x5e\x5a\x99\x5b\x50\xdf\xdb\xf7\x7d\xfc\x7f\x1f\xfc\xbf\
|
||||
\x3f\xf0\x1f\x15\x73\x1e\xd9\x9a\x2e\x3c\x24\x33\xb1\x3b\x38\x23\
|
||||
\xfe\x45\x18\xdd\x82\x54\x4d\x27\x6e\xcb\xb5\x98\x10\x56\x50\xc2\
|
||||
\x4f\x43\x0c\xee\xc8\x70\x82\x95\x95\x9e\x84\xd8\x58\xa9\x66\xca\
|
||||
\x32\xb9\x43\x4e\xb2\xfc\x3b\xdb\x1c\xd5\xd4\x3f\x5c\x44\xe8\x24\
|
||||
\x52\xa0\x41\x01\xb0\xff\xf5\x1a\xc3\xf4\x95\xf0\x82\xd1\xf1\x78\
|
||||
\xa4\xdc\xab\x89\x53\xd6\xd4\x9d\xd4\x1f\x7d\x69\xad\x10\x53\x8c\
|
||||
\xa4\xa4\x3e\x8e\x6f\x11\x7b\xf1\x02\x80\x3a\xac\x78\x75\xf5\x8e\
|
||||
\x21\x20\x5c\x63\xe6\x1c\xc7\xa4\xba\x53\xd9\x23\x00\x54\x64\x06\
|
||||
\x48\x7d\xa7\x7a\x5e\xd7\x46\x4a\xcd\x17\x0d\xd3\x91\x5a\x79\x01\
|
||||
\x00\x79\x58\x0f\x94\xca\xef\xed\x94\xcf\xaa\xf4\xad\x05\x30\x6b\
|
||||
\xf5\xbc\x01\xc0\xa8\x8e\xa0\x79\x59\xf4\xa6\x1d\x8a\xc8\x44\x7d\
|
||||
\x7d\xf6\xf6\xc6\x86\xbc\xfd\xc0\x6f\x0f\x7e\x01\x86\x86\xce\xa8\
|
||||
\x78\x19\x5d\xcc\x70\x7e\xf8\x39\x01\xd4\x0a\x63\x53\x37\x42\x4f\
|
||||
\xc4\xe3\x6a\x16\x95\xb0\x76\xba\x72\x27\xd4\xd1\x0a\xa4\x67\xa8\
|
||||
\xcb\x00\x44\x86\x00\x72\x73\xa5\x24\x2e\xe0\x89\x08\xf6\x7e\x41\
|
||||
\x08\xc8\x93\xd0\x23\xd2\x60\x0f\xeb\xf4\xc3\xc9\xc9\x9b\x00\x00\
|
||||
\x2a\x95\x3c\x05\x80\x2a\x04\x60\x36\x3b\xdd\x3c\x38\x09\x00\x08\
|
||||
\x42\x86\x2d\x45\x9a\x73\x07\xb2\xf3\x0a\x8b\xb8\x9c\xc1\xda\xea\
|
||||
\x82\x31\x99\x4c\x06\x00\xb0\xd3\x1c\x0b\x40\x0a\x01\x94\x95\x3d\
|
||||
\x70\xd9\x5d\xac\x19\x00\xa2\x54\x24\x0e\x1a\xb6\xe6\x47\x8c\x8a\
|
||||
\x96\xa6\xaa\x9c\xd2\xd8\x44\xf2\x0a\x2f\x8a\xe0\x38\x01\x1f\xde\
|
||||
\xd2\x13\x00\x7c\xe1\x4c\x14\x5f\x3f\xa7\xba\x58\x86\x07\x41\xc8\
|
||||
\x30\x69\x59\x72\xf6\xdf\x9a\xac\xcd\x48\x8f\xeb\x76\x31\x54\x94\
|
||||
\x3f\x20\xe0\xd5\xb3\xe5\x35\xd3\xf0\xc2\x3d\x00\xfe\x10\x00\xb9\
|
||||
\x0d\xc4\x59\xb3\x69\xa9\xf3\xd1\x47\x87\x9d\x66\x50\x55\x96\x45\
|
||||
\x1a\x76\x25\xba\xb5\xf1\x9a\x48\x00\x98\x9a\x70\x06\x6e\x5c\x37\
|
||||
\x1b\xdd\x6e\x6e\xb4\xa3\xa3\xea\xcf\x37\x46\x55\x42\xa1\x2c\x46\
|
||||
\xbb\x40\xa3\x77\xf0\xd3\xe7\xb8\x13\x97\x9f\x7e\x99\x18\x77\xcc\
|
||||
\xb4\xb6\xed\x19\x98\xb1\xb1\x0d\x82\x28\xc2\xeb\xe5\x7d\x4e\xbb\
|
||||
\xd0\xc7\xb2\x77\x5b\xd7\x58\x7b\x43\xb8\x1c\x29\x00\x68\x55\x15\
|
||||
\xb8\x1f\xb9\x0f\xdd\x3f\xd3\x96\xf6\xc4\x54\x7a\xc1\x4a\x55\x4b\
|
||||
\x56\xaa\x5a\x72\xf9\x5a\xfc\xbd\x03\xe5\x76\x85\x82\x28\x0c\x8a\
|
||||
\xe4\xeb\x3d\x00\xe0\x53\xe4\x63\x41\xa4\x01\x61\x11\x63\x00\x3c\
|
||||
\x8b\x5f\x99\x71\x8f\xdb\x9f\x6a\x9b\x5d\x8d\x19\x1c\xb4\xcc\xdf\
|
||||
\x34\xbe\xbf\xe4\x71\xfb\x4d\xeb\xc3\xb4\xb1\x08\xb9\x0e\x9b\x37\
|
||||
\xcc\x48\x00\x1a\x00\x31\x00\x64\xeb\x17\x3f\x00\x3d\x4b\x18\xbb\
|
||||
\x0e\x57\x7e\xbc\x00\x00\x00\x00\x49\x45\x4e\x44\xae\x42\x60\x82\
|
||||
\
|
||||
\x00\x00\x13\x3e\
|
||||
\x89\
|
||||
\x50\x4e\x47\x0d\x0a\x1a\x0a\x00\x00\x00\x0d\x49\x48\x44\x52\x00\
|
||||
\x00\x00\x20\x00\x00\x00\x20\x08\x06\x00\x00\x00\x73\x7a\x7a\xf4\
|
||||
\x00\x00\x00\x09\x70\x48\x59\x73\x00\x00\x0b\x13\x00\x00\x0b\x13\
|
||||
\x01\x00\x9a\x9c\x18\x00\x00\x0a\x4f\x69\x43\x43\x50\x50\x68\x6f\
|
||||
\x74\x6f\x73\x68\x6f\x70\x20\x49\x43\x43\x20\x70\x72\x6f\x66\x69\
|
||||
\x6c\x65\x00\x00\x78\xda\x9d\x53\x67\x54\x53\xe9\x16\x3d\xf7\xde\
|
||||
\xf4\x42\x4b\x88\x80\x94\x4b\x6f\x52\x15\x08\x20\x52\x42\x8b\x80\
|
||||
\x14\x91\x26\x2a\x21\x09\x10\x4a\x88\x21\xa1\xd9\x15\x51\xc1\x11\
|
||||
\x45\x45\x04\x1b\xc8\xa0\x88\x03\x8e\x8e\x80\x8c\x15\x51\x2c\x0c\
|
||||
\x8a\x0a\xd8\x07\xe4\x21\xa2\x8e\x83\xa3\x88\x8a\xca\xfb\xe1\x7b\
|
||||
\xa3\x6b\xd6\xbc\xf7\xe6\xcd\xfe\xb5\xd7\x3e\xe7\xac\xf3\x9d\xb3\
|
||||
\xcf\x07\xc0\x08\x0c\x96\x48\x33\x51\x35\x80\x0c\xa9\x42\x1e\x11\
|
||||
\xe0\x83\xc7\xc4\xc6\xe1\xe4\x2e\x40\x81\x0a\x24\x70\x00\x10\x08\
|
||||
\xb3\x64\x21\x73\xfd\x23\x01\x00\xf8\x7e\x3c\x3c\x2b\x22\xc0\x07\
|
||||
\xbe\x00\x01\x78\xd3\x0b\x08\x00\xc0\x4d\x9b\xc0\x30\x1c\x87\xff\
|
||||
\x0f\xea\x42\x99\x5c\x01\x80\x84\x01\xc0\x74\x91\x38\x4b\x08\x80\
|
||||
\x14\x00\x40\x7a\x8e\x42\xa6\x00\x40\x46\x01\x80\x9d\x98\x26\x53\
|
||||
\x00\xa0\x04\x00\x60\xcb\x63\x62\xe3\x00\x50\x2d\x00\x60\x27\x7f\
|
||||
\xe6\xd3\x00\x80\x9d\xf8\x99\x7b\x01\x00\x5b\x94\x21\x15\x01\xa0\
|
||||
\x91\x00\x20\x13\x65\x88\x44\x00\x68\x3b\x00\xac\xcf\x56\x8a\x45\
|
||||
\x00\x58\x30\x00\x14\x66\x4b\xc4\x39\x00\xd8\x2d\x00\x30\x49\x57\
|
||||
\x66\x48\x00\xb0\xb7\x00\xc0\xce\x10\x0b\xb2\x00\x08\x0c\x00\x30\
|
||||
\x51\x88\x85\x29\x00\x04\x7b\x00\x60\xc8\x23\x23\x78\x00\x84\x99\
|
||||
\x00\x14\x46\xf2\x57\x3c\xf1\x2b\xae\x10\xe7\x2a\x00\x00\x78\x99\
|
||||
\xb2\x3c\xb9\x24\x39\x45\x81\x5b\x08\x2d\x71\x07\x57\x57\x2e\x1e\
|
||||
\x28\xce\x49\x17\x2b\x14\x36\x61\x02\x61\x9a\x40\x2e\xc2\x79\x99\
|
||||
\x19\x32\x81\x34\x0f\xe0\xf3\xcc\x00\x00\xa0\x91\x15\x11\xe0\x83\
|
||||
\xf3\xfd\x78\xce\x0e\xae\xce\xce\x36\x8e\xb6\x0e\x5f\x2d\xea\xbf\
|
||||
\x06\xff\x22\x62\x62\xe3\xfe\xe5\xcf\xab\x70\x40\x00\x00\xe1\x74\
|
||||
\x7e\xd1\xfe\x2c\x2f\xb3\x1a\x80\x3b\x06\x80\x6d\xfe\xa2\x25\xee\
|
||||
\x04\x68\x5e\x0b\xa0\x75\xf7\x8b\x66\xb2\x0f\x40\xb5\x00\xa0\xe9\
|
||||
\xda\x57\xf3\x70\xf8\x7e\x3c\x3c\x45\xa1\x90\xb9\xd9\xd9\xe5\xe4\
|
||||
\xe4\xd8\x4a\xc4\x42\x5b\x61\xca\x57\x7d\xfe\x67\xc2\x5f\xc0\x57\
|
||||
\xfd\x6c\xf9\x7e\x3c\xfc\xf7\xf5\xe0\xbe\xe2\x24\x81\x32\x5d\x81\
|
||||
\x47\x04\xf8\xe0\xc2\xcc\xf4\x4c\xa5\x1c\xcf\x92\x09\x84\x62\xdc\
|
||||
\xe6\x8f\x47\xfc\xb7\x0b\xff\xfc\x1d\xd3\x22\xc4\x49\x62\xb9\x58\
|
||||
\x2a\x14\xe3\x51\x12\x71\x8e\x44\x9a\x8c\xf3\x32\xa5\x22\x89\x42\
|
||||
\x92\x29\xc5\x25\xd2\xff\x64\xe2\xdf\x2c\xfb\x03\x3e\xdf\x35\x00\
|
||||
\xb0\x6a\x3e\x01\x7b\x91\x2d\xa8\x5d\x63\x03\xf6\x4b\x27\x10\x58\
|
||||
\x74\xc0\xe2\xf7\x00\x00\xf2\xbb\x6f\xc1\xd4\x28\x08\x03\x80\x68\
|
||||
\x83\xe1\xcf\x77\xff\xef\x3f\xfd\x47\xa0\x25\x00\x80\x66\x49\x92\
|
||||
\x71\x00\x00\x5e\x44\x24\x2e\x54\xca\xb3\x3f\xc7\x08\x00\x00\x44\
|
||||
\xa0\x81\x2a\xb0\x41\x1b\xf4\xc1\x18\x2c\xc0\x06\x1c\xc1\x05\xdc\
|
||||
\xc1\x0b\xfc\x60\x36\x84\x42\x24\xc4\xc2\x42\x10\x42\x0a\x64\x80\
|
||||
\x1c\x72\x60\x29\xac\x82\x42\x28\x86\xcd\xb0\x1d\x2a\x60\x2f\xd4\
|
||||
\x40\x1d\x34\xc0\x51\x68\x86\x93\x70\x0e\x2e\xc2\x55\xb8\x0e\x3d\
|
||||
\x70\x0f\xfa\x61\x08\x9e\xc1\x28\xbc\x81\x09\x04\x41\xc8\x08\x13\
|
||||
\x61\x21\xda\x88\x01\x62\x8a\x58\x23\x8e\x08\x17\x99\x85\xf8\x21\
|
||||
\xc1\x48\x04\x12\x8b\x24\x20\xc9\x88\x14\x51\x22\x4b\x91\x35\x48\
|
||||
\x31\x52\x8a\x54\x20\x55\x48\x1d\xf2\x3d\x72\x02\x39\x87\x5c\x46\
|
||||
\xba\x91\x3b\xc8\x00\x32\x82\xfc\x86\xbc\x47\x31\x94\x81\xb2\x51\
|
||||
\x3d\xd4\x0c\xb5\x43\xb9\xa8\x37\x1a\x84\x46\xa2\x0b\xd0\x64\x74\
|
||||
\x31\x9a\x8f\x16\xa0\x9b\xd0\x72\xb4\x1a\x3d\x8c\x36\xa1\xe7\xd0\
|
||||
\xab\x68\x0f\xda\x8f\x3e\x43\xc7\x30\xc0\xe8\x18\x07\x33\xc4\x6c\
|
||||
\x30\x2e\xc6\xc3\x42\xb1\x38\x2c\x09\x93\x63\xcb\xb1\x22\xac\x0c\
|
||||
\xab\xc6\x1a\xb0\x56\xac\x03\xbb\x89\xf5\x63\xcf\xb1\x77\x04\x12\
|
||||
\x81\x45\xc0\x09\x36\x04\x77\x42\x20\x61\x1e\x41\x48\x58\x4c\x58\
|
||||
\x4e\xd8\x48\xa8\x20\x1c\x24\x34\x11\xda\x09\x37\x09\x03\x84\x51\
|
||||
\xc2\x27\x22\x93\xa8\x4b\xb4\x26\xba\x11\xf9\xc4\x18\x62\x32\x31\
|
||||
\x87\x58\x48\x2c\x23\xd6\x12\x8f\x13\x2f\x10\x7b\x88\x43\xc4\x37\
|
||||
\x24\x12\x89\x43\x32\x27\xb9\x90\x02\x49\xb1\xa4\x54\xd2\x12\xd2\
|
||||
\x46\xd2\x6e\x52\x23\xe9\x2c\xa9\x9b\x34\x48\x1a\x23\x93\xc9\xda\
|
||||
\x64\x6b\xb2\x07\x39\x94\x2c\x20\x2b\xc8\x85\xe4\x9d\xe4\xc3\xe4\
|
||||
\x33\xe4\x1b\xe4\x21\xf2\x5b\x0a\x9d\x62\x40\x71\xa4\xf8\x53\xe2\
|
||||
\x28\x52\xca\x6a\x4a\x19\xe5\x10\xe5\x34\xe5\x06\x65\x98\x32\x41\
|
||||
\x55\xa3\x9a\x52\xdd\xa8\xa1\x54\x11\x35\x8f\x5a\x42\xad\xa1\xb6\
|
||||
\x52\xaf\x51\x87\xa8\x13\x34\x75\x9a\x39\xcd\x83\x16\x49\x4b\xa5\
|
||||
\xad\xa2\x95\xd3\x1a\x68\x17\x68\xf7\x69\xaf\xe8\x74\xba\x11\xdd\
|
||||
\x95\x1e\x4e\x97\xd0\x57\xd2\xcb\xe9\x47\xe8\x97\xe8\x03\xf4\x77\
|
||||
\x0c\x0d\x86\x15\x83\xc7\x88\x67\x28\x19\x9b\x18\x07\x18\x67\x19\
|
||||
\x77\x18\xaf\x98\x4c\xa6\x19\xd3\x8b\x19\xc7\x54\x30\x37\x31\xeb\
|
||||
\x98\xe7\x99\x0f\x99\x6f\x55\x58\x2a\xb6\x2a\x7c\x15\x91\xca\x0a\
|
||||
\x95\x4a\x95\x26\x95\x1b\x2a\x2f\x54\xa9\xaa\xa6\xaa\xde\xaa\x0b\
|
||||
\x55\xf3\x55\xcb\x54\x8f\xa9\x5e\x53\x7d\xae\x46\x55\x33\x53\xe3\
|
||||
\xa9\x09\xd4\x96\xab\x55\xaa\x9d\x50\xeb\x53\x1b\x53\x67\xa9\x3b\
|
||||
\xa8\x87\xaa\x67\xa8\x6f\x54\x3f\xa4\x7e\x59\xfd\x89\x06\x59\xc3\
|
||||
\x4c\xc3\x4f\x43\xa4\x51\xa0\xb1\x5f\xe3\xbc\xc6\x20\x0b\x63\x19\
|
||||
\xb3\x78\x2c\x21\x6b\x0d\xab\x86\x75\x81\x35\xc4\x26\xb1\xcd\xd9\
|
||||
\x7c\x76\x2a\xbb\x98\xfd\x1d\xbb\x8b\x3d\xaa\xa9\xa1\x39\x43\x33\
|
||||
\x4a\x33\x57\xb3\x52\xf3\x94\x66\x3f\x07\xe3\x98\x71\xf8\x9c\x74\
|
||||
\x4e\x09\xe7\x28\xa7\x97\xf3\x7e\x8a\xde\x14\xef\x29\xe2\x29\x1b\
|
||||
\xa6\x34\x4c\xb9\x31\x65\x5c\x6b\xaa\x96\x97\x96\x58\xab\x48\xab\
|
||||
\x51\xab\x47\xeb\xbd\x36\xae\xed\xa7\x9d\xa6\xbd\x45\xbb\x59\xfb\
|
||||
\x81\x0e\x41\xc7\x4a\x27\x5c\x27\x47\x67\x8f\xce\x05\x9d\xe7\x53\
|
||||
\xd9\x53\xdd\xa7\x0a\xa7\x16\x4d\x3d\x3a\xf5\xae\x2e\xaa\x6b\xa5\
|
||||
\x1b\xa1\xbb\x44\x77\xbf\x6e\xa7\xee\x98\x9e\xbe\x5e\x80\x9e\x4c\
|
||||
\x6f\xa7\xde\x79\xbd\xe7\xfa\x1c\x7d\x2f\xfd\x54\xfd\x6d\xfa\xa7\
|
||||
\xf5\x47\x0c\x58\x06\xb3\x0c\x24\x06\xdb\x0c\xce\x18\x3c\xc5\x35\
|
||||
\x71\x6f\x3c\x1d\x2f\xc7\xdb\xf1\x51\x43\x5d\xc3\x40\x43\xa5\x61\
|
||||
\x95\x61\x97\xe1\x84\x91\xb9\xd1\x3c\xa3\xd5\x46\x8d\x46\x0f\x8c\
|
||||
\x69\xc6\x5c\xe3\x24\xe3\x6d\xc6\x6d\xc6\xa3\x26\x06\x26\x21\x26\
|
||||
\x4b\x4d\xea\x4d\xee\x9a\x52\x4d\xb9\xa6\x29\xa6\x3b\x4c\x3b\x4c\
|
||||
\xc7\xcd\xcc\xcd\xa2\xcd\xd6\x99\x35\x9b\x3d\x31\xd7\x32\xe7\x9b\
|
||||
\xe7\x9b\xd7\x9b\xdf\xb7\x60\x5a\x78\x5a\x2c\xb6\xa8\xb6\xb8\x65\
|
||||
\x49\xb2\xe4\x5a\xa6\x59\xee\xb6\xbc\x6e\x85\x5a\x39\x59\xa5\x58\
|
||||
\x55\x5a\x5d\xb3\x46\xad\x9d\xad\x25\xd6\xbb\xad\xbb\xa7\x11\xa7\
|
||||
\xb9\x4e\x93\x4e\xab\x9e\xd6\x67\xc3\xb0\xf1\xb6\xc9\xb6\xa9\xb7\
|
||||
\x19\xb0\xe5\xd8\x06\xdb\xae\xb6\x6d\xb6\x7d\x61\x67\x62\x17\x67\
|
||||
\xb7\xc5\xae\xc3\xee\x93\xbd\x93\x7d\xba\x7d\x8d\xfd\x3d\x07\x0d\
|
||||
\x87\xd9\x0e\xab\x1d\x5a\x1d\x7e\x73\xb4\x72\x14\x3a\x56\x3a\xde\
|
||||
\x9a\xce\x9c\xee\x3f\x7d\xc5\xf4\x96\xe9\x2f\x67\x58\xcf\x10\xcf\
|
||||
\xd8\x33\xe3\xb6\x13\xcb\x29\xc4\x69\x9d\x53\x9b\xd3\x47\x67\x17\
|
||||
\x67\xb9\x73\x83\xf3\x88\x8b\x89\x4b\x82\xcb\x2e\x97\x3e\x2e\x9b\
|
||||
\x1b\xc6\xdd\xc8\xbd\xe4\x4a\x74\xf5\x71\x5d\xe1\x7a\xd2\xf5\x9d\
|
||||
\x9b\xb3\x9b\xc2\xed\xa8\xdb\xaf\xee\x36\xee\x69\xee\x87\xdc\x9f\
|
||||
\xcc\x34\x9f\x29\x9e\x59\x33\x73\xd0\xc3\xc8\x43\xe0\x51\xe5\xd1\
|
||||
\x3f\x0b\x9f\x95\x30\x6b\xdf\xac\x7e\x4f\x43\x4f\x81\x67\xb5\xe7\
|
||||
\x23\x2f\x63\x2f\x91\x57\xad\xd7\xb0\xb7\xa5\x77\xaa\xf7\x61\xef\
|
||||
\x17\x3e\xf6\x3e\x72\x9f\xe3\x3e\xe3\x3c\x37\xde\x32\xde\x59\x5f\
|
||||
\xcc\x37\xc0\xb7\xc8\xb7\xcb\x4f\xc3\x6f\x9e\x5f\x85\xdf\x43\x7f\
|
||||
\x23\xff\x64\xff\x7a\xff\xd1\x00\xa7\x80\x25\x01\x67\x03\x89\x81\
|
||||
\x41\x81\x5b\x02\xfb\xf8\x7a\x7c\x21\xbf\x8e\x3f\x3a\xdb\x65\xf6\
|
||||
\xb2\xd9\xed\x41\x8c\xa0\xb9\x41\x15\x41\x8f\x82\xad\x82\xe5\xc1\
|
||||
\xad\x21\x68\xc8\xec\x90\xad\x21\xf7\xe7\x98\xce\x91\xce\x69\x0e\
|
||||
\x85\x50\x7e\xe8\xd6\xd0\x07\x61\xe6\x61\x8b\xc3\x7e\x0c\x27\x85\
|
||||
\x87\x85\x57\x86\x3f\x8e\x70\x88\x58\x1a\xd1\x31\x97\x35\x77\xd1\
|
||||
\xdc\x43\x73\xdf\x44\xfa\x44\x96\x44\xde\x9b\x67\x31\x4f\x39\xaf\
|
||||
\x2d\x4a\x35\x2a\x3e\xaa\x2e\x6a\x3c\xda\x37\xba\x34\xba\x3f\xc6\
|
||||
\x2e\x66\x59\xcc\xd5\x58\x9d\x58\x49\x6c\x4b\x1c\x39\x2e\x2a\xae\
|
||||
\x36\x6e\x6c\xbe\xdf\xfc\xed\xf3\x87\xe2\x9d\xe2\x0b\xe3\x7b\x17\
|
||||
\x98\x2f\xc8\x5d\x70\x79\xa1\xce\xc2\xf4\x85\xa7\x16\xa9\x2e\x12\
|
||||
\x2c\x3a\x96\x40\x4c\x88\x4e\x38\x94\xf0\x41\x10\x2a\xa8\x16\x8c\
|
||||
\x25\xf2\x13\x77\x25\x8e\x0a\x79\xc2\x1d\xc2\x67\x22\x2f\xd1\x36\
|
||||
\xd1\x88\xd8\x43\x5c\x2a\x1e\x4e\xf2\x48\x2a\x4d\x7a\x92\xec\x91\
|
||||
\xbc\x35\x79\x24\xc5\x33\xa5\x2c\xe5\xb9\x84\x27\xa9\x90\xbc\x4c\
|
||||
\x0d\x4c\xdd\x9b\x3a\x9e\x16\x9a\x76\x20\x6d\x32\x3d\x3a\xbd\x31\
|
||||
\x83\x92\x91\x90\x71\x42\xaa\x21\x4d\x93\xb6\x67\xea\x67\xe6\x66\
|
||||
\x76\xcb\xac\x65\x85\xb2\xfe\xc5\x6e\x8b\xb7\x2f\x1e\x95\x07\xc9\
|
||||
\x6b\xb3\x90\xac\x05\x59\x2d\x0a\xb6\x42\xa6\xe8\x54\x5a\x28\xd7\
|
||||
\x2a\x07\xb2\x67\x65\x57\x66\xbf\xcd\x89\xca\x39\x96\xab\x9e\x2b\
|
||||
\xcd\xed\xcc\xb3\xca\xdb\x90\x37\x9c\xef\x9f\xff\xed\x12\xc2\x12\
|
||||
\xe1\x92\xb6\xa5\x86\x4b\x57\x2d\x1d\x58\xe6\xbd\xac\x6a\x39\xb2\
|
||||
\x3c\x71\x79\xdb\x0a\xe3\x15\x05\x2b\x86\x56\x06\xac\x3c\xb8\x8a\
|
||||
\xb6\x2a\x6d\xd5\x4f\xab\xed\x57\x97\xae\x7e\xbd\x26\x7a\x4d\x6b\
|
||||
\x81\x5e\xc1\xca\x82\xc1\xb5\x01\x6b\xeb\x0b\x55\x0a\xe5\x85\x7d\
|
||||
\xeb\xdc\xd7\xed\x5d\x4f\x58\x2f\x59\xdf\xb5\x61\xfa\x86\x9d\x1b\
|
||||
\x3e\x15\x89\x8a\xae\x14\xdb\x17\x97\x15\x7f\xd8\x28\xdc\x78\xe5\
|
||||
\x1b\x87\x6f\xca\xbf\x99\xdc\x94\xb4\xa9\xab\xc4\xb9\x64\xcf\x66\
|
||||
\xd2\x66\xe9\xe6\xde\x2d\x9e\x5b\x0e\x96\xaa\x97\xe6\x97\x0e\x6e\
|
||||
\x0d\xd9\xda\xb4\x0d\xdf\x56\xb4\xed\xf5\xf6\x45\xdb\x2f\x97\xcd\
|
||||
\x28\xdb\xbb\x83\xb6\x43\xb9\xa3\xbf\x3c\xb8\xbc\x65\xa7\xc9\xce\
|
||||
\xcd\x3b\x3f\x54\xa4\x54\xf4\x54\xfa\x54\x36\xee\xd2\xdd\xb5\x61\
|
||||
\xd7\xf8\x6e\xd1\xee\x1b\x7b\xbc\xf6\x34\xec\xd5\xdb\x5b\xbc\xf7\
|
||||
\xfd\x3e\xc9\xbe\xdb\x55\x01\x55\x4d\xd5\x66\xd5\x65\xfb\x49\xfb\
|
||||
\xb3\xf7\x3f\xae\x89\xaa\xe9\xf8\x96\xfb\x6d\x5d\xad\x4e\x6d\x71\
|
||||
\xed\xc7\x03\xd2\x03\xfd\x07\x23\x0e\xb6\xd7\xb9\xd4\xd5\x1d\xd2\
|
||||
\x3d\x54\x52\x8f\xd6\x2b\xeb\x47\x0e\xc7\x1f\xbe\xfe\x9d\xef\x77\
|
||||
\x2d\x0d\x36\x0d\x55\x8d\x9c\xc6\xe2\x23\x70\x44\x79\xe4\xe9\xf7\
|
||||
\x09\xdf\xf7\x1e\x0d\x3a\xda\x76\x8c\x7b\xac\xe1\x07\xd3\x1f\x76\
|
||||
\x1d\x67\x1d\x2f\x6a\x42\x9a\xf2\x9a\x46\x9b\x53\x9a\xfb\x5b\x62\
|
||||
\x5b\xba\x4f\xcc\x3e\xd1\xd6\xea\xde\x7a\xfc\x47\xdb\x1f\x0f\x9c\
|
||||
\x34\x3c\x59\x79\x4a\xf3\x54\xc9\x69\xda\xe9\x82\xd3\x93\x67\xf2\
|
||||
\xcf\x8c\x9d\x95\x9d\x7d\x7e\x2e\xf9\xdc\x60\xdb\xa2\xb6\x7b\xe7\
|
||||
\x63\xce\xdf\x6a\x0f\x6f\xef\xba\x10\x74\xe1\xd2\x45\xff\x8b\xe7\
|
||||
\x3b\xbc\x3b\xce\x5c\xf2\xb8\x74\xf2\xb2\xdb\xe5\x13\x57\xb8\x57\
|
||||
\x9a\xaf\x3a\x5f\x6d\xea\x74\xea\x3c\xfe\x93\xd3\x4f\xc7\xbb\x9c\
|
||||
\xbb\x9a\xae\xb9\x5c\x6b\xb9\xee\x7a\xbd\xb5\x7b\x66\xf7\xe9\x1b\
|
||||
\x9e\x37\xce\xdd\xf4\xbd\x79\xf1\x16\xff\xd6\xd5\x9e\x39\x3d\xdd\
|
||||
\xbd\xf3\x7a\x6f\xf7\xc5\xf7\xf5\xdf\x16\xdd\x7e\x72\x27\xfd\xce\
|
||||
\xcb\xbb\xd9\x77\x27\xee\xad\xbc\x4f\xbc\x5f\xf4\x40\xed\x41\xd9\
|
||||
\x43\xdd\x87\xd5\x3f\x5b\xfe\xdc\xd8\xef\xdc\x7f\x6a\xc0\x77\xa0\
|
||||
\xf3\xd1\xdc\x47\xf7\x06\x85\x83\xcf\xfe\x91\xf5\x8f\x0f\x43\x05\
|
||||
\x8f\x99\x8f\xcb\x86\x0d\x86\xeb\x9e\x38\x3e\x39\x39\xe2\x3f\x72\
|
||||
\xfd\xe9\xfc\xa7\x43\xcf\x64\xcf\x26\x9e\x17\xfe\xa2\xfe\xcb\xae\
|
||||
\x17\x16\x2f\x7e\xf8\xd5\xeb\xd7\xce\xd1\x98\xd1\xa1\x97\xf2\x97\
|
||||
\x93\xbf\x6d\x7c\xa5\xfd\xea\xc0\xeb\x19\xaf\xdb\xc6\xc2\xc6\x1e\
|
||||
\xbe\xc9\x78\x33\x31\x5e\xf4\x56\xfb\xed\xc1\x77\xdc\x77\x1d\xef\
|
||||
\xa3\xdf\x0f\x4f\xe4\x7c\x20\x7f\x28\xff\x68\xf9\xb1\xf5\x53\xd0\
|
||||
\xa7\xfb\x93\x19\x93\x93\xff\x04\x03\x98\xf3\xfc\x63\x33\x2d\xdb\
|
||||
\x00\x00\x00\x04\x67\x41\x4d\x41\x00\x00\xb1\x8e\x7c\xfb\x51\x93\
|
||||
\x00\x00\x00\x20\x63\x48\x52\x4d\x00\x00\x7a\x25\x00\x00\x80\x83\
|
||||
\x00\x00\xf9\xff\x00\x00\x80\xe9\x00\x00\x75\x30\x00\x00\xea\x60\
|
||||
\x00\x00\x3a\x98\x00\x00\x17\x6f\x92\x5f\xc5\x46\x00\x00\x08\x59\
|
||||
\x49\x44\x41\x54\x78\xda\x94\x96\x6b\x8c\x5d\x55\x15\xc7\xff\x6b\
|
||||
\xef\x7d\xce\x7d\xcc\xb3\x33\x6d\xa7\xcc\x14\xda\x02\xa6\x29\x05\
|
||||
\x94\x47\xc0\x58\x21\x3e\x0a\x58\x8d\x31\xe0\x23\x01\x0b\xa2\x41\
|
||||
\x93\x0a\x24\x7c\x30\xd1\x26\x12\x3f\xa0\x51\x1a\x0d\x69\x42\x24\
|
||||
\xa4\x31\xea\x07\x0d\x11\xf0\x85\xb1\x15\x1a\x11\x4a\x10\x11\x0a\
|
||||
\x6d\x41\xa6\x33\x8c\x2d\xd3\x17\x6d\xe7\xce\xdc\xd7\xb9\xf7\x9c\
|
||||
\xb3\xf7\x5e\xcb\x0f\xe7\xce\xbd\x73\x3b\x6d\xd5\x7d\xb3\x32\x37\
|
||||
\x37\x27\xf7\xff\x5b\xff\xfd\x5f\xeb\x0e\xe1\x2c\x67\xed\xda\xb5\
|
||||
\xd7\x6f\xd9\xb2\xe5\x9b\xd6\x5a\xcf\xcc\x22\x22\x60\x66\x88\x48\
|
||||
\xfb\x19\x22\x6a\xff\x15\x11\x28\xa5\xc2\xa9\xa9\xa9\xf1\x1d\x3b\
|
||||
\x76\xfc\x60\xfe\x19\xa5\x34\x0a\x85\x1c\xea\xf5\x08\xe7\x3a\x04\
|
||||
\x00\x03\x03\x3d\xa3\x77\xdf\x75\xfd\x5d\x7f\xde\xb9\xff\xe9\xc9\
|
||||
\x77\x67\x26\x37\x6e\xdc\xf8\x8d\x5d\xbb\x76\x3d\xde\x68\x34\x90\
|
||||
\xa6\x29\xbc\xf7\xed\x9a\x87\x50\x4a\xb5\xcb\x7b\x0f\xe7\x1c\xf6\
|
||||
\xec\xd9\xb3\x77\xf3\xe6\xcd\xd7\x02\xa0\xdb\x6e\xbd\x66\xb3\xd6\
|
||||
\x1c\xfd\xee\xf7\x07\x9e\xb6\xd6\x9e\x13\xc0\x00\xc0\xc8\xc8\x92\
|
||||
\x2b\x1e\xf9\xc9\x75\x3f\x9c\x7e\xef\xe0\xe1\xc9\x77\x31\xe9\x9c\
|
||||
\xa3\x4a\xa5\x8a\x28\xaa\xc3\x5a\x0b\xef\x3d\x98\xb9\xed\x42\xab\
|
||||
\x63\x10\x51\x17\x40\x14\x45\x1e\x80\x00\xe8\xbf\xff\xbe\xeb\xbf\
|
||||
\x05\x7f\xf8\xc4\x93\x4f\xbd\xf9\x34\xce\x73\x0c\x00\xb0\xf7\x36\
|
||||
\x8d\x66\xe0\x5d\xec\x00\x40\x81\xe3\x1c\x59\x58\x72\x80\xa4\x50\
|
||||
\xe2\xe1\x39\x13\x11\x11\x08\x00\xf2\x1d\x17\xc4\x7b\x28\xe7\xa0\
|
||||
\x7c\xc2\xad\xef\x4d\x7d\x5c\x91\x4a\xf9\xa4\xcb\x78\xce\x0b\x40\
|
||||
\x83\x03\x57\x7c\xf9\xce\x47\x5f\xbc\x06\xa5\xb1\xb1\xaf\x2d\xb9\
|
||||
\x21\xfa\x70\x6d\xf5\xca\x0f\xfe\x78\x77\x79\x41\xf7\x59\xd7\xcc\
|
||||
\x59\x7f\x2d\x04\x10\x65\x1f\x88\x30\x98\x09\xa7\x4a\x6b\x56\x8f\
|
||||
\xde\xbc\x75\xbb\x73\x1c\x3e\x39\x71\xe9\x68\xda\xbc\x72\x79\xb8\
|
||||
\x8c\x6e\x00\xb0\xe7\x3c\x19\x08\x2e\xf9\xf8\x83\xcf\xbe\x58\xed\
|
||||
\x5d\x35\x5a\x6b\x26\x30\x81\x82\xb5\x16\x51\xd4\xc8\x82\x46\xad\
|
||||
\xa0\x74\x22\x73\xce\x6f\x32\x5a\xa3\x50\x28\x80\x88\x50\xaf\xd4\
|
||||
\x40\x36\x41\x65\xf7\xa3\x5b\xe7\xf6\xff\xfa\x47\xe7\x74\x80\x00\
|
||||
\x1d\xc5\x0e\x35\xe3\x51\x6e\x38\x18\x24\x59\x9b\x44\x99\x79\xb2\
|
||||
\xd0\xc4\x6e\x3b\xb5\xc4\x58\x93\xfc\x0c\x79\xaa\x42\xeb\x02\x02\
|
||||
\x13\x42\x8b\x01\xa0\x90\x72\x02\xc7\x31\xcc\x75\x07\xbf\xfe\xf9\
|
||||
\x7b\xd7\x5e\xad\x48\x6d\x51\x4a\x97\xce\x04\xd0\x00\x07\x23\x4b\
|
||||
\x07\xaf\xf8\xd2\xc7\xe8\xb2\x53\xfb\x5e\xd8\x57\xaa\xf5\xf5\xb2\
|
||||
\xf3\x21\x37\x22\x70\xb3\xd1\xa9\xc6\xe2\xba\x44\x3d\x87\xf5\xfd\
|
||||
\xff\xc2\x48\xaf\x60\xe5\xa0\xc6\xaa\xa1\x1c\x56\x0f\x17\xb0\x72\
|
||||
\x40\x63\x79\xd1\x62\x38\x1f\xa3\xa7\x18\x2e\xc9\x99\xfc\x7a\x52\
|
||||
\xa4\x53\x1b\x3f\x9b\x5d\x60\xe7\x65\x00\x54\xef\xdc\x30\x4d\xf7\
|
||||
\x7d\x6a\x0e\x4b\x8f\xbf\xa4\x1f\x7a\xe5\xa2\x0a\x17\x47\x7a\x45\
|
||||
\xc9\x82\x8e\xe5\xac\x59\xba\xff\x0b\x9b\xb0\xe1\xf2\xdb\xdb\xe3\
|
||||
\x29\xe0\x2c\x0f\xad\xd0\x32\x5b\x78\x4e\x21\xe4\x30\x39\x3e\xfd\
|
||||
\xd1\x43\x87\x0e\x43\x6b\xbd\x68\x0a\x54\xcf\x40\xdf\x60\x2a\x80\
|
||||
\x0a\x7d\x80\x53\x47\xa7\x7b\xfb\x86\xc7\xa2\x62\x5f\x4b\x78\x5e\
|
||||
\x5c\xce\xc8\x81\x00\x3a\x07\xa7\x2a\x60\xca\x9e\x13\x78\xb0\xf8\
|
||||
\x16\x80\x05\x8b\x85\xe7\x04\x1e\x09\x04\xec\xfa\xf3\x2b\xa0\x34\
|
||||
\x2d\x1e\x43\x61\x11\x52\x0a\x3a\x08\xb4\x1a\x5a\xb1\xd4\xe6\x8b\
|
||||
\x50\xa4\x01\x9b\x74\xf4\x88\x16\xe5\xa0\x16\x45\x48\xac\x05\x8b\
|
||||
\x6f\x75\xce\x10\xf1\x99\xb0\x38\x78\x4e\x5b\x00\x29\xaa\xb5\x8a\
|
||||
\x2d\xcd\x35\xa0\xcd\x62\x00\xca\xe5\x03\x5d\xe8\x57\xe8\x29\x08\
|
||||
\x90\xc4\xf5\x00\x04\xaf\x0d\x48\x13\x48\x65\x63\x20\x36\xcd\xdc\
|
||||
\x58\x10\xc8\x6a\x9c\x22\xf5\x4d\x30\x3b\x88\x78\x78\xf1\x10\x71\
|
||||
\xf0\xe2\x32\xfb\x5b\x0e\x38\x49\x51\xad\x57\xa3\x5a\x3d\x3a\x2b\
|
||||
\x00\xef\xdb\x77\x74\xdf\xce\x67\x8a\x7d\xaf\xbf\x61\x0e\x99\x20\
|
||||
\x5c\xa7\x54\x00\xa3\x35\x44\xb8\xd5\xb9\x00\xa2\x16\xe5\xa0\x16\
|
||||
\x3b\x24\xb6\x06\x16\x0b\x16\x06\x8b\x6b\x97\x67\x0b\x2f\x29\x3c\
|
||||
\xa7\x70\x3e\x41\xb5\x52\x2d\x47\x71\x03\xfa\x2c\x57\x90\x3c\xb2\
|
||||
\x7d\xf7\xd6\x47\xb6\xc3\x99\x70\x60\xdd\xa5\xb7\xf7\xfe\xc9\x87\
|
||||
\x06\xda\x28\xb0\x57\x9d\x31\x2f\xe6\x16\xed\x81\x84\x9b\x88\x6d\
|
||||
\x15\x8c\x79\x07\x5c\xe6\x00\x77\xae\x80\x25\x41\x62\x63\x04\x26\
|
||||
\xac\x2d\x1b\x1a\x05\x29\x59\x04\xe0\x5a\x05\x66\xeb\xb9\x32\x37\
|
||||
\x13\xf6\x5f\x78\x51\x92\xcf\x65\x5d\x03\x10\x11\x10\x51\xfb\x17\
|
||||
\x70\xfe\x34\x9b\x11\x52\x1f\xc1\x4b\x92\x85\x8f\x5b\xdd\x8b\xcd\
|
||||
\x20\x38\x05\xc3\xc2\xba\x04\xa5\x39\x6f\x1b\xe5\x59\x28\xdd\x89\
|
||||
\x32\xc3\x65\x21\x6c\x2f\x05\x1d\x84\xe1\xd2\xe5\x23\xbe\x90\x83\
|
||||
\xd1\x04\xcb\xd4\xda\x49\x04\x78\x5e\xb4\x88\x9a\xa9\x43\x6c\x6b\
|
||||
\xf0\x88\x21\xec\xb2\xf4\xcf\x8b\x8b\x03\xb7\x01\x3c\x6a\xf5\xd8\
|
||||
\x55\x2b\xdc\x02\x50\xf0\x54\x87\xa3\xd9\x6e\x00\xf6\xce\xfa\xb9\
|
||||
\xb9\x59\x5d\x1c\x1b\x8b\xc3\x10\x4a\xe9\x4e\xf0\x94\x5a\xb4\x07\
|
||||
\xa2\x54\x10\x27\x75\xb0\x6e\x80\xb9\x13\xbe\x79\x17\x98\x1d\x84\
|
||||
\x3c\x9c\x13\x24\x89\x8d\x9d\x15\x28\x26\x88\x69\x40\x4c\x15\x04\
|
||||
\xea\x06\x20\xa5\xb5\x14\x8b\xc5\x9a\x08\x92\xc4\xa3\x3f\xa4\xf3\
|
||||
\x6d\x7f\x34\x52\x8d\x38\xad\x43\x82\x7a\x6b\xf1\xb8\x56\x20\x5d\
|
||||
\x2b\x0f\x1e\xa4\x08\xd6\x02\x69\x62\xeb\xce\x03\x3a\x48\x40\x41\
|
||||
\xd4\xce\x53\x17\x80\x40\x10\xc7\x4e\xd8\x4b\x36\x7a\x9a\x20\x72\
|
||||
\x6e\x84\x58\x4c\x96\x01\xaa\xc0\xf3\xc2\xe5\xe3\x00\x08\x08\x0a\
|
||||
\x9a\x34\xac\x55\xb0\x29\x9f\xa6\x30\x01\xe5\x9a\x5d\x61\xee\x02\
|
||||
\x00\x33\x23\x6d\xc4\x46\x18\xa9\x07\x6a\xcd\xee\x3b\xef\xe5\xc3\
|
||||
\xc8\xcb\x0c\x04\x0a\x1e\x01\x1c\x4a\x48\x5c\x1d\x29\x97\xe0\xbc\
|
||||
\x6d\xd9\x6e\xc1\x60\x28\x68\x28\x32\x30\x30\x48\xd2\x00\x64\xf8\
|
||||
\x32\x13\xd8\x9b\x45\xa8\x28\x59\x57\x29\x11\x3d\xdf\x7d\x05\xda\
|
||||
\x68\xea\x1b\x1a\x4c\x75\xf6\xb1\x70\x07\xa0\x47\x8e\xe3\xb2\xe6\
|
||||
\xc3\xd0\x1c\x21\x9f\x2b\xa2\x98\xef\xc3\x50\xfe\x02\x24\x69\x0c\
|
||||
\x1f\x36\xe1\x99\x5b\xb6\x33\x14\xe9\xae\x62\x06\x8a\x85\xde\x07\
|
||||
\x44\xbb\x07\xa2\x46\x0d\xd6\x26\x50\x0a\xd0\x46\x6d\xed\x0e\xa1\
|
||||
\x4b\x2c\x97\xa6\x4f\xe4\xfb\x46\x56\xd6\x25\x6c\xaf\xdf\x1e\x2a\
|
||||
\x61\x75\xe1\x08\x3e\x79\xf5\x06\x04\x79\x01\x7b\x81\x22\x05\x65\
|
||||
\x14\x52\x7d\x0c\x9e\x1d\x58\xb2\x29\xe9\x08\x1b\x28\x32\x20\x18\
|
||||
\x14\x7a\x14\xd6\x5e\x39\x26\x83\xbd\x17\x90\xf7\x0e\xda\x10\xe6\
|
||||
\xe6\xaa\xb0\x51\x6e\x5d\x17\x80\xd2\x61\x40\x43\x17\x8c\x24\x26\
|
||||
\x5c\xb0\xfb\x81\x48\x86\xf1\x76\x73\x18\xc5\x83\x25\x7c\xe6\x13\
|
||||
\xaf\xa2\xd0\x9f\x20\x89\x53\x24\xdc\x80\x75\x09\x3c\x33\x04\x0c\
|
||||
\x05\xb5\x40\x5c\x43\xa9\x0c\x20\x5f\x08\xd0\xb7\xae\x44\x46\xd5\
|
||||
\x11\xe6\x02\xc4\x15\x85\xf7\xf7\xfb\x27\xae\x5a\xbb\xf1\x1e\xd5\
|
||||
\x1d\x01\xe7\xa8\x51\x8b\x72\x64\x40\x26\x0f\x0a\x5a\x65\x42\x40\
|
||||
\x80\x57\xa3\x4f\xe3\x89\x3f\xae\xc7\xe9\x13\x35\x38\xd4\x61\x6d\
|
||||
\xdc\x0e\x5c\x26\x9e\x75\xad\x94\x81\x52\x01\x34\x99\x76\x81\x09\
|
||||
\xa4\x18\x95\x19\x8b\xbf\x3f\x53\xff\x4d\x34\xab\xbf\x02\xc5\xb6\
|
||||
\xdb\x01\xa5\x11\xd5\x4b\x47\xe3\x89\x3d\xb3\x4a\xbc\xcf\x46\xc1\
|
||||
\x33\xe5\x06\x96\x05\x63\x97\xae\x27\x66\x8c\xdb\x1b\xd1\x7c\xaa\
|
||||
\x86\x5b\x36\xbd\x84\x25\xa3\x1e\x2e\xe1\xec\x3a\xe6\xc5\x5b\xa5\
|
||||
\xdb\xef\x03\x28\x32\x08\xc2\x00\xd1\xac\xc2\x1b\x7f\xb1\xbf\xac\
|
||||
\x9c\xb6\xf7\x0c\x0d\xc3\x41\xa4\x6b\xcc\x09\x40\x1e\x80\xea\x9a\
|
||||
\x4c\x00\xc1\x8a\x0f\xdd\x31\xbc\x65\xdb\x0e\x93\xa6\x90\x52\x84\
|
||||
\xca\xd1\x0a\x56\xca\x0b\xb8\xf5\x8e\x7f\x60\xd9\x2a\x0d\x4e\x75\
|
||||
\xa7\xf3\x79\x00\x15\xb4\x41\xc2\x5c\x80\xea\x29\xc2\xfe\xe7\xf8\
|
||||
\xf1\xda\x9c\xdb\x02\xed\x64\x68\xc9\x52\xdc\xb8\x61\x23\xf4\x19\
|
||||
\xa3\xed\x00\xd8\x33\xcb\x0c\x5e\x74\x2d\x3e\x72\xdb\x67\x53\x2b\
|
||||
\x48\x1a\x40\xad\xcc\x98\x99\x59\x85\x99\xb7\xde\x3f\xb4\xe6\x03\
|
||||
\x95\x25\xfd\xc3\x01\xc0\x1d\x00\xad\xb2\xce\xe7\xc5\xcb\x27\x08\
|
||||
\xaf\xef\xb4\x8f\x26\x11\xdd\x9b\xef\xd1\x20\x02\x6a\xe5\x26\xde\
|
||||
\x7a\x63\xea\x8c\x3d\x70\xf6\xa3\xd2\xd9\xa3\xd3\x9b\xd4\xe9\xd3\
|
||||
\x97\xac\xbf\x70\x59\x5a\xd1\x9c\x5e\x4c\x42\x69\xaa\x77\x3e\x35\
|
||||
\xf4\xcc\xbe\x5d\xef\x4d\x5d\x75\x8b\xde\xbe\xe2\x62\x03\xb1\x1d\
|
||||
\xdb\xe7\xc5\x67\x8f\x11\xf6\xef\x76\xdb\xc4\xa9\x6f\x3b\x97\xe2\
|
||||
\xdf\x07\x4e\xe2\xf0\xd4\x09\x9c\x3c\x3e\x0b\xef\xf8\x7f\x02\x00\
|
||||
\x1a\xc7\x5f\xfb\xea\xea\x53\x6f\x7e\xee\x8b\x37\xde\xe4\xea\x41\
|
||||
\x53\x51\x8e\x55\xbe\x81\x9b\xfe\x7a\xe0\xb7\x49\x43\x5e\x98\x78\
|
||||
\xc9\xd8\x5c\x10\xfc\x74\xf9\x2a\x03\x76\x2d\xdb\xf3\x01\xe6\x8e\
|
||||
\x69\xbc\xfd\xbc\xff\x7e\x75\x36\x7e\x70\x6a\xe2\x28\xc6\x0f\x4c\
|
||||
\xa3\xd9\x48\x16\xff\x4b\xf6\x5f\x0e\x03\xe0\x44\x28\xb5\x89\xaf\
|
||||
\xd6\x63\xae\x42\xbc\x2d\x0a\x62\x16\x9d\xbc\xbc\x73\x1c\x17\xae\
|
||||
\x19\x7a\x2c\xaa\x8c\x36\x6f\xb8\x6d\xe9\x8e\x91\x35\xca\x10\x19\
|
||||
\x94\x8f\x05\x78\xe5\x0f\xd5\xef\xbc\xbd\xf7\xbd\x87\x27\xdf\x39\
|
||||
\xb2\x48\xf8\xff\x01\x00\x00\xb6\xd6\x9e\x4a\x6d\x7a\x24\x4e\xe2\
|
||||
\xb2\x77\x8d\xc8\xbb\x64\xae\x56\x6b\x24\x8d\x7a\xda\x73\xf0\xc0\
|
||||
\xfb\x34\x71\xe0\xe4\x2f\x0e\xbd\xb3\xca\xdc\xfd\xdd\xcb\x1f\x0b\
|
||||
\x43\x63\x7e\xb5\xed\xe0\xf7\x5e\x7f\x79\x62\x9b\x73\xae\xb7\xfd\
|
||||
\xf3\x9f\x95\x6f\x15\x03\x90\xff\x15\xc0\x36\x1a\xcd\x37\xcb\xe5\
|
||||
\x72\xed\xb5\x7f\xee\xe5\xc9\x89\x71\x2e\x97\x67\xa2\x77\xc6\xa7\
|
||||
\xd7\x00\x58\x06\x40\x0b\x84\xde\xda\x7b\x78\xfc\xe7\x0f\x61\x7b\
|
||||
\x2e\x17\x0c\xed\x7d\x65\xf2\x6f\x00\x36\x2d\x10\x9f\x17\x4e\x01\
|
||||
\xc4\x00\x4e\x03\x38\xf2\x9f\x01\x00\x7c\x97\x4a\xe1\x34\x7b\x75\
|
||||
\xb6\x00\x00\x00\x00\x49\x45\x4e\x44\xae\x42\x60\x82\
|
||||
"
|
||||
|
||||
qt_resource_name = "\
|
||||
\x00\x07\
|
||||
\x07\x3b\xe0\xb3\
|
||||
\x00\x70\
|
||||
\x00\x6c\x00\x75\x00\x67\x00\x69\x00\x6e\x00\x73\
|
||||
\x00\x09\
|
||||
\x0a\xa8\xd2\x62\
|
||||
\x00\x69\
|
||||
\x00\x6e\x00\x73\x00\x74\x00\x61\x00\x6c\x00\x6c\x00\x65\x00\x72\
|
||||
\x00\x10\
|
||||
\x05\xc8\x49\xa7\
|
||||
\x00\x72\
|
||||
\x00\x65\x00\x70\x00\x6f\x00\x44\x00\x69\x00\x73\x00\x61\x00\x62\x00\x6c\x00\x65\x00\x64\x00\x2e\x00\x70\x00\x6e\x00\x67\
|
||||
\x00\x11\
|
||||
\x0f\x1e\xdc\xe7\
|
||||
\x00\x72\
|
||||
\x00\x65\x00\x70\x00\x6f\x00\x43\x00\x6f\x00\x6e\x00\x6e\x00\x65\x00\x63\x00\x74\x00\x65\x00\x64\x00\x2e\x00\x70\x00\x6e\x00\x67\
|
||||
\
|
||||
\x00\x13\
|
||||
\x0b\xb7\x61\x47\
|
||||
\x00\x72\
|
||||
\x00\x65\x00\x70\x00\x6f\x00\x55\x00\x6e\x00\x61\x00\x76\x00\x61\x00\x69\x00\x6c\x00\x61\x00\x62\x00\x6c\x00\x65\x00\x2e\x00\x70\
|
||||
\x00\x6e\x00\x67\
|
||||
\x00\x0d\
|
||||
\x09\xa1\x91\x67\
|
||||
\x00\x71\
|
||||
\x00\x67\x00\x69\x00\x73\x00\x2d\x00\x69\x00\x63\x00\x6f\x00\x6e\x00\x2e\x00\x70\x00\x6e\x00\x67\
|
||||
\x00\x13\
|
||||
\x06\x9f\x85\x27\
|
||||
\x00\x50\
|
||||
\x00\x6c\x00\x75\x00\x67\x00\x69\x00\x6e\x00\x49\x00\x6e\x00\x73\x00\x74\x00\x61\x00\x6c\x00\x6c\x00\x65\x00\x72\x00\x2e\x00\x70\
|
||||
\x00\x6e\x00\x67\
|
||||
"
|
||||
|
||||
qt_resource_struct = "\
|
||||
\x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x01\
|
||||
\x00\x00\x00\x00\x00\x02\x00\x00\x00\x01\x00\x00\x00\x02\
|
||||
\x00\x00\x00\x14\x00\x02\x00\x00\x00\x05\x00\x00\x00\x03\
|
||||
\x00\x00\x00\x2c\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\
|
||||
\x00\x00\x00\xc6\x00\x00\x00\x00\x00\x01\x00\x00\x0c\x26\
|
||||
\x00\x00\x00\xa6\x00\x00\x00\x00\x00\x01\x00\x00\x09\x11\
|
||||
\x00\x00\x00\x7a\x00\x00\x00\x00\x00\x01\x00\x00\x05\x7f\
|
||||
\x00\x00\x00\x52\x00\x00\x00\x00\x00\x01\x00\x00\x01\xe6\
|
||||
"
|
||||
|
||||
def qInitResources():
|
||||
QtCore.qRegisterResourceData(0x01, qt_resource_struct, qt_resource_name, qt_resource_data)
|
||||
|
||||
def qCleanupResources():
|
||||
QtCore.qUnregisterResourceData(0x01, qt_resource_struct, qt_resource_name, qt_resource_data)
|
||||
|
||||
qInitResources()
|
89
python/plugins/plugin_installer/unzip.py
Normal file
89
python/plugins/plugin_installer/unzip.py
Normal file
@ -0,0 +1,89 @@
|
||||
""" 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.mkdir(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
|
Loading…
x
Reference in New Issue
Block a user