diff --git a/picard/plugin.py b/picard/plugin.py
index 841bdea9c..a71cfb15d 100644
--- a/picard/plugin.py
+++ b/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
diff --git a/picard/tagger.py b/picard/tagger.py
index fb2346572..1eaa667c7 100644
--- a/picard/tagger.py
+++ b/picard/tagger.py
@@ -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()
diff --git a/picard/ui/options/plugins.py b/picard/ui/options/plugins.py
index 71512f397..ee0a02f0f 100644
--- a/picard/ui/options/plugins.py
+++ b/picard/ui/options/plugins.py
@@ -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("" + _("File") + ": " + plugin.file[len(plugin.dir)+1:])
self.ui.details.setText("
%s
" % "
\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)
diff --git a/picard/ui/ui_options_plugins.py b/picard/ui/ui_options_plugins.py
index bdf1e6b2e..cc5e56c64 100644
--- a/picard/ui/ui_options_plugins.py
+++ b/picard/ui/ui_options_plugins.py
@@ -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"))
+
diff --git a/ui/options_plugins.ui b/ui/options_plugins.ui
index 845d2cd38..03300535b 100644
--- a/ui/options_plugins.ui
+++ b/ui/options_plugins.ui
@@ -6,17 +6,11 @@
0
0
- 406
- 297
+ 513
+ 312
-
- 6
-
-
- 9
-
-
@@ -33,9 +27,6 @@
2
-
- 9
-
-
@@ -44,6 +35,12 @@
0
+
+ true
+
+
+ QAbstractItemView::DropOnly
+
false
@@ -66,6 +63,19 @@
-
+
-
+
+
+
+ 0
+ 0
+
+
+
+ Install plugin…
+
+
+
-
@@ -110,9 +120,6 @@
0
-
- 9
-
-
@@ -147,8 +154,8 @@
0
0
- 368
- 69
+ 459
+ 76