mirror of
https://github.com/fergalmoran/picard.git
synced 2026-02-22 15:44:59 +00:00
Add the ability to install plugins while Picard is running.
This commit is contained in:
128
picard/plugin.py
128
picard/plugin.py
@@ -20,15 +20,27 @@
|
||||
from PyQt4 import QtCore
|
||||
import imp
|
||||
import os.path
|
||||
import shutil
|
||||
import picard.plugins
|
||||
import traceback
|
||||
|
||||
_suffixes = [s[0] for s in imp.get_suffixes()]
|
||||
_package_entries = ["__init__.py", "__init__.pyc", "__init__.pyo"]
|
||||
|
||||
def plugin_name_from_module(module):
|
||||
name = module.__name__
|
||||
if name.startswith("picard.plugins"):
|
||||
return name[15:]
|
||||
|
||||
def plugin_name_from_path(path):
|
||||
path = os.path.normpath(path)
|
||||
file = os.path.basename(path)
|
||||
if os.path.isdir(path):
|
||||
for entry in _package_entries:
|
||||
if os.path.isfile(os.path.join(path, entry)):
|
||||
return file
|
||||
else:
|
||||
if file in _package_entries:
|
||||
return None
|
||||
name, ext = os.path.splitext(file)
|
||||
if ext in _suffixes:
|
||||
return name
|
||||
return None
|
||||
|
||||
|
||||
@@ -41,6 +53,10 @@ class ExtensionPoint(QtCore.QObject):
|
||||
def register(self, module, item):
|
||||
if module.startswith("picard.plugins"):
|
||||
module = module[15:]
|
||||
for i, (module_, item_) in enumerate(self.__items):
|
||||
if module == module_:
|
||||
self.__items[i] = (module, item)
|
||||
return
|
||||
else:
|
||||
module = None
|
||||
self.__items.append((module, item))
|
||||
@@ -56,15 +72,23 @@ class PluginWrapper(object):
|
||||
|
||||
def __init__(self, module, plugindir):
|
||||
self.module = module
|
||||
self.compatible = False
|
||||
self.dir = plugindir
|
||||
|
||||
def __get_name(self):
|
||||
try:
|
||||
return self.module.PLUGIN_NAME
|
||||
except AttributeError:
|
||||
return self.module.__name__
|
||||
return self.module_name
|
||||
name = property(__get_name)
|
||||
|
||||
def __get_module_name(self):
|
||||
name = self.module.__name__
|
||||
if name.startswith("picard.plugins"):
|
||||
name = name[15:]
|
||||
return name
|
||||
module_name = property(__get_module_name)
|
||||
|
||||
def __get_author(self):
|
||||
try:
|
||||
return self.module.PLUGIN_AUTHOR
|
||||
@@ -104,57 +128,67 @@ class PluginManager(QtCore.QObject):
|
||||
QtCore.QObject.__init__(self)
|
||||
self.plugins = []
|
||||
|
||||
def load(self, plugindir):
|
||||
def load_plugindir(self, plugindir):
|
||||
if not os.path.isdir(plugindir):
|
||||
self.log.debug("Plugin directory %r doesn't exist", plugindir)
|
||||
return
|
||||
|
||||
names = set()
|
||||
suffixes = [s[0] for s in imp.get_suffixes()]
|
||||
package_entries = ["__init__.py", "__init__.pyc", "__init__.pyo"]
|
||||
for name in os.listdir(plugindir):
|
||||
if name in package_entries:
|
||||
continue
|
||||
path = os.path.join(plugindir, name)
|
||||
if os.path.isdir(path):
|
||||
for entry in package_entries:
|
||||
if os.path.isfile(os.path.join(path, entry)):
|
||||
break
|
||||
else:
|
||||
continue
|
||||
else:
|
||||
name, suffix = os.path.splitext(name)
|
||||
if suffix not in suffixes:
|
||||
continue
|
||||
if hasattr(picard.plugins, name):
|
||||
self.log.debug("Plugin %r already loaded!", name)
|
||||
else:
|
||||
for path in [os.path.join(plugindir, file) for file in os.listdir(plugindir)]:
|
||||
name = plugin_name_from_path(path)
|
||||
if name:
|
||||
names.add(name)
|
||||
|
||||
for name in names:
|
||||
self.log.debug("Loading plugin %r", name)
|
||||
info = imp.find_module(name, [plugindir])
|
||||
try:
|
||||
plugin_module = imp.load_module('picard.plugins.' + name, *info)
|
||||
plugin = PluginWrapper(plugin_module, plugindir)
|
||||
for version in list(plugin.api_versions):
|
||||
found = False
|
||||
for api_version in picard.api_versions:
|
||||
if api_version.startswith(version):
|
||||
setattr(picard.plugins, name, plugin_module)
|
||||
self.load_plugin(name, plugindir)
|
||||
|
||||
def load_plugin(self, name, plugindir):
|
||||
self.log.debug("Loading plugin %r", name)
|
||||
info = imp.find_module(name, [plugindir])
|
||||
plugin = None
|
||||
try:
|
||||
plugin_module = imp.load_module("picard.plugins." + name, *info)
|
||||
plugin = PluginWrapper(plugin_module, plugindir)
|
||||
for version in list(plugin.api_versions):
|
||||
for api_version in picard.api_versions:
|
||||
if api_version.startswith(version):
|
||||
plugin.compatible = True
|
||||
setattr(picard.plugins, name, plugin_module)
|
||||
for i, p in enumerate(self.plugins):
|
||||
if name == p.module_name:
|
||||
self.plugins[i] = plugin
|
||||
break
|
||||
else:
|
||||
self.plugins.append(plugin)
|
||||
found = True
|
||||
break
|
||||
if found:
|
||||
break
|
||||
else:
|
||||
self.log.info("Plugin '%s' from '%s' is not compatible "
|
||||
"with this version of Picard." %
|
||||
(plugin.name, plugin.file))
|
||||
except:
|
||||
self.log.error(traceback.format_exc())
|
||||
if info[0] is not None:
|
||||
info[0].close()
|
||||
continue
|
||||
break
|
||||
else:
|
||||
self.log.info("Plugin '%s' from '%s' is not compatible"
|
||||
" with this version of Picard." % (plugin.name, plugin.file))
|
||||
except:
|
||||
self.log.error(traceback.format_exc())
|
||||
if info[0] is not None:
|
||||
info[0].close()
|
||||
return plugin
|
||||
|
||||
def install_plugin(self, path, dest):
|
||||
plugin_name = plugin_name_from_path(path)
|
||||
plugin_dir = self.tagger.user_plugin_dir
|
||||
if plugin_name:
|
||||
try:
|
||||
dest_exists = os.path.exists(dest)
|
||||
same_file = os.path.samefile(path, dest) if dest_exists else False
|
||||
if os.path.isfile(path) and not (dest_exists and same_file):
|
||||
shutil.copy(path, dest)
|
||||
elif os.path.isdir(path) and not same_file:
|
||||
if dest_exists:
|
||||
shutil.rmtree(dest)
|
||||
shutil.copytree(path, dest)
|
||||
plugin = self.load_plugin(plugin_name, plugin_dir)
|
||||
if plugin is not None:
|
||||
self.emit(QtCore.SIGNAL("plugin_installed"), plugin, False)
|
||||
except OSError, IOError:
|
||||
self.tagger.log.debug("Unable to copy %s to plugin folder %s" % (path, plugin_dir))
|
||||
|
||||
def enabled(self, name):
|
||||
return True
|
||||
|
||||
@@ -185,14 +185,14 @@ class Tagger(QtGui.QApplication):
|
||||
|
||||
# Load plugins
|
||||
self.pluginmanager = PluginManager()
|
||||
user_plugin_dir = os.path.join(self.userdir, "plugins")
|
||||
if not os.path.exists(user_plugin_dir):
|
||||
os.makedirs(user_plugin_dir)
|
||||
self.pluginmanager.load(user_plugin_dir)
|
||||
self.user_plugin_dir = os.path.join(self.userdir, "plugins")
|
||||
if not os.path.exists(self.user_plugin_dir):
|
||||
os.makedirs(self.user_plugin_dir)
|
||||
self.pluginmanager.load_plugindir(self.user_plugin_dir)
|
||||
if hasattr(sys, "frozen"):
|
||||
self.pluginmanager.load(os.path.join(os.path.dirname(sys.argv[0]), "plugins"))
|
||||
self.pluginmanager.load_plugindir(os.path.join(os.path.dirname(sys.argv[0]), "plugins"))
|
||||
else:
|
||||
self.pluginmanager.load(os.path.join(os.path.dirname(__file__), "plugins"))
|
||||
self.pluginmanager.load_plugindir(os.path.join(os.path.dirname(__file__), "plugins"))
|
||||
|
||||
self.puidmanager = PUIDManager()
|
||||
|
||||
|
||||
@@ -22,7 +22,6 @@ import os.path
|
||||
import sys
|
||||
from PyQt4 import QtCore, QtGui
|
||||
from picard.config import TextOption
|
||||
from picard.plugin import plugin_name_from_module
|
||||
from picard.ui.options import OptionsPage, register_options_page
|
||||
from picard.ui.ui_options_plugins import Ui_PluginsOptionsPage
|
||||
|
||||
@@ -47,40 +46,65 @@ class PluginsOptionsPage(OptionsPage):
|
||||
super(PluginsOptionsPage, self).__init__(parent)
|
||||
self.ui = Ui_PluginsOptionsPage()
|
||||
self.ui.setupUi(self)
|
||||
self.items = {}
|
||||
self.connect(self.ui.plugins, QtCore.SIGNAL("itemSelectionChanged()"), self.change_details)
|
||||
self.user_plugin_dir = os.path.join(self.tagger.userdir, "plugins")
|
||||
self.ui.plugins.__class__.mimeTypes = self.mimeTypes
|
||||
self.ui.plugins.__class__.dropEvent = self.dropEvent
|
||||
if sys.platform == "win32":
|
||||
self.loader="file:///%s"
|
||||
self.loader="file:///%s"
|
||||
else:
|
||||
self.loader="file://%s"
|
||||
self.connect(self.ui.install_plugin, QtCore.SIGNAL("clicked()"), self.open_plugins)
|
||||
self.connect(self.ui.folder_open, QtCore.SIGNAL("clicked()"), self.open_plugin_dir)
|
||||
self.connect(self.ui.plugin_download, QtCore.SIGNAL("clicked()"), self.open_plugin_site)
|
||||
self.connect(self.tagger.pluginmanager, QtCore.SIGNAL("plugin_installed"), self.plugin_installed)
|
||||
|
||||
def load(self):
|
||||
plugins = sorted(self.tagger.pluginmanager.plugins, cmp=cmp_plugins)
|
||||
enabled_plugins = self.config.setting["enabled_plugins"].split()
|
||||
self.items = {}
|
||||
firstitem = None
|
||||
for plugin in plugins:
|
||||
item = QtGui.QTreeWidgetItem(self.ui.plugins)
|
||||
item.setText(0, plugin.name)
|
||||
if plugin_name_from_module(plugin.module) in enabled_plugins:
|
||||
item.setCheckState(0, QtCore.Qt.Checked)
|
||||
else:
|
||||
item.setCheckState(0, QtCore.Qt.Unchecked)
|
||||
item.setText(1, plugin.version)
|
||||
item.setText(2, plugin.author)
|
||||
enabled = plugin.module_name in enabled_plugins
|
||||
item = self.add_plugin_item(plugin, enabled=enabled)
|
||||
if not firstitem:
|
||||
firstitem = item
|
||||
self.items[item] = plugin
|
||||
self.ui.plugins.header().resizeSections(QtGui.QHeaderView.ResizeToContents)
|
||||
self.ui.plugins.setCurrentItem(firstitem)
|
||||
|
||||
def plugin_installed(self, plugin):
|
||||
if not plugin.compatible:
|
||||
msgbox = QtGui.QMessageBox(self)
|
||||
msgbox.setText(u"The plugin ‘%s’ is not compatible with this version of Picard." % plugin.name)
|
||||
msgbox.setStandardButtons(QtGui.QMessageBox.Ok)
|
||||
msgbox.setDefaultButton(QtGui.QMessageBox.Ok)
|
||||
msgbox.exec_()
|
||||
return
|
||||
for i, p in self.items.items():
|
||||
if plugin.module_name == p.module_name:
|
||||
enabled = i.checkState(0) == QtCore.Qt.Checked
|
||||
self.add_plugin_item(plugin, enabled=enabled, item=i)
|
||||
break
|
||||
else:
|
||||
self.add_plugin_item(plugin)
|
||||
|
||||
def add_plugin_item(self, plugin, enabled=False, item=None):
|
||||
if item is None:
|
||||
item = QtGui.QTreeWidgetItem(self.ui.plugins)
|
||||
item.setText(0, plugin.name)
|
||||
if enabled:
|
||||
item.setCheckState(0, QtCore.Qt.Checked)
|
||||
else:
|
||||
item.setCheckState(0, QtCore.Qt.Unchecked)
|
||||
item.setText(1, plugin.version)
|
||||
item.setText(2, plugin.author)
|
||||
self.ui.plugins.header().resizeSections(QtGui.QHeaderView.ResizeToContents)
|
||||
self.items[item] = plugin
|
||||
return item
|
||||
|
||||
def save(self):
|
||||
enabled_plugins = []
|
||||
for item, plugin in self.items.iteritems():
|
||||
if item.checkState(0) == QtCore.Qt.Checked:
|
||||
enabled_plugins.append(plugin_name_from_module(plugin.module))
|
||||
enabled_plugins.append(plugin.module_name)
|
||||
self.config.setting["enabled_plugins"] = " ".join(enabled_plugins)
|
||||
|
||||
def change_details(self):
|
||||
@@ -99,11 +123,38 @@ class PluginsOptionsPage(OptionsPage):
|
||||
text.append("<b>" + _("File") + "</b>: " + plugin.file[len(plugin.dir)+1:])
|
||||
self.ui.details.setText("<p>%s</p>" % "<br/>\n".join(text))
|
||||
|
||||
def open_plugins(self):
|
||||
files = QtGui.QFileDialog.getOpenFileNames(self, "", "/", "Picard plugin (*.py *.pyc)")
|
||||
if files:
|
||||
files = map(unicode, files)
|
||||
for path in files:
|
||||
self.install_plugin(path)
|
||||
|
||||
def install_plugin(self, path):
|
||||
file = os.path.basename(path)
|
||||
dest = os.path.join(self.tagger.user_plugin_dir, file)
|
||||
if os.path.exists(dest):
|
||||
msgbox = QtGui.QMessageBox(self)
|
||||
msgbox.setText("A plugin named %s is already installed." % file)
|
||||
msgbox.setInformativeText("Do you want to overwrite the existing plugin?")
|
||||
msgbox.setStandardButtons(QtGui.QMessageBox.Yes | QtGui.QMessageBox.No)
|
||||
msgbox.setDefaultButton(QtGui.QMessageBox.No)
|
||||
if msgbox.exec_() == QtGui.QMessageBox.No:
|
||||
return
|
||||
self.tagger.pluginmanager.install_plugin(path, dest)
|
||||
|
||||
def open_plugin_dir(self):
|
||||
QtGui.QDesktopServices.openUrl(QtCore.QUrl(self.loader % self.user_plugin_dir, QtCore.QUrl.TolerantMode))
|
||||
QtGui.QDesktopServices.openUrl(QtCore.QUrl(self.loader % self.tagger.user_plugin_dir, QtCore.QUrl.TolerantMode))
|
||||
|
||||
def open_plugin_site(self):
|
||||
QtGui.QDesktopServices.openUrl(QtCore.QUrl("http://musicbrainz.org/doc/Picard_Plugins", QtCore.QUrl.TolerantMode))
|
||||
|
||||
def mimeTypes(self):
|
||||
return ["text/uri-list"]
|
||||
|
||||
def dropEvent(self, event):
|
||||
for path in [os.path.normpath(unicode(u.toLocalFile())) for u in event.mimeData().urls()]:
|
||||
self.install_plugin(path)
|
||||
|
||||
|
||||
register_options_page(PluginsOptionsPage)
|
||||
|
||||
@@ -1,126 +1,117 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Form implementation generated from reading ui file 'ui\options_plugins.ui'
|
||||
#
|
||||
# Created: Thu Oct 22 00:04:48 2009
|
||||
# by: PyQt4 UI code generator 4.6
|
||||
#
|
||||
# WARNING! All changes made in this file will be lost!
|
||||
|
||||
from PyQt4 import QtCore, QtGui
|
||||
|
||||
class Ui_PluginsOptionsPage(object):
|
||||
def setupUi(self, PluginsOptionsPage):
|
||||
PluginsOptionsPage.setObjectName("PluginsOptionsPage")
|
||||
PluginsOptionsPage.resize(406, 297)
|
||||
self.vboxlayout = QtGui.QVBoxLayout(PluginsOptionsPage)
|
||||
self.vboxlayout.setSpacing(6)
|
||||
self.vboxlayout.setMargin(9)
|
||||
self.vboxlayout.setObjectName("vboxlayout")
|
||||
self.splitter = QtGui.QSplitter(PluginsOptionsPage)
|
||||
self.splitter.setOrientation(QtCore.Qt.Vertical)
|
||||
self.splitter.setHandleWidth(2)
|
||||
self.splitter.setObjectName("splitter")
|
||||
self.groupBox_2 = QtGui.QGroupBox(self.splitter)
|
||||
self.groupBox_2.setObjectName("groupBox_2")
|
||||
self.vboxlayout1 = QtGui.QVBoxLayout(self.groupBox_2)
|
||||
self.vboxlayout1.setSpacing(2)
|
||||
self.vboxlayout1.setMargin(9)
|
||||
self.vboxlayout1.setObjectName("vboxlayout1")
|
||||
self.plugins = QtGui.QTreeWidget(self.groupBox_2)
|
||||
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.MinimumExpanding, QtGui.QSizePolicy.Expanding)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.plugins.sizePolicy().hasHeightForWidth())
|
||||
self.plugins.setSizePolicy(sizePolicy)
|
||||
self.plugins.setRootIsDecorated(False)
|
||||
self.plugins.setObjectName("plugins")
|
||||
self.vboxlayout1.addWidget(self.plugins)
|
||||
self.horizontalLayout = QtGui.QHBoxLayout()
|
||||
self.horizontalLayout.setObjectName("horizontalLayout")
|
||||
self.folder_open = QtGui.QPushButton(self.groupBox_2)
|
||||
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Fixed)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.folder_open.sizePolicy().hasHeightForWidth())
|
||||
self.folder_open.setSizePolicy(sizePolicy)
|
||||
self.folder_open.setObjectName("folder_open")
|
||||
self.horizontalLayout.addWidget(self.folder_open)
|
||||
self.plugin_download = QtGui.QPushButton(self.groupBox_2)
|
||||
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Fixed)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.plugin_download.sizePolicy().hasHeightForWidth())
|
||||
self.plugin_download.setSizePolicy(sizePolicy)
|
||||
self.plugin_download.setObjectName("plugin_download")
|
||||
self.horizontalLayout.addWidget(self.plugin_download)
|
||||
self.vboxlayout1.addLayout(self.horizontalLayout)
|
||||
self.groupBox = QtGui.QGroupBox(self.splitter)
|
||||
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.groupBox.sizePolicy().hasHeightForWidth())
|
||||
self.groupBox.setSizePolicy(sizePolicy)
|
||||
self.groupBox.setObjectName("groupBox")
|
||||
self.vboxlayout2 = QtGui.QVBoxLayout(self.groupBox)
|
||||
self.vboxlayout2.setSpacing(0)
|
||||
self.vboxlayout2.setMargin(9)
|
||||
self.vboxlayout2.setObjectName("vboxlayout2")
|
||||
self.scrollArea = QtGui.QScrollArea(self.groupBox)
|
||||
self.scrollArea.setEnabled(True)
|
||||
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.scrollArea.sizePolicy().hasHeightForWidth())
|
||||
self.scrollArea.setSizePolicy(sizePolicy)
|
||||
self.scrollArea.setFrameShape(QtGui.QFrame.HLine)
|
||||
self.scrollArea.setFrameShadow(QtGui.QFrame.Plain)
|
||||
self.scrollArea.setLineWidth(0)
|
||||
self.scrollArea.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAsNeeded)
|
||||
self.scrollArea.setWidgetResizable(True)
|
||||
self.scrollArea.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter)
|
||||
self.scrollArea.setObjectName("scrollArea")
|
||||
self.scrollAreaWidgetContents = QtGui.QWidget(self.scrollArea)
|
||||
self.scrollAreaWidgetContents.setGeometry(QtCore.QRect(0, 0, 368, 69))
|
||||
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.scrollAreaWidgetContents.sizePolicy().hasHeightForWidth())
|
||||
self.scrollAreaWidgetContents.setSizePolicy(sizePolicy)
|
||||
self.scrollAreaWidgetContents.setObjectName("scrollAreaWidgetContents")
|
||||
self.verticalLayout = QtGui.QVBoxLayout(self.scrollAreaWidgetContents)
|
||||
self.verticalLayout.setSizeConstraint(QtGui.QLayout.SetNoConstraint)
|
||||
self.verticalLayout.setContentsMargins(0, 0, 6, 0)
|
||||
self.verticalLayout.setObjectName("verticalLayout")
|
||||
self.details = QtGui.QLabel(self.scrollAreaWidgetContents)
|
||||
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding)
|
||||
sizePolicy.setHorizontalStretch(0)
|
||||
sizePolicy.setVerticalStretch(0)
|
||||
sizePolicy.setHeightForWidth(self.details.sizePolicy().hasHeightForWidth())
|
||||
self.details.setSizePolicy(sizePolicy)
|
||||
self.details.setMinimumSize(QtCore.QSize(0, 0))
|
||||
self.details.setFrameShape(QtGui.QFrame.Box)
|
||||
self.details.setLineWidth(0)
|
||||
self.details.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignTop)
|
||||
self.details.setWordWrap(True)
|
||||
self.details.setIndent(0)
|
||||
self.details.setOpenExternalLinks(True)
|
||||
self.details.setTextInteractionFlags(QtCore.Qt.LinksAccessibleByMouse|QtCore.Qt.TextSelectableByMouse)
|
||||
self.details.setObjectName("details")
|
||||
self.verticalLayout.addWidget(self.details)
|
||||
self.scrollArea.setWidget(self.scrollAreaWidgetContents)
|
||||
self.vboxlayout2.addWidget(self.scrollArea)
|
||||
self.vboxlayout.addWidget(self.splitter)
|
||||
|
||||
self.retranslateUi(PluginsOptionsPage)
|
||||
QtCore.QMetaObject.connectSlotsByName(PluginsOptionsPage)
|
||||
|
||||
def retranslateUi(self, PluginsOptionsPage):
|
||||
self.groupBox_2.setTitle(_("Plugins"))
|
||||
self.plugins.headerItem().setText(0, _("Name"))
|
||||
self.plugins.headerItem().setText(1, _("Version"))
|
||||
self.plugins.headerItem().setText(2, _("Author"))
|
||||
self.folder_open.setText(_("Open plugin folder"))
|
||||
self.plugin_download.setText(_("Download plugins"))
|
||||
self.groupBox.setTitle(_("Details"))
|
||||
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
# Form implementation generated from reading ui file 'ui/options_plugins.ui'
|
||||
#
|
||||
# Created: Mon Jun 20 19:52:58 2011
|
||||
# by: PyQt4 UI code generator 4.8.4
|
||||
#
|
||||
# WARNING! All changes made in this file will be lost!
|
||||
|
||||
from PyQt4 import QtCore, QtGui
|
||||
|
||||
class Ui_PluginsOptionsPage(object):
|
||||
def setupUi(self, PluginsOptionsPage):
|
||||
PluginsOptionsPage.setObjectName("PluginsOptionsPage")
|
||||
PluginsOptionsPage.resize(513, 312)
|
||||
self.vboxlayout = QtGui.QVBoxLayout(PluginsOptionsPage)
|
||||
self.vboxlayout.setObjectName("vboxlayout")
|
||||
self.splitter = QtGui.QSplitter(PluginsOptionsPage)
|
||||
self.splitter.setOrientation(QtCore.Qt.Vertical)
|
||||
self.splitter.setHandleWidth(2)
|
||||
self.splitter.setObjectName("splitter")
|
||||
self.groupBox_2 = QtGui.QGroupBox(self.splitter)
|
||||
self.groupBox_2.setObjectName("groupBox_2")
|
||||
self.vboxlayout1 = QtGui.QVBoxLayout(self.groupBox_2)
|
||||
self.vboxlayout1.setSpacing(2)
|
||||
self.vboxlayout1.setObjectName("vboxlayout1")
|
||||
self.plugins = QtGui.QTreeWidget(self.groupBox_2)
|
||||
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.MinimumExpanding, QtGui.QSizePolicy.Expanding)
|
||||
sizePolicy.setHeightForWidth(self.plugins.sizePolicy().hasHeightForWidth())
|
||||
self.plugins.setSizePolicy(sizePolicy)
|
||||
self.plugins.setAcceptDrops(True)
|
||||
self.plugins.setDragDropMode(QtGui.QAbstractItemView.DropOnly)
|
||||
self.plugins.setRootIsDecorated(False)
|
||||
self.plugins.setObjectName("plugins")
|
||||
self.vboxlayout1.addWidget(self.plugins)
|
||||
self.horizontalLayout = QtGui.QHBoxLayout()
|
||||
self.horizontalLayout.setObjectName("horizontalLayout")
|
||||
self.install_plugin = QtGui.QPushButton(self.groupBox_2)
|
||||
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Fixed)
|
||||
sizePolicy.setHeightForWidth(self.install_plugin.sizePolicy().hasHeightForWidth())
|
||||
self.install_plugin.setSizePolicy(sizePolicy)
|
||||
self.install_plugin.setObjectName("install_plugin")
|
||||
self.horizontalLayout.addWidget(self.install_plugin)
|
||||
self.folder_open = QtGui.QPushButton(self.groupBox_2)
|
||||
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Fixed)
|
||||
sizePolicy.setHeightForWidth(self.folder_open.sizePolicy().hasHeightForWidth())
|
||||
self.folder_open.setSizePolicy(sizePolicy)
|
||||
self.folder_open.setObjectName("folder_open")
|
||||
self.horizontalLayout.addWidget(self.folder_open)
|
||||
self.plugin_download = QtGui.QPushButton(self.groupBox_2)
|
||||
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Fixed)
|
||||
sizePolicy.setHeightForWidth(self.plugin_download.sizePolicy().hasHeightForWidth())
|
||||
self.plugin_download.setSizePolicy(sizePolicy)
|
||||
self.plugin_download.setObjectName("plugin_download")
|
||||
self.horizontalLayout.addWidget(self.plugin_download)
|
||||
self.vboxlayout1.addLayout(self.horizontalLayout)
|
||||
self.groupBox = QtGui.QGroupBox(self.splitter)
|
||||
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding)
|
||||
sizePolicy.setHeightForWidth(self.groupBox.sizePolicy().hasHeightForWidth())
|
||||
self.groupBox.setSizePolicy(sizePolicy)
|
||||
self.groupBox.setObjectName("groupBox")
|
||||
self.vboxlayout2 = QtGui.QVBoxLayout(self.groupBox)
|
||||
self.vboxlayout2.setSpacing(0)
|
||||
self.vboxlayout2.setObjectName("vboxlayout2")
|
||||
self.scrollArea = QtGui.QScrollArea(self.groupBox)
|
||||
self.scrollArea.setEnabled(True)
|
||||
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding)
|
||||
sizePolicy.setHeightForWidth(self.scrollArea.sizePolicy().hasHeightForWidth())
|
||||
self.scrollArea.setSizePolicy(sizePolicy)
|
||||
self.scrollArea.setFrameShape(QtGui.QFrame.HLine)
|
||||
self.scrollArea.setFrameShadow(QtGui.QFrame.Plain)
|
||||
self.scrollArea.setLineWidth(0)
|
||||
self.scrollArea.setVerticalScrollBarPolicy(QtCore.Qt.ScrollBarAsNeeded)
|
||||
self.scrollArea.setWidgetResizable(True)
|
||||
self.scrollArea.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignVCenter)
|
||||
self.scrollArea.setObjectName("scrollArea")
|
||||
self.scrollAreaWidgetContents = QtGui.QWidget()
|
||||
self.scrollAreaWidgetContents.setGeometry(QtCore.QRect(0, 0, 459, 76))
|
||||
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding)
|
||||
sizePolicy.setHeightForWidth(self.scrollAreaWidgetContents.sizePolicy().hasHeightForWidth())
|
||||
self.scrollAreaWidgetContents.setSizePolicy(sizePolicy)
|
||||
self.scrollAreaWidgetContents.setObjectName("scrollAreaWidgetContents")
|
||||
self.verticalLayout = QtGui.QVBoxLayout(self.scrollAreaWidgetContents)
|
||||
self.verticalLayout.setSizeConstraint(QtGui.QLayout.SetNoConstraint)
|
||||
self.verticalLayout.setContentsMargins(0, 0, 6, 0)
|
||||
self.verticalLayout.setObjectName("verticalLayout")
|
||||
self.details = QtGui.QLabel(self.scrollAreaWidgetContents)
|
||||
sizePolicy = QtGui.QSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding)
|
||||
sizePolicy.setHeightForWidth(self.details.sizePolicy().hasHeightForWidth())
|
||||
self.details.setSizePolicy(sizePolicy)
|
||||
self.details.setFrameShape(QtGui.QFrame.Box)
|
||||
self.details.setLineWidth(0)
|
||||
self.details.setText("")
|
||||
self.details.setAlignment(QtCore.Qt.AlignLeading|QtCore.Qt.AlignLeft|QtCore.Qt.AlignTop)
|
||||
self.details.setWordWrap(True)
|
||||
self.details.setIndent(0)
|
||||
self.details.setOpenExternalLinks(True)
|
||||
self.details.setTextInteractionFlags(QtCore.Qt.LinksAccessibleByMouse|QtCore.Qt.TextSelectableByMouse)
|
||||
self.details.setObjectName("details")
|
||||
self.verticalLayout.addWidget(self.details)
|
||||
self.scrollArea.setWidget(self.scrollAreaWidgetContents)
|
||||
self.vboxlayout2.addWidget(self.scrollArea)
|
||||
self.vboxlayout.addWidget(self.splitter)
|
||||
|
||||
self.retranslateUi(PluginsOptionsPage)
|
||||
QtCore.QMetaObject.connectSlotsByName(PluginsOptionsPage)
|
||||
|
||||
def retranslateUi(self, PluginsOptionsPage):
|
||||
self.groupBox_2.setTitle(_("Plugins"))
|
||||
self.plugins.headerItem().setText(0, _("Name"))
|
||||
self.plugins.headerItem().setText(1, _("Version"))
|
||||
self.plugins.headerItem().setText(2, _("Author"))
|
||||
self.install_plugin.setText(_(u"Install plugin…"))
|
||||
self.folder_open.setText(_("Open plugin folder"))
|
||||
self.plugin_download.setText(_("Download plugins"))
|
||||
self.groupBox.setTitle(_("Details"))
|
||||
|
||||
|
||||
@@ -6,17 +6,11 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>406</width>
|
||||
<height>297</height>
|
||||
<width>513</width>
|
||||
<height>312</height>
|
||||
</rect>
|
||||
</property>
|
||||
<layout class="QVBoxLayout">
|
||||
<property name="spacing">
|
||||
<number>6</number>
|
||||
</property>
|
||||
<property name="margin">
|
||||
<number>9</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QSplitter" name="splitter">
|
||||
<property name="orientation">
|
||||
@@ -33,9 +27,6 @@
|
||||
<property name="spacing">
|
||||
<number>2</number>
|
||||
</property>
|
||||
<property name="margin">
|
||||
<number>9</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QTreeWidget" name="plugins">
|
||||
<property name="sizePolicy">
|
||||
@@ -44,6 +35,12 @@
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="acceptDrops">
|
||||
<bool>true</bool>
|
||||
</property>
|
||||
<property name="dragDropMode">
|
||||
<enum>QAbstractItemView::DropOnly</enum>
|
||||
</property>
|
||||
<property name="rootIsDecorated">
|
||||
<bool>false</bool>
|
||||
</property>
|
||||
@@ -66,6 +63,19 @@
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QPushButton" name="install_plugin">
|
||||
<property name="sizePolicy">
|
||||
<sizepolicy hsizetype="Expanding" vsizetype="Fixed">
|
||||
<horstretch>0</horstretch>
|
||||
<verstretch>0</verstretch>
|
||||
</sizepolicy>
|
||||
</property>
|
||||
<property name="text">
|
||||
<string>Install plugin…</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="folder_open">
|
||||
<property name="sizePolicy">
|
||||
@@ -110,9 +120,6 @@
|
||||
<property name="spacing">
|
||||
<number>0</number>
|
||||
</property>
|
||||
<property name="margin">
|
||||
<number>9</number>
|
||||
</property>
|
||||
<item>
|
||||
<widget class="QScrollArea" name="scrollArea">
|
||||
<property name="enabled">
|
||||
@@ -147,8 +154,8 @@
|
||||
<rect>
|
||||
<x>0</x>
|
||||
<y>0</y>
|
||||
<width>368</width>
|
||||
<height>69</height>
|
||||
<width>459</width>
|
||||
<height>76</height>
|
||||
</rect>
|
||||
</property>
|
||||
<property name="sizePolicy">
|
||||
|
||||
Reference in New Issue
Block a user