diff --git a/share/qtcreator/templates/wizards/helloworld/wizard_sample.xml b/share/qtcreator/templates/wizards/helloworld/wizard_sample.xml
index 58e7748bccc..23af3d6802b 100644
--- a/share/qtcreator/templates/wizards/helloworld/wizard_sample.xml
+++ b/share/qtcreator/templates/wizards/helloworld/wizard_sample.xml
@@ -53,7 +53,8 @@ leave room for the Qt 4 target page.
Hallo Welt Parameter
-
+
Hello world message:
Hallo-Welt-Nachricht:
diff --git a/src/plugins/projectexplorer/baseprojectwizarddialog.cpp b/src/plugins/projectexplorer/baseprojectwizarddialog.cpp
index 166d2eb6222..a2324054709 100644
--- a/src/plugins/projectexplorer/baseprojectwizarddialog.cpp
+++ b/src/plugins/projectexplorer/baseprojectwizarddialog.cpp
@@ -41,13 +41,17 @@ namespace ProjectExplorer {
struct BaseProjectWizardDialogPrivate {
explicit BaseProjectWizardDialogPrivate(Utils::ProjectIntroPage *page, int id = -1);
- const int introId;
+ const int desiredIntroPageId;
Utils::ProjectIntroPage *introPage;
+ int introPageId;
+ int lastId;
};
BaseProjectWizardDialogPrivate::BaseProjectWizardDialogPrivate(Utils::ProjectIntroPage *page, int id) :
- introId(id),
- introPage(page)
+ desiredIntroPageId(id),
+ introPage(page),
+ introPageId(-1),
+ lastId(-1)
{
}
@@ -70,8 +74,14 @@ BaseProjectWizardDialog::BaseProjectWizardDialog(Utils::ProjectIntroPage *introP
void BaseProjectWizardDialog::init()
{
Core::BaseFileWizard::setupWizard(this);
- addPage(d->introPage);
+ if (d->introPageId == -1) {
+ d->introPageId = addPage(d->introPage);
+ } else {
+ d->introPageId = d->desiredIntroPageId;
+ setPage(d->desiredIntroPageId, d->introPage);
+ }
connect(this, SIGNAL(accepted()), this, SLOT(slotAccepted()));
+ connect(this, SIGNAL(currentIdChanged(int)), this, SLOT(slotBaseCurrentIdChanged(int)));
}
BaseProjectWizardDialog::~BaseProjectWizardDialog()
@@ -107,12 +117,21 @@ void BaseProjectWizardDialog::setProjectName(const QString &name)
void BaseProjectWizardDialog::slotAccepted()
{
if (d->introPage->useAsDefaultPath()) {
+ // Store the path as default path for new projects if desired.
Core::FileManager *fm = Core::ICore::instance()->fileManager();
fm->setProjectsDirectory(path());
fm->setUseProjectsDirectory(true);
}
}
+void BaseProjectWizardDialog::slotBaseCurrentIdChanged(int id)
+{
+ if (d->lastId == d->introPageId) {
+ emit introPageLeft(d->introPage->projectName(), d->introPage->path());
+ }
+ d->lastId = id;
+}
+
Utils::ProjectIntroPage *BaseProjectWizardDialog::introPage() const
{
return d->introPage;
diff --git a/src/plugins/projectexplorer/baseprojectwizarddialog.h b/src/plugins/projectexplorer/baseprojectwizarddialog.h
index f4f40c27813..a0b669644ae 100644
--- a/src/plugins/projectexplorer/baseprojectwizarddialog.h
+++ b/src/plugins/projectexplorer/baseprojectwizarddialog.h
@@ -71,11 +71,15 @@ public slots:
void setPath(const QString &path);
void setProjectName(const QString &name);
+signals:
+ void introPageLeft(const QString &projectName, const QString &path);
+
protected:
Utils::ProjectIntroPage *introPage() const;
private slots:
void slotAccepted();
+ void slotBaseCurrentIdChanged(int);
private:
void init();
diff --git a/src/plugins/projectexplorer/customwizard/customwizard.cpp b/src/plugins/projectexplorer/customwizard/customwizard.cpp
index ff468835af0..87dfbb2f2b1 100644
--- a/src/plugins/projectexplorer/customwizard/customwizard.cpp
+++ b/src/plugins/projectexplorer/customwizard/customwizard.cpp
@@ -35,8 +35,6 @@
#include
#include
-#include
-#include
#include
#include
@@ -52,7 +50,10 @@ static const char configFileC[] = "wizard.xml";
namespace ProjectExplorer {
struct CustomWizardPrivate {
+ CustomWizardPrivate() : m_context(new Internal::CustomWizardContext) {}
+
QSharedPointer m_parameters;
+ QSharedPointer m_context;
static int verbose;
};
@@ -105,7 +106,9 @@ void CustomWizard::initWizardDialog(QWizard *wizard, const QString &defaultPath,
const WizardPageList &extensionPages) const
{
QTC_ASSERT(!parameters().isNull(), return);
- Internal::CustomWizardPage *customPage = new Internal::CustomWizardPage(parameters()->fields);
+
+ d->m_context->reset();
+ Internal::CustomWizardPage *customPage = new Internal::CustomWizardPage(d->m_context, parameters()->fields);
customPage->setPath(defaultPath);
addWizardPage(wizard, customPage, parameters()->firstPageId);
if (!parameters()->fieldPageTitle.isEmpty())
@@ -127,57 +130,6 @@ QWizard *CustomWizard::createWizardDialog(QWidget *parent,
return wizard;
}
-// Replace field values delimited by '%' with special modifiers:
-// %Field% -> simple replacement
-// %Field:l% -> lower case replacement, 'u' for upper case and so on.
-static void replaceFields(const CustomProjectWizard::FieldReplacementMap &fm, QString *s)
-{
- const QChar delimiter = QLatin1Char('%');
- const QChar modifierDelimiter = QLatin1Char(':');
- int pos = 0;
- while (pos < s->size()) {
- pos = s->indexOf(delimiter, pos);
- if (pos < 0)
- break;
- int nextPos = s->indexOf(delimiter, pos + 1);
- if (nextPos == -1)
- break;
- nextPos++; // Point past 2nd delimiter
- if (nextPos == pos + 2) {
- pos = nextPos; // Skip '%%'
- continue;
- }
- // Evaluate field specification for modifiers
- // "%field:l%"
- QString fieldSpec = s->mid(pos + 1, nextPos - pos - 2);
- const int fieldSpecSize = fieldSpec.size();
- char modifier = '\0';
- if (fieldSpecSize >= 3 && fieldSpec.at(fieldSpecSize - 2) == modifierDelimiter) {
- modifier = fieldSpec.at(fieldSpecSize - 1).toLatin1();
- fieldSpec.truncate(fieldSpecSize - 2);
- }
- const CustomProjectWizard::FieldReplacementMap::const_iterator it = fm.constFind(fieldSpec);
- if (it == fm.constEnd()) {
- pos = nextPos; // Not found, skip
- continue;
- }
- // Assign
- QString replacement = it.value();
- switch (modifier) {
- case 'l':
- replacement = it.value().toLower();
- break;
- case 'u':
- replacement = it.value().toUpper();
- break;
- default:
- break;
- }
- s->replace(pos, nextPos - pos, replacement);
- pos += replacement.size();
- }
-}
-
// Read out files and store contents with field contents replaced.
static inline bool createFile(Internal::CustomWizardFile cwFile,
const QString &sourceDirectory,
@@ -188,7 +140,8 @@ static inline bool createFile(Internal::CustomWizardFile cwFile,
{
const QChar slash = QLatin1Char('/');
const QString sourcePath = sourceDirectory + slash + cwFile.source;
- replaceFields(fm, &cwFile.target);
+ // Field replacement on target path
+ Internal::CustomWizardContext::replaceFields(fm, &cwFile.target);
const QString targetPath = QDir::toNativeSeparators(targetDirectory + slash + cwFile.target);
if (CustomWizardPrivate::verbose)
qDebug() << "generating " << targetPath << sourcePath << fm;
@@ -197,9 +150,10 @@ static inline bool createFile(Internal::CustomWizardFile cwFile,
*errorMessage = QString::fromLatin1("Cannot open %1: %2").arg(sourcePath, file.errorString());
return false;
}
+ // Field replacement on contents
QString contents = QString::fromLocal8Bit(file.readAll());
if (!contents.isEmpty() && !fm.isEmpty())
- replaceFields(fm, &contents);
+ Internal::CustomWizardContext::replaceFields(fm, &contents);
Core::GeneratedFile generatedFile;
generatedFile.setContents(contents);
generatedFile.setPath(targetPath);
@@ -223,9 +177,16 @@ Core::GeneratedFiles CustomWizard::generateFiles(const QWizard *dialog, QString
const Internal::CustomWizardPage *cwp = findWizardPage(dialog);
QTC_ASSERT(cwp, return Core::GeneratedFiles())
QString path = cwp->path();
- const FieldReplacementMap fieldMap = defaultReplacementMap(dialog);
- if (CustomWizardPrivate::verbose)
- qDebug() << "CustomWizard::generateFiles" << dialog << path << fieldMap;
+ const FieldReplacementMap fieldMap = replacementMap(dialog);
+ if (CustomWizardPrivate::verbose) {
+ QString logText;
+ QTextStream str(&logText);
+ str << "CustomWizard::generateFiles: " << path << '\n';
+ const FieldReplacementMap::const_iterator cend = fieldMap.constEnd();
+ for (FieldReplacementMap::const_iterator it = fieldMap.constBegin(); it != cend; ++it)
+ str << " '" << it.key() << "' -> '" << it.value() << "'\n";
+ qWarning("%s", qPrintable(logText));
+ }
return generateWizardFiles(path, fieldMap, errorMessage);
}
@@ -243,20 +204,14 @@ Core::GeneratedFiles CustomWizard::generateWizardFiles(const QString &targetPath
return rc;
}
-// Create a default replacement map from the wizard dialog via fields
-// and add some useful fields.
-CustomWizard::FieldReplacementMap CustomWizard::defaultReplacementMap(const QWizard *w) const
+// Create a replacement map of static base fields + wizard dialog fields
+CustomWizard::FieldReplacementMap CustomWizard::replacementMap(const QWizard *w) const
{
- FieldReplacementMap fieldReplacementMap;
+ FieldReplacementMap fieldReplacementMap = d->m_context->baseReplacements;
foreach(const Internal::CustomWizardField &field, d->m_parameters->fields) {
const QString value = w->field(field.name).toString();
fieldReplacementMap.insert(field.name, value);
}
- const Core::MimeDatabase *mdb = Core::ICore::instance()->mimeDatabase();
- fieldReplacementMap.insert(QLatin1String("CppSourceSuffix"),
- mdb->preferredSuffixByType(QLatin1String(CppTools::Constants::CPP_SOURCE_MIMETYPE)));
- fieldReplacementMap.insert(QLatin1String("CppHeaderSuffix"),
- mdb->preferredSuffixByType(QLatin1String(CppTools::Constants::CPP_HEADER_MIMETYPE)));
return fieldReplacementMap;
}
@@ -265,6 +220,11 @@ CustomWizard::CustomWizardParametersPtr CustomWizard::parameters() const
return d->m_parameters;
}
+CustomWizard::CustomWizardContextPtr CustomWizard::context() const
+{
+ return d->m_context;
+}
+
// Static factory map
typedef QMap > CustomWizardFactoryMap;
Q_GLOBAL_STATIC(CustomWizardFactoryMap, customWizardFactoryMap)
@@ -407,17 +367,25 @@ void CustomProjectWizard::initProjectWizardDialog(BaseProjectWizardDialog *w,
const QString &defaultPath,
const WizardPageList &extensionPages) const
{
- QTC_ASSERT(!parameters().isNull(), return);
- if (!parameters()->fields.isEmpty()) {
- Internal::CustomWizardFieldPage *cp = new Internal::CustomWizardFieldPage(parameters()->fields);
+ const CustomWizardParametersPtr pa = parameters();
+ QTC_ASSERT(!pa.isNull(), return);
+
+ const CustomWizardContextPtr ctx = context();
+ ctx->reset();
+
+ if (!pa->fields.isEmpty()) {
+ Internal::CustomWizardFieldPage *cp = new Internal::CustomWizardFieldPage(ctx, pa->fields);
addWizardPage(w, cp, parameters()->firstPageId);
- if (!parameters()->fieldPageTitle.isEmpty())
- cp->setTitle(parameters()->fieldPageTitle);
+ if (!pa->fieldPageTitle.isEmpty())
+ cp->setTitle(pa->fieldPageTitle);
}
foreach(QWizardPage *ep, extensionPages)
w->addPage(ep);
w->setPath(defaultPath);
w->setProjectName(BaseProjectWizardDialog::uniqueProjectName(defaultPath));
+
+ connect(w, SIGNAL(introPageLeft(QString,QString)), this, SLOT(introPageLeft(QString,QString)));
+
if (CustomWizardPrivate::verbose)
qDebug() << "initProjectWizardDialog" << w << w->pageIds();
}
@@ -428,7 +396,7 @@ Core::GeneratedFiles CustomProjectWizard::generateFiles(const QWizard *w, QStrin
QTC_ASSERT(dialog, return Core::GeneratedFiles())
const QString targetPath = dialog->path() + QLatin1Char('/') + dialog->projectName();
// Add project name as macro.
- FieldReplacementMap fieldReplacementMap = defaultReplacementMap(dialog);
+ FieldReplacementMap fieldReplacementMap = replacementMap(dialog);
fieldReplacementMap.insert(QLatin1String("ProjectName"), dialog->projectName());
if (CustomWizardPrivate::verbose)
qDebug() << "CustomProjectWizard::generateFiles" << dialog << targetPath << fieldReplacementMap;
@@ -449,4 +417,10 @@ bool CustomProjectWizard::postGenerateFiles(const QWizard *, const Core::Generat
return true;
}
+void CustomProjectWizard::introPageLeft(const QString &project, const QString & /* path */)
+{
+ // Make '%ProjectName%' available in base replacements.
+ context()->baseReplacements.insert(QLatin1String("ProjectName"), project);
+}
+
} // namespace ProjectExplorer
diff --git a/src/plugins/projectexplorer/customwizard/customwizard.h b/src/plugins/projectexplorer/customwizard/customwizard.h
index b294a7bef3d..842afd85f51 100644
--- a/src/plugins/projectexplorer/customwizard/customwizard.h
+++ b/src/plugins/projectexplorer/customwizard/customwizard.h
@@ -49,6 +49,7 @@ class BaseProjectWizardDialog;
namespace Internal {
struct CustomWizardParameters;
+ struct CustomWizardContext;
}
// Factory for creating wizard. Can be registered under a name
@@ -105,6 +106,7 @@ public:
protected:
typedef QSharedPointer CustomWizardParametersPtr;
+ typedef QSharedPointer CustomWizardContextPtr;
void initWizardDialog(QWizard *w, const QString &defaultPath,
const WizardPageList &extensionPages) const;
@@ -113,10 +115,11 @@ protected:
Core::GeneratedFiles generateWizardFiles(const QString &path,
const FieldReplacementMap &defaultFields,
QString *errorMessage) const;
- // Create replacement map from QWizard fields with additional useful fields.
- FieldReplacementMap defaultReplacementMap(const QWizard *w) const;
+ // Create replacement map as static base fields + QWizard fields
+ FieldReplacementMap replacementMap(const QWizard *w) const;
CustomWizardParametersPtr parameters() const;
+ CustomWizardContextPtr context() const;
private:
void setParameters(const CustomWizardParametersPtr &p);
@@ -128,7 +131,9 @@ private:
// A custom project wizard presenting CustomProjectWizardDialog
// (Project intro page and fields page) for wizards of type "project".
// Overwrites postGenerateFiles() to open the project file which is the
-// last one by convention.
+// last one by convention. Also inserts '%ProjectName%' into the base
+// replacement map once the intro page is left to have it available
+// for QLineEdit-type fields' default text.
class PROJECTEXPLORER_EXPORT CustomProjectWizard : public CustomWizard
{
@@ -150,6 +155,9 @@ protected:
void initProjectWizardDialog(BaseProjectWizardDialog *w, const QString &defaultPath,
const WizardPageList &extensionPages) const;
+
+private slots:
+ void introPageLeft(const QString &project, const QString &path);
};
} // namespace ProjectExplorer
diff --git a/src/plugins/projectexplorer/customwizard/customwizardpage.cpp b/src/plugins/projectexplorer/customwizard/customwizardpage.cpp
index 290aba4884e..bb33911f04f 100644
--- a/src/plugins/projectexplorer/customwizard/customwizardpage.cpp
+++ b/src/plugins/projectexplorer/customwizard/customwizardpage.cpp
@@ -63,9 +63,17 @@ void TextFieldComboBox::setText(const QString &s)
}
// --------------- CustomWizardFieldPage
-CustomWizardFieldPage::CustomWizardFieldPage(const FieldList &fields,
+
+CustomWizardFieldPage::LineEditData::LineEditData(QLineEdit* le, const QString &defText) :
+ lineEdit(le), defaultText(defText)
+{
+}
+
+CustomWizardFieldPage::CustomWizardFieldPage(const QSharedPointer &ctx,
+ const FieldList &fields,
QWidget *parent) :
QWizardPage(parent),
+ m_context(ctx),
m_formLayout(new QFormLayout)
{
if (debug)
@@ -75,6 +83,10 @@ CustomWizardFieldPage::CustomWizardFieldPage(const FieldList &fields,
setLayout(m_formLayout);
}
+CustomWizardFieldPage::~CustomWizardFieldPage()
+{
+}
+
void CustomWizardFieldPage::addRow(const QString &name, QWidget *w)
{
m_formLayout->addRow(name, w);
@@ -82,36 +94,50 @@ void CustomWizardFieldPage::addRow(const QString &name, QWidget *w)
// Create widget a control based on the control attributes map
// and register it with the QWizard.
-QWidget *CustomWizardFieldPage::registerControl(const CustomWizardField &field)
+void CustomWizardFieldPage::addField(const CustomWizardField &field)\
{
- // Register field, Indicate mandatory by '*' (only when registering)
+ // Register field, indicate mandatory by '*' (only when registering)
QString fieldName = field.name;
if (field.mandatory)
fieldName += QLatin1Char('*');
// Check known classes: QComboBox
const QString className = field.controlAttributes.value(QLatin1String("class"));
+ QWidget *fieldWidget = 0;
if (className == QLatin1String("QComboBox")) {
- TextFieldComboBox *combo = new TextFieldComboBox;
- // Set up items
- do {
- const QString choices = field.controlAttributes.value(QLatin1String("combochoices"));
- if (choices.isEmpty())
- break;
- combo->addItems(choices.split(QLatin1Char(',')));
- bool ok;
- const QString currentIndexS = field.controlAttributes.value(QLatin1String("defaultindex"));
- if (currentIndexS.isEmpty())
- break;
- const int currentIndex = currentIndexS.toInt(&ok);
- if (!ok || currentIndex < 0 || currentIndex >= combo->count())
- break;
- combo->setCurrentIndex(currentIndex);
- } while (false);
- registerField(fieldName, combo, "text", SIGNAL(text4Changed(QString)));
- return combo;
- } // QComboBox
- // Default to QLineEdit
+ fieldWidget = registerComboBox(fieldName, field);
+ } else {
+ fieldWidget = registerLineEdit(fieldName, field);
+ }
+ addRow(field.description, fieldWidget);
+}
+
+QWidget *CustomWizardFieldPage::registerComboBox(const QString &fieldName,
+ const CustomWizardField &field)
+{
+ TextFieldComboBox *combo = new TextFieldComboBox;
+ do { // Set up items and current index
+ const QString choices = field.controlAttributes.value(QLatin1String("combochoices"));
+ if (choices.isEmpty())
+ break;
+ combo->addItems(choices.split(QLatin1Char(',')));
+ bool ok;
+ const QString currentIndexS = field.controlAttributes.value(QLatin1String("defaultindex"));
+ if (currentIndexS.isEmpty())
+ break;
+ const int currentIndex = currentIndexS.toInt(&ok);
+ if (!ok || currentIndex < 0 || currentIndex >= combo->count())
+ break;
+ combo->setCurrentIndex(currentIndex);
+ } while (false);
+ registerField(fieldName, combo, "text", SIGNAL(text4Changed(QString)));
+ return combo;
+} // QComboBox
+
+QWidget *CustomWizardFieldPage::registerLineEdit(const QString &fieldName,
+ const CustomWizardField &field)
+{
QLineEdit *lineEdit = new QLineEdit;
+
const QString validationRegExp = field.controlAttributes.value(QLatin1String("validator"));
if (!validationRegExp.isEmpty()) {
QRegExp re(validationRegExp);
@@ -120,29 +146,40 @@ QWidget *CustomWizardFieldPage::registerControl(const CustomWizardField &field)
} else {
qWarning("Invalid custom wizard field validator regular expression %s.", qPrintable(validationRegExp));
}
- m_validatorLineEdits.push_back(lineEdit);
}
- lineEdit->setText(field.controlAttributes.value(QLatin1String("defaulttext")));
registerField(fieldName, lineEdit, "text", SIGNAL(textEdited(QString)));
+
+ const QString defaultText = field.controlAttributes.value(QLatin1String("defaulttext"));
+ m_lineEdits.push_back(LineEditData(lineEdit, defaultText));
return lineEdit;
}
-void CustomWizardFieldPage::addField(const CustomWizardField &field)
+void CustomWizardFieldPage::initializePage()
{
- addRow(field.description, registerControl(field));
+ QWizardPage::initializePage();
+ // Note that the field mechanism will always restore the value
+ // set on it when entering the page, so, there is no point in
+ // trying to preserve user modifications of the text.
+ foreach(const LineEditData &led, m_lineEdits) {
+ if (!led.defaultText.isEmpty()) {
+ QString defaultText = led.defaultText;
+ CustomWizardContext::replaceFields(m_context->baseReplacements, &defaultText);
+ led.lineEdit->setText(defaultText);
+ }
+ }
}
bool CustomWizardFieldPage::validatePage()
{
// Check line edits with validators
- foreach(QLineEdit *le, m_validatorLineEdits) {
- int pos = 0;
- const QValidator *val = le->validator();
- QTC_ASSERT(val, return false);
- QString text = le->text();
- if (val->validate(text, pos) != QValidator::Acceptable) {
- le->setFocus();
- return false;
+ foreach(const LineEditData &led, m_lineEdits) {
+ if (const QValidator *val = led.lineEdit->validator()) {
+ int pos = 0;
+ QString text = led.lineEdit->text();
+ if (val->validate(text, pos) != QValidator::Acceptable) {
+ led.lineEdit->setFocus();
+ return false;
+ }
}
}
return QWizardPage::validatePage();
@@ -150,9 +187,10 @@ bool CustomWizardFieldPage::validatePage()
// --------------- CustomWizardPage
-CustomWizardPage::CustomWizardPage(const FieldList &f,
+CustomWizardPage::CustomWizardPage(const QSharedPointer &ctx,
+ const FieldList &f,
QWidget *parent) :
- CustomWizardFieldPage(f, parent),
+ CustomWizardFieldPage(ctx, f, parent),
m_pathChooser(new Utils::PathChooser)
{
addRow(tr("Path:"), m_pathChooser);
diff --git a/src/plugins/projectexplorer/customwizard/customwizardpage.h b/src/plugins/projectexplorer/customwizard/customwizardpage.h
index ce1484ab0c3..fe27a0873f3 100644
--- a/src/plugins/projectexplorer/customwizard/customwizardpage.h
+++ b/src/plugins/projectexplorer/customwizard/customwizardpage.h
@@ -48,6 +48,7 @@ namespace Internal {
struct CustomWizardField;
struct CustomWizardParameters;
+struct CustomWizardContext;
// A non-editable combo for text editing purposes that plays
// with QWizard::registerField (providing a settable text property).
@@ -74,19 +75,33 @@ class CustomWizardFieldPage : public QWizardPage {
public:
typedef QList FieldList;
- explicit CustomWizardFieldPage(const FieldList &f,
+ explicit CustomWizardFieldPage(const QSharedPointer &ctx,
+ const FieldList &f,
QWidget *parent = 0);
+ virtual ~CustomWizardFieldPage();
+
virtual bool validatePage();
+ virtual void initializePage();
protected:
inline void addRow(const QString &name, QWidget *w);
private:
- QWidget *registerControl(const CustomWizardField &f);
+ struct LineEditData {
+ explicit LineEditData(QLineEdit* le = 0, const QString &defText = QString());
+ QLineEdit* lineEdit;
+ QString defaultText;
+ };
+ typedef QList LineEditDataList;
+
+ QWidget *registerLineEdit(const QString &fieldName, const CustomWizardField &field);
+ QWidget *registerComboBox(const QString &fieldName, const CustomWizardField &field);
void addField(const CustomWizardField &f);
+
+ const QSharedPointer m_context;
QFormLayout *m_formLayout;
- QList m_validatorLineEdits;
+ LineEditDataList m_lineEdits;
};
// A custom wizard page presenting the fields to be used and a path chooser
@@ -96,7 +111,8 @@ private:
class CustomWizardPage : public CustomWizardFieldPage {
Q_OBJECT
public:
- explicit CustomWizardPage(const FieldList &f,
+ explicit CustomWizardPage(const QSharedPointer &ctx,
+ const FieldList &f,
QWidget *parent = 0);
QString path() const;
diff --git a/src/plugins/projectexplorer/customwizard/customwizardparameters.cpp b/src/plugins/projectexplorer/customwizard/customwizardparameters.cpp
index bf89b9fe902..c64c62c8c15 100644
--- a/src/plugins/projectexplorer/customwizard/customwizardparameters.cpp
+++ b/src/plugins/projectexplorer/customwizard/customwizardparameters.cpp
@@ -29,6 +29,10 @@
#include "customwizardparameters.h"
+#include
+#include
+#include
+
#include
#include
#include
@@ -467,5 +471,75 @@ QString CustomWizardParameters::toString() const
return rc;
}
+// ------------ CustomWizardContext
+
+void CustomWizardContext::replaceFields(const FieldReplacementMap &fm, QString *s)
+{
+ if (debug) {
+ qDebug().nospace() << "CustomWizardContext::replaceFields with " <<
+ fm << *s;
+ }
+ const QChar delimiter = QLatin1Char('%');
+ const QChar modifierDelimiter = QLatin1Char(':');
+ int pos = 0;
+ while (pos < s->size()) {
+ pos = s->indexOf(delimiter, pos);
+ if (pos < 0)
+ break;
+ int nextPos = s->indexOf(delimiter, pos + 1);
+ if (nextPos == -1)
+ break;
+ nextPos++; // Point past 2nd delimiter
+ if (nextPos == pos + 2) {
+ pos = nextPos; // Skip '%%'
+ continue;
+ }
+ // Evaluate field specification for modifiers
+ // "%field:l%"
+ QString fieldSpec = s->mid(pos + 1, nextPos - pos - 2);
+ const int fieldSpecSize = fieldSpec.size();
+ char modifier = '\0';
+ if (fieldSpecSize >= 3 && fieldSpec.at(fieldSpecSize - 2) == modifierDelimiter) {
+ modifier = fieldSpec.at(fieldSpecSize - 1).toLatin1();
+ fieldSpec.truncate(fieldSpecSize - 2);
+ }
+ const FieldReplacementMap::const_iterator it = fm.constFind(fieldSpec);
+ if (it == fm.constEnd()) {
+ pos = nextPos; // Not found, skip
+ continue;
+ }
+ // Assign
+ QString replacement = it.value();
+ switch (modifier) {
+ case 'l':
+ replacement = it.value().toLower();
+ break;
+ case 'u':
+ replacement = it.value().toUpper();
+ break;
+ case 'c': // Capitalize first letter
+ replacement = it.value();
+ if (!replacement.isEmpty())
+ replacement[0] = replacement.at(0).toUpper();
+ break;
+ default:
+ break;
+ }
+ s->replace(pos, nextPos - pos, replacement);
+ pos += replacement.size();
+ }
+}
+
+void CustomWizardContext::reset()
+{
+ // Basic replacement fields: Suffixes.
+ baseReplacements.clear();
+ const Core::MimeDatabase *mdb = Core::ICore::instance()->mimeDatabase();
+ baseReplacements.insert(QLatin1String("CppSourceSuffix"),
+ mdb->preferredSuffixByType(QLatin1String(CppTools::Constants::CPP_SOURCE_MIMETYPE)));
+ baseReplacements.insert(QLatin1String("CppHeaderSuffix"),
+ mdb->preferredSuffixByType(QLatin1String(CppTools::Constants::CPP_HEADER_MIMETYPE)));
+}
+
} // namespace Internal
} // namespace ProjectExplorer
diff --git a/src/plugins/projectexplorer/customwizard/customwizardparameters.h b/src/plugins/projectexplorer/customwizard/customwizardparameters.h
index 3ee6a19b23d..63c6c0adbc1 100644
--- a/src/plugins/projectexplorer/customwizard/customwizardparameters.h
+++ b/src/plugins/projectexplorer/customwizard/customwizardparameters.h
@@ -79,6 +79,28 @@ public:
int firstPageId;
};
+// Context used for one wizard run, shared between CustomWizard
+// and the CustomWizardPage as it is used for the QLineEdit-type fields'
+// default texts as well. Contains basic replacement fields
+// like '%CppSourceSuffix%', '%CppHeaderSuffix%' (settings-dependent)
+// reset() should be called before each wizard run to refresh them.
+// CustomProjectWizard additionally inserts '%ProjectName%' from
+// the intro page to have it available for default texts.
+
+struct CustomWizardContext {
+ typedef QMap FieldReplacementMap;
+
+ void reset();
+
+ // Replace field values delimited by '%' with special modifiers:
+ // %Field% -> simple replacement
+ // %Field:l% -> lower case replacement, 'u' upper case,
+ // 'c' capitalize first letter.
+ static void replaceFields(const FieldReplacementMap &fm, QString *s);
+
+ FieldReplacementMap baseReplacements;
+};
+
} // namespace Internal
} // namespace ProjectExplorer