diff options
author | con <qtc-commiter@nokia.com> | 2008-12-02 12:01:29 +0100 |
---|---|---|
committer | con <qtc-commiter@nokia.com> | 2008-12-02 12:01:29 +0100 |
commit | 05c35356abc31549c5db6eba31fb608c0365c2a0 (patch) | |
tree | be044530104267afaff13f8943889cb97f8c8bad /src/libs/utils/newclasswidget.cpp | |
download | qt-creator-05c35356abc31549c5db6eba31fb608c0365c2a0.tar.gz |
Initial import
Diffstat (limited to 'src/libs/utils/newclasswidget.cpp')
-rw-r--r-- | src/libs/utils/newclasswidget.cpp | 462 |
1 files changed, 462 insertions, 0 deletions
diff --git a/src/libs/utils/newclasswidget.cpp b/src/libs/utils/newclasswidget.cpp new file mode 100644 index 0000000000..67cd1f8691 --- /dev/null +++ b/src/libs/utils/newclasswidget.cpp @@ -0,0 +1,462 @@ +/*************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Qt Software Information (qt-info@nokia.com) +** +** +** Non-Open Source Usage +** +** Licensees may use this file in accordance with the Qt Beta Version +** License Agreement, Agreement version 2.2 provided with the Software or, +** alternatively, in accordance with the terms contained in a written +** agreement between you and Nokia. +** +** GNU General Public License Usage +** +** Alternatively, this file may be used under the terms of the GNU General +** Public License versions 2.0 or 3.0 as published by the Free Software +** Foundation and appearing in the file LICENSE.GPL included in the packaging +** of this file. Please review the following information to ensure GNU +** General Public Licensing requirements will be met: +** +** http://www.fsf.org/licensing/licenses/info/GPLv2.html and +** http://www.gnu.org/copyleft/gpl.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt GPL Exception version +** 1.2, included in the file GPL_EXCEPTION.txt in this package. +** +***************************************************************************/ +#include "newclasswidget.h" +#include "ui_newclasswidget.h" + +#include <utils/filewizardpage.h> + +#include <QtGui/QFileDialog> +#include <QtCore/QFileInfo> +#include <QtCore/QStringList> +#include <QtCore/QDir> +#include <QtCore/QDebug> +#include <QtCore/QRegExp> + +enum { debugNewClassWidget = 0 }; + +namespace Core { +namespace Utils { + +struct NewClassWidgetPrivate { + NewClassWidgetPrivate(); + + Ui::NewClassWidget m_ui; + QString m_headerExtension; + QString m_sourceExtension; + QString m_formExtension; + bool m_valid; + bool m_classEdited; + // Store the "visible" values to prevent the READ accessors from being + // fooled by a temporarily hidden widget + bool m_baseClassInputVisible; + bool m_formInputVisible; + bool m_pathInputVisible; + bool m_formInputCheckable; +}; + +NewClassWidgetPrivate:: NewClassWidgetPrivate() : + m_headerExtension(QLatin1String("h")), + m_sourceExtension(QLatin1String("cpp")), + m_formExtension(QLatin1String("ui")), + m_valid(false), + m_classEdited(false), + m_baseClassInputVisible(true), + m_formInputVisible(true), + m_pathInputVisible(true), + m_formInputCheckable(false) +{ +} + +// --------------------- NewClassWidget +NewClassWidget::NewClassWidget(QWidget *parent) : + QWidget(parent), + m_d(new NewClassWidgetPrivate) +{ + m_d->m_ui.setupUi(this); + + m_d->m_ui.baseClassComboBox->setEditable(false); + + connect(m_d->m_ui.classLineEdit, SIGNAL(updateFileName(QString)), + this, SLOT(updateFileNames(QString))); + connect(m_d->m_ui.classLineEdit, SIGNAL(textEdited(QString)), + this, SLOT(classNameEdited())); + connect(m_d->m_ui.baseClassComboBox, SIGNAL(currentIndexChanged(int)), + this, SLOT(suggestClassNameFromBase())); + connect(m_d->m_ui.baseClassComboBox, SIGNAL(editTextChanged(QString)), + this, SLOT(slotValidChanged())); + connect(m_d->m_ui.classLineEdit, SIGNAL(validChanged()), + this, SLOT(slotValidChanged())); + connect(m_d->m_ui.headerFileLineEdit, SIGNAL(validChanged()), + this, SLOT(slotValidChanged())); + connect(m_d->m_ui.sourceFileLineEdit, SIGNAL(validChanged()), + this, SLOT(slotValidChanged())); + connect(m_d->m_ui.formFileLineEdit, SIGNAL(validChanged()), + this, SLOT(slotValidChanged())); + connect(m_d->m_ui.pathChooser, SIGNAL(validChanged()), + this, SLOT(slotValidChanged())); + + connect(m_d->m_ui.classLineEdit, SIGNAL(validReturnPressed()), + this, SLOT(slotActivated())); + connect(m_d->m_ui.headerFileLineEdit, SIGNAL(validReturnPressed()), + this, SLOT(slotActivated())); + connect(m_d->m_ui.sourceFileLineEdit, SIGNAL(validReturnPressed()), + this, SLOT(slotActivated())); + connect(m_d->m_ui.formFileLineEdit, SIGNAL(validReturnPressed()), + this, SLOT(slotActivated())); + connect(m_d->m_ui.formFileLineEdit, SIGNAL(validReturnPressed()), + this, SLOT(slotActivated())); + connect(m_d->m_ui.pathChooser, SIGNAL(returnPressed()), + this, SLOT(slotActivated())); + + connect(m_d->m_ui.generateFormCheckBox, SIGNAL(stateChanged(int)), + this, SLOT(slotFormInputChecked())); + + m_d->m_ui.generateFormCheckBox->setChecked(true); + setFormInputCheckable(false, true); +} + +NewClassWidget::~NewClassWidget() +{ + delete m_d; +} + +void NewClassWidget::classNameEdited() +{ + if (debugNewClassWidget) + qDebug() << Q_FUNC_INFO << m_d->m_headerExtension << m_d->m_sourceExtension; + m_d->m_classEdited = true; +} + +void NewClassWidget::suggestClassNameFromBase() +{ + if (debugNewClassWidget) + qDebug() << Q_FUNC_INFO << m_d->m_headerExtension << m_d->m_sourceExtension; + if (m_d->m_classEdited) + return; + // Suggest a class unless edited ("QMainWindow"->"MainWindow") + QString base = baseClassName(); + if (base.startsWith(QLatin1Char('Q'))) { + base.remove(0, 1); + setClassName(base); + } +} + +QStringList NewClassWidget::baseClassChoices() const +{ + QStringList rc; + const int count = m_d->m_ui.baseClassComboBox->count(); + for (int i = 0; i < count; i++) + rc.push_back(m_d->m_ui.baseClassComboBox->itemText(i)); + return rc; +} + +void NewClassWidget::setBaseClassChoices(const QStringList &choices) +{ + m_d->m_ui.baseClassComboBox->clear(); + m_d->m_ui.baseClassComboBox->addItems(choices); +} + +void NewClassWidget::setBaseClassInputVisible(bool visible) +{ + m_d->m_baseClassInputVisible = visible; + m_d->m_ui.baseClassLabel->setVisible(visible); + m_d->m_ui.baseClassComboBox->setVisible(visible); +} + +void NewClassWidget::setBaseClassEditable(bool editable) +{ + m_d->m_ui.baseClassComboBox->setEditable(editable); +} + +bool NewClassWidget::isBaseClassInputVisible() const +{ + return m_d->m_baseClassInputVisible; +} + +bool NewClassWidget::isBaseClassEditable() const +{ + return m_d->m_ui.baseClassComboBox->isEditable(); +} + +void NewClassWidget::setFormInputVisible(bool visible) +{ + m_d->m_formInputVisible = visible; + m_d->m_ui.formLabel->setVisible(visible); + m_d->m_ui.formFileLineEdit->setVisible(visible); +} + +bool NewClassWidget::isFormInputVisible() const +{ + return m_d->m_formInputVisible; +} + +void NewClassWidget::setFormInputCheckable(bool checkable) +{ + setFormInputCheckable(checkable, false); +} + +void NewClassWidget::setFormInputCheckable(bool checkable, bool force) +{ + if (!force && checkable == m_d->m_formInputCheckable) + return; + m_d->m_formInputCheckable = checkable; + m_d->m_ui.generateFormLabel->setVisible(checkable); + m_d->m_ui.generateFormCheckBox->setVisible(checkable); +} + +void NewClassWidget::setFormInputChecked(bool v) +{ + m_d->m_ui.generateFormCheckBox->setChecked(v); +} + +bool NewClassWidget::formInputCheckable() const +{ + return m_d->m_formInputCheckable; +} + +bool NewClassWidget::formInputChecked() const +{ + return m_d->m_ui.generateFormCheckBox->isChecked(); +} + +void NewClassWidget::slotFormInputChecked() +{ + const bool checked = formInputChecked(); + m_d->m_ui.formLabel->setEnabled(checked); + m_d->m_ui.formFileLineEdit->setEnabled(checked); +} + +void NewClassWidget::setPathInputVisible(bool visible) +{ + m_d->m_pathInputVisible = visible; + m_d->m_ui.pathLabel->setVisible(visible); + m_d->m_ui.pathChooser->setVisible(visible); +} + +bool NewClassWidget::isPathInputVisible() const +{ + return m_d->m_pathInputVisible; +} + +void NewClassWidget::setClassName(const QString &suggestedName) +{ + if (debugNewClassWidget) + qDebug() << Q_FUNC_INFO << suggestedName << m_d->m_headerExtension << m_d->m_sourceExtension; + m_d->m_ui.classLineEdit->setText(ClassNameValidatingLineEdit::createClassName(suggestedName)); +} + +QString NewClassWidget::className() const +{ + return m_d->m_ui.classLineEdit->text(); +} + +QString NewClassWidget::baseClassName() const +{ + return m_d->m_ui.baseClassComboBox->currentText(); +} + +void NewClassWidget::setBaseClassName(const QString &c) +{ + const int index = m_d->m_ui.baseClassComboBox->findText(c); + if (index != -1) { + m_d->m_ui.baseClassComboBox->setCurrentIndex(index); + suggestClassNameFromBase(); + } +} + +QString NewClassWidget::sourceFileName() const +{ + return m_d->m_ui.sourceFileLineEdit->text(); +} + +QString NewClassWidget::headerFileName() const +{ + return m_d->m_ui.headerFileLineEdit->text(); +} + +QString NewClassWidget::formFileName() const +{ + return m_d->m_ui.formFileLineEdit->text(); +} + +QString NewClassWidget::path() const +{ + return m_d->m_ui.pathChooser->path(); +} + +void NewClassWidget::setPath(const QString &path) +{ + m_d->m_ui.pathChooser->setPath(path); +} + +bool NewClassWidget::namespacesEnabled() const +{ + return m_d->m_ui.classLineEdit->namespacesEnabled(); +} + +void NewClassWidget::setNamespacesEnabled(bool b) +{ + m_d->m_ui.classLineEdit->setNamespacesEnabled(b); +} + +QString NewClassWidget::sourceExtension() const +{ + return m_d->m_sourceExtension; +} + +void NewClassWidget::setSourceExtension(const QString &e) +{ + if (debugNewClassWidget) + qDebug() << Q_FUNC_INFO << e; + m_d->m_sourceExtension = fixSuffix(e); +} + +QString NewClassWidget::headerExtension() const +{ + return m_d->m_headerExtension; +} + +void NewClassWidget::setHeaderExtension(const QString &e) +{ + if (debugNewClassWidget) + qDebug() << Q_FUNC_INFO << e; + m_d->m_headerExtension = fixSuffix(e); +} + +QString NewClassWidget::formExtension() const +{ + return m_d->m_formExtension; +} + +void NewClassWidget::setFormExtension(const QString &e) +{ + if (debugNewClassWidget) + qDebug() << Q_FUNC_INFO << e; + m_d->m_formExtension = fixSuffix(e); +} + +void NewClassWidget::slotValidChanged() +{ + const bool newValid = isValid(); + if (newValid != m_d->m_valid) { + m_d->m_valid = newValid; + emit validChanged(); + } +} + +bool NewClassWidget::isValid(QString *error) const +{ + if (!m_d->m_ui.classLineEdit->isValid()) { + if (error) + *error = m_d->m_ui.classLineEdit->errorMessage(); + return false; + } + + if (isBaseClassInputVisible() && isBaseClassEditable()) { + // TODO: Should this be a ClassNameValidatingComboBox? + QRegExp classNameValidator(QLatin1String("[a-zA-Z_][a-zA-Z0-9_]*(::[a-zA-Z_][a-zA-Z0-9_]*)*")); + const QString baseClass = m_d->m_ui.baseClassComboBox->currentText().trimmed(); + if (!baseClass.isEmpty() && !classNameValidator.exactMatch(baseClass)) { + if (error) + *error = tr("Invalid base class name"); + return false; + } + } + + if (!m_d->m_ui.headerFileLineEdit->isValid()) { + if (error) + *error = tr("Invalid header file name: %1").arg(m_d->m_ui.headerFileLineEdit->errorMessage()); + return false; + } + + if (!m_d->m_ui.sourceFileLineEdit->isValid()) { + if (error) + *error = tr("Invalid source file name: %1").arg(m_d->m_ui.sourceFileLineEdit->errorMessage()); + return false; + } + + if (isFormInputVisible()) { + if (!m_d->m_ui.formFileLineEdit->isValid()) { + if (error) + *error = tr("Invalid form file name: %1").arg(m_d->m_ui.formFileLineEdit->errorMessage()); + return false; + } + } + + if (isPathInputVisible()) { + if (!m_d->m_ui.pathChooser->isValid()) { + if (error) + *error = m_d->m_ui.pathChooser->errorMessage(); + return false; + } + } + return true; +} + +void NewClassWidget::updateFileNames(const QString &baseName) +{ + if (debugNewClassWidget) + qDebug() << Q_FUNC_INFO << baseName << m_d->m_headerExtension << m_d->m_sourceExtension; + const QChar dot = QLatin1Char('.'); + m_d->m_ui.sourceFileLineEdit->setText(baseName + dot + m_d->m_sourceExtension); + m_d->m_ui.headerFileLineEdit->setText(baseName + dot + m_d->m_headerExtension); + m_d->m_ui.formFileLineEdit->setText(baseName + dot + m_d->m_formExtension); +} + +void NewClassWidget::slotActivated() +{ + if (m_d->m_valid) + emit activated(); +} + +QString NewClassWidget::fixSuffix(const QString &suffix) +{ + QString s = suffix; + if (s.startsWith(QLatin1Char('.'))) + s.remove(0, 1); + return s; +} + +// Utility to add a suffix to a file unless the user specified one +static QString ensureSuffix(QString f, const QString &extension) +{ + const QChar dot = QLatin1Char('.'); + if (f.contains(dot)) + return f; + f += dot; + f += extension; + return f; +} + +// If a non-empty name was passed, expand to directory and suffix +static QString expandFileName(const QDir &dir, const QString name, const QString &extension) +{ + if (name.isEmpty()) + return QString(); + return dir.absoluteFilePath(ensureSuffix(name, extension)); +} + +QStringList NewClassWidget::files() const +{ + QStringList rc; + const QDir dir = QDir(path()); + rc.push_back(expandFileName(dir, headerFileName(), headerExtension())); + rc.push_back(expandFileName(dir, sourceFileName(), sourceExtension())); + if (isFormInputVisible()) + rc.push_back(expandFileName(dir, formFileName(), formExtension())); + return rc; +} + + +} // namespace Utils +} // namespace Core |