diff --git a/src/app/main.cpp b/src/app/main.cpp index edfcd51efed4a46dab0f6f38463817c5ef29fda5..8aaca6ecdec8a3c1aae860c8385fb08e1f3193d8 100644 --- a/src/app/main.cpp +++ b/src/app/main.cpp @@ -202,7 +202,6 @@ int main(int argc, char **argv) QLatin1String("Nokia"), QLatin1String("QtCreator")); locale = settings.value("General/OverrideLanguage", locale).toString(); - const QString &creatorTrPath = QCoreApplication::applicationDirPath() + QLatin1String(SHARE_PATH "/translations"); if (translator.load(QLatin1String("qtcreator_") + locale, creatorTrPath)) { diff --git a/src/libs/extensionsystem/extensionsystem.pro b/src/libs/extensionsystem/extensionsystem.pro index 9cacadb3306cf3cab76ab3537389966b5e6418a6..027139c89ee42448426df952f4c4daa634f935b1 100644 --- a/src/libs/extensionsystem/extensionsystem.pro +++ b/src/libs/extensionsystem/extensionsystem.pro @@ -19,14 +19,16 @@ HEADERS += pluginerrorview.h \ pluginspec_p.h \ pluginview.h \ pluginview_p.h \ - optionsparser.h + optionsparser.h \ + plugincollection.h SOURCES += pluginerrorview.cpp \ plugindetailsview.cpp \ iplugin.cpp \ pluginmanager.cpp \ pluginspec.cpp \ pluginview.cpp \ - optionsparser.cpp + optionsparser.cpp \ + plugincollection.cpp FORMS += pluginview.ui \ pluginerrorview.ui \ plugindetailsview.ui diff --git a/src/libs/extensionsystem/images/notloaded.png b/src/libs/extensionsystem/images/notloaded.png new file mode 100644 index 0000000000000000000000000000000000000000..a72883bd40782aed509a88c94a5b964d48dbdbdd Binary files /dev/null and b/src/libs/extensionsystem/images/notloaded.png differ diff --git a/src/libs/extensionsystem/optionsparser.cpp b/src/libs/extensionsystem/optionsparser.cpp index 5fb9254475310ffa64bf10af7d1866d7f7e3550a..538d37068f0f83bed599d3bef4ca88b3f3a98f57 100644 --- a/src/libs/extensionsystem/optionsparser.cpp +++ b/src/libs/extensionsystem/optionsparser.cpp @@ -128,8 +128,7 @@ bool OptionsParser::checkForNoLoadOption() "The plugin '%1' does not exist.").arg(m_currentArg); m_hasError = true; } else { - m_pmPrivate->pluginSpecs.removeAll(spec); - delete spec; + m_pmPrivate->removePluginSpec(spec); m_isDependencyRefreshNeeded = true; } } diff --git a/src/libs/extensionsystem/plugincollection.cpp b/src/libs/extensionsystem/plugincollection.cpp new file mode 100644 index 0000000000000000000000000000000000000000..f54ad4bd6db93dc787e84a8b4cfd0d40f3165888 --- /dev/null +++ b/src/libs/extensionsystem/plugincollection.cpp @@ -0,0 +1,37 @@ +#include "plugincollection.h" +#include "pluginspec.h" + +namespace ExtensionSystem { + +PluginCollection::PluginCollection(const QString& name) : + m_name(name) +{ + +} + +PluginCollection::~PluginCollection() +{ + +} + +QString PluginCollection::name() const +{ + return m_name; +} + +void PluginCollection::addPlugin(PluginSpec *spec) +{ + m_plugins.append(spec); +} + +void PluginCollection::removePlugin(PluginSpec *spec) +{ + m_plugins.removeOne(spec); +} + +QList<PluginSpec *> PluginCollection::plugins() const +{ + return m_plugins; +} + +} diff --git a/src/libs/extensionsystem/plugincollection.h b/src/libs/extensionsystem/plugincollection.h new file mode 100644 index 0000000000000000000000000000000000000000..4ff598207051071046d8137ac083a5582c0d288b --- /dev/null +++ b/src/libs/extensionsystem/plugincollection.h @@ -0,0 +1,31 @@ +#ifndef PLUGINCOLLECTION_H +#define PLUGINCOLLECTION_H + +#include <QList> +#include <QString> +#include "extensionsystem_global.h" + + +namespace ExtensionSystem { +class PluginSpec; + +class EXTENSIONSYSTEM_EXPORT PluginCollection +{ + +public: + explicit PluginCollection(const QString& name); + ~PluginCollection(); + + QString name() const; + void addPlugin(PluginSpec *spec); + void removePlugin(PluginSpec *spec); + QList<PluginSpec *> plugins() const; +private: + QString m_name; + QList<PluginSpec *> m_plugins; + +}; + +} + +#endif // PLUGINCOLLECTION_H diff --git a/src/libs/extensionsystem/plugindetailsview.cpp b/src/libs/extensionsystem/plugindetailsview.cpp index 3dcd228ec907740838075ac5574824036c0f955c..3508b4f167cca2be5325357d26a7db7f0adc0f04 100644 --- a/src/libs/extensionsystem/plugindetailsview.cpp +++ b/src/libs/extensionsystem/plugindetailsview.cpp @@ -78,6 +78,10 @@ void PluginDetailsView::update(PluginSpec *spec) m_ui->vendor->setText(spec->vendor()); const QString link = QString::fromLatin1("<a href=\"%1\">%1</a>").arg(spec->url()); m_ui->url->setText(link); + QString component = tr("None"); + if (!spec->category().isEmpty()) + component = spec->category(); + m_ui->component->setText(component); m_ui->location->setText(QDir::toNativeSeparators(spec->filePath())); m_ui->description->setText(spec->description()); m_ui->copyright->setText(spec->copyright()); diff --git a/src/libs/extensionsystem/plugindetailsview.ui b/src/libs/extensionsystem/plugindetailsview.ui index 10d6e987f354488c7661b33fb7b24904ad5d70ab..2d4dfb872123a28fcdba3237df4cbd816043c492 100644 --- a/src/libs/extensionsystem/plugindetailsview.ui +++ b/src/libs/extensionsystem/plugindetailsview.ui @@ -66,7 +66,7 @@ <item row="3" column="1"> <widget class="QLabel" name="vendor"/> </item> - <item row="4" column="0"> + <item row="5" column="0"> <widget class="QLabel" name="label_6"> <property name="text"> <string>Url:</string> @@ -76,14 +76,14 @@ </property> </widget> </item> - <item row="4" column="1"> + <item row="5" column="1"> <widget class="QLabel" name="url"> <property name="openExternalLinks"> <bool>true</bool> </property> </widget> </item> - <item row="5" column="0"> + <item row="6" column="0"> <widget class="QLabel" name="label_7"> <property name="text"> <string>Location:</string> @@ -93,14 +93,14 @@ </property> </widget> </item> - <item row="5" column="1"> + <item row="6" column="1"> <widget class="QLabel" name="location"> <property name="wordWrap"> <bool>false</bool> </property> </widget> </item> - <item row="6" column="0"> + <item row="7" column="0"> <layout class="QVBoxLayout"> <item> <widget class="QLabel" name="label_8"> @@ -127,7 +127,7 @@ </item> </layout> </item> - <item row="6" column="1"> + <item row="7" column="1"> <widget class="QTextEdit" name="description"> <property name="tabChangesFocus"> <bool>true</bool> @@ -137,7 +137,7 @@ </property> </widget> </item> - <item row="7" column="0"> + <item row="8" column="0"> <widget class="QLabel" name="label_5"> <property name="text"> <string>Copyright:</string> @@ -147,10 +147,10 @@ </property> </widget> </item> - <item row="7" column="1"> + <item row="8" column="1"> <widget class="QLabel" name="copyright"/> </item> - <item row="8" column="0"> + <item row="9" column="0"> <layout class="QVBoxLayout"> <item> <widget class="QLabel" name="label_9"> @@ -177,7 +177,7 @@ </item> </layout> </item> - <item row="8" column="1"> + <item row="9" column="1"> <widget class="QTextEdit" name="license"> <property name="tabChangesFocus"> <bool>true</bool> @@ -187,7 +187,7 @@ </property> </widget> </item> - <item row="9" column="0"> + <item row="10" column="0"> <layout class="QVBoxLayout"> <item> <widget class="QLabel" name="label_10"> @@ -214,9 +214,26 @@ </item> </layout> </item> - <item row="9" column="1"> + <item row="10" column="1"> <widget class="QListWidget" name="dependencies"/> </item> + <item row="4" column="0"> + <widget class="QLabel" name="label_11"> + <property name="text"> + <string>Group:</string> + </property> + <property name="alignment"> + <set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set> + </property> + </widget> + </item> + <item row="4" column="1"> + <widget class="QLabel" name="component"> + <property name="text"> + <string/> + </property> + </widget> + </item> </layout> </widget> <resources/> diff --git a/src/libs/extensionsystem/pluginmanager.cpp b/src/libs/extensionsystem/pluginmanager.cpp index f5c6994f05aded1889c5d660e6f423e8c0534ca4..1f6baeea05f83cec2280628a8e86bdfc01e1c9cc 100644 --- a/src/libs/extensionsystem/pluginmanager.cpp +++ b/src/libs/extensionsystem/pluginmanager.cpp @@ -33,6 +33,7 @@ #include "pluginspec_p.h" #include "optionsparser.h" #include "iplugin.h" +#include "plugincollection.h" #include <QtCore/QMetaProperty> #include <QtCore/QDir> @@ -40,11 +41,14 @@ #include <QtCore/QWriteLocker> #include <QtCore/QTime> #include <QtCore/QDateTime> +#include <QtCore/QSettings> #include <QtDebug> #ifdef WITH_TESTS #include <QTest> #endif +static const char * const C_IGNORED_PLUGINS = "Plugins/Ignored"; + typedef QList<ExtensionSystem::PluginSpec *> PluginSpecSet; enum { debugLeaks = 0 }; @@ -297,6 +301,16 @@ void PluginManager::setFileExtension(const QString &extension) d->extension = extension; } +void PluginManager::loadSettings() +{ + d->loadSettings(); +} + +void PluginManager::writeSettings() +{ + d->writeSettings(); +} + /*! \fn QStringList PluginManager::arguments() const The arguments left over after parsing (Neither startup nor plugin @@ -322,6 +336,11 @@ QList<PluginSpec *> PluginManager::plugins() const return d->pluginSpecs; } +QHash<QString, PluginCollection *> PluginManager::pluginCollections() const +{ + return d->pluginCategories; +} + /*! \fn QString PluginManager::serializedArguments() const @@ -593,11 +612,35 @@ PluginManagerPrivate::~PluginManagerPrivate() { stopAll(); qDeleteAll(pluginSpecs); + qDeleteAll(pluginCategories); if (!allObjects.isEmpty()) { qDebug() << "There are" << allObjects.size() << "objects left in the plugin manager pool: " << allObjects; } } +void PluginManagerPrivate::writeSettings() +{ + QSettings settings(QSettings::IniFormat, QSettings::UserScope, + QLatin1String("Nokia"), QLatin1String("QtCreator")); + + QStringList notLoadedPlugins; + foreach(PluginSpec *spec, pluginSpecs) { + if (!spec->loadOnStartup()) + notLoadedPlugins.append(spec->name()); + } + + settings.setValue(QLatin1String(C_IGNORED_PLUGINS), notLoadedPlugins); +} + +void PluginManagerPrivate::loadSettings() +{ + const QSettings settings(QSettings::IniFormat, QSettings::UserScope, + QLatin1String("Nokia"), QLatin1String("QtCreator")); + + + notLoadedPlugins = settings.value(QLatin1String(C_IGNORED_PLUGINS)).toStringList(); +} + void PluginManagerPrivate::stopAll() { QList<PluginSpec *> queue = loadQueue(); @@ -719,9 +762,11 @@ bool PluginManagerPrivate::loadQueue(PluginSpec *spec, QList<PluginSpec *> &queu circularityCheckQueue.append(spec); // check if we have the dependencies if (spec->state() == PluginSpec::Invalid || spec->state() == PluginSpec::Read) { - spec->d->hasError = true; - spec->d->errorString += "\n"; - spec->d->errorString += PluginManager::tr("Cannot load plugin because dependencies are not resolved"); + if (!spec->d->ignoreOnStartup && spec->d->loadOnStartup) { + spec->d->hasError = true; + spec->d->errorString += "\n"; + spec->d->errorString += PluginManager::tr("Cannot load plugin because dependencies are not resolved"); + } return false; } // add dependencies @@ -745,8 +790,9 @@ bool PluginManagerPrivate::loadQueue(PluginSpec *spec, QList<PluginSpec *> &queu */ void PluginManagerPrivate::loadPlugin(PluginSpec *spec, PluginSpec::State destState) { - if (spec->hasError()) + if (spec->hasError() || spec->ignoreOnStartup()) return; + switch (destState) { case PluginSpec::Running: profilingReport(">initializeExtensions", spec); @@ -796,6 +842,7 @@ void PluginManagerPrivate::loadPlugin(PluginSpec *spec, PluginSpec::State destSt void PluginManagerPrivate::setPluginPaths(const QStringList &paths) { pluginPaths = paths; + loadSettings(); readPluginPaths(); } @@ -805,8 +852,10 @@ void PluginManagerPrivate::setPluginPaths(const QStringList &paths) */ void PluginManagerPrivate::readPluginPaths() { + qDeleteAll(pluginCategories); qDeleteAll(pluginSpecs); pluginSpecs.clear(); + pluginCategories.clear(); QStringList specFiles; QStringList searchPaths = pluginPaths; @@ -820,9 +869,25 @@ void PluginManagerPrivate::readPluginPaths() foreach (const QFileInfo &subdir, dirs) searchPaths << subdir.absoluteFilePath(); } + defaultCollection = new PluginCollection(QString()); + pluginCategories.insert("", defaultCollection); + foreach (const QString &specFile, specFiles) { PluginSpec *spec = new PluginSpec; spec->d->read(specFile); + + PluginCollection *collection = 0; + // find correct plugin collection or create a new one + if (pluginCategories.contains(spec->category())) + collection = pluginCategories.value(spec->category()); + else { + collection = new PluginCollection(spec->category()); + pluginCategories.insert(spec->category(), collection); + } + if (notLoadedPlugins.contains(spec->name())) + spec->setLoadOnStartup(false); + + collection->addPlugin(spec); pluginSpecs.append(spec); } resolveDependencies(); @@ -862,6 +927,21 @@ PluginSpec *PluginManagerPrivate::pluginForOption(const QString &option, bool *r return 0; } +void PluginManagerPrivate::removePluginSpec(PluginSpec *spec) +{ + pluginSpecs.removeAll(spec); + + if (pluginCategories.contains(spec->category())) + pluginCategories.value(spec->category())->removePlugin(spec); + + foreach(PluginSpec *dep, spec->dependencySpecs()) { + dep->removeDependentPlugin(spec); + } + + delete spec; + spec = 0; +} + PluginSpec *PluginManagerPrivate::pluginByName(const QString &name) const { foreach (PluginSpec *spec, pluginSpecs) diff --git a/src/libs/extensionsystem/pluginmanager.h b/src/libs/extensionsystem/pluginmanager.h index 3d47fc00a37d9124614f8ee9f46765723c6fe7de..23d011f07f83ea81a4db126f1f7f4b5f81929709 100644 --- a/src/libs/extensionsystem/pluginmanager.h +++ b/src/libs/extensionsystem/pluginmanager.h @@ -42,7 +42,7 @@ class QTextStream; QT_END_NAMESPACE namespace ExtensionSystem { - +class PluginCollection; namespace Internal { class PluginManagerPrivate; } @@ -95,9 +95,14 @@ public: QStringList pluginPaths() const; void setPluginPaths(const QStringList &paths); QList<PluginSpec *> plugins() const; + QHash<QString, PluginCollection *> pluginCollections() const; void setFileExtension(const QString &extension); QString fileExtension() const; + // Settings + void loadSettings(); + void writeSettings(); + // command line arguments QStringList arguments() const; bool parseOptions(const QStringList &args, diff --git a/src/libs/extensionsystem/pluginmanager_p.h b/src/libs/extensionsystem/pluginmanager_p.h index 419ff989905eaf19b9300d8b2dfa35f1e8e4127d..4b76c4eddb1e912784a75a1f7fa4ceba79a38323 100644 --- a/src/libs/extensionsystem/pluginmanager_p.h +++ b/src/libs/extensionsystem/pluginmanager_p.h @@ -45,6 +45,7 @@ QT_END_NAMESPACE namespace ExtensionSystem { class PluginManager; +class PluginCollection; namespace Internal { @@ -68,12 +69,17 @@ public: void resolveDependencies(); void initProfiling(); void profilingReport(const char *what, const PluginSpec *spec = 0); + void loadSettings(); + void writeSettings(); + void removePluginSpec(PluginSpec *spec); + QHash<QString, PluginCollection *> pluginCategories; QList<PluginSpec *> pluginSpecs; QList<PluginSpec *> testSpecs; QStringList pluginPaths; QString extension; QList<QObject *> allObjects; // ### make this a QList<QPointer<QObject> > > ? + QStringList notLoadedPlugins; QStringList arguments; QScopedPointer<QTime> m_profileTimer; @@ -87,6 +93,7 @@ public: static PluginSpec *createSpec(); static PluginSpecPrivate *privateSpec(PluginSpec *spec); private: + PluginCollection *defaultCollection; PluginManager *q; void readPluginPaths(); diff --git a/src/libs/extensionsystem/pluginspec.cpp b/src/libs/extensionsystem/pluginspec.cpp index 8a395c7f0f5d0246b5fee0e1b55b83dc43c8a9c9..b4095250aec793050608f82071cf633cebb978b2 100644 --- a/src/libs/extensionsystem/pluginspec.cpp +++ b/src/libs/extensionsystem/pluginspec.cpp @@ -226,6 +226,30 @@ QString PluginSpec::url() const return d->url; } +/*! + \fn QString PluginSpec::category() const + The category that the plugin belongs to. Categories are groups of plugins which allow for keeping them together in the UI. + Returns an empty string if the plugin does not belong to a category. +*/ +QString PluginSpec::category() const +{ + return d->category; +} + +/*! + \fn bool PluginSpec::loadOnStartup() const + True if the plugin is loaded at startup. True by default - the user can change it from the Plugin settings. +*/ +bool PluginSpec::loadOnStartup() const +{ + return d->loadOnStartup; +} + +bool PluginSpec::ignoreOnStartup() const +{ + return d->ignoreOnStartup; +} + /*! \fn QList<PluginDependency> PluginSpec::dependencies() const The plugin dependencies. This is valid after the PluginSpec::Read state is reached. @@ -358,6 +382,33 @@ QList<PluginSpec *> PluginSpec::dependencySpecs() const return d->dependencySpecs; } +/*! + \fn QList<PluginSpec *> PluginSpec::providesSpecs() const + Returns the list of plugins that depend on this one. + + \sa PluginSpec::dependencySpecs() +*/ +QList<PluginSpec *> PluginSpec::providesSpecs() const +{ + return d->providesSpecs; +} + +/*! + \fn void PluginSpec::addDependentPlugin(PluginSpec *dependent) + Adds a dependent the list of plugins that depend on this one. + + \sa PluginSpec::providesSpecs() +*/ +void PluginSpec::addDependentPlugin(PluginSpec *dependent) +{ + d->providesSpecs.append(dependent); +} + +void PluginSpec::removeDependentPlugin(PluginSpec *dependent) +{ + d->providesSpecs.removeOne(dependent); +} + //==========PluginSpecPrivate================== namespace { @@ -370,6 +421,7 @@ namespace { const char * const LICENSE = "license"; const char * const DESCRIPTION = "description"; const char * const URL = "url"; + const char * const CATEGORY = "category"; const char * const DEPENDENCYLIST = "dependencyList"; const char * const DEPENDENCY = "dependency"; const char * const DEPENDENCY_NAME = "name"; @@ -384,7 +436,10 @@ namespace { \internal */ PluginSpecPrivate::PluginSpecPrivate(PluginSpec *spec) - : plugin(0), + : + loadOnStartup(true), + ignoreOnStartup(false), + plugin(0), state(PluginSpec::Invalid), hasError(false), q(spec) @@ -405,6 +460,7 @@ bool PluginSpecPrivate::read(const QString &fileName) = license = description = url + = category = location = ""; state = PluginSpec::Invalid; @@ -440,6 +496,16 @@ bool PluginSpecPrivate::read(const QString &fileName) return true; } +void PluginSpec::setLoadOnStartup(bool value) +{ + d->loadOnStartup = value; +} + +void PluginSpec::setIgnoreOnStartup(bool value) +{ + d->ignoreOnStartup = value; +} + /*! \fn bool PluginSpecPrivate::reportError(const QString &err) \internal @@ -523,6 +589,8 @@ void PluginSpecPrivate::readPluginSpec(QXmlStreamReader &reader) description = reader.readElementText().trimmed(); else if (element == URL) url = reader.readElementText().trimmed(); + else if (element == CATEGORY) + category = reader.readElementText().trimmed(); else if (element == DEPENDENCYLIST) readDependencies(reader); else if (element == ARGUMENTLIST) @@ -725,9 +793,15 @@ bool PluginSpecPrivate::resolveDependencies(const QList<PluginSpec *> &specs) QList<PluginSpec *> resolvedDependencies; foreach (const PluginDependency &dependency, dependencies) { PluginSpec *found = 0; + foreach (PluginSpec *spec, specs) { if (spec->provides(dependency.name, dependency.version)) { found = spec; + if (!spec->loadOnStartup() || spec->ignoreOnStartup()) + ignoreOnStartup = true; + + spec->addDependentPlugin(q); + break; } } @@ -743,8 +817,12 @@ bool PluginSpecPrivate::resolveDependencies(const QList<PluginSpec *> &specs) } if (hasError) return false; + dependencySpecs = resolvedDependencies; - state = PluginSpec::Resolved; + + if (loadOnStartup && !ignoreOnStartup) + state = PluginSpec::Resolved; + return true; } diff --git a/src/libs/extensionsystem/pluginspec.h b/src/libs/extensionsystem/pluginspec.h index dc24239ee47ec2be5587c2a0c5b479a9d35926c6..405651886fee2cb204ce5c96b30272a141deedbe 100644 --- a/src/libs/extensionsystem/pluginspec.h +++ b/src/libs/extensionsystem/pluginspec.h @@ -78,6 +78,10 @@ public: QString license() const; QString description() const; QString url() const; + QString category() const; + bool loadOnStartup() const; + // true if loading was not done due to user unselecting this plugin or its dependencies + bool ignoreOnStartup() const; QList<PluginDependency> dependencies() const; typedef QList<PluginArgumentDescription> PluginArgumentDescriptions; @@ -87,6 +91,9 @@ public: QString location() const; QString filePath() const; + void setLoadOnStartup(bool value); + void setIgnoreOnStartup(bool value); + QStringList arguments() const; void setArguments(const QStringList &arguments); void addArgument(const QString &argument); @@ -96,6 +103,13 @@ public: // dependency specs, valid after 'Resolved' state is reached QList<PluginSpec *> dependencySpecs() const; + // list of plugins that depend on this - e.g. this plugins provides for them + QList<PluginSpec *> providesSpecs() const; + + // add/remove from providesSpecs + void addDependentPlugin(PluginSpec *dependent); + void removeDependentPlugin(PluginSpec *dependent); + // linked plugin instance, valid after 'Loaded' state is reached IPlugin *plugin() const; diff --git a/src/libs/extensionsystem/pluginspec_p.h b/src/libs/extensionsystem/pluginspec_p.h index 687dab7217618c65dc129bdecdc47cf7bd7281ed..245142ce996a4a5bdc663cf1a72fc0ec43588fb8 100644 --- a/src/libs/extensionsystem/pluginspec_p.h +++ b/src/libs/extensionsystem/pluginspec_p.h @@ -67,12 +67,16 @@ public: QString license; QString description; QString url; + QString category; QList<PluginDependency> dependencies; + bool loadOnStartup; + bool ignoreOnStartup; QString location; QString filePath; QStringList arguments; + QList<PluginSpec *> providesSpecs; QList<PluginSpec *> dependencySpecs; PluginSpec::PluginArgumentDescriptions argumentDescriptions; IPlugin *plugin; diff --git a/src/libs/extensionsystem/pluginview.cpp b/src/libs/extensionsystem/pluginview.cpp index c1c36de93649aa55c80afc8c48c1e90bd53786cd..286e12f787507f582a3381911c44e84c70af5f0b 100644 --- a/src/libs/extensionsystem/pluginview.cpp +++ b/src/libs/extensionsystem/pluginview.cpp @@ -31,11 +31,14 @@ #include "pluginview_p.h" #include "pluginmanager.h" #include "pluginspec.h" +#include "plugincollection.h" #include "ui_pluginview.h" #include <QtCore/QDir> #include <QtGui/QHeaderView> #include <QtGui/QTreeWidgetItem> +#include <QtGui/QPalette> + #include <QtDebug> /*! @@ -65,6 +68,7 @@ using namespace ExtensionSystem; Q_DECLARE_METATYPE(ExtensionSystem::PluginSpec*); +Q_DECLARE_METATYPE(ExtensionSystem::PluginCollection*); /*! \fn PluginView::PluginView(PluginManager *manager, QWidget *parent) @@ -74,20 +78,30 @@ Q_DECLARE_METATYPE(ExtensionSystem::PluginSpec*); PluginView::PluginView(PluginManager *manager, QWidget *parent) : QWidget(parent), m_ui(new Internal::Ui::PluginView), - p(new Internal::PluginViewPrivate) + p(new Internal::PluginViewPrivate), + m_allowCheckStateUpdate(true), + C_LOAD(1) { m_ui->setupUi(this); - QHeaderView *header = m_ui->pluginWidget->header(); + QHeaderView *header = m_ui->categoryWidget->header(); header->setResizeMode(0, QHeaderView::ResizeToContents); - header->setResizeMode(1, QHeaderView::ResizeToContents); header->setResizeMode(2, QHeaderView::ResizeToContents); - m_ui->pluginWidget->sortItems(1, Qt::AscendingOrder); + + m_okIcon = QIcon(QLatin1String(":/extensionsystem/images/ok.png")); + m_errorIcon = QIcon(QLatin1String(":/extensionsystem/images/error.png")); + m_notLoadedIcon = QIcon(QLatin1String(":/extensionsystem/images/notloaded.png")); + + // cannot disable these + m_whitelist << QString("Core") << QString("Locator") + << QString("Find") << QString("TextEditor"); + p->manager = manager; connect(p->manager, SIGNAL(pluginsChanged()), this, SLOT(updateList())); - connect(m_ui->pluginWidget, SIGNAL(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)), + connect(m_ui->categoryWidget, SIGNAL(currentItemChanged(QTreeWidgetItem*,QTreeWidgetItem*)), this, SLOT(selectPlugin(QTreeWidgetItem*))); - connect(m_ui->pluginWidget, SIGNAL(itemActivated(QTreeWidgetItem*,int)), + connect(m_ui->categoryWidget, SIGNAL(itemActivated(QTreeWidgetItem*,int)), this, SLOT(activatePlugin(QTreeWidgetItem*))); + updateList(); } @@ -107,51 +121,230 @@ PluginView::~PluginView() */ PluginSpec *PluginView::currentPlugin() const { - if (!m_ui->pluginWidget->currentItem()) + if (!m_ui->categoryWidget->currentItem()) return 0; - return m_ui->pluginWidget->currentItem()->data(0, Qt::UserRole).value<PluginSpec *>(); + if (!m_ui->categoryWidget->currentItem()->data(0, Qt::UserRole).isNull()) + return m_ui->categoryWidget->currentItem()->data(0, Qt::UserRole).value<PluginSpec *>(); + return 0; } void PluginView::updateList() { - const QIcon okIcon(QLatin1String(":/extensionsystem/images/ok.png")); - const QIcon errorIcon(QLatin1String(":/extensionsystem/images/error.png")); - QList<QTreeWidgetItem *> items; - QTreeWidgetItem *currentItem = 0; - PluginSpec *currPlugin = currentPlugin(); - foreach (PluginSpec *spec, p->manager->plugins()) { - QTreeWidgetItem *item = new QTreeWidgetItem(QStringList() - << QString() + connect(m_ui->categoryWidget, SIGNAL(itemChanged(QTreeWidgetItem*,int)), + this, SLOT(updatePluginSettings(QTreeWidgetItem*, int))); + + PluginCollection *defaultCollection = 0; + foreach(PluginCollection *collection, p->manager->pluginCollections()) { + if (collection->name().isEmpty()) { + defaultCollection = collection; + continue; + } + // State, name, load, version, vendor. + QTreeWidgetItem *collectionItem = new QTreeWidgetItem(QStringList() + << collection->name() + << QString() // state + << QString() // load + << QString() // version + << QString()); // vendor + m_items.append(collectionItem); + + Qt::CheckState groupState = Qt::Unchecked; + bool hasErrors = parsePluginSpecs(collectionItem, groupState, collection->plugins()); + + collectionItem->setIcon(0, hasErrors ? m_errorIcon : m_okIcon); + collectionItem->setData(C_LOAD, Qt::CheckStateRole, QVariant(groupState)); + collectionItem->setToolTip(C_LOAD, tr("Load on Startup")); + collectionItem->setData(0, Qt::UserRole, qVariantFromValue(collection)); + } + + // add all non-categorized plugins into utilities. could also be added as root items + // but that makes the tree ugly. + QTreeWidgetItem *defaultCollectionItem = new QTreeWidgetItem(QStringList() + << QString(tr("Utilities")) + << QString() + << QString() + << QString() + << QString()); + + m_items.append(defaultCollectionItem); + Qt::CheckState groupState = Qt::Unchecked; + bool hasErrors = parsePluginSpecs(defaultCollectionItem, groupState, defaultCollection->plugins()); + + defaultCollectionItem->setIcon(0, hasErrors ? m_errorIcon : m_okIcon); + defaultCollectionItem->setData(C_LOAD, Qt::CheckStateRole, QVariant(groupState)); + defaultCollectionItem->setToolTip(C_LOAD, tr("Load on Startup")); + defaultCollectionItem->setData(0, Qt::UserRole, qVariantFromValue(defaultCollection)); + + + foreach (PluginSpec *spec, m_specToItem.keys()) + toggleRelatedPlugins(spec, spec->loadOnStartup() && !spec->ignoreOnStartup()); + + m_ui->categoryWidget->clear(); + if (!m_items.isEmpty()) { + m_ui->categoryWidget->addTopLevelItems(m_items); + m_ui->categoryWidget->expandAll(); + } + + m_ui->categoryWidget->sortItems(0, Qt::AscendingOrder); + if (m_ui->categoryWidget->topLevelItemCount()) + m_ui->categoryWidget->setCurrentItem(m_ui->categoryWidget->topLevelItem(0)); +} + +bool PluginView::parsePluginSpecs(QTreeWidgetItem *parentItem, Qt::CheckState &groupState, QList<PluginSpec*> plugins) +{ + bool hasErrors = false; + int loadCount = 0; + for (int i = 0; i < plugins.length(); ++i) { + PluginSpec *spec = plugins[i]; + if (spec->hasError()) + hasErrors = true; + + QTreeWidgetItem *pluginItem = new QTreeWidgetItem(QStringList() << spec->name() + << QString() // load on startup << QString::fromLatin1("%1 (%2)").arg(spec->version(), spec->compatVersion()) - << spec->vendor() - << QDir::toNativeSeparators(spec->filePath())); - item->setToolTip(4, QDir::toNativeSeparators(spec->filePath())); - item->setIcon(0, spec->hasError() ? errorIcon : okIcon); - item->setData(0, Qt::UserRole, qVariantFromValue(spec)); - items.append(item); - if (currPlugin == spec) - currentItem = item; + << spec->vendor()); + + pluginItem->setToolTip(0, QDir::toNativeSeparators(spec->filePath())); + bool ok = !spec->hasError(); + QIcon &icon = ok ? m_okIcon : m_errorIcon; + if (ok && (spec->state() != PluginSpec::Running)) + icon = m_notLoadedIcon; + + pluginItem->setIcon(0, icon); + pluginItem->setData(0, Qt::UserRole, qVariantFromValue(spec)); + + Qt::CheckState state = Qt::Unchecked; + if (spec->loadOnStartup()) { + state = Qt::Checked; + //if (!spec->ignoreOnStartup()) + ++loadCount; + } else + hasErrors = true; + + if (!m_whitelist.contains(spec->name())) + pluginItem->setData(C_LOAD, Qt::CheckStateRole, state); + else { + QColor disabledColor = palette().color(QPalette::Disabled,QPalette::WindowText).lighter(120); + pluginItem->setData(C_LOAD, Qt::CheckStateRole, Qt::Checked); + pluginItem->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); + pluginItem->setSizeHint(C_LOAD, QSize(1,1)); + pluginItem->setForeground(C_LOAD, QBrush(disabledColor)); // QBrush(Qt::white, Qt::NoBrush)); + //pluginItem->setBackground(C_LOAD, QBrush(Qt::white, Qt::NoBrush)); + } + pluginItem->setToolTip(C_LOAD, tr("Load on Startup")); + + m_specToItem.insert(spec, pluginItem); + + if (parentItem) + parentItem->addChild(pluginItem); + else + m_items.append(pluginItem); + } - m_ui->pluginWidget->clear(); - if (!items.isEmpty()) - m_ui->pluginWidget->addTopLevelItems(items); - if (currentItem) - m_ui->pluginWidget->setCurrentItem(currentItem); - else if (!items.isEmpty()) - m_ui->pluginWidget->setCurrentItem(items.first()); + + if (loadCount == plugins.length()) + groupState = Qt::Checked; + else if (loadCount == 0) + groupState = Qt::Unchecked; + else + groupState = Qt::PartiallyChecked; + + return hasErrors; } void PluginView::selectPlugin(QTreeWidgetItem *current) { if (!current) emit currentPluginChanged(0); - else + else if (current->data(0, Qt::UserRole).canConvert<PluginSpec*>()) emit currentPluginChanged(current->data(0, Qt::UserRole).value<PluginSpec *>()); + else + emit currentPluginChanged(0); + } void PluginView::activatePlugin(QTreeWidgetItem *item) { - emit pluginActivated(item->data(0, Qt::UserRole).value<PluginSpec *>()); + if (item->data(0, Qt::UserRole).canConvert<PluginSpec*>()) { + emit pluginActivated(item->data(0, Qt::UserRole).value<PluginSpec *>()); + } else + emit pluginActivated(0); +} + +void PluginView::updatePluginSettings(QTreeWidgetItem *item, int column) +{ + if (!m_allowCheckStateUpdate) + return; + + m_allowCheckStateUpdate = false; + + bool loadOnStartup = item->data(C_LOAD, Qt::CheckStateRole).toBool(); + + if (item->data(0, Qt::UserRole).canConvert<PluginSpec*>()) { + PluginSpec *spec = item->data(0, Qt::UserRole).value<PluginSpec *>(); + + if (column == C_LOAD) { + + spec->setLoadOnStartup(loadOnStartup); + toggleRelatedPlugins(spec, loadOnStartup); + + if (item->parent()) { + PluginCollection *collection = item->parent()->data(0, Qt::UserRole).value<PluginCollection *>(); + Qt::CheckState state = Qt::PartiallyChecked; + int loadCount = 0; + for (int i = 0; i < collection->plugins().length(); ++i) { + if (collection->plugins().at(i)->loadOnStartup()) + ++loadCount; + } + if (loadCount == collection->plugins().length()) + state = Qt::Checked; + else if (loadCount == 0) + state = Qt::Unchecked; + + item->parent()->setData(C_LOAD, Qt::CheckStateRole, state); + } + + emit pluginSettingsChanged(spec); + } + + } else { + PluginCollection *collection = item->data(0, Qt::UserRole).value<PluginCollection *>(); + for (int i = 0; i < collection->plugins().length(); ++i) { + PluginSpec *spec = collection->plugins().at(i); + QTreeWidgetItem *child = m_specToItem.value(spec); + + if (!m_whitelist.contains(spec->name())) { + spec->setLoadOnStartup(loadOnStartup); + Qt::CheckState state = (loadOnStartup ? Qt::Checked : Qt::Unchecked); + child->setData(C_LOAD, Qt::CheckStateRole, state); + toggleRelatedPlugins(spec, loadOnStartup); + } else { + child->setData(C_LOAD, Qt::CheckStateRole, Qt::Checked); + child->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); + } + } + emit pluginSettingsChanged(collection->plugins().first()); + } + + m_allowCheckStateUpdate = true; +} + +void PluginView::toggleRelatedPlugins(PluginSpec *modifiedPlugin, bool isPluginEnabled) +{ + + for(int i = 0; i < modifiedPlugin->providesSpecs().length(); ++i) { + PluginSpec *spec = modifiedPlugin->providesSpecs().at(i); + QTreeWidgetItem *childItem = m_specToItem.value(spec); + + if (childItem->isDisabled() != !isPluginEnabled) { + childItem->setDisabled(!isPluginEnabled); + if (childItem->parent() && !childItem->parent()->isExpanded()) + childItem->parent()->setExpanded(true); + + + toggleRelatedPlugins(spec, isPluginEnabled); + } + } } diff --git a/src/libs/extensionsystem/pluginview.h b/src/libs/extensionsystem/pluginview.h index 47fae9b9231f18efffe7528571863db83e30aead..28d410035e73f216b24af31c9e59baecbf104de0 100644 --- a/src/libs/extensionsystem/pluginview.h +++ b/src/libs/extensionsystem/pluginview.h @@ -32,7 +32,9 @@ #include "extensionsystem_global.h" +#include <QtCore/QHash> #include <QtGui/QWidget> +#include <QtGui/QIcon> QT_BEGIN_NAMESPACE class QTreeWidgetItem; @@ -42,6 +44,7 @@ namespace ExtensionSystem { class PluginManager; class PluginSpec; +class PluginCollection; namespace Internal { class PluginViewPrivate; @@ -63,15 +66,30 @@ public: signals: void currentPluginChanged(ExtensionSystem::PluginSpec *spec); void pluginActivated(ExtensionSystem::PluginSpec *spec); + void pluginSettingsChanged(ExtensionSystem::PluginSpec *spec); private slots: + void updatePluginSettings(QTreeWidgetItem *item, int column); void updateList(); void selectPlugin(QTreeWidgetItem *current); void activatePlugin(QTreeWidgetItem *item); private: + void toggleRelatedPlugins(PluginSpec *spec, bool isPluginEnabled = true); + bool parsePluginSpecs(QTreeWidgetItem *parentItem, Qt::CheckState &groupState, QList<PluginSpec*> plugins); + Internal::Ui::PluginView *m_ui; Internal::PluginViewPrivate *p; + QList<QTreeWidgetItem*> m_items; + QHash<PluginSpec*, QTreeWidgetItem*> m_specToItem; + + QStringList m_whitelist; + QIcon m_okIcon; + QIcon m_errorIcon; + QIcon m_notLoadedIcon; + bool m_allowCheckStateUpdate; + + const int C_LOAD; }; } // namespae ExtensionSystem diff --git a/src/libs/extensionsystem/pluginview.qrc b/src/libs/extensionsystem/pluginview.qrc index 7b78566568feaee0cfda86fb2ea717c28fc09479..aa772f9547c3d57e93da13fa32842f4d702a53b4 100644 --- a/src/libs/extensionsystem/pluginview.qrc +++ b/src/libs/extensionsystem/pluginview.qrc @@ -1,6 +1,7 @@ <RCC> - <qresource prefix="/extensionsystem" > + <qresource prefix="/extensionsystem"> <file>images/ok.png</file> <file>images/error.png</file> + <file>images/notloaded.png</file> </qresource> </RCC> diff --git a/src/libs/extensionsystem/pluginview.ui b/src/libs/extensionsystem/pluginview.ui index a995bbe8ed74f568e3d01205567062ea24259649..8dfb08ae2c10808e0e2d6d62daf7964ab7e862f5 100644 --- a/src/libs/extensionsystem/pluginview.ui +++ b/src/libs/extensionsystem/pluginview.ui @@ -14,37 +14,55 @@ <property name="margin"> <number>2</number> </property> - <item row="0" column="0"> - <widget class="QTreeWidget" name="pluginWidget"> + <item row="1" column="0"> + <widget class="QTreeWidget" name="categoryWidget"> <property name="alternatingRowColors"> <bool>true</bool> </property> <property name="indentation"> - <number>0</number> + <number>20</number> </property> <property name="rootIsDecorated"> - <bool>false</bool> + <bool>true</bool> </property> <property name="uniformRowHeights"> - <bool>true</bool> + <bool>false</bool> </property> <property name="itemsExpandable"> - <bool>false</bool> + <bool>true</bool> </property> <property name="sortingEnabled"> <bool>true</bool> </property> <property name="columnCount"> - <number>5</number> + <number>4</number> </property> + <attribute name="headerDefaultSectionSize"> + <number>120</number> + </attribute> + <attribute name="headerHighlightSections"> + <bool>false</bool> + </attribute> + <attribute name="headerMinimumSectionSize"> + <number>35</number> + </attribute> + <attribute name="headerDefaultSectionSize"> + <number>120</number> + </attribute> + <attribute name="headerMinimumSectionSize"> + <number>35</number> + </attribute> + <attribute name="headerHighlightSections"> + <bool>false</bool> + </attribute> <column> <property name="text"> - <string>State</string> + <string>Name</string> </property> </column> <column> <property name="text"> - <string>Name</string> + <string>Load</string> </property> </column> <column> @@ -57,11 +75,6 @@ <string>Vendor</string> </property> </column> - <column> - <property name="text"> - <string>Location</string> - </property> - </column> </widget> </item> </layout> diff --git a/src/plugins/bineditor/BinEditor.pluginspec b/src/plugins/bineditor/BinEditor.pluginspec index 3b60fcc78168a7d6647716d2bfd5602b81742b27..4091f86779d54cc08fb95de8aebd8182e1479246 100644 --- a/src/plugins/bineditor/BinEditor.pluginspec +++ b/src/plugins/bineditor/BinEditor.pluginspec @@ -10,6 +10,7 @@ GNU Lesser General Public License Usage Alternatively, this plugin may be used under the terms of the GNU Lesser General Public License version 2.1 as published by the Free Software Foundation. Please review the following information to ensure the GNU Lesser General Public License version 2.1 requirements will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. </license> + <category>Qt Creator</category> <description>Binary editor component.</description> <url>http://qt.nokia.com</url> <dependencyList> diff --git a/src/plugins/bookmarks/Bookmarks.pluginspec b/src/plugins/bookmarks/Bookmarks.pluginspec index 247b4ad9b51d6d4eff353f8d13874d96073e162f..654377aa5f26e7fdf24894d476950f09fce2a536 100644 --- a/src/plugins/bookmarks/Bookmarks.pluginspec +++ b/src/plugins/bookmarks/Bookmarks.pluginspec @@ -10,6 +10,7 @@ GNU Lesser General Public License Usage Alternatively, this plugin may be used under the terms of the GNU Lesser General Public License version 2.1 as published by the Free Software Foundation. Please review the following information to ensure the GNU Lesser General Public License version 2.1 requirements will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. </license> + <category>Qt Creator</category> <description>Bookmarks in text editors.</description> <url>http://qt.nokia.com</url> <dependencyList> diff --git a/src/plugins/cmakeprojectmanager/CMakeProjectManager.pluginspec b/src/plugins/cmakeprojectmanager/CMakeProjectManager.pluginspec index 3e0281d01e825185e7b130d2e9384b803f724eb9..41f798d5011b77bf78386f4f5bfe71f864223172 100644 --- a/src/plugins/cmakeprojectmanager/CMakeProjectManager.pluginspec +++ b/src/plugins/cmakeprojectmanager/CMakeProjectManager.pluginspec @@ -10,6 +10,7 @@ GNU Lesser General Public License Usage Alternatively, this plugin may be used under the terms of the GNU Lesser General Public License version 2.1 as published by the Free Software Foundation. Please review the following information to ensure the GNU Lesser General Public License version 2.1 requirements will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. </license> + <category>Build Systems</category> <description>CMake support</description> <url>http://qt.nokia.com</url> <dependencyList> diff --git a/src/plugins/coreplugin/Core.pluginspec b/src/plugins/coreplugin/Core.pluginspec index a2f4f95086d9641bbcfea5ebcb849ed54f538ed4..b33392833e649b73fb4efbc746be6cfa4255f12f 100644 --- a/src/plugins/coreplugin/Core.pluginspec +++ b/src/plugins/coreplugin/Core.pluginspec @@ -10,6 +10,7 @@ GNU Lesser General Public License Usage Alternatively, this plugin may be used under the terms of the GNU Lesser General Public License version 2.1 as published by the Free Software Foundation. Please review the following information to ensure the GNU Lesser General Public License version 2.1 requirements will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. </license> + <category>Qt Creator</category> <description>The core plugin for the Qt IDE.</description> <url>http://qt.nokia.com</url> <argumentList> diff --git a/src/plugins/coreplugin/plugindialog.cpp b/src/plugins/coreplugin/plugindialog.cpp index 8549d356c61c8dd5addcc3b7606b3f40bdfa8987..7d9387f4bdcda47360fa77227009f484961545c4 100644 --- a/src/plugins/coreplugin/plugindialog.cpp +++ b/src/plugins/coreplugin/plugindialog.cpp @@ -40,10 +40,13 @@ #include <QtGui/QDialog> #include <QtGui/QDialogButtonBox> #include <QtGui/QPushButton> +#include <QtGui/QLabel> #include <QtDebug> using namespace Core::Internal; +bool PluginDialog::m_isRestartRequired = false; + PluginDialog::PluginDialog(QWidget *parent) : QDialog(parent), m_view(new ExtensionSystem::PluginView(ExtensionSystem::PluginManager::instance(), this)) @@ -59,14 +62,21 @@ PluginDialog::PluginDialog(QWidget *parent) m_closeButton->setEnabled(true); m_closeButton->setDefault(true); + m_restartRequired = new QLabel(tr("Restart required."), this); + if (!m_isRestartRequired) + m_restartRequired->setVisible(false); + QHBoxLayout *hl = new QHBoxLayout; hl->addWidget(m_detailsButton); hl->addWidget(m_errorDetailsButton); + hl->addSpacing(10); + hl->addWidget(m_restartRequired); hl->addStretch(5); hl->addWidget(m_closeButton); vl->addLayout(hl); + resize(650, 400); setWindowTitle(tr("Installed Plugins")); @@ -74,18 +84,35 @@ PluginDialog::PluginDialog(QWidget *parent) this, SLOT(updateButtons())); connect(m_view, SIGNAL(pluginActivated(ExtensionSystem::PluginSpec*)), this, SLOT(openDetails(ExtensionSystem::PluginSpec*))); + connect(m_view, SIGNAL(pluginSettingsChanged(ExtensionSystem::PluginSpec*)), + this, SLOT(updateRestartRequired())); connect(m_detailsButton, SIGNAL(clicked()), this, SLOT(openDetails())); connect(m_errorDetailsButton, SIGNAL(clicked()), this, SLOT(openErrorDetails())); - connect(m_closeButton, SIGNAL(clicked()), this, SLOT(accept())); + connect(m_closeButton, SIGNAL(clicked()), this, SLOT(closeDialog())); updateButtons(); } +void PluginDialog::closeDialog() +{ + ExtensionSystem::PluginManager::instance()->writeSettings(); + accept(); +} + +void PluginDialog::updateRestartRequired() +{ + // just display the notice all the time after once changing something + m_isRestartRequired = true; + m_restartRequired->setVisible(true); +} + void PluginDialog::updateButtons() { ExtensionSystem::PluginSpec *selectedSpec = m_view->currentPlugin(); if (selectedSpec) { m_detailsButton->setEnabled(true); - m_errorDetailsButton->setEnabled(selectedSpec->hasError()); + m_errorDetailsButton->setEnabled(selectedSpec->hasError() + || selectedSpec->ignoreOnStartup() + || !selectedSpec->loadOnStartup()); } else { m_detailsButton->setEnabled(false); m_errorDetailsButton->setEnabled(false); diff --git a/src/plugins/coreplugin/plugindialog.h b/src/plugins/coreplugin/plugindialog.h index 30aa1a5b2c68c5b8a3e6d1e0ad117d7fdc5f2d03..56200aa182456df23b974c7860135b15c5d2b6f4 100644 --- a/src/plugins/coreplugin/plugindialog.h +++ b/src/plugins/coreplugin/plugindialog.h @@ -34,6 +34,7 @@ QT_BEGIN_NAMESPACE class QPushButton; +class QLabel; QT_END_NAMESPACE namespace ExtensionSystem { @@ -52,10 +53,12 @@ public: explicit PluginDialog(QWidget *parent); private slots: + void updateRestartRequired(); void updateButtons(); void openDetails(); void openDetails(ExtensionSystem::PluginSpec *spec); void openErrorDetails(); + void closeDialog(); private: ExtensionSystem::PluginView *m_view; @@ -63,6 +66,8 @@ private: QPushButton *m_detailsButton; QPushButton *m_errorDetailsButton; QPushButton *m_closeButton; + QLabel *m_restartRequired; + static bool m_isRestartRequired; }; } // namespace Internal diff --git a/src/plugins/cppeditor/CppEditor.pluginspec b/src/plugins/cppeditor/CppEditor.pluginspec index 19d693127a2dcf71b8bb02aef4947e6039c03fd0..167900e3621b6d1a9a246071dda39473c6a962c6 100644 --- a/src/plugins/cppeditor/CppEditor.pluginspec +++ b/src/plugins/cppeditor/CppEditor.pluginspec @@ -10,6 +10,7 @@ GNU Lesser General Public License Usage Alternatively, this plugin may be used under the terms of the GNU Lesser General Public License version 2.1 as published by the Free Software Foundation. Please review the following information to ensure the GNU Lesser General Public License version 2.1 requirements will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. </license> + <category>C++</category> <description>C/C++ editor component.</description> <url>http://qt.nokia.com</url> <dependencyList> diff --git a/src/plugins/cpptools/CppTools.pluginspec b/src/plugins/cpptools/CppTools.pluginspec index c8685ddd2e8c7f5e363385f0141c646be175514b..c6b53bdfbf20564412f0b1f6f67602c199d36517 100644 --- a/src/plugins/cpptools/CppTools.pluginspec +++ b/src/plugins/cpptools/CppTools.pluginspec @@ -10,6 +10,7 @@ GNU Lesser General Public License Usage Alternatively, this plugin may be used under the terms of the GNU Lesser General Public License version 2.1 as published by the Free Software Foundation. Please review the following information to ensure the GNU Lesser General Public License version 2.1 requirements will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. </license> + <category>C++</category> <description>Tools for analyzing C/C++ code.</description> <url>http://qt.nokia.com</url> <dependencyList> diff --git a/src/plugins/cvs/CVS.pluginspec b/src/plugins/cvs/CVS.pluginspec index e6e28e074beefa1f5780b931e16a960c4dd23db5..ee3148cb855ff56229de02c45dedcb4c66295514 100644 --- a/src/plugins/cvs/CVS.pluginspec +++ b/src/plugins/cvs/CVS.pluginspec @@ -10,6 +10,7 @@ GNU Lesser General Public License Usage Alternatively, this plugin may be used under the terms of the GNU Lesser General Public License version 2.1 as published by the Free Software Foundation. Please review the following information to ensure the GNU Lesser General Public License version 2.1 requirements will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. </license> + <category>Version Control</category> <description>CVS integration.</description> <url>http://qt.nokia.com</url> <dependencyList> diff --git a/src/plugins/debugger/Debugger.pluginspec b/src/plugins/debugger/Debugger.pluginspec index 4e10ecff6a317ce6ad7546b953ff93f156703259..4194600ee943137f7f0db1c3acddc371d3270b96 100644 --- a/src/plugins/debugger/Debugger.pluginspec +++ b/src/plugins/debugger/Debugger.pluginspec @@ -10,6 +10,7 @@ GNU Lesser General Public License Usage Alternatively, this plugin may be used under the terms of the GNU Lesser General Public License version 2.1 as published by the Free Software Foundation. Please review the following information to ensure the GNU Lesser General Public License version 2.1 requirements will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. </license> + <category>Qt Creator</category> <description>Debugger integration.</description> <url>http://qt.nokia.com</url> <dependencyList> diff --git a/src/plugins/designer/Designer.pluginspec b/src/plugins/designer/Designer.pluginspec index 94cdf06414815727a564771f3f0d136cdb9d0aea..c56bf55f8225f522d6f28505298797290f41755c 100644 --- a/src/plugins/designer/Designer.pluginspec +++ b/src/plugins/designer/Designer.pluginspec @@ -10,6 +10,7 @@ GNU Lesser General Public License Usage Alternatively, this plugin may be used under the terms of the GNU Lesser General Public License version 2.1 as published by the Free Software Foundation. Please review the following information to ensure the GNU Lesser General Public License version 2.1 requirements will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. </license> + <category>Qt Creator</category> <description>Qt Designer integration.</description> <url>http://qt.nokia.com</url> <dependencyList> diff --git a/src/plugins/find/Find.pluginspec b/src/plugins/find/Find.pluginspec index 1cd1cd351748d604e71e425dc314ef7189c0d6e3..a62a6099b6c1fedca016a4437e400bee971284e3 100644 --- a/src/plugins/find/Find.pluginspec +++ b/src/plugins/find/Find.pluginspec @@ -10,6 +10,7 @@ GNU Lesser General Public License Usage Alternatively, this plugin may be used under the terms of the GNU Lesser General Public License version 2.1 as published by the Free Software Foundation. Please review the following information to ensure the GNU Lesser General Public License version 2.1 requirements will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. </license> + <category>Qt Creator</category> <description>Provides the find widget and the hooks for find implementations.</description> <url>http://qt.nokia.com</url> <dependencyList> diff --git a/src/plugins/genericprojectmanager/GenericProjectManager.pluginspec b/src/plugins/genericprojectmanager/GenericProjectManager.pluginspec index c735fa2b7cc12f77028f311689829a83c32cebd7..8a4edee551452d9a84e1493b6235d20d64e915e4 100644 --- a/src/plugins/genericprojectmanager/GenericProjectManager.pluginspec +++ b/src/plugins/genericprojectmanager/GenericProjectManager.pluginspec @@ -10,6 +10,7 @@ GNU Lesser General Public License Usage Alternatively, this plugin may be used under the terms of the GNU Lesser General Public License version 2.1 as published by the Free Software Foundation. Please review the following information to ensure the GNU Lesser General Public License version 2.1 requirements will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. </license> + <category>Build Systems</category> <description>Generic support</description> <url>http://qt.nokia.com</url> <dependencyList> diff --git a/src/plugins/git/ScmGit.pluginspec b/src/plugins/git/ScmGit.pluginspec index 87ef25a05a5f69617bed5aa951c50a27ff1492a8..822d26afb35798c81f390bb4c7b2e61b283131a9 100644 --- a/src/plugins/git/ScmGit.pluginspec +++ b/src/plugins/git/ScmGit.pluginspec @@ -10,6 +10,7 @@ GNU Lesser General Public License Usage Alternatively, this plugin may be used under the terms of the GNU Lesser General Public License version 2.1 as published by the Free Software Foundation. Please review the following information to ensure the GNU Lesser General Public License version 2.1 requirements will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. </license> + <category>Version Control</category> <description>Git integration.</description> <url>http://qt.nokia.com</url> <dependencyList> diff --git a/src/plugins/help/Help.pluginspec b/src/plugins/help/Help.pluginspec index 9b06871d63d246ea306df0ab46fa3ad37386dbbd..ce7d606b8e2f772c2fe53d9915c8e369e9d1e04c 100644 --- a/src/plugins/help/Help.pluginspec +++ b/src/plugins/help/Help.pluginspec @@ -10,6 +10,7 @@ GNU Lesser General Public License Usage Alternatively, this plugin may be used under the terms of the GNU Lesser General Public License version 2.1 as published by the Free Software Foundation. Please review the following information to ensure the GNU Lesser General Public License version 2.1 requirements will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. </license> + <category>Qt Creator</category> <description>Help system.</description> <url>http://qt.nokia.com</url> <dependencyList> diff --git a/src/plugins/locator/Locator.pluginspec b/src/plugins/locator/Locator.pluginspec index dc25c5bbb299a224d47ea3147c6885e4cc1cc553..a71278899f9a0708205f67a53bf0909bded6f3ba 100644 --- a/src/plugins/locator/Locator.pluginspec +++ b/src/plugins/locator/Locator.pluginspec @@ -10,6 +10,7 @@ GNU Lesser General Public License Usage Alternatively, this plugin may be used under the terms of the GNU Lesser General Public License version 2.1 as published by the Free Software Foundation. Please review the following information to ensure the GNU Lesser General Public License version 2.1 requirements will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. </license> + <category>Qt Creator</category> <description>Provides the Locator widget and the hooks for Locator filter implementations.</description> <url>http://qt.nokia.com</url> <dependencyList> diff --git a/src/plugins/mercurial/Mercurial.pluginspec b/src/plugins/mercurial/Mercurial.pluginspec index 029767a34c8d5856f4be9ff07ddb9a0da21b102c..b054669a2e88aa3f5a715a10ecfbe5b4bfffff38 100644 --- a/src/plugins/mercurial/Mercurial.pluginspec +++ b/src/plugins/mercurial/Mercurial.pluginspec @@ -10,6 +10,7 @@ GNU Lesser General Public License Usage Alternatively, this plugin may be used under the terms of the GNU Lesser General Public License version 2.1 as published by the Free Software Foundation. Please review the following information to ensure the GNU Lesser General Public License version 2.1 requirements will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. </license> + <category>Version Control</category> <description>Mercurial integration.</description> <url>http://qt.nokia.com</url> <dependencyList> diff --git a/src/plugins/perforce/Perforce.pluginspec b/src/plugins/perforce/Perforce.pluginspec index 75acf2800a862b160032addf09105b5db3e5bf5b..c82605c826baa9c6b41d7266d7e90cf0ac605aa9 100644 --- a/src/plugins/perforce/Perforce.pluginspec +++ b/src/plugins/perforce/Perforce.pluginspec @@ -10,6 +10,7 @@ GNU Lesser General Public License Usage Alternatively, this plugin may be used under the terms of the GNU Lesser General Public License version 2.1 as published by the Free Software Foundation. Please review the following information to ensure the GNU Lesser General Public License version 2.1 requirements will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. </license> + <category>Version Control</category> <description>Perforce integration.</description> <url>http://qt.nokia.com</url> <dependencyList> diff --git a/src/plugins/projectexplorer/ProjectExplorer.pluginspec b/src/plugins/projectexplorer/ProjectExplorer.pluginspec index 138b35cc550d09ae600e903e3f0e70e8a0f2210f..772f357b4e1519eaa96ff45610259d547cec0e10 100644 --- a/src/plugins/projectexplorer/ProjectExplorer.pluginspec +++ b/src/plugins/projectexplorer/ProjectExplorer.pluginspec @@ -10,6 +10,7 @@ GNU Lesser General Public License Usage Alternatively, this plugin may be used under the terms of the GNU Lesser General Public License version 2.1 as published by the Free Software Foundation. Please review the following information to ensure the GNU Lesser General Public License version 2.1 requirements will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. </license> + <category>Qt Creator</category> <description>ProjectExplorer framework that can be extended with different kind of project types.</description> <url>http://qt.nokia.com</url> <dependencyList> diff --git a/src/plugins/qmldesigner/QmlDesigner.pluginspec b/src/plugins/qmldesigner/QmlDesigner.pluginspec index 6cecd7dc57dc3a21537ffcad1b4130801c268839..70bab152f88774c2c875fa610b449a2111344cc1 100644 --- a/src/plugins/qmldesigner/QmlDesigner.pluginspec +++ b/src/plugins/qmldesigner/QmlDesigner.pluginspec @@ -16,6 +16,7 @@ General Public License version 2.1 as published by the Free Software Foundation. Please review the following information to ensure the GNU Lesser General Public License version 2.1 requirements will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.</license> + <category>QML</category> <description>Editor for QML.</description> <url>http://qt.nokia.com</url> <dependencyList> diff --git a/src/plugins/qmldesigner/qmldesignerplugin.cpp b/src/plugins/qmldesigner/qmldesignerplugin.cpp index 91d02d7cae9014de9b0871644c63e3ffd9eb80f7..07aff5d0e374969e97cd418fb9ec01e7fec7c153 100644 --- a/src/plugins/qmldesigner/qmldesignerplugin.cpp +++ b/src/plugins/qmldesigner/qmldesignerplugin.cpp @@ -80,6 +80,7 @@ BauhausPlugin::BauhausPlugin() : m_closeAllEditorsAction(new QAction(this)), m_closeOtherEditorsAction(new QAction(this)) { + // Exceptions should never ever assert: they are handled in a number of // places where it is actually VALID AND EXPECTED BEHAVIOUR to get an // exception. diff --git a/src/plugins/qmlinspector/QmlInspector.pluginspec b/src/plugins/qmlinspector/QmlInspector.pluginspec index 0756edfb54a7fed8829dc20f6d5349cb28d795e2..46f2903c7c3b569d23d53b02822a95766043a708 100644 --- a/src/plugins/qmlinspector/QmlInspector.pluginspec +++ b/src/plugins/qmlinspector/QmlInspector.pluginspec @@ -16,6 +16,7 @@ General Public License version 2.1 as published by the Free Software Foundation. Please review the following information to ensure the GNU Lesser General Public License version 2.1 requirements will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.</license> + <category>QML</category> <description>Qml support</description> <url>http://qt.nokia.com</url> <dependencyList> diff --git a/src/plugins/qmljseditor/QmlJSEditor.pluginspec b/src/plugins/qmljseditor/QmlJSEditor.pluginspec index 16a858ff27ce5323216ebd8cd9102dccea7a0f79..2a9f5abee147662a9286692dc6cb7c339bd7bf8e 100644 --- a/src/plugins/qmljseditor/QmlJSEditor.pluginspec +++ b/src/plugins/qmljseditor/QmlJSEditor.pluginspec @@ -10,6 +10,7 @@ GNU Lesser General Public License Usage Alternatively, this plugin may be used under the terms of the GNU Lesser General Public License version 2.1 as published by the Free Software Foundation. Please review the following information to ensure the GNU Lesser General Public License version 2.1 requirements will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. </license> + <category>QML</category> <description>Editor for QML and JavaScript.</description> <url>http://qt.nokia.com</url> <dependencyList> diff --git a/src/plugins/qmlprojectmanager/QmlProjectManager.pluginspec b/src/plugins/qmlprojectmanager/QmlProjectManager.pluginspec index dc72d7003811e8a1ce74c9d09462740b2ad42f59..ed511bd1b05a5b78e0392191e5a9472deba605e3 100644 --- a/src/plugins/qmlprojectmanager/QmlProjectManager.pluginspec +++ b/src/plugins/qmlprojectmanager/QmlProjectManager.pluginspec @@ -10,6 +10,7 @@ GNU Lesser General Public License Usage Alternatively, this plugin may be used under the terms of the GNU Lesser General Public License version 2.1 as published by the Free Software Foundation. Please review the following information to ensure the GNU Lesser General Public License version 2.1 requirements will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. </license> + <category>QML</category> <description>Qml support</description> <url>http://qt.nokia.com</url> <dependencyList> diff --git a/src/plugins/qt4projectmanager/Qt4ProjectManager.pluginspec b/src/plugins/qt4projectmanager/Qt4ProjectManager.pluginspec index 62810ae00b4c67cad8d7a440bec62582a536cb28..b5c0fa54db1dcbaf2cc4e6e7586382411af9017a 100644 --- a/src/plugins/qt4projectmanager/Qt4ProjectManager.pluginspec +++ b/src/plugins/qt4projectmanager/Qt4ProjectManager.pluginspec @@ -10,6 +10,7 @@ GNU Lesser General Public License Usage Alternatively, this plugin may be used under the terms of the GNU Lesser General Public License version 2.1 as published by the Free Software Foundation. Please review the following information to ensure the GNU Lesser General Public License version 2.1 requirements will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. </license> + <category>Build Systems</category> <description>Provides project type for Qt 4 pro files and tools.</description> <url>http://qt.nokia.com</url> <dependencyList> diff --git a/src/plugins/resourceeditor/ResourceEditor.pluginspec b/src/plugins/resourceeditor/ResourceEditor.pluginspec index ce931a12b139a2feabed947f3f058c15b20a4828..fead8f7a5d08878a1e66cc6ba7e3b020b0a91c11 100644 --- a/src/plugins/resourceeditor/ResourceEditor.pluginspec +++ b/src/plugins/resourceeditor/ResourceEditor.pluginspec @@ -10,6 +10,7 @@ GNU Lesser General Public License Usage Alternatively, this plugin may be used under the terms of the GNU Lesser General Public License version 2.1 as published by the Free Software Foundation. Please review the following information to ensure the GNU Lesser General Public License version 2.1 requirements will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. </license> + <category>Qt Creator</category> <description>Editor for qrc files.</description> <url>http://qt.nokia.com</url> <dependencyList> diff --git a/src/plugins/subversion/Subversion.pluginspec b/src/plugins/subversion/Subversion.pluginspec index 97ac13bd264347475a47d81daece06d38e96f03e..8a939f78c8d4f043f9c2de432b9e2b486b40db65 100644 --- a/src/plugins/subversion/Subversion.pluginspec +++ b/src/plugins/subversion/Subversion.pluginspec @@ -10,6 +10,7 @@ GNU Lesser General Public License Usage Alternatively, this plugin may be used under the terms of the GNU Lesser General Public License version 2.1 as published by the Free Software Foundation. Please review the following information to ensure the GNU Lesser General Public License version 2.1 requirements will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. </license> + <category>Version Control</category> <description>Subversion integration.</description> <url>http://qt.nokia.com</url> <dependencyList> diff --git a/src/plugins/texteditor/TextEditor.pluginspec b/src/plugins/texteditor/TextEditor.pluginspec index 5d5a09b0bf2729eec72a6f27e744fa376920146b..19d2e755c202b481e3b1377dd541ab1c5b62fd20 100644 --- a/src/plugins/texteditor/TextEditor.pluginspec +++ b/src/plugins/texteditor/TextEditor.pluginspec @@ -10,6 +10,7 @@ GNU Lesser General Public License Usage Alternatively, this plugin may be used under the terms of the GNU Lesser General Public License version 2.1 as published by the Free Software Foundation. Please review the following information to ensure the GNU Lesser General Public License version 2.1 requirements will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. </license> + <category>Qt Creator</category> <description>Text editor framework and the implementation of the basic text editor.</description> <url>http://qt.nokia.com</url> <dependencyList> diff --git a/src/plugins/vcsbase/VCSBase.pluginspec b/src/plugins/vcsbase/VCSBase.pluginspec index 565b1341b7d0ab2f9d1fe85aa681370f5a6b1f09..90d1207bec0c618837a62f3c674478e6569e44c2 100644 --- a/src/plugins/vcsbase/VCSBase.pluginspec +++ b/src/plugins/vcsbase/VCSBase.pluginspec @@ -10,6 +10,7 @@ GNU Lesser General Public License Usage Alternatively, this plugin may be used under the terms of the GNU Lesser General Public License version 2.1 as published by the Free Software Foundation. Please review the following information to ensure the GNU Lesser General Public License version 2.1 requirements will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. </license> + <category>Version Control</category> <description>Version Control System Base Plugin</description> <url>http://qt.nokia.com</url> <dependencyList> diff --git a/src/plugins/welcome/Welcome.pluginspec b/src/plugins/welcome/Welcome.pluginspec index f475c877567a1d1c54e6af93379be6b9d17a0888..139a9a6f7b0040b683469b06ea05ed8593af6b24 100644 --- a/src/plugins/welcome/Welcome.pluginspec +++ b/src/plugins/welcome/Welcome.pluginspec @@ -10,6 +10,7 @@ GNU Lesser General Public License Usage Alternatively, this plugin may be used under the terms of the GNU Lesser General Public License version 2.1 as published by the Free Software Foundation. Please review the following information to ensure the GNU Lesser General Public License version 2.1 requirements will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. </license> + <category>Qt Creator</category> <description>Default Welcome Screen Plugin</description> <url>http://qt.nokia.com</url> <dependencyList>