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 <david.schulz@qt.io>
This commit is contained in:
Alessandro Portale
2020-01-22 19:00:24 +00:00
parent 132d9a55d3
commit 8757c3d7df
8 changed files with 662 additions and 12 deletions

View File

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

View File

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

View File

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

View File

@@ -13,7 +13,7 @@
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<widget class="Utils::NewClassWidget" name="newClassWidget"/>
<widget class="Designer::Internal::NewClassWidget" name="newClassWidget"/>
</item>
</layout>
</widget>
@@ -22,9 +22,9 @@
</widget>
<customwidgets>
<customwidget>
<class>Utils::NewClassWidget</class>
<class>Designer::Internal::NewClassWidget</class>
<extends>QWidget</extends>
<header location="global">utils/newclasswidget.h</header>
<header location="local">newclasswidget.h</header>
<container>1</container>
</customwidget>
</customwidgets>

View File

@@ -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 <QFileDialog>
#include <QDebug>
#include <QRegExp>
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<int>::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

View File

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

View File

@@ -0,0 +1,212 @@
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>Designer::Internal::NewClassWidget</class>
<widget class="QWidget" name="Designer::Internal::NewClassWidget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>300</width>
<height>194</height>
</rect>
</property>
<layout class="QFormLayout" name="formLayout">
<property name="fieldGrowthPolicy">
<enum>QFormLayout::ExpandingFieldsGrow</enum>
</property>
<property name="leftMargin">
<number>0</number>
</property>
<property name="topMargin">
<number>0</number>
</property>
<property name="rightMargin">
<number>0</number>
</property>
<property name="bottomMargin">
<number>0</number>
</property>
<item row="0" column="0">
<widget class="QLabel" name="classNameLabel">
<property name="text">
<string>&amp;Class name:</string>
</property>
<property name="buddy">
<cstring>classLineEdit</cstring>
</property>
</widget>
</item>
<item row="0" column="1">
<widget class="Utils::ClassNameValidatingLineEdit" name="classLineEdit"/>
</item>
<item row="1" column="0">
<widget class="QLabel" name="baseClassLabel">
<property name="text">
<string>&amp;Base class:</string>
</property>
<property name="buddy">
<cstring>baseClassComboBox</cstring>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QComboBox" name="baseClassComboBox">
<property name="sizePolicy">
<sizepolicy hsizetype="MinimumExpanding" vsizetype="Fixed">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="classTypeLabel">
<property name="text">
<string>&amp;Type information:</string>
</property>
<property name="buddy">
<cstring>classTypeComboBox</cstring>
</property>
</widget>
</item>
<item row="2" column="1">
<widget class="QComboBox" name="classTypeComboBox">
<item>
<property name="text">
<string>None</string>
</property>
</item>
<item>
<property name="text">
<string>Inherits QObject</string>
</property>
</item>
<item>
<property name="text">
<string>Inherits QWidget</string>
</property>
</item>
<item>
<property name="text">
<string>Inherits QDeclarativeItem - Qt Quick 1</string>
</property>
</item>
<item>
<property name="text">
<string>Inherits QQuickItem - Qt Quick 2</string>
</property>
</item>
<item>
<property name="text">
<string>Based on QSharedData</string>
</property>
</item>
</widget>
</item>
<item row="3" column="0">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
</spacer>
</item>
<item row="3" column="1">
<spacer name="verticalSpacer_2">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeType">
<enum>QSizePolicy::Fixed</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>0</width>
<height>0</height>
</size>
</property>
</spacer>
</item>
<item row="4" column="0">
<widget class="QLabel" name="headerLabel">
<property name="text">
<string>&amp;Header file:</string>
</property>
<property name="buddy">
<cstring>headerFileLineEdit</cstring>
</property>
</widget>
</item>
<item row="4" column="1">
<widget class="Utils::FileNameValidatingLineEdit" name="headerFileLineEdit"/>
</item>
<item row="5" column="0">
<widget class="QLabel" name="sourceLabel">
<property name="text">
<string>&amp;Source file:</string>
</property>
<property name="buddy">
<cstring>sourceFileLineEdit</cstring>
</property>
</widget>
</item>
<item row="5" column="1">
<widget class="Utils::FileNameValidatingLineEdit" name="sourceFileLineEdit"/>
</item>
<item row="6" column="0">
<widget class="QLabel" name="formLabel">
<property name="text">
<string>&amp;Form file:</string>
</property>
<property name="buddy">
<cstring>formFileLineEdit</cstring>
</property>
</widget>
</item>
<item row="6" column="1">
<widget class="Utils::FileNameValidatingLineEdit" name="formFileLineEdit"/>
</item>
<item row="7" column="0">
<widget class="QLabel" name="pathLabel">
<property name="text">
<string>&amp;Path:</string>
</property>
<property name="buddy">
<cstring>pathLabel</cstring>
</property>
</widget>
</item>
<item row="7" column="1">
<widget class="Utils::PathChooser" name="pathChooser" native="true"/>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>Utils::ClassNameValidatingLineEdit</class>
<extends>QLineEdit</extends>
<header location="global">utils/classnamevalidatinglineedit.h</header>
</customwidget>
<customwidget>
<class>Utils::FileNameValidatingLineEdit</class>
<extends>QLineEdit</extends>
<header location="global">utils/filenamevalidatinglineedit.h</header>
</customwidget>
<customwidget>
<class>Utils::PathChooser</class>
<extends>QWidget</extends>
<header location="global">utils/pathchooser.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>

View File

@@ -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",
]
}