diff --git a/src/plugins/coreplugin/editormanager/editormanager.cpp b/src/plugins/coreplugin/editormanager/editormanager.cpp index a430488c38f..3b98fa3763e 100644 --- a/src/plugins/coreplugin/editormanager/editormanager.cpp +++ b/src/plugins/coreplugin/editormanager/editormanager.cpp @@ -477,13 +477,25 @@ void EditorManager::init() d->m_openEditorsFactory = new OpenEditorsViewFactory(); ExtensionSystem::PluginManager::addObject(d->m_openEditorsFactory); - VariableManager::registerFileVariables(kCurrentDocumentPrefix, tr("Current document")); - VariableManager::registerVariable(kCurrentDocumentXPos, - tr("X-coordinate of the current editor's upper left corner, relative to screen.")); - VariableManager::registerVariable(kCurrentDocumentYPos, - tr("Y-coordinate of the current editor's upper left corner, relative to screen.")); - connect(VariableManager::instance(), SIGNAL(variableUpdateRequested(QByteArray)), - m_instance, SLOT(updateVariable(QByteArray))); + VariableManager::registerFileVariables(kCurrentDocumentPrefix, tr("Current document"), + []() -> QString { + IDocument *document = currentDocument(); + return document ? document->filePath() : QString(); + }); + + VariableManager::registerIntVariable(kCurrentDocumentXPos, + tr("X-coordinate of the current editor's upper left corner, relative to screen."), + []() -> int { + IEditor *editor = currentEditor(); + return editor ? editor->widget()->mapToGlobal(QPoint(0, 0)).x() : 0; + }); + + VariableManager::registerIntVariable(kCurrentDocumentYPos, + tr("Y-coordinate of the current editor's upper left corner, relative to screen."), + []() -> int { + IEditor *editor = currentEditor(); + return editor ? editor->widget()->mapToGlobal(QPoint(0, 0)).y() : 0; + }); } void EditorManager::updateAutoSave() @@ -2579,30 +2591,3 @@ QString EditorManager::windowTitleVcsTopic() { return d->m_titleVcsTopic; } - -void EditorManager::updateVariable(const QByteArray &variable) -{ - if (VariableManager::isFileVariable(variable, kCurrentDocumentPrefix)) { - QString value; - IDocument *document = currentDocument(); - if (document) { - QString fileName = document->filePath(); - if (!fileName.isEmpty()) - value = VariableManager::fileVariableValue(variable, kCurrentDocumentPrefix, - fileName); - } - VariableManager::insert(variable, value); - } else if (variable == kCurrentDocumentXPos) { - QString value; - IEditor *curEditor = currentEditor(); - if (curEditor) - value = QString::number(curEditor->widget()->mapToGlobal(QPoint(0,0)).x()); - VariableManager::insert(variable, value); - } else if (variable == kCurrentDocumentYPos) { - QString value; - IEditor *curEditor = currentEditor(); - if (curEditor) - value = QString::number(curEditor->widget()->mapToGlobal(QPoint(0,0)).y()); - VariableManager::insert(variable, value); - } -} diff --git a/src/plugins/coreplugin/editormanager/editormanager.h b/src/plugins/coreplugin/editormanager/editormanager.h index d75d8effb0a..274badcd5c4 100644 --- a/src/plugins/coreplugin/editormanager/editormanager.h +++ b/src/plugins/coreplugin/editormanager/editormanager.h @@ -218,7 +218,6 @@ private slots: static void vcsOpenCurrentEditor(); static void updateWindowTitle(); void handleDocumentStateChange(); - static void updateVariable(const QByteArray &variable); static void autoSave(); static void saveDocumentFromContextMenu(); diff --git a/src/plugins/coreplugin/variablemanager.cpp b/src/plugins/coreplugin/variablemanager.cpp index 45d45f1dfe9..7981e222588 100644 --- a/src/plugins/coreplugin/variablemanager.cpp +++ b/src/plugins/coreplugin/variablemanager.cpp @@ -31,6 +31,7 @@ #include +#include #include #include #include @@ -56,7 +57,7 @@ public: class VariableManagerPrivate { public: - QHash m_map; + QHash m_map; VMMapExpander m_macroExpander; QMap m_descriptions; }; @@ -88,43 +89,31 @@ public: Plugins can register variables together with a description through registerVariable(), and then need to connect to the variableUpdateRequested() signal to actually give - the variable its value when requested. A typical setup is to + the variable its value when requested. A typical setup is to register + variables in the Plugin::initialize() function. - \list 1 - \li Register the variables in ExtensionSystem::IPlugin::initialize(): - \code - static const char kMyVariable[] = "MyVariable"; - - bool MyPlugin::initialize(const QStringList &arguments, QString *errorString) - { + \code + bool MyPlugin::initialize(const QStringList &arguments, QString *errorString) + { [...] - VariableManager::registerVariable(kMyVariable, tr("The current value of whatever I want.")); - connect(VariableManager::instance(), SIGNAL(variableUpdateRequested(QByteArray)), - this, SLOT(updateVariable(QByteArray))); - [...] - } - \endcode - - \li Set the variable value when requested: - \code - void MyPlugin::updateVariable(const QByteArray &variable) - { - if (variable == kMyVariable) { + VariableManager::registerVariable( + "MyVariable", + tr("The current value of whatever I want.")); + []() -> QString { QString value; // do whatever is necessary to retrieve the value [...] - VariableManager::insert(variable, value); + return value; } - } - \endcode - \endlist + ); + [...] + } + \endcode - If there are conditions where your variable is not valid, you should call - VariableManager::remove(kMyVariable) in updateVariable(). - For variables that refer to a file, you should use the convenience functions - VariableManager::registerFileVariables(), VariableManager::fileVariableValue() and - VariableManager::isFileVariable(). The functions take a variable prefix, like \c MyFileVariable, + For variables that refer to a file, you should use the convenience function + VariableManager::registerFileVariables(). + The functions take a variable prefix, like \c MyFileVariable, and automatically handle standardized postfixes like \c{:FilePath}, \c{:Path} and \c{:FileBaseName}, resulting in the combined variables, such as \c{MyFileVariable:FilePath}. @@ -205,46 +194,15 @@ VariableManager::~VariableManager() } /*! - * Used to set the \a value of a \a variable. Most of the time this is only done when - * requested by VariableManager::variableUpdateRequested(). If the value of the variable - * does not change, or changes very seldom, you can also keep the value up to date by calling - * this function whenever the value changes. - * - * As long as insert() was never called for a variable, it will not have a value, not even - * an empty string, meaning that the variable will not be expanded when expanding strings. - * - * \sa remove() - */ -void VariableManager::insert(const QByteArray &variable, const QString &value) -{ - d->m_map.insert(variable, value); -} - -/*! - * Removes any previous value for the given \a variable. This means that the variable - * will not be expanded at all when expanding strings, not even to an empty string. - * - * Returns true if the variable value could be removed, false if the variable value - * was not set when remove() was called. - * - * \sa insert() - */ -bool VariableManager::remove(const QByteArray &variable) -{ - return d->m_map.remove(variable) > 0; -} - -/*! - * Returns the value of the given \a variable. This will request an - * update of the variable's value first, by sending the variableUpdateRequested() signal. - * If \a found is given, it is set to true if the variable has a value at all, false if not. + * Returns the value of the given \a variable. If \a found is given, it is + * set to true if the variable has a value at all, false if not. */ QString VariableManager::value(const QByteArray &variable, bool *found) { - variableManagerInstance->variableUpdateRequested(variable); if (found) *found = d->m_map.contains(variable); - return d->m_map.value(variable); + StringFunction f = d->m_map.value(variable); + return f ? f() : QString(); } /*! @@ -273,24 +231,29 @@ Utils::AbstractMacroExpander *VariableManager::macroExpander() } /*! - * Returns the variable manager instance, for connecting to signals. All other functions are static - * and should be called as class functions, not through the instance. + * Makes the given string-valued \a variable known to the variable manager, + * together with a localized \a description. + * + * \sa registerFileVariables(), registerIntVariable() */ -QObject *VariableManager::instance() +void VariableManager::registerVariable(const QByteArray &variable, + const QString &description, const StringFunction &value) { - return variableManagerInstance; + d->m_descriptions.insert(variable, description); + d->m_map.insert(variable, value); } /*! - * Makes the given \a variable known to the variable manager, together with a localized - * \a description. It is not strictly necessary to register variables, but highly recommended, - * because this information is used and presented to the user by the VariableChooser. + * Makes the given integral-valued \a variable known to the variable manager, + * together with a localized \a description. * - * \sa registerFileVariables() + * \sa registerVariable(), registerFileVariables() */ -void VariableManager::registerVariable(const QByteArray &variable, const QString &description) +void VariableManager::registerIntVariable(const QByteArray &variable, + const QString &description, const VariableManager::IntFunction &value) { - d->m_descriptions.insert(variable, description); + registerVariable(variable, description, + [=]() -> QString { return QString::number(value ? value() : 0); }); } /*! @@ -300,71 +263,25 @@ void VariableManager::registerVariable(const QByteArray &variable, const QString * For example \c{registerFileVariables("CurrentDocument", tr("Current Document"))} registers * variables such as \c{CurrentDocument:FilePath} with description * "Current Document: Full path including file name." - * - * \sa isFileVariable() - * \sa fileVariableValue() */ -void VariableManager::registerFileVariables(const QByteArray &prefix, const QString &heading) +void VariableManager::registerFileVariables(const QByteArray &prefix, + const QString &heading, const StringFunction &base) { - registerVariable(prefix + kFilePathPostfix, tr("%1: Full path including file name.").arg(heading)); - registerVariable(prefix + kPathPostfix, tr("%1: Full path excluding file name.").arg(heading)); - registerVariable(prefix + kFileNamePostfix, tr("%1: File name without path.").arg(heading)); - registerVariable(prefix + kFileBaseNamePostfix, tr("%1: File base name without path and suffix.").arg(heading)); -} + registerVariable(prefix + kFilePathPostfix, + QCoreApplication::translate("Core::VariableManager", "%1: Full path including file name.").arg(heading), + [=]() -> QString { return QFileInfo(base()).filePath(); }); -/*! - * Returns whether the \a variable is a file kind of variable with the given \a prefix. For example - * \c{MyVariable:FilePath} is a file variable with prefix \c{MyVariable}. - * - * \sa registerFileVariables() - * \sa fileVariableValue() - */ -bool VariableManager::isFileVariable(const QByteArray &variable, const QByteArray &prefix) -{ - return variable == prefix + kFilePathPostfix - || variable == prefix + kPathPostfix - || variable == prefix + kFileNamePostfix - || variable == prefix + kFileBaseNamePostfix; -} + registerVariable(prefix + kPathPostfix, + QCoreApplication::translate("Core::VariableManager", "%1: Full path excluding file name.").arg(heading), + [=]() -> QString { return QFileInfo(base()).path(); }); -/*! - * Checks if the \a variable is a variable of the file type with the given \a prefix, and returns - * the value of the variable by extracting the wanted information from the given absolute - * \a fileName. - * Returns an empty string if the variable does not have the prefix, or does not have a - * postfix that is used for file variables, or if the file name is empty. - * - * \sa registerFileVariables() - * \sa isFileVariable() - */ -QString VariableManager::fileVariableValue(const QByteArray &variable, const QByteArray &prefix, - const QString &fileName) -{ - return fileVariableValue(variable, prefix, QFileInfo(fileName)); -} + registerVariable(prefix + kFileNamePostfix, + QCoreApplication::translate("Core::VariableManager", "%1: File name without path.").arg(heading), + [=]() -> QString { return QFileInfo(base()).fileName(); }); -/*! - * Checks if the \a variable is a variable of the file type with the given \a prefix, and returns - * the value of the variable by extracting the wanted information from the given - * \a fileInfo. - * Returns an empty string if the variable does not have the prefix, or does not have a - * postfix that is used for file variables, or if the file name is empty. - * - * \sa registerFileVariables() - * \sa isFileVariable() - */ -QString VariableManager::fileVariableValue(const QByteArray &variable, const QByteArray &prefix, - const QFileInfo &fileInfo) -{ - if (variable == prefix + kFilePathPostfix) - return fileInfo.filePath(); - else if (variable == prefix + kPathPostfix) - return fileInfo.path(); - else if (variable == prefix + kFileNamePostfix) - return fileInfo.fileName(); - else if (variable == prefix + kFileBaseNamePostfix) - return fileInfo.baseName(); - return QString(); + registerVariable(prefix + kFileBaseNamePostfix, + QCoreApplication::translate("Core::VariableManager", "%1: File base name without path and suffix.").arg(heading), + [=]() -> QString { return QFileInfo(base()).baseName(); }); } /*! diff --git a/src/plugins/coreplugin/variablemanager.h b/src/plugins/coreplugin/variablemanager.h index 4612bd8f4f3..a9d08b65baf 100644 --- a/src/plugins/coreplugin/variablemanager.h +++ b/src/plugins/coreplugin/variablemanager.h @@ -32,10 +32,10 @@ #include "core_global.h" -#include -#include +#include -QT_FORWARD_DECLARE_CLASS(QFileInfo) +#include +#include namespace Utils { class AbstractMacroExpander; } @@ -43,37 +43,30 @@ namespace Core { namespace Internal { class MainWindow; } -class CORE_EXPORT VariableManager : public QObject +class CORE_EXPORT VariableManager { - Q_OBJECT - public: - static QObject *instance(); - - static void insert(const QByteArray &variable, const QString &value); - static bool remove(const QByteArray &variable); static QString value(const QByteArray &variable, bool *found = 0); static QString expandedString(const QString &stringWithVariables); static Utils::AbstractMacroExpander *macroExpander(); + + typedef std::function StringFunction; + typedef std::function IntFunction; + static void registerVariable(const QByteArray &variable, - const QString &description); + const QString &description, const StringFunction &value); + + static void registerIntVariable(const QByteArray &variable, + const QString &description, const IntFunction &value); static void registerFileVariables(const QByteArray &prefix, - const QString &heading); - static bool isFileVariable(const QByteArray &variable, const QByteArray &prefix); - static QString fileVariableValue(const QByteArray &variable, const QByteArray &prefix, - const QString &fileName); - static QString fileVariableValue(const QByteArray &variable, const QByteArray &prefix, - const QFileInfo &fileInfo); + const QString &heading, const StringFunction &value); static QList variables(); static QString variableDescription(const QByteArray &variable); -signals: - void variableUpdateRequested(const QByteArray &variable); - private: VariableManager(); ~VariableManager(); diff --git a/src/plugins/debugger/debuggerengine.cpp b/src/plugins/debugger/debuggerengine.cpp index f3b7315dbcc..47d0bbac1b7 100644 --- a/src/plugins/debugger/debuggerengine.cpp +++ b/src/plugins/debugger/debuggerengine.cpp @@ -175,10 +175,10 @@ public: connect(&m_locationTimer, SIGNAL(timeout()), SLOT(resetLocation())); connect(debuggerCore()->action(IntelFlavor), SIGNAL(valueChanged(QVariant)), SLOT(reloadDisassembly())); + VariableManager::registerFileVariables(PrefixDebugExecutable, - tr("Debugged executable")); - connect(VariableManager::instance(), SIGNAL(variableUpdateRequested(QByteArray)), - SLOT(updateVariable(QByteArray))); + tr("Debugged executable"), + [&]() { return this->m_startParameters.executable; }); } public slots: @@ -190,13 +190,6 @@ public slots: void doInterruptInferior(); void doFinishDebugger(); - void updateVariable(const QByteArray &variable) - { - if (VariableManager::isFileVariable(variable, PrefixDebugExecutable)) - VariableManager::insert(variable, - VariableManager::fileVariableValue(variable, PrefixDebugExecutable, m_startParameters.executable)); - } - void reloadDisassembly() { m_disassemblerAgent.reload(); diff --git a/src/plugins/projectexplorer/projectexplorer.cpp b/src/plugins/projectexplorer/projectexplorer.cpp index 9c166eb1527..73f586b9b24 100644 --- a/src/plugins/projectexplorer/projectexplorer.cpp +++ b/src/plugins/projectexplorer/projectexplorer.cpp @@ -164,6 +164,18 @@ using namespace Core; namespace ProjectExplorer { +static Target *activeTarget() +{ + Project *project = ProjectExplorerPlugin::currentProject(); + return project ? project->activeTarget() : 0; +} + +static BuildConfiguration *activeBuildConfiguration() +{ + Target *target = activeTarget(); + return target ? target->activeBuildConfiguration() : 0; +} + struct ProjectExplorerPluginPrivate { ProjectExplorerPluginPrivate(); @@ -323,6 +335,25 @@ bool ProjectExplorerPlugin::parseArguments(const QStringList &arguments, QString return true; } +static QString variableValue(const char *variable) +{ + QString projectName; + QString projectFilePath; + Kit *kit = 0; + QString buildConfigurationName; + if (Project *project = ProjectExplorerPlugin::currentProject()) { + projectName = project->displayName(); + if (IDocument *doc = project->document()) + projectFilePath = doc->filePath(); + if (BuildConfiguration *buildConfiguration = activeBuildConfiguration()) + buildConfigurationName = buildConfiguration->displayName(); + } + ProjectMacroExpander expander(projectFilePath, projectName, kit, buildConfigurationName); + QString result; + expander.resolveProjectMacro(QString::fromUtf8(variable), &result); + return result; +} + bool ProjectExplorerPlugin::initialize(const QStringList &arguments, QString *error) { qRegisterMetaType(); @@ -1016,30 +1047,80 @@ bool ProjectExplorerPlugin::initialize(const QStringList &arguments, QString *er updateWelcomePage(); - VariableManager::registerFileVariables(Constants::VAR_CURRENTPROJECT_PREFIX, tr("Current project's main file")); - VariableManager::registerVariable(Constants::VAR_CURRENTPROJECT_BUILDPATH, - tr("Full build path of the current project's active build configuration.")); - VariableManager::registerVariable(Constants::VAR_CURRENTPROJECT_NAME, tr("The current project's name.")); - VariableManager::registerVariable(Constants::VAR_CURRENTKIT_NAME, tr("The currently active kit's name.")); - VariableManager::registerVariable(Constants::VAR_CURRENTKIT_FILESYSTEMNAME, - tr("The currently active kit's name in a filesystem friendly version.")); - VariableManager::registerVariable(Constants::VAR_CURRENTKIT_ID, tr("The currently active kit's id.")); - VariableManager::registerVariable(Constants::VAR_CURRENTDEVICE_HOSTADDRESS, - tr("The host address of the device in the currently active kit.")); - VariableManager::registerVariable(Constants::VAR_CURRENTDEVICE_SSHPORT, - tr("The SSH port of the device in the currently active kit.")); - VariableManager::registerVariable(Constants::VAR_CURRENTDEVICE_USERNAME, - tr("The user name with which to log into the device in the currently active kit.")); - VariableManager::registerVariable(Constants::VAR_CURRENTDEVICE_PRIVATEKEYFILE, - tr("The private key file with which to authenticate when logging into the device " - "in the currently active kit.")); - VariableManager::registerVariable(Constants::VAR_CURRENTBUILD_NAME, tr("The currently active build configuration's name.")); - VariableManager::registerVariable(Constants::VAR_CURRENTBUILD_TYPE, tr("The currently active build configuration's type.")); - VariableManager::registerFileVariables(Constants::VAR_CURRENTSESSION_PREFIX, tr("File where current session is saved.")); - VariableManager::registerVariable(Constants::VAR_CURRENTSESSION_NAME, tr("Name of current session.")); + VariableManager::registerFileVariables(Constants::VAR_CURRENTPROJECT_PREFIX, + tr("Current project's main file"), + []() { + QString projectFilePath; + if (Project *project = ProjectExplorerPlugin::currentProject()) + if (IDocument *doc = project->document()) + projectFilePath = doc->filePath(); + return projectFilePath; + }); - connect(VariableManager::instance(), SIGNAL(variableUpdateRequested(QByteArray)), - this, SLOT(updateVariable(QByteArray))); + VariableManager::registerVariable(Constants::VAR_CURRENTPROJECT_BUILDPATH, + tr("Full build path of the current project's active build configuration."), + []() -> QString { + BuildConfiguration *bc = activeBuildConfiguration(); + return bc ? bc->buildDirectory().toUserOutput() : QString(); + }); + + VariableManager::registerVariable(Constants::VAR_CURRENTPROJECT_NAME, + tr("The current project's name."), + []() -> QString { return variableValue(Constants::VAR_CURRENTPROJECT_NAME); }); + + VariableManager::registerVariable(Constants::VAR_CURRENTKIT_NAME, + tr("The currently active kit's name."), + []() -> QString { return variableValue(Constants::VAR_CURRENTKIT_NAME); }); + + VariableManager::registerVariable(Constants::VAR_CURRENTKIT_FILESYSTEMNAME, + tr("The currently active kit's name in a filesystem friendly version."), + []() -> QString { return variableValue(Constants::VAR_CURRENTKIT_FILESYSTEMNAME); }); + + VariableManager::registerVariable(Constants::VAR_CURRENTKIT_ID, + tr("The currently active kit's id."), + []() -> QString { return variableValue(Constants::VAR_CURRENTKIT_ID); }); + + VariableManager::registerVariable(Constants::VAR_CURRENTDEVICE_HOSTADDRESS, + tr("The host address of the device in the currently active kit."), + []() -> QString { return variableValue(Constants::VAR_CURRENTDEVICE_HOSTADDRESS); }); + + VariableManager::registerVariable(Constants::VAR_CURRENTDEVICE_SSHPORT, + tr("The SSH port of the device in the currently active kit."), + []() -> QString { return variableValue(Constants::VAR_CURRENTDEVICE_SSHPORT); }); + + VariableManager::registerVariable(Constants::VAR_CURRENTDEVICE_USERNAME, + tr("The user name with which to log into the device in the currently active kit."), + []() -> QString { return variableValue(Constants::VAR_CURRENTDEVICE_USERNAME); }); + + VariableManager::registerVariable(Constants::VAR_CURRENTDEVICE_PRIVATEKEYFILE, + tr("The private key file with which to authenticate when logging into the device " + "in the currently active kit."), + []() -> QString { return variableValue(Constants::VAR_CURRENTDEVICE_PRIVATEKEYFILE); }); + + VariableManager::registerVariable(Constants::VAR_CURRENTBUILD_NAME, + tr("The currently active build configuration's name."), + []() -> QString { return variableValue(Constants::VAR_CURRENTBUILD_NAME); }); + + VariableManager::registerVariable(Constants::VAR_CURRENTBUILD_TYPE, + tr("The currently active build configuration's type."), + []() -> QString { + if (BuildConfiguration *bc = activeBuildConfiguration()) { + BuildConfiguration::BuildType type = bc->buildType(); + if (type == BuildConfiguration::Debug) + return tr("debug"); + if (type == BuildConfiguration::Release) + return tr("release"); + } + return tr("unknown"); + }); + + VariableManager::registerFileVariables(Constants::VAR_CURRENTSESSION_PREFIX, + tr("File where current session is saved."), + []() -> QString { return SessionManager::sessionNameToFileName(SessionManager::activeSession()).toString(); }); + + VariableManager::registerVariable(Constants::VAR_CURRENTSESSION_NAME, + tr("Name of current session."), + []() -> QString { return SessionManager::activeSession(); }); return true; } @@ -1154,67 +1235,6 @@ void ProjectExplorerPlugin::loadCustomWizards() } } -void ProjectExplorerPlugin::updateVariable(const QByteArray &variable) -{ - if (variable == Constants::VAR_CURRENTPROJECT_BUILDPATH) { - if (currentProject() && currentProject()->activeTarget() && currentProject()->activeTarget()->activeBuildConfiguration()) { - VariableManager::insert(variable, - currentProject()->activeTarget()->activeBuildConfiguration()->buildDirectory().toUserOutput()); - } else { - VariableManager::remove(variable); - } - } else if (variable == Constants::VAR_CURRENTBUILD_TYPE) { - if (currentProject() && currentProject()->activeTarget() && currentProject()->activeTarget()->activeBuildConfiguration()) { - BuildConfiguration::BuildType type = currentProject()->activeTarget()->activeBuildConfiguration()->buildType(); - QString typeString; - if (type == BuildConfiguration::Debug) - typeString = tr("debug"); - else if (type == BuildConfiguration::Release) - typeString = tr("release"); - else - typeString = tr("unknown"); - VariableManager::insert(variable, typeString); - } else { - VariableManager::remove(variable); - } - } else if (variable == Constants::VAR_CURRENTSESSION_NAME) { - if (!SessionManager::activeSession().isEmpty()) - VariableManager::insert(variable, SessionManager::activeSession()); - else - VariableManager::remove(variable); - } else if (Core::VariableManager::isFileVariable( - variable, ProjectExplorer::Constants::VAR_CURRENTSESSION_PREFIX)) { - if (!SessionManager::activeSession().isEmpty()) { - VariableManager::insert(variable, Core::VariableManager::fileVariableValue(variable, - ProjectExplorer::Constants::VAR_CURRENTSESSION_PREFIX, - SessionManager::sessionNameToFileName(SessionManager::activeSession()).toFileInfo())); - } else { - VariableManager::remove(variable); - } - } else { - QString projectName; - QString projectFilePath; - Kit *kit = 0; - QString buildConfigurationName; - if (Project *project = currentProject()) { - projectName = project->displayName(); - if (IDocument *doc = project->document()) - projectFilePath = doc->filePath(); - if (Target *target = project->activeTarget()) { - kit = target->kit(); - if (BuildConfiguration *buildConfiguration = target->activeBuildConfiguration()) - buildConfigurationName = buildConfiguration->displayName(); - } - } - ProjectMacroExpander expander(projectFilePath, projectName, kit, buildConfigurationName); - QString result; - if (expander.resolveProjectMacro(QString::fromUtf8(variable), &result)) - VariableManager::insert(variable, result); - else - VariableManager::remove(variable); - } -} - void ProjectExplorerPlugin::updateRunWithoutDeployMenu() { d->m_runWithoutDeployAction->setVisible(d->m_projectExplorerSettings.deployBeforeRun); diff --git a/src/plugins/projectexplorer/projectexplorer.h b/src/plugins/projectexplorer/projectexplorer.h index 73e0a8a57a8..731a1723eb3 100644 --- a/src/plugins/projectexplorer/projectexplorer.h +++ b/src/plugins/projectexplorer/projectexplorer.h @@ -226,7 +226,6 @@ private slots: void currentModeChanged(Core::IMode *mode, Core::IMode *oldMode); void updateActions(); void loadCustomWizards(); - void updateVariable(const QByteArray &variable); void updateRunWithoutDeployMenu(); void updateWelcomePage(); diff --git a/src/plugins/projectexplorer/projectmacroexpander.cpp b/src/plugins/projectexplorer/projectmacroexpander.cpp index 4ce2f4086fc..04c87e7431a 100644 --- a/src/plugins/projectexplorer/projectmacroexpander.cpp +++ b/src/plugins/projectexplorer/projectmacroexpander.cpp @@ -51,14 +51,6 @@ bool ProjectMacroExpander::resolveProjectMacro(const QString &name, QString *ret result = m_projectName; found = true; } - } else if (Core::VariableManager::isFileVariable( - name.toUtf8(), ProjectExplorer::Constants::VAR_CURRENTPROJECT_PREFIX)) { - if (!m_projectFile.filePath().isEmpty()) { - result = Core::VariableManager::fileVariableValue(name.toUtf8(), - ProjectExplorer::Constants::VAR_CURRENTPROJECT_PREFIX, - m_projectFile); - found = true; - } } else if (m_kit && name == QLatin1String(ProjectExplorer::Constants::VAR_CURRENTKIT_NAME)) { result = m_kit->displayName(); found = true; @@ -101,6 +93,7 @@ bool ProjectMacroExpander::resolveProjectMacro(const QString &name, QString *ret return found; } +// Try to resolve using local information, otherwise fall back to global variables. bool ProjectMacroExpander::resolveMacro(const QString &name, QString *ret) { bool found = resolveProjectMacro(name, ret); diff --git a/src/plugins/projectexplorer/projectmacroexpander.h b/src/plugins/projectexplorer/projectmacroexpander.h index 6f8eda93ead..f54f9201891 100644 --- a/src/plugins/projectexplorer/projectmacroexpander.h +++ b/src/plugins/projectexplorer/projectmacroexpander.h @@ -50,6 +50,7 @@ private: const Kit *m_kit; QString m_bcName; }; -} // namespace + +} // namespace ProjectExplorer #endif // PROJECTMACROEXPANDER_H diff --git a/src/plugins/qtsupport/qtsupportplugin.cpp b/src/plugins/qtsupport/qtsupportplugin.cpp index 0fb831fcd20..15b9712e6ef 100644 --- a/src/plugins/qtsupport/qtsupportplugin.cpp +++ b/src/plugins/qtsupport/qtsupportplugin.cpp @@ -101,15 +101,28 @@ bool QtSupportPlugin::initialize(const QStringList &arguments, QString *errorMes return true; } +static QString qmakeProperty(const char *propertyName) +{ + ProjectExplorer::Project *project = ProjectExplorer::ProjectExplorerPlugin::currentProject(); + if (!project || !project->activeTarget()) + return QString(); + + const BaseQtVersion *qtVersion = QtKitInformation::qtVersion(project->activeTarget()->kit()); + if (!qtVersion) + return QString(); + return qtVersion->qmakeProperty(propertyName); +} + void QtSupportPlugin::extensionsInitialized() { VariableManager::registerVariable(kHostBins, - tr("Full path to the host bin directory of the current project's Qt version.")); + tr("Full path to the host bin directory of the current project's Qt version."), + []() -> QString { return qmakeProperty("QT_HOST_BINS"); }); + VariableManager::registerVariable(kInstallBins, tr("Full path to the target bin directory of the current project's Qt version." - " You probably want %1 instead.").arg(QString::fromLatin1(kHostBins))); - connect(VariableManager::instance(), SIGNAL(variableUpdateRequested(QByteArray)), - this, SLOT(updateVariable(QByteArray))); + " You probably want %1 instead.").arg(QString::fromLatin1(kHostBins)), + []() -> QString { return qmakeProperty("QT_INSTALL_BINS"); }); } bool QtSupportPlugin::delayedInitialize() @@ -117,25 +130,4 @@ bool QtSupportPlugin::delayedInitialize() return QtVersionManager::delayedInitialize(); } -void QtSupportPlugin::updateVariable(const QByteArray &variable) -{ - if (variable != kHostBins && variable != kInstallBins) - return; - - ProjectExplorer::Project *project = ProjectExplorer::ProjectExplorerPlugin::currentProject(); - if (!project || !project->activeTarget()) { - VariableManager::remove(variable); - return; - } - - const BaseQtVersion *qtVersion = QtKitInformation::qtVersion(project->activeTarget()->kit()); - if (!qtVersion) { - VariableManager::remove(variable); - return; - } - - QString value = qtVersion->qmakeProperty(variable == kHostBins ? "QT_HOST_BINS" : "QT_INSTALL_BINS"); - VariableManager::insert(variable, value); -} - Q_EXPORT_PLUGIN(QtSupportPlugin) diff --git a/src/plugins/qtsupport/qtsupportplugin.h b/src/plugins/qtsupport/qtsupportplugin.h index 60da5202009..9351a740e2a 100644 --- a/src/plugins/qtsupport/qtsupportplugin.h +++ b/src/plugins/qtsupport/qtsupportplugin.h @@ -47,10 +47,8 @@ public: void extensionsInitialized(); bool delayedInitialize(); -private slots: - void updateVariable(const QByteArray &variable); - #ifdef WITH_TESTS +private slots: void testQtOutputParser_data(); void testQtOutputParser(); void testQtOutputFormatter_data(); diff --git a/src/plugins/texteditor/texteditorplugin.cpp b/src/plugins/texteditor/texteditorplugin.cpp index c759ec8b2a5..998793ac0ea 100644 --- a/src/plugins/texteditor/texteditorplugin.cpp +++ b/src/plugins/texteditor/texteditorplugin.cpp @@ -200,6 +200,11 @@ bool TextEditorPlugin::initialize(const QStringList &arguments, QString *errorMe return true; } +static ITextEditor *currentTextEditor() +{ + return qobject_cast(Core::EditorManager::currentEditor()); +} + void TextEditorPlugin::extensionsInitialized() { m_searchResultWindow = Core::SearchResultWindow::instance(); @@ -216,19 +221,52 @@ void TextEditorPlugin::extensionsInitialized() addAutoReleasedObject(new FindInOpenFiles); Core::VariableManager::registerVariable(kCurrentDocumentSelection, - tr("Selected text within the current document.")); - Core::VariableManager::registerVariable(kCurrentDocumentRow, - tr("Line number of the text cursor position in current document (starts with 1).")); - Core::VariableManager::registerVariable(kCurrentDocumentColumn, - tr("Column number of the text cursor position in current document (starts with 0).")); - Core::VariableManager::registerVariable(kCurrentDocumentRowCount, - tr("Number of lines visible in current document.")); - Core::VariableManager::registerVariable(kCurrentDocumentColumnCount, - tr("Number of columns visible in current document.")); - Core::VariableManager::registerVariable(kCurrentDocumentFontSize, - tr("Current document's font size in points.")); - connect(Core::VariableManager::instance(), SIGNAL(variableUpdateRequested(QByteArray)), - this, SLOT(updateVariable(QByteArray))); + tr("Selected text within the current document."), + []() -> QString { + QString value; + if (ITextEditor *editor = currentTextEditor()) { + value = editor->selectedText(); + value.replace(QChar::ParagraphSeparator, QLatin1String("\n")); + } + return value; + }); + + Core::VariableManager::registerIntVariable(kCurrentDocumentRow, + tr("Line number of the text cursor position in current document (starts with 1)."), + []() -> int { + ITextEditor *editor = currentTextEditor(); + return editor ? editor->currentLine() : 0; + }); + + Core::VariableManager::registerIntVariable(kCurrentDocumentColumn, + tr("Column number of the text cursor position in current document (starts with 0)."), + []() -> int { + ITextEditor *editor = currentTextEditor(); + return editor ? editor->currentColumn() : 0; + }); + + Core::VariableManager::registerIntVariable(kCurrentDocumentRowCount, + tr("Number of lines visible in current document."), + []() -> int { + ITextEditor *editor = currentTextEditor(); + return editor ? editor->rowCount() : 0; + }); + + Core::VariableManager::registerIntVariable(kCurrentDocumentColumnCount, + tr("Number of columns visible in current document."), + []() -> int { + ITextEditor *editor = currentTextEditor(); + return editor ? editor->columnCount() : 0; + }); + + Core::VariableManager::registerIntVariable(kCurrentDocumentFontSize, + tr("Current document's font size in points."), + []() -> int { + ITextEditor *editor = currentTextEditor(); + return editor ? editor->widget()->font().pointSize() : 0; + }); + + connect(Core::ExternalToolManager::instance(), SIGNAL(replaceSelectionRequested(QString)), this, SLOT(updateCurrentSelection(QString))); } @@ -259,39 +297,6 @@ void TextEditorPlugin::updateSearchResultsFont(const FontSettings &settings) } } -void TextEditorPlugin::updateVariable(const QByteArray &variable) -{ - static QSet variables = QSet() - << kCurrentDocumentSelection - << kCurrentDocumentRow - << kCurrentDocumentColumn - << kCurrentDocumentRowCount - << kCurrentDocumentColumnCount - << kCurrentDocumentFontSize; - if (variables.contains(variable)) { - QString value; - Core::IEditor *iface = Core::EditorManager::currentEditor(); - ITextEditor *editor = qobject_cast(iface); - if (editor) { - if (variable == kCurrentDocumentSelection) { - value = editor->selectedText(); - value.replace(QChar::ParagraphSeparator, QLatin1String("\n")); - } else if (variable == kCurrentDocumentRow) { - value = QString::number(editor->currentLine()); - } else if (variable == kCurrentDocumentColumn) { - value = QString::number(editor->currentColumn()); - } else if (variable == kCurrentDocumentRowCount) { - value = QString::number(editor->rowCount()); - } else if (variable == kCurrentDocumentColumnCount) { - value = QString::number(editor->columnCount()); - } else if (variable == kCurrentDocumentFontSize) { - value = QString::number(editor->widget()->font().pointSize()); - } - } - Core::VariableManager::insert(variable, value); - } -} - void TextEditorPlugin::updateCurrentSelection(const QString &text) { if (ITextEditor *editor = qobject_cast(Core::EditorManager::currentEditor())) { diff --git a/src/plugins/texteditor/texteditorplugin.h b/src/plugins/texteditor/texteditorplugin.h index db057c7c840..dcbdc843770 100644 --- a/src/plugins/texteditor/texteditorplugin.h +++ b/src/plugins/texteditor/texteditorplugin.h @@ -70,7 +70,6 @@ private slots: void invokeCompletion(); void invokeQuickFix(); void updateSearchResultsFont(const TextEditor::FontSettings &); - void updateVariable(const QByteArray &variable); void updateCurrentSelection(const QString &text); private: diff --git a/src/plugins/vcsbase/vcsplugin.cpp b/src/plugins/vcsbase/vcsplugin.cpp index cabda189fd5..1ea2bf04f10 100644 --- a/src/plugins/vcsbase/vcsplugin.cpp +++ b/src/plugins/vcsbase/vcsplugin.cpp @@ -46,6 +46,9 @@ #include #include +using namespace Core; +using namespace ProjectExplorer; + namespace VcsBase { namespace Internal { @@ -83,15 +86,33 @@ bool VcsPlugin::initialize(const QStringList &arguments, QString *errorMessage) this, SLOT(slotSettingsChanged())); slotSettingsChanged(); - connect(Core::VariableManager::instance(), SIGNAL(variableUpdateRequested(QByteArray)), - this, SLOT(updateVariable(QByteArray))); + VariableManager::registerVariable(Constants::VAR_VCS_NAME, + tr("Name of the version control system in use by the current project."), + []() -> QString { + IVersionControl *vc = 0; + if (Project *project = ProjectExplorerPlugin::currentProject()) + vc = VcsManager::findVersionControlForDirectory(project->projectDirectory().toString()); + return vc ? vc->displayName() : QString(); + }); - Core::VariableManager::registerVariable(Constants::VAR_VCS_NAME, - tr("Name of the version control system in use by the current project.")); - Core::VariableManager::registerVariable(Constants::VAR_VCS_TOPIC, - tr("The current version control topic (branch or tag) identification of the current project.")); - Core::VariableManager::registerVariable(Constants::VAR_VCS_TOPLEVELPATH, - tr("The top level path to the repository the current project is in.")); + VariableManager::registerVariable(Constants::VAR_VCS_TOPIC, + tr("The current version control topic (branch or tag) identification of the current project."), + []() -> QString { + IVersionControl *vc = 0; + QString topLevel; + if (Project *project = ProjectExplorerPlugin::currentProject()) + vc = VcsManager::findVersionControlForDirectory(project->projectDirectory().toString(), &topLevel); + return vc ? vc->vcsTopic(topLevel) : QString(); + }); + + VariableManager::registerVariable(Constants::VAR_VCS_TOPLEVELPATH, + tr("The top level path to the repository the current project is in."), + []() -> QString { + QString topLevel; + if (Project *project = ProjectExplorerPlugin::currentProject()) + VcsManager::findVersionControlForDirectory(project->projectDirectory().toString(), &topLevel); + return topLevel; + }); return true; } @@ -141,42 +162,6 @@ void VcsPlugin::slotSettingsChanged() populateNickNameModel(); } -void VcsPlugin::updateVariable(const QByteArray &variable) -{ - static ProjectExplorer::Project *cachedProject = 0; - static Core::IVersionControl *cachedVc = 0; - static QString cachedTopLevel; - - ProjectExplorer::Project *project = ProjectExplorer::ProjectExplorerPlugin::currentProject(); - if (cachedProject != project) { - if (project) { - cachedVc = Core::VcsManager::findVersionControlForDirectory(project->projectDirectory().toString(), - &cachedTopLevel); - } else { - cachedVc = 0; - cachedTopLevel.clear(); - } - cachedProject = project; - } - - if (variable == Constants::VAR_VCS_NAME) { - if (cachedVc) - Core::VariableManager::insert(variable, cachedVc->displayName()); - else - Core::VariableManager::remove(variable); - } else if (variable == Constants::VAR_VCS_TOPIC) { - if (cachedVc) - Core::VariableManager::insert(variable, cachedVc->vcsTopic(cachedTopLevel)); - else - Core::VariableManager::remove(variable); - } else if (variable == Constants::VAR_VCS_TOPLEVELPATH) { - if (cachedVc) - Core::VariableManager::insert(variable, cachedTopLevel); - else - Core::VariableManager::remove(variable); - } -} - } // namespace Internal } // namespace VcsBase diff --git a/src/plugins/vcsbase/vcsplugin.h b/src/plugins/vcsbase/vcsplugin.h index c0baf218562..fd73b0d89a3 100644 --- a/src/plugins/vcsbase/vcsplugin.h +++ b/src/plugins/vcsbase/vcsplugin.h @@ -72,7 +72,6 @@ signals: private slots: void slotSettingsChanged(); - void updateVariable(const QByteArray &variable); private: void populateNickNameModel();