From 8757c3d7df5b1739034c4e0d5b40b29179b15d62 Mon Sep 17 00:00:00 2001 From: Alessandro Portale Date: Wed, 22 Jan 2020 19:00:24 +0000 Subject: [PATCH] Designer: Restore and move NewClassWizard from Utils to Designer Commit a8af381 prematurely deleted newclasswizard.cpp/h/ui although they are still used by the Designer plugin. That caused a build breakage. This change partially amends a8af381 and moves the code into the Designer plugin. Unneeded code got removed. Change-Id: I56858a6b44a8964620397dd2c8cf95cdcd1bb9fe Reviewed-by: David Schulz --- src/plugins/designer/CMakeLists.txt | 1 + src/plugins/designer/cpp/cpp.pri | 10 +- .../designer/cpp/formclasswizardpage.cpp | 8 +- .../designer/cpp/formclasswizardpage.ui | 6 +- src/plugins/designer/cpp/newclasswidget.cpp | 331 ++++++++++++++++++ src/plugins/designer/cpp/newclasswidget.h | 105 ++++++ src/plugins/designer/cpp/newclasswidget.ui | 212 +++++++++++ src/plugins/designer/designer.qbs | 1 + 8 files changed, 662 insertions(+), 12 deletions(-) create mode 100644 src/plugins/designer/cpp/newclasswidget.cpp create mode 100644 src/plugins/designer/cpp/newclasswidget.h create mode 100644 src/plugins/designer/cpp/newclasswidget.ui diff --git a/src/plugins/designer/CMakeLists.txt b/src/plugins/designer/CMakeLists.txt index d51c0ccf3e9..71a999dd8b4 100644 --- a/src/plugins/designer/CMakeLists.txt +++ b/src/plugins/designer/CMakeLists.txt @@ -17,6 +17,7 @@ add_qtc_plugin(Designer cpp/formclasswizarddialog.cpp cpp/formclasswizarddialog.h cpp/formclasswizardpage.cpp cpp/formclasswizardpage.h cpp/formclasswizardpage.ui cpp/formclasswizardparameters.cpp cpp/formclasswizardparameters.h + cpp/newclasswidget.cpp cpp/newclasswidget.h cpp/newclasswidget.ui designer_export.h designerconstants.h designercontext.cpp designercontext.h diff --git a/src/plugins/designer/cpp/cpp.pri b/src/plugins/designer/cpp/cpp.pri index 1527c50cdea..0941cafbda0 100644 --- a/src/plugins/designer/cpp/cpp.pri +++ b/src/plugins/designer/cpp/cpp.pri @@ -3,11 +3,15 @@ DEFINES+=CPP_ENABLED HEADERS+=$$PWD/formclasswizardpage.h \ $$PWD/formclasswizarddialog.h \ $$PWD/formclasswizard.h \ - $$PWD/formclasswizardparameters.h + $$PWD/formclasswizardparameters.h \ + $$PWD/newclasswidget.h SOURCES+=$$PWD/formclasswizardpage.cpp \ $$PWD/formclasswizarddialog.cpp \ $$PWD/formclasswizard.cpp \ - $$PWD/formclasswizardparameters.cpp + $$PWD/formclasswizardparameters.cpp \ + $$PWD/newclasswidget.cpp -FORMS+=$$PWD/formclasswizardpage.ui +FORMS+= \ + $$PWD/formclasswizardpage.ui \ + $$PWD/newclasswidget.ui diff --git a/src/plugins/designer/cpp/formclasswizardpage.cpp b/src/plugins/designer/cpp/formclasswizardpage.cpp index 358db5a691d..5fd54dbaa0d 100644 --- a/src/plugins/designer/cpp/formclasswizardpage.cpp +++ b/src/plugins/designer/cpp/formclasswizardpage.cpp @@ -48,12 +48,8 @@ FormClassWizardPage::FormClassWizardPage(QWidget * parent) : { m_ui->setupUi(this); - m_ui->newClassWidget->setBaseClassInputVisible(false); - m_ui->newClassWidget->setNamespacesEnabled(true); - m_ui->newClassWidget->setAllowDirectories(true); - m_ui->newClassWidget->setClassTypeComboVisible(false); - - connect(m_ui->newClassWidget, &Utils::NewClassWidget::validChanged, this, &FormClassWizardPage::slotValidChanged); + connect(m_ui->newClassWidget, &NewClassWidget::validChanged, this, + &FormClassWizardPage::slotValidChanged); initFileGenerationSettings(); diff --git a/src/plugins/designer/cpp/formclasswizardpage.ui b/src/plugins/designer/cpp/formclasswizardpage.ui index 473125d2786..c36c5c274f4 100644 --- a/src/plugins/designer/cpp/formclasswizardpage.ui +++ b/src/plugins/designer/cpp/formclasswizardpage.ui @@ -13,7 +13,7 @@ - + @@ -22,9 +22,9 @@ - Utils::NewClassWidget + Designer::Internal::NewClassWidget QWidget -
utils/newclasswidget.h
+
newclasswidget.h
1
diff --git a/src/plugins/designer/cpp/newclasswidget.cpp b/src/plugins/designer/cpp/newclasswidget.cpp new file mode 100644 index 00000000000..2cd400e666c --- /dev/null +++ b/src/plugins/designer/cpp/newclasswidget.cpp @@ -0,0 +1,331 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +#include "newclasswidget.h" +#include "ui_newclasswidget.h" + +#include +#include +#include + +enum { debugNewClassWidget = 0 }; + +/*! \class Utils::NewClassWidget + + \brief The NewClassWidget class is a utility widget for 'New Class' wizards. + + This widget prompts the user + to enter a class name (optionally derived from some base class) and file + names for header, source and form files. Has some smart logic to derive + the file names from the class name. */ + +namespace Designer { +namespace Internal { + +struct NewClassWidgetPrivate { + NewClassWidgetPrivate(); + + Ui::NewClassWidget m_ui; + QString m_headerExtension; + QString m_sourceExtension; + QString m_formExtension; + bool m_valid = false; + bool m_classEdited = false; + QRegExp m_classNameValidator; +}; + +NewClassWidgetPrivate:: NewClassWidgetPrivate() : + m_headerExtension(QLatin1Char('h')), + m_sourceExtension(QLatin1String("cpp")), + m_formExtension(QLatin1String("ui")) +{ +} + +// --------------------- NewClassWidget +NewClassWidget::NewClassWidget(QWidget *parent) : + QWidget(parent), + d(new NewClassWidgetPrivate) +{ + d->m_ui.setupUi(this); + + d->m_ui.baseClassLabel->setVisible(false); + d->m_ui.baseClassComboBox->setVisible(false); + d->m_ui.classTypeLabel->setVisible(false); + d->m_ui.classTypeComboBox->setVisible(false); + + setNamesDelimiter(QLatin1String("::")); + + connect(d->m_ui.classLineEdit, &Utils::ClassNameValidatingLineEdit::updateFileName, + this, &NewClassWidget::slotUpdateFileNames); + connect(d->m_ui.classLineEdit, &QLineEdit::textEdited, + this, &NewClassWidget::classNameEdited); + connect(d->m_ui.baseClassComboBox, + QOverload::of(&QComboBox::currentIndexChanged), + this, &NewClassWidget::suggestClassNameFromBase); + connect(d->m_ui.baseClassComboBox, &QComboBox::editTextChanged, + this, &NewClassWidget::slotValidChanged); + connect(d->m_ui.classLineEdit, &Utils::FancyLineEdit::validChanged, + this, &NewClassWidget::slotValidChanged); + connect(d->m_ui.headerFileLineEdit, &Utils::FancyLineEdit::validChanged, + this, &NewClassWidget::slotValidChanged); + connect(d->m_ui.sourceFileLineEdit, &Utils::FancyLineEdit::validChanged, + this, &NewClassWidget::slotValidChanged); + connect(d->m_ui.formFileLineEdit, &Utils::FancyLineEdit::validChanged, + this, &NewClassWidget::slotValidChanged); + connect(d->m_ui.pathChooser, &Utils::PathChooser::validChanged, + this, &NewClassWidget::slotValidChanged); + + connect(d->m_ui.classLineEdit, &Utils::FancyLineEdit::validReturnPressed, + this, &NewClassWidget::slotActivated); + connect(d->m_ui.headerFileLineEdit, &Utils::FancyLineEdit::validReturnPressed, + this, &NewClassWidget::slotActivated); + connect(d->m_ui.sourceFileLineEdit, &Utils::FancyLineEdit::validReturnPressed, + this, &NewClassWidget::slotActivated); + connect(d->m_ui.formFileLineEdit, &Utils::FancyLineEdit::validReturnPressed, + this, &NewClassWidget::slotActivated); + connect(d->m_ui.formFileLineEdit, &Utils::FancyLineEdit::validReturnPressed, + this, &NewClassWidget::slotActivated); + connect(d->m_ui.pathChooser, &Utils::PathChooser::returnPressed, + this, &NewClassWidget::slotActivated); + + setClassType(NoClassType); +} + +NewClassWidget::~NewClassWidget() +{ + delete d; +} + +void NewClassWidget::classNameEdited() +{ + if (debugNewClassWidget) + qDebug() << Q_FUNC_INFO << d->m_headerExtension << d->m_sourceExtension; + d->m_classEdited = true; +} + +void NewClassWidget::suggestClassNameFromBase() +{ + if (debugNewClassWidget) + qDebug() << Q_FUNC_INFO << d->m_headerExtension << d->m_sourceExtension; + if (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); + } +} + +void NewClassWidget::setClassName(const QString &suggestedName) +{ + if (debugNewClassWidget) + qDebug() << Q_FUNC_INFO << suggestedName << d->m_headerExtension << d->m_sourceExtension; + d->m_ui.classLineEdit->setText( + Utils::ClassNameValidatingLineEdit::createClassName(suggestedName)); +} + +QString NewClassWidget::className() const +{ + return d->m_ui.classLineEdit->text(); +} + +QString NewClassWidget::baseClassName() const +{ + return d->m_ui.baseClassComboBox->currentText(); +} + +QString NewClassWidget::sourceFileName() const +{ + return d->m_ui.sourceFileLineEdit->text(); +} + +QString NewClassWidget::headerFileName() const +{ + return d->m_ui.headerFileLineEdit->text(); +} + +QString NewClassWidget::formFileName() const +{ + return d->m_ui.formFileLineEdit->text(); +} + +QString NewClassWidget::path() const +{ + return d->m_ui.pathChooser->path(); +} + +void NewClassWidget::setPath(const QString &path) +{ + d->m_ui.pathChooser->setPath(path); +} + +QString NewClassWidget::sourceExtension() const +{ + return d->m_sourceExtension; +} + +void NewClassWidget::setSourceExtension(const QString &e) +{ + if (debugNewClassWidget) + qDebug() << Q_FUNC_INFO << e; + d->m_sourceExtension = fixSuffix(e); +} + +QString NewClassWidget::headerExtension() const +{ + return d->m_headerExtension; +} + +void NewClassWidget::setHeaderExtension(const QString &e) +{ + if (debugNewClassWidget) + qDebug() << Q_FUNC_INFO << e; + d->m_headerExtension = fixSuffix(e); +} + +QString NewClassWidget::formExtension() const +{ + return d->m_formExtension; +} + + +void NewClassWidget::setLowerCaseFiles(bool v) +{ + d->m_ui.classLineEdit->setLowerCaseFileName(v); +} + +void NewClassWidget::setClassType(ClassType ct) +{ + d->m_ui.classTypeComboBox->setCurrentIndex(ct); +} + +void NewClassWidget::setNamesDelimiter(const QString &delimiter) +{ + d->m_ui.classLineEdit->setNamespaceDelimiter(delimiter); + const QString escaped = QRegExp::escape(delimiter); + d->m_classNameValidator = QRegExp(QLatin1String("[a-zA-Z_][a-zA-Z0-9_]*(") + + escaped + + QLatin1String("[a-zA-Z_][a-zA-Z0-9_]*)*")); +} + +void NewClassWidget::slotValidChanged() +{ + const bool newValid = isValid(); + if (newValid != d->m_valid) { + d->m_valid = newValid; + emit validChanged(); + } +} + +bool NewClassWidget::isValid(QString *error) const +{ + if (!d->m_ui.classLineEdit->isValid()) { + if (error) + *error = d->m_ui.classLineEdit->errorMessage(); + return false; + } + + if (!d->m_ui.headerFileLineEdit->isValid()) { + if (error) + *error = tr("Invalid header file name: \"%1\"").arg(d->m_ui.headerFileLineEdit->errorMessage()); + return false; + } + + if (!d->m_ui.sourceFileLineEdit->isValid()) { + if (error) + *error = tr("Invalid source file name: \"%1\"").arg(d->m_ui.sourceFileLineEdit->errorMessage()); + return false; + } + + if (!d->m_ui.formFileLineEdit->isValid()) { + if (error) + *error = tr("Invalid form file name: \"%1\"").arg(d->m_ui.formFileLineEdit->errorMessage()); + return false; + } + + if (!d->m_ui.pathChooser->isValid()) { + if (error) + *error = d->m_ui.pathChooser->errorMessage(); + return false; + } + return true; +} + +void NewClassWidget::slotUpdateFileNames(const QString &baseName) +{ + if (debugNewClassWidget) + qDebug() << Q_FUNC_INFO << baseName << d->m_headerExtension << d->m_sourceExtension; + const QChar dot = QLatin1Char('.'); + d->m_ui.sourceFileLineEdit->setText(baseName + dot + d->m_sourceExtension); + d->m_ui.headerFileLineEdit->setText(baseName + dot + d->m_headerExtension); + d->m_ui.formFileLineEdit->setText(baseName + dot + d->m_formExtension); +} + +void NewClassWidget::slotActivated() +{ + if (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())); + rc.push_back(expandFileName(dir, formFileName(), formExtension())); + return rc; +} + +} // namespace Internal +} // namespace Designer diff --git a/src/plugins/designer/cpp/newclasswidget.h b/src/plugins/designer/cpp/newclasswidget.h new file mode 100644 index 00000000000..91868c13cfc --- /dev/null +++ b/src/plugins/designer/cpp/newclasswidget.h @@ -0,0 +1,105 @@ +/**************************************************************************** +** +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of Qt Creator. +** +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +****************************************************************************/ + +#pragma once + +#include + +QT_BEGIN_NAMESPACE +class QStringList; +QT_END_NAMESPACE + +namespace Designer { +namespace Internal { + +struct NewClassWidgetPrivate; + +class NewClassWidget : public QWidget +{ + Q_OBJECT + Q_ENUMS(ClassType) + +public: + enum ClassType { NoClassType, + ClassInheritsQObject, + ClassInheritsQWidget, + ClassInheritsQDeclarativeItem, + ClassInheritsQQuickItem, + SharedDataClass + }; + explicit NewClassWidget(QWidget *parent = nullptr); + ~NewClassWidget() override; + + QString className() const; + QString baseClassName() const; + QString sourceFileName() const; + QString headerFileName() const; + QString formFileName() const; + QString path() const; + QString sourceExtension() const; + QString headerExtension() const; + QString formExtension() const; + + bool isValid(QString *error = nullptr) const; + + QStringList files() const; + +signals: + void validChanged(); + void activated(); + +public slots: + + /** + * The name passed into the new class widget will be reformatted to be a + * valid class name. + */ + void setClassName(const QString &suggestedName); + void setPath(const QString &path); + void setSourceExtension(const QString &e); + void setHeaderExtension(const QString &e); + void setLowerCaseFiles(bool v); + void setClassType(ClassType ct); + void setNamesDelimiter(const QString &delimiter); + + /** + * 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(); + +private: + void slotUpdateFileNames(const QString &t); + void slotValidChanged(); + void slotActivated(); + void classNameEdited(); + + QString fixSuffix(const QString &suffix); + NewClassWidgetPrivate *d; +}; + +} // namespace Internal +} // namespace Designer diff --git a/src/plugins/designer/cpp/newclasswidget.ui b/src/plugins/designer/cpp/newclasswidget.ui new file mode 100644 index 00000000000..50a01383029 --- /dev/null +++ b/src/plugins/designer/cpp/newclasswidget.ui @@ -0,0 +1,212 @@ + + + Designer::Internal::NewClassWidget + + + + 0 + 0 + 300 + 194 + + + + + QFormLayout::ExpandingFieldsGrow + + + 0 + + + 0 + + + 0 + + + 0 + + + + + &Class name: + + + classLineEdit + + + + + + + + + + &Base class: + + + baseClassComboBox + + + + + + + + 0 + 0 + + + + + + + + &Type information: + + + classTypeComboBox + + + + + + + + None + + + + + Inherits QObject + + + + + Inherits QWidget + + + + + Inherits QDeclarativeItem - Qt Quick 1 + + + + + Inherits QQuickItem - Qt Quick 2 + + + + + Based on QSharedData + + + + + + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 0 + 0 + + + + + + + + Qt::Vertical + + + QSizePolicy::Fixed + + + + 0 + 0 + + + + + + + + &Header file: + + + headerFileLineEdit + + + + + + + + + + &Source file: + + + sourceFileLineEdit + + + + + + + + + + &Form file: + + + formFileLineEdit + + + + + + + + + + &Path: + + + pathLabel + + + + + + + + + + + Utils::ClassNameValidatingLineEdit + QLineEdit +
utils/classnamevalidatinglineedit.h
+
+ + Utils::FileNameValidatingLineEdit + QLineEdit +
utils/filenamevalidatinglineedit.h
+
+ + Utils::PathChooser + QWidget +
utils/pathchooser.h
+ 1 +
+
+ + +
diff --git a/src/plugins/designer/designer.qbs b/src/plugins/designer/designer.qbs index b991840f919..af855234fde 100644 --- a/src/plugins/designer/designer.qbs +++ b/src/plugins/designer/designer.qbs @@ -72,6 +72,7 @@ QtcPlugin { "formclasswizarddialog.cpp", "formclasswizarddialog.h", "formclasswizardpage.cpp", "formclasswizardpage.h", "formclasswizardpage.ui", "formclasswizardparameters.cpp", "formclasswizardparameters.h", + "newclasswidget.cpp", "newclasswidget.h", "newclasswidget.ui", ] }