Commit bccf4a1f authored by Friedemann Kleint's avatar Friedemann Kleint

Fixes: Introduce a cpp settingspage containing file naming conventions (lower...

Fixes: Introduce a cpp settingspage containing file naming conventions (lower case and suffixes). Reorder VCS settings pages.

Task: 241959, 248085

RevBy: Optics/Naming checked by con
Details: Give IOptionPage an id() to differentiate from trName(). Make showOptionsDialog return a bool (applied) and give it an optional parent. Change Cpp and form class wizards, give them a Configure... button to change those settings.
parent 3b030572
......@@ -150,5 +150,10 @@ void BaseValidatingLineEdit::slotReturnPressed()
emit validReturnPressed();
}
void BaseValidatingLineEdit::triggerChanged()
{
slotChanged(text());
}
} // namespace Utils
} // namespace Core
......@@ -72,6 +72,9 @@ public:
QColor errorColor() const;
void setErrorColor(const QColor &);
// Trigger an update (after changing settings)
void triggerChanged();
static QColor textColor(const QWidget *w);
static void setTextColor(QWidget *w, const QColor &c);
......
......@@ -43,13 +43,15 @@ struct ClassNameValidatingLineEditPrivate {
const QRegExp m_nameRegexp;
const QString m_namespaceDelimiter;
bool m_namespacesEnabled;
bool m_lowerCaseFileName;
};
// Match something like "Namespace1::Namespace2::ClassName".
ClassNameValidatingLineEditPrivate:: ClassNameValidatingLineEditPrivate() :
m_nameRegexp(QLatin1String("[a-zA-Z_][a-zA-Z0-9_]*(::[a-zA-Z_][a-zA-Z0-9_]*)*")),
m_namespaceDelimiter(QLatin1String("::")),
m_namespacesEnabled(false)
m_namespacesEnabled(false),
m_lowerCaseFileName(false)
{
QTC_ASSERT(m_nameRegexp.isValid(), return);
}
......@@ -96,7 +98,7 @@ void ClassNameValidatingLineEdit::slotChanged(const QString &t)
Core::Utils::BaseValidatingLineEdit::slotChanged(t);
if (isValid()) {
// Suggest file names, strip namespaces
QString fileName = t.toLower();
QString fileName = m_d->m_lowerCaseFileName ? t.toLower() : t;
if (m_d->m_namespacesEnabled) {
const int namespaceIndex = fileName.lastIndexOf(m_d->m_namespaceDelimiter);
if (namespaceIndex != -1)
......@@ -132,5 +134,15 @@ QString ClassNameValidatingLineEdit::createClassName(const QString &name)
return className;
}
bool ClassNameValidatingLineEdit::lowerCaseFileName() const
{
return m_d->m_lowerCaseFileName;
}
void ClassNameValidatingLineEdit::setLowerCaseFileName(bool v)
{
m_d->m_lowerCaseFileName = v;
}
} // namespace Utils
} // namespace Core
......@@ -46,6 +46,7 @@ class QWORKBENCH_UTILS_EXPORT ClassNameValidatingLineEdit
{
Q_DISABLE_COPY(ClassNameValidatingLineEdit)
Q_PROPERTY(bool namespacesEnabled READ namespacesEnabled WRITE setNamespacesEnabled DESIGNABLE true)
Q_PROPERTY(bool lowerCaseFileName READ lowerCaseFileName WRITE setLowerCaseFileName)
Q_OBJECT
public:
......@@ -55,6 +56,9 @@ public:
bool namespacesEnabled() const;
void setNamespacesEnabled(bool b);
bool lowerCaseFileName() const;
void setLowerCaseFileName(bool v);
// Clean an input string to get a valid class name.
static QString createClassName(const QString &name);
......
......@@ -84,7 +84,7 @@ NewClassWidget::NewClassWidget(QWidget *parent) :
m_d->m_ui.baseClassComboBox->setEditable(false);
connect(m_d->m_ui.classLineEdit, SIGNAL(updateFileName(QString)),
this, SLOT(updateFileNames(QString)));
this, SLOT(slotUpdateFileNames(QString)));
connect(m_d->m_ui.classLineEdit, SIGNAL(textEdited(QString)),
this, SLOT(classNameEdited()));
connect(m_d->m_ui.baseClassComboBox, SIGNAL(currentIndexChanged(int)),
......@@ -357,6 +357,16 @@ void NewClassWidget::setAllowDirectories(bool v)
}
}
bool NewClassWidget::lowerCaseFiles() const
{
return m_d->m_ui.classLineEdit->lowerCaseFileName();
}
void NewClassWidget::setLowerCaseFiles(bool v)
{
m_d->m_ui.classLineEdit->setLowerCaseFileName(v);
}
void NewClassWidget::slotValidChanged()
{
const bool newValid = isValid();
......@@ -415,7 +425,12 @@ bool NewClassWidget::isValid(QString *error) const
return true;
}
void NewClassWidget::updateFileNames(const QString &baseName)
void NewClassWidget::triggerUpdateFileNames()
{
m_d->m_ui.classLineEdit->triggerChanged();
}
void NewClassWidget::slotUpdateFileNames(const QString &baseName)
{
if (debugNewClassWidget)
qDebug() << Q_FUNC_INFO << baseName << m_d->m_headerExtension << m_d->m_sourceExtension;
......
......@@ -70,6 +70,7 @@ class QWORKBENCH_UTILS_EXPORT NewClassWidget : public QWidget
Q_PROPERTY(bool formInputCheckable READ formInputCheckable WRITE setFormInputCheckable DESIGNABLE true)
Q_PROPERTY(bool formInputChecked READ formInputChecked WRITE setFormInputChecked DESIGNABLE true)
Q_PROPERTY(bool allowDirectories READ allowDirectories WRITE setAllowDirectories)
Q_PROPERTY(bool lowerCaseFiles READ lowerCaseFiles WRITE setLowerCaseFiles)
// Utility "USER" property for wizards containing file names.
Q_PROPERTY(QStringList files READ files DESIGNABLE false USER true)
public:
......@@ -95,6 +96,7 @@ public:
QString headerExtension() const;
QString formExtension() const;
bool allowDirectories() const;
bool lowerCaseFiles() const;
bool isValid(QString *error = 0) const;
......@@ -123,19 +125,25 @@ public slots:
void setHeaderExtension(const QString &e);
void setFormExtension(const QString &e);
void setAllowDirectories(bool v);
void setLowerCaseFiles(bool v);
/* Suggest a class name from the base class by stripping the leading 'Q'
* character. This will happen automagically if the base class combo
* changes until the class line edited is manually edited. */
void suggestClassNameFromBase();
public slots:
// Trigger an update (after changing settings)
void triggerUpdateFileNames();
private slots:
void updateFileNames(const QString &t);
void slotUpdateFileNames(const QString &t);
void slotValidChanged();
void slotActivated();
void classNameEdited();
void slotFormInputChecked();
private:
void setFormInputCheckable(bool checkable, bool force);
......
......@@ -234,15 +234,19 @@ QString CMakeSettingsPage::findCmakeExecutable() const
return env.searchInPath("cmake");
}
QString CMakeSettingsPage::id() const
{
return QLatin1String("CMake");
}
QString CMakeSettingsPage::name() const
QString CMakeSettingsPage::trName() const
{
return "CMake";
return tr("CMake");
}
QString CMakeSettingsPage::category() const
{
return "CMake";
return QLatin1String("CMake");
}
QString CMakeSettingsPage::trCategory() const
......
......@@ -92,7 +92,8 @@ class CMakeSettingsPage : public Core::IOptionsPage
public:
CMakeSettingsPage();
virtual ~CMakeSettingsPage();
virtual QString name() const;
virtual QString id() const;
virtual QString trName() const;
virtual QString category() const;
virtual QString trCategory() const;
......
......@@ -64,9 +64,9 @@ QStringList CoreImpl::showNewItemDialog(const QString &title,
return m_mainwindow->showNewItemDialog(title, wizards, defaultLocation);
}
void CoreImpl::showOptionsDialog(const QString &group, const QString &page)
bool CoreImpl::showOptionsDialog(const QString &group, const QString &page, QWidget *parent)
{
m_mainwindow->showOptionsDialog(group, page);
return m_mainwindow->showOptionsDialog(group, page, parent);
}
ActionManager *CoreImpl::actionManager() const
......
......@@ -47,8 +47,9 @@ public:
QStringList showNewItemDialog(const QString &title,
const QList<IWizard *> &wizards,
const QString &defaultLocation = QString());
void showOptionsDialog(const QString &group = QString(),
const QString &page = QString());
bool showOptionsDialog(const QString &group = QString(),
const QString &page = QString(),
QWidget *parent = 0);
ActionManager *actionManager() const;
FileManager *fileManager() const ;
......
......@@ -38,6 +38,21 @@
namespace Core {
/*!
\class Core::IOptionsPage
\brief The IOptionsPage is an interface for providing options pages.
Guidelines for implementing:
\list
\o id() is an id used for filtering when calling ICore:: showOptionsDialog()
\o trName() is the (translated) name for display.
\o category() is the category used for filtering when calling ICore:: showOptionsDialog()
\o trCategory() is the translated category
\o apply() is called to store the settings. It should detect if any changes have been
made and store those.
\endlist
*/
class CORE_EXPORT IOptionsPage : public QObject
{
Q_OBJECT
......@@ -45,7 +60,8 @@ public:
IOptionsPage(QObject *parent = 0) : QObject(parent) {}
virtual ~IOptionsPage() {}
virtual QString name() const = 0;
virtual QString id() const = 0;
virtual QString trName() const = 0;
virtual QString category() const = 0;
virtual QString trCategory() const = 0;
......
......@@ -39,7 +39,7 @@ using namespace Core::Internal;
SettingsDialog::SettingsDialog(QWidget *parent, const QString &initialCategory,
const QString &initialPage)
: QDialog(parent)
: QDialog(parent), m_applied(false)
{
setupUi(this);
buttonBox->button(QDialogButtonBox::Ok)->setDefault(true);
......@@ -60,7 +60,7 @@ SettingsDialog::SettingsDialog(QWidget *parent, const QString &initialCategory,
int index = 0;
foreach (IOptionsPage *page, pages) {
QTreeWidgetItem *item = new QTreeWidgetItem;
item->setText(0, page->name());
item->setText(0, page->trName());
item->setData(0, Qt::UserRole, index);
QStringList categoriesId = page->category().split(QLatin1Char('|'));
......@@ -94,7 +94,7 @@ SettingsDialog::SettingsDialog(QWidget *parent, const QString &initialCategory,
m_pages.append(page);
stackedPages->addWidget(page->createPage(stackedPages));
if (page->name() == initialPage && currentCategory == initialCategory) {
if (page->id() == initialPage && currentCategory == initialCategory) {
stackedPages->setCurrentIndex(stackedPages->count());
pageTree->setCurrentItem(item);
}
......@@ -123,6 +123,7 @@ void SettingsDialog::pageSelected(QTreeWidgetItem *)
void SettingsDialog::accept()
{
m_applied = true;
foreach (IOptionsPage *page, m_pages) {
page->apply();
page->finish();
......@@ -141,4 +142,12 @@ void SettingsDialog::apply()
{
foreach (IOptionsPage *page, m_pages)
page->apply();
m_applied = true;
}
bool SettingsDialog::execDialog()
{
m_applied = false;
exec();
return m_applied;
}
......@@ -49,6 +49,10 @@ public:
const QString &initialPage = QString());
~SettingsDialog();
// Run the dialog and return true if 'Ok' was choosen or 'Apply' was invoked
// at least once
bool execDialog();
private slots:
void pageSelected(QTreeWidgetItem *cat);
void accept();
......@@ -57,6 +61,7 @@ private slots:
private:
QList<Core::IOptionsPage*> m_pages;
bool m_applied;
};
} // namespace Internal
......
......@@ -59,7 +59,13 @@ ShortcutSettings::~ShortcutSettings()
}
// IOptionsPage
QString ShortcutSettings::name() const
QString ShortcutSettings::id() const
{
return QLatin1String("Keyboard");
}
QString ShortcutSettings::trName() const
{
return tr("Keyboard");
}
......
......@@ -67,7 +67,8 @@ public:
~ShortcutSettings();
// IOptionsPage
QString name() const;
QString id() const;
QString trName() const;
QString category() const;
QString trCategory() const;
......
......@@ -43,7 +43,12 @@ GeneralSettings::GeneralSettings():
{
}
QString GeneralSettings::name() const
QString GeneralSettings::id() const
{
return QLatin1String("General");
}
QString GeneralSettings::trName() const
{
return tr("General");
}
......
......@@ -47,7 +47,8 @@ class GeneralSettings : public IOptionsPage
public:
GeneralSettings();
QString name() const;
QString id() const;
QString trName() const;
QString category() const;
QString trCategory() const;
QWidget* createPage(QWidget *parent);
......
......@@ -70,8 +70,9 @@ public:
const QList<IWizard *> &wizards,
const QString &defaultLocation = QString()) = 0;
virtual void showOptionsDialog(const QString &group = QString(),
const QString &page = QString()) = 0;
virtual bool showOptionsDialog(const QString &group = QString(),
const QString &page = QString(),
QWidget *parent = 0) = 0;
virtual ActionManager *actionManager() const = 0;
virtual FileManager *fileManager() const = 0;
......
......@@ -865,11 +865,15 @@ QStringList MainWindow::showNewItemDialog(const QString &title,
return wizard->runWizard(defaultDir, this);
}
void MainWindow::showOptionsDialog(const QString &category, const QString &page)
bool MainWindow::showOptionsDialog(const QString &category,
const QString &page,
QWidget *parent)
{
emit m_coreImpl->optionsDialogRequested();
SettingsDialog dlg(this, category, page);
dlg.exec();
if (!parent)
parent = this;
SettingsDialog dlg(parent, category, page);
return dlg.execDialog();
}
void MainWindow::saveAll()
......
......@@ -132,7 +132,9 @@ public slots:
const QList<IWizard *> &wizards,
const QString &defaultLocation = QString());
void showOptionsDialog(const QString &category = QString(), const QString &page = QString());
bool showOptionsDialog(const QString &category = QString(),
const QString &page = QString(),
QWidget *parent = 0);
protected:
virtual void changeEvent(QEvent *e);
......
......@@ -52,14 +52,19 @@ SettingsPage::SettingsPage()
}
}
QString SettingsPage::name() const
QString SettingsPage::id() const
{
return "General";
return QLatin1String("General");
}
QString SettingsPage::trName() const
{
return tr("General");
}
QString SettingsPage::category() const
{
return "CodePaster";
return QLatin1String("CodePaster");
}
QString SettingsPage::trCategory() const
......
......@@ -50,7 +50,8 @@ class SettingsPage : public Core::IOptionsPage
public:
SettingsPage();
QString name() const;
QString id() const;
QString trName() const;
QString category() const;
QString trCategory() const;
......
......@@ -30,6 +30,10 @@
#include "cppclasswizard.h"
#include "cppeditorconstants.h"
#include <cpptools/cpptoolsconstants.h>
#include <coreplugin/icore.h>
#include <coreplugin/mimedatabase.h>
#include <utils/codegeneration.h>
#include <utils/newclasswidget.h>
#include <utils/qtcassert.h>
......@@ -37,19 +41,21 @@
#include <QtCore/QDebug>
#include <QtCore/QDir>
#include <QtCore/QTextStream>
#include <QtCore/QSettings>
#include <QtGui/QVBoxLayout>
#include <QtGui/QHBoxLayout>
#include <QtGui/QPushButton>
#include <QtGui/QToolButton>
#include <QtGui/QSpacerItem>
#include <QtGui/QWizard>
using namespace CppEditor;
using namespace CppEditor::Internal;
// ========= ClassNamePage =========
ClassNamePage::ClassNamePage(const QString &sourceSuffix,
const QString &headerSuffix,
QWidget *parent) :
ClassNamePage::ClassNamePage(QWidget *parent) :
QWizardPage(parent),
m_isValid(false)
{
......@@ -58,8 +64,6 @@ ClassNamePage::ClassNamePage(const QString &sourceSuffix,
m_newClassWidget = new Core::Utils::NewClassWidget;
// Order, set extensions first before suggested name is derived
m_newClassWidget->setHeaderExtension(headerSuffix);
m_newClassWidget->setSourceExtension(sourceSuffix);
m_newClassWidget->setBaseClassInputVisible(true);
m_newClassWidget->setBaseClassChoices(QStringList() << QString()
<< QLatin1String("QObject")
......@@ -70,11 +74,50 @@ ClassNamePage::ClassNamePage(const QString &sourceSuffix,
m_newClassWidget->setNamespacesEnabled(true);
m_newClassWidget->setAllowDirectories(true);
connect(m_newClassWidget, SIGNAL(validChanged()),
this, SLOT(slotValidChanged()));
connect(m_newClassWidget, SIGNAL(validChanged()), this, SLOT(slotValidChanged()));
QVBoxLayout *pageLayout = new QVBoxLayout(this);
pageLayout->addWidget(m_newClassWidget);
QSpacerItem *vSpacer = new QSpacerItem(0, 0, QSizePolicy::Ignored, QSizePolicy::Expanding);
pageLayout->addItem(vSpacer);
QHBoxLayout *buttonLayout = new QHBoxLayout;
pageLayout->addLayout(buttonLayout);
QSpacerItem *hSpacer = new QSpacerItem(0, 0, QSizePolicy::Expanding, QSizePolicy::Ignored);
buttonLayout->addItem(hSpacer);
QToolButton *settingsButton = new QToolButton;
settingsButton->setText(tr("Configure..."));
connect(settingsButton, SIGNAL(clicked()), this, SLOT(slotSettings()));
buttonLayout->addWidget(settingsButton);
initParameters();
}
// Retrieve settings of CppTools plugin.
static inline bool lowerCaseFiles(const Core::ICore *core)
{
QString camelCaseSettingsKey = QLatin1String(CppTools::Constants::CPPTOOLS_SETTINGSGROUP);
camelCaseSettingsKey += QLatin1Char('/');
camelCaseSettingsKey += QLatin1String(CppTools::Constants::LOWERCASE_CPPFILES_KEY);
return core->settings()->value(camelCaseSettingsKey, QVariant(false)).toBool();
}
// Set up new class widget from settings
void ClassNamePage::initParameters()
{
Core::ICore *core = Core::ICore::instance();
const Core::MimeDatabase *mdb = core->mimeDatabase();
m_newClassWidget->setHeaderExtension(mdb->preferredSuffixByType(QLatin1String(Constants::CPP_HEADER_MIMETYPE)));
m_newClassWidget->setSourceExtension(mdb->preferredSuffixByType(QLatin1String(Constants::CPP_SOURCE_MIMETYPE)));
m_newClassWidget->setLowerCaseFiles(lowerCaseFiles(core));
}
void ClassNamePage::slotSettings()
{
const QString id = QLatin1String(CppTools::Constants::CPP_SETTINGS_ID);
const QString cat = QLatin1String(CppTools::Constants::CPP_SETTINGS_CATEGORY);
if (Core::ICore::instance()->showOptionsDialog(cat, id, this)) {
initParameters();
m_newClassWidget->triggerUpdateFileNames();
}
}
void ClassNamePage::slotValidChanged()
......@@ -86,11 +129,9 @@ void ClassNamePage::slotValidChanged()
}
}
CppClassWizardDialog::CppClassWizardDialog(const QString &sourceSuffix,
const QString &headerSuffix,
QWidget *parent) :
CppClassWizardDialog::CppClassWizardDialog(QWidget *parent) :
QWizard(parent),
m_classNamePage(new ClassNamePage(sourceSuffix, headerSuffix, this))
m_classNamePage(new ClassNamePage(this))
{
Core::BaseFileWizard::setupWizard(this);
setWindowTitle(tr("C++ Class Wizard"));
......@@ -136,7 +177,7 @@ QWizard *CppClassWizard::createWizardDialog(QWidget *parent,
const QString &defaultPath,
const WizardPageList &extensionPages) const
{
CppClassWizardDialog *wizard = new CppClassWizardDialog(sourceSuffix(), headerSuffix(), parent);
CppClassWizardDialog *wizard = new CppClassWizardDialog(parent);
foreach (QWizardPage *p, extensionPages)
wizard->addPage(p);
wizard->setPath(defaultPath);
......
......@@ -52,17 +52,18 @@ class ClassNamePage : public QWizardPage
Q_OBJECT
public:
ClassNamePage(const QString &sourceSuffix,
const QString &headerSuffix,
QWidget *parent = 0);
explicit ClassNamePage(QWidget *parent = 0);
bool isComplete() const { return m_isValid; }
Core::Utils::NewClassWidget *newClassWidget() const { return m_newClassWidget; }
private slots:
void slotValidChanged();
void slotSettings();
private:
void initParameters();
Core::Utils::NewClassWidget *m_newClassWidget;
bool m_isValid;
};
......@@ -82,9 +83,7 @@ class CppClassWizardDialog : public QWizard
Q_OBJECT
Q_DISABLE_COPY(CppClassWizardDialog)
public:
explicit CppClassWizardDialog(const QString &sourceSuffix,
const QString &headerSuffix,
QWidget *parent = 0);
explicit CppClassWizardDialog(QWidget *parent = 0);
void setPath(const QString &path);
CppClassWizardParameters parameters() const;
......
......@@ -56,9 +56,6 @@
#include <QtGui/QMenu>
#include <QtGui/QAction>
static const char *headerSuffixKeyC = "CppEditor/HeaderSuffix";