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();
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);
}
}

View File

@@ -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();

View File

@@ -31,6 +31,7 @@
#include <utils/stringutils.h>
#include <QCoreApplication>
#include <QFileInfo>
#include <QMap>
#include <QDebug>
@@ -56,7 +57,7 @@ public:
class VariableManagerPrivate
{
public:
QHash<QByteArray, QString> m_map;
QHash<QByteArray, VariableManager::StringFunction> m_map;
VMMapExpander m_macroExpander;
QMap<QByteArray, QString> 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)
{
[...]
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
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(); });
}
/*!

View File

@@ -32,10 +32,10 @@
#include "core_global.h"
#include <QObject>
#include <QString>
#include <functional>
QT_FORWARD_DECLARE_CLASS(QFileInfo)
#include <QFileInfo>
#include <QString>
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<QString()> StringFunction;
typedef std::function<int()> 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<QByteArray> variables();
static QString variableDescription(const QByteArray &variable);
signals:
void variableUpdateRequested(const QByteArray &variable);
private:
VariableManager();
~VariableManager();

View File

@@ -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();

View File

@@ -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<ProjectExplorer::RunControl *>();
@@ -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::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,
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."));
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."));
VariableManager::registerVariable(Constants::VAR_CURRENTKIT_ID, tr("The currently active kit's id."));
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."));
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."));
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."));
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."));
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."));
"in the currently active kit."),
[]() -> QString { return variableValue(Constants::VAR_CURRENTDEVICE_PRIVATEKEYFILE); });
connect(VariableManager::instance(), SIGNAL(variableUpdateRequested(QByteArray)),
this, SLOT(updateVariable(QByteArray)));
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);

View File

@@ -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();

View File

@@ -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);

View File

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

View File

@@ -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)

View File

@@ -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();

View File

@@ -200,6 +200,11 @@ bool TextEditorPlugin::initialize(const QStringList &arguments, QString *errorMe
return true;
}
static ITextEditor *currentTextEditor()
{
return qobject_cast<ITextEditor *>(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<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)
{
if (ITextEditor *editor = qobject_cast<ITextEditor *>(Core::EditorManager::currentEditor())) {

View File

@@ -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:

View File

@@ -46,6 +46,9 @@
#include <QtPlugin>
#include <QDebug>
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

View File

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