Variables: Use lambdas as callbacks to resolve variables

Instead of broadcasting for each resolution we ask the code
that knows about a specific variable directly.

Change-Id: I2f0f4f2acceba85a236995d236980594a3166bd8
Reviewed-by: Eike Ziller <eike.ziller@digia.com>
Reviewed-by: Daniel Teske <daniel.teske@digia.com>
This commit is contained in:
hjk
2014-06-23 16:57:56 +02:00
parent 000fbe63bc
commit 2982a763ac
15 changed files with 292 additions and 414 deletions

View File

@@ -477,13 +477,25 @@ void EditorManager::init()
d->m_openEditorsFactory = new OpenEditorsViewFactory(); d->m_openEditorsFactory = new OpenEditorsViewFactory();
ExtensionSystem::PluginManager::addObject(d->m_openEditorsFactory); ExtensionSystem::PluginManager::addObject(d->m_openEditorsFactory);
VariableManager::registerFileVariables(kCurrentDocumentPrefix, tr("Current document")); VariableManager::registerFileVariables(kCurrentDocumentPrefix, tr("Current document"),
VariableManager::registerVariable(kCurrentDocumentXPos, []() -> QString {
tr("X-coordinate of the current editor's upper left corner, relative to screen.")); IDocument *document = currentDocument();
VariableManager::registerVariable(kCurrentDocumentYPos, return document ? document->filePath() : QString();
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::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() void EditorManager::updateAutoSave()
@@ -2579,30 +2591,3 @@ QString EditorManager::windowTitleVcsTopic()
{ {
return d->m_titleVcsTopic; 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);
}
}

View File

@@ -218,7 +218,6 @@ private slots:
static void vcsOpenCurrentEditor(); static void vcsOpenCurrentEditor();
static void updateWindowTitle(); static void updateWindowTitle();
void handleDocumentStateChange(); void handleDocumentStateChange();
static void updateVariable(const QByteArray &variable);
static void autoSave(); static void autoSave();
static void saveDocumentFromContextMenu(); static void saveDocumentFromContextMenu();

View File

@@ -31,6 +31,7 @@
#include <utils/stringutils.h> #include <utils/stringutils.h>
#include <QCoreApplication>
#include <QFileInfo> #include <QFileInfo>
#include <QMap> #include <QMap>
#include <QDebug> #include <QDebug>
@@ -56,7 +57,7 @@ public:
class VariableManagerPrivate class VariableManagerPrivate
{ {
public: public:
QHash<QByteArray, QString> m_map; QHash<QByteArray, VariableManager::StringFunction> m_map;
VMMapExpander m_macroExpander; VMMapExpander m_macroExpander;
QMap<QByteArray, QString> m_descriptions; QMap<QByteArray, QString> m_descriptions;
}; };
@@ -88,43 +89,31 @@ public:
Plugins can register variables together with a description through registerVariable(), Plugins can register variables together with a description through registerVariable(),
and then need to connect to the variableUpdateRequested() signal to actually give 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 \code
static const char kMyVariable[] = "MyVariable";
bool MyPlugin::initialize(const QStringList &arguments, QString *errorString) bool MyPlugin::initialize(const QStringList &arguments, QString *errorString)
{ {
[...] [...]
VariableManager::registerVariable(kMyVariable, tr("The current value of whatever I want.")); VariableManager::registerVariable(
connect(VariableManager::instance(), SIGNAL(variableUpdateRequested(QByteArray)), "MyVariable",
this, SLOT(updateVariable(QByteArray))); tr("The current value of whatever I want."));
[...] []() -> QString {
}
\endcode
\li Set the variable value when requested:
\code
void MyPlugin::updateVariable(const QByteArray &variable)
{
if (variable == kMyVariable) {
QString value; QString value;
// do whatever is necessary to retrieve the value // do whatever is necessary to retrieve the value
[...] [...]
VariableManager::insert(variable, value); return value;
} }
);
[...]
} }
\endcode \endcode
\endlist
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 For variables that refer to a file, you should use the convenience function
VariableManager::registerFileVariables(), VariableManager::fileVariableValue() and VariableManager::registerFileVariables().
VariableManager::isFileVariable(). The functions take a variable prefix, like \c MyFileVariable, The functions take a variable prefix, like \c MyFileVariable,
and automatically handle standardized postfixes like \c{:FilePath}, and automatically handle standardized postfixes like \c{:FilePath},
\c{:Path} and \c{:FileBaseName}, resulting in the combined variables, such as \c{:Path} and \c{:FileBaseName}, resulting in the combined variables, such as
\c{MyFileVariable:FilePath}. \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 * Returns the value of the given \a variable. If \a found is given, it is
* requested by VariableManager::variableUpdateRequested(). If the value of the variable * set to true if the variable has a value at all, false if not.
* 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.
*/ */
QString VariableManager::value(const QByteArray &variable, bool *found) QString VariableManager::value(const QByteArray &variable, bool *found)
{ {
variableManagerInstance->variableUpdateRequested(variable);
if (found) if (found)
*found = d->m_map.contains(variable); *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 * Makes the given string-valued \a variable known to the variable manager,
* and should be called as class functions, not through the instance. * 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 * Makes the given integral-valued \a variable known to the variable manager,
* \a description. It is not strictly necessary to register variables, but highly recommended, * together with a localized \a description.
* because this information is used and presented to the user by the VariableChooser.
* *
* \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 * For example \c{registerFileVariables("CurrentDocument", tr("Current Document"))} registers
* variables such as \c{CurrentDocument:FilePath} with description * variables such as \c{CurrentDocument:FilePath} with description
* "Current Document: Full path including file name." * "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 + kFilePathPostfix,
registerVariable(prefix + kPathPostfix, tr("%1: Full path excluding file name.").arg(heading)); QCoreApplication::translate("Core::VariableManager", "%1: Full path including file name.").arg(heading),
registerVariable(prefix + kFileNamePostfix, tr("%1: File name without path.").arg(heading)); [=]() -> QString { return QFileInfo(base()).filePath(); });
registerVariable(prefix + kFileBaseNamePostfix, tr("%1: File base name without path and suffix.").arg(heading));
}
/*! registerVariable(prefix + kPathPostfix,
* Returns whether the \a variable is a file kind of variable with the given \a prefix. For example QCoreApplication::translate("Core::VariableManager", "%1: Full path excluding file name.").arg(heading),
* \c{MyVariable:FilePath} is a file variable with prefix \c{MyVariable}. [=]() -> QString { return QFileInfo(base()).path(); });
*
* \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 + kFileNamePostfix,
* Checks if the \a variable is a variable of the file type with the given \a prefix, and returns QCoreApplication::translate("Core::VariableManager", "%1: File name without path.").arg(heading),
* the value of the variable by extracting the wanted information from the given absolute [=]() -> QString { return QFileInfo(base()).fileName(); });
* \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 + kFileBaseNamePostfix,
* Checks if the \a variable is a variable of the file type with the given \a prefix, and returns QCoreApplication::translate("Core::VariableManager", "%1: File base name without path and suffix.").arg(heading),
* the value of the variable by extracting the wanted information from the given [=]() -> QString { return QFileInfo(base()).baseName(); });
* \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();
} }
/*! /*!

View File

@@ -32,10 +32,10 @@
#include "core_global.h" #include "core_global.h"
#include <QObject> #include <functional>
#include <QString>
QT_FORWARD_DECLARE_CLASS(QFileInfo) #include <QFileInfo>
#include <QString>
namespace Utils { class AbstractMacroExpander; } namespace Utils { class AbstractMacroExpander; }
@@ -43,37 +43,30 @@ namespace Core {
namespace Internal { class MainWindow; } namespace Internal { class MainWindow; }
class CORE_EXPORT VariableManager : public QObject class CORE_EXPORT VariableManager
{ {
Q_OBJECT
public: 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 value(const QByteArray &variable, bool *found = 0);
static QString expandedString(const QString &stringWithVariables); static QString expandedString(const QString &stringWithVariables);
static Utils::AbstractMacroExpander *macroExpander(); static Utils::AbstractMacroExpander *macroExpander();
typedef std::function<QString()> StringFunction;
typedef std::function<int()> IntFunction;
static void registerVariable(const QByteArray &variable, 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, static void registerFileVariables(const QByteArray &prefix,
const QString &heading); const QString &heading, const StringFunction &value);
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);
static QList<QByteArray> variables(); static QList<QByteArray> variables();
static QString variableDescription(const QByteArray &variable); static QString variableDescription(const QByteArray &variable);
signals:
void variableUpdateRequested(const QByteArray &variable);
private: private:
VariableManager(); VariableManager();
~VariableManager(); ~VariableManager();

View File

@@ -175,10 +175,10 @@ public:
connect(&m_locationTimer, SIGNAL(timeout()), SLOT(resetLocation())); connect(&m_locationTimer, SIGNAL(timeout()), SLOT(resetLocation()));
connect(debuggerCore()->action(IntelFlavor), SIGNAL(valueChanged(QVariant)), connect(debuggerCore()->action(IntelFlavor), SIGNAL(valueChanged(QVariant)),
SLOT(reloadDisassembly())); SLOT(reloadDisassembly()));
VariableManager::registerFileVariables(PrefixDebugExecutable, VariableManager::registerFileVariables(PrefixDebugExecutable,
tr("Debugged executable")); tr("Debugged executable"),
connect(VariableManager::instance(), SIGNAL(variableUpdateRequested(QByteArray)), [&]() { return this->m_startParameters.executable; });
SLOT(updateVariable(QByteArray)));
} }
public slots: public slots:
@@ -190,13 +190,6 @@ public slots:
void doInterruptInferior(); void doInterruptInferior();
void doFinishDebugger(); void doFinishDebugger();
void updateVariable(const QByteArray &variable)
{
if (VariableManager::isFileVariable(variable, PrefixDebugExecutable))
VariableManager::insert(variable,
VariableManager::fileVariableValue(variable, PrefixDebugExecutable, m_startParameters.executable));
}
void reloadDisassembly() void reloadDisassembly()
{ {
m_disassemblerAgent.reload(); m_disassemblerAgent.reload();

View File

@@ -164,6 +164,18 @@ using namespace Core;
namespace ProjectExplorer { 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 { struct ProjectExplorerPluginPrivate {
ProjectExplorerPluginPrivate(); ProjectExplorerPluginPrivate();
@@ -323,6 +335,25 @@ bool ProjectExplorerPlugin::parseArguments(const QStringList &arguments, QString
return true; 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) bool ProjectExplorerPlugin::initialize(const QStringList &arguments, QString *error)
{ {
qRegisterMetaType<ProjectExplorer::RunControl *>(); qRegisterMetaType<ProjectExplorer::RunControl *>();
@@ -1016,30 +1047,80 @@ bool ProjectExplorerPlugin::initialize(const QStringList &arguments, QString *er
updateWelcomePage(); updateWelcomePage();
VariableManager::registerFileVariables(Constants::VAR_CURRENTPROJECT_PREFIX, tr("Current project's main file")); 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;
});
VariableManager::registerVariable(Constants::VAR_CURRENTPROJECT_BUILDPATH, VariableManager::registerVariable(Constants::VAR_CURRENTPROJECT_BUILDPATH,
tr("Full build path of the current project's active build configuration.")); tr("Full build path of the current project's active build configuration."),
VariableManager::registerVariable(Constants::VAR_CURRENTPROJECT_NAME, tr("The current project's name.")); []() -> QString {
VariableManager::registerVariable(Constants::VAR_CURRENTKIT_NAME, tr("The currently active kit's name.")); 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, VariableManager::registerVariable(Constants::VAR_CURRENTKIT_FILESYSTEMNAME,
tr("The currently active kit's name in a filesystem friendly version.")); 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.")); []() -> 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, VariableManager::registerVariable(Constants::VAR_CURRENTDEVICE_HOSTADDRESS,
tr("The host address of the device in the currently active kit.")); 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, VariableManager::registerVariable(Constants::VAR_CURRENTDEVICE_SSHPORT,
tr("The SSH port of the device in the currently active kit.")); 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, VariableManager::registerVariable(Constants::VAR_CURRENTDEVICE_USERNAME,
tr("The user name with which to log into the device in the currently active kit.")); 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, VariableManager::registerVariable(Constants::VAR_CURRENTDEVICE_PRIVATEKEYFILE,
tr("The private key file with which to authenticate when logging into the device " tr("The private key file with which to authenticate when logging into the device "
"in the currently active kit.")); "in the currently active kit."),
VariableManager::registerVariable(Constants::VAR_CURRENTBUILD_NAME, tr("The currently active build configuration's name.")); []() -> QString { return variableValue(Constants::VAR_CURRENTDEVICE_PRIVATEKEYFILE); });
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."));
connect(VariableManager::instance(), SIGNAL(variableUpdateRequested(QByteArray)), VariableManager::registerVariable(Constants::VAR_CURRENTBUILD_NAME,
this, SLOT(updateVariable(QByteArray))); 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; 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() void ProjectExplorerPlugin::updateRunWithoutDeployMenu()
{ {
d->m_runWithoutDeployAction->setVisible(d->m_projectExplorerSettings.deployBeforeRun); d->m_runWithoutDeployAction->setVisible(d->m_projectExplorerSettings.deployBeforeRun);

View File

@@ -226,7 +226,6 @@ private slots:
void currentModeChanged(Core::IMode *mode, Core::IMode *oldMode); void currentModeChanged(Core::IMode *mode, Core::IMode *oldMode);
void updateActions(); void updateActions();
void loadCustomWizards(); void loadCustomWizards();
void updateVariable(const QByteArray &variable);
void updateRunWithoutDeployMenu(); void updateRunWithoutDeployMenu();
void updateWelcomePage(); void updateWelcomePage();

View File

@@ -51,14 +51,6 @@ bool ProjectMacroExpander::resolveProjectMacro(const QString &name, QString *ret
result = m_projectName; result = m_projectName;
found = true; 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)) { } else if (m_kit && name == QLatin1String(ProjectExplorer::Constants::VAR_CURRENTKIT_NAME)) {
result = m_kit->displayName(); result = m_kit->displayName();
found = true; found = true;
@@ -101,6 +93,7 @@ bool ProjectMacroExpander::resolveProjectMacro(const QString &name, QString *ret
return found; return found;
} }
// Try to resolve using local information, otherwise fall back to global variables.
bool ProjectMacroExpander::resolveMacro(const QString &name, QString *ret) bool ProjectMacroExpander::resolveMacro(const QString &name, QString *ret)
{ {
bool found = resolveProjectMacro(name, ret); bool found = resolveProjectMacro(name, ret);

View File

@@ -50,6 +50,7 @@ private:
const Kit *m_kit; const Kit *m_kit;
QString m_bcName; QString m_bcName;
}; };
} // namespace
} // namespace ProjectExplorer
#endif // PROJECTMACROEXPANDER_H #endif // PROJECTMACROEXPANDER_H

View File

@@ -101,15 +101,28 @@ bool QtSupportPlugin::initialize(const QStringList &arguments, QString *errorMes
return true; 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() void QtSupportPlugin::extensionsInitialized()
{ {
VariableManager::registerVariable(kHostBins, 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, VariableManager::registerVariable(kInstallBins,
tr("Full path to the target bin directory of the current project's Qt version." tr("Full path to the target bin directory of the current project's Qt version."
" You probably want %1 instead.").arg(QString::fromLatin1(kHostBins))); " You probably want %1 instead.").arg(QString::fromLatin1(kHostBins)),
connect(VariableManager::instance(), SIGNAL(variableUpdateRequested(QByteArray)), []() -> QString { return qmakeProperty("QT_INSTALL_BINS"); });
this, SLOT(updateVariable(QByteArray)));
} }
bool QtSupportPlugin::delayedInitialize() bool QtSupportPlugin::delayedInitialize()
@@ -117,25 +130,4 @@ bool QtSupportPlugin::delayedInitialize()
return QtVersionManager::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) Q_EXPORT_PLUGIN(QtSupportPlugin)

View File

@@ -47,10 +47,8 @@ public:
void extensionsInitialized(); void extensionsInitialized();
bool delayedInitialize(); bool delayedInitialize();
private slots:
void updateVariable(const QByteArray &variable);
#ifdef WITH_TESTS #ifdef WITH_TESTS
private slots:
void testQtOutputParser_data(); void testQtOutputParser_data();
void testQtOutputParser(); void testQtOutputParser();
void testQtOutputFormatter_data(); void testQtOutputFormatter_data();

View File

@@ -200,6 +200,11 @@ bool TextEditorPlugin::initialize(const QStringList &arguments, QString *errorMe
return true; return true;
} }
static ITextEditor *currentTextEditor()
{
return qobject_cast<ITextEditor *>(Core::EditorManager::currentEditor());
}
void TextEditorPlugin::extensionsInitialized() void TextEditorPlugin::extensionsInitialized()
{ {
m_searchResultWindow = Core::SearchResultWindow::instance(); m_searchResultWindow = Core::SearchResultWindow::instance();
@@ -216,19 +221,52 @@ void TextEditorPlugin::extensionsInitialized()
addAutoReleasedObject(new FindInOpenFiles); addAutoReleasedObject(new FindInOpenFiles);
Core::VariableManager::registerVariable(kCurrentDocumentSelection, Core::VariableManager::registerVariable(kCurrentDocumentSelection,
tr("Selected text within the current document.")); tr("Selected text within the current document."),
Core::VariableManager::registerVariable(kCurrentDocumentRow, []() -> QString {
tr("Line number of the text cursor position in current document (starts with 1).")); QString value;
Core::VariableManager::registerVariable(kCurrentDocumentColumn, if (ITextEditor *editor = currentTextEditor()) {
tr("Column number of the text cursor position in current document (starts with 0).")); value = editor->selectedText();
Core::VariableManager::registerVariable(kCurrentDocumentRowCount, value.replace(QChar::ParagraphSeparator, QLatin1String("\n"));
tr("Number of lines visible in current document.")); }
Core::VariableManager::registerVariable(kCurrentDocumentColumnCount, return value;
tr("Number of columns visible in current document.")); });
Core::VariableManager::registerVariable(kCurrentDocumentFontSize,
tr("Current document's font size in points.")); Core::VariableManager::registerIntVariable(kCurrentDocumentRow,
connect(Core::VariableManager::instance(), SIGNAL(variableUpdateRequested(QByteArray)), tr("Line number of the text cursor position in current document (starts with 1)."),
this, SLOT(updateVariable(QByteArray))); []() -> 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)), connect(Core::ExternalToolManager::instance(), SIGNAL(replaceSelectionRequested(QString)),
this, SLOT(updateCurrentSelection(QString))); this, SLOT(updateCurrentSelection(QString)));
} }
@@ -259,39 +297,6 @@ void TextEditorPlugin::updateSearchResultsFont(const FontSettings &settings)
} }
} }
void TextEditorPlugin::updateVariable(const QByteArray &variable)
{
static QSet<QByteArray> variables = QSet<QByteArray>()
<< kCurrentDocumentSelection
<< kCurrentDocumentRow
<< kCurrentDocumentColumn
<< kCurrentDocumentRowCount
<< kCurrentDocumentColumnCount
<< kCurrentDocumentFontSize;
if (variables.contains(variable)) {
QString value;
Core::IEditor *iface = Core::EditorManager::currentEditor();
ITextEditor *editor = qobject_cast<ITextEditor *>(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) void TextEditorPlugin::updateCurrentSelection(const QString &text)
{ {
if (ITextEditor *editor = qobject_cast<ITextEditor *>(Core::EditorManager::currentEditor())) { if (ITextEditor *editor = qobject_cast<ITextEditor *>(Core::EditorManager::currentEditor())) {

View File

@@ -70,7 +70,6 @@ private slots:
void invokeCompletion(); void invokeCompletion();
void invokeQuickFix(); void invokeQuickFix();
void updateSearchResultsFont(const TextEditor::FontSettings &); void updateSearchResultsFont(const TextEditor::FontSettings &);
void updateVariable(const QByteArray &variable);
void updateCurrentSelection(const QString &text); void updateCurrentSelection(const QString &text);
private: private:

View File

@@ -46,6 +46,9 @@
#include <QtPlugin> #include <QtPlugin>
#include <QDebug> #include <QDebug>
using namespace Core;
using namespace ProjectExplorer;
namespace VcsBase { namespace VcsBase {
namespace Internal { namespace Internal {
@@ -83,15 +86,33 @@ bool VcsPlugin::initialize(const QStringList &arguments, QString *errorMessage)
this, SLOT(slotSettingsChanged())); this, SLOT(slotSettingsChanged()));
slotSettingsChanged(); slotSettingsChanged();
connect(Core::VariableManager::instance(), SIGNAL(variableUpdateRequested(QByteArray)), VariableManager::registerVariable(Constants::VAR_VCS_NAME,
this, SLOT(updateVariable(QByteArray))); 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, VariableManager::registerVariable(Constants::VAR_VCS_TOPIC,
tr("Name of the version control system in use by the current project.")); tr("The current version control topic (branch or tag) identification of the current project."),
Core::VariableManager::registerVariable(Constants::VAR_VCS_TOPIC, []() -> QString {
tr("The current version control topic (branch or tag) identification of the current project.")); IVersionControl *vc = 0;
Core::VariableManager::registerVariable(Constants::VAR_VCS_TOPLEVELPATH, QString topLevel;
tr("The top level path to the repository the current project is in.")); 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; return true;
} }
@@ -141,42 +162,6 @@ void VcsPlugin::slotSettingsChanged()
populateNickNameModel(); 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 Internal
} // namespace VcsBase } // namespace VcsBase

View File

@@ -72,7 +72,6 @@ signals:
private slots: private slots:
void slotSettingsChanged(); void slotSettingsChanged();
void updateVariable(const QByteArray &variable);
private: private:
void populateNickNameModel(); void populateNickNameModel();