classwizard.cpp Example File
dialogs/classwizard/classwizard.cpp
/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the examples of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:BSD$
** 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.
**
** BSD License Usage
** Alternatively, you may use this file under the terms of the BSD license
** as follows:
**
** "Redistribution and use in source and binary forms, with or without
** modification, are permitted provided that the following conditions are
** met:
** * Redistributions of source code must retain the above copyright
** notice, this list of conditions and the following disclaimer.
** * Redistributions in binary form must reproduce the above copyright
** notice, this list of conditions and the following disclaimer in
** the documentation and/or other materials provided with the
** distribution.
** * Neither the name of The Qt Company Ltd nor the names of its
** contributors may be used to endorse or promote products derived
** from this software without specific prior written permission.
**
**
** THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
** "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
** LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
** A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
** OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
** SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
** LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
** OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include <QtWidgets>
#include "classwizard.h"
ClassWizard:: ClassWizard(QWidget * parent)
: QWizard (parent)
{
addPage(new IntroPage);
addPage(new ClassInfoPage);
addPage(new CodeStylePage);
addPage(new OutputFilesPage);
addPage(new ConclusionPage);
setPixmap(QWizard :: BannerPixmap, QPixmap (":/images/banner.png" ));
setPixmap(QWizard :: BackgroundPixmap, QPixmap (":/images/background.png" ));
setWindowTitle(tr("Class Wizard" ));
}
void ClassWizard:: accept()
{
QByteArray className = field("className" ). toByteArray();
QByteArray baseClass = field("baseClass" ). toByteArray();
QByteArray macroName = field("macroName" ). toByteArray();
QByteArray baseInclude = field("baseInclude" ). toByteArray();
QString outputDir = field("outputDir" ). toString();
QString header = field("header" ). toString();
QString implementation = field("implementation" ). toString();
QByteArray block;
if (field("comment" ). toBool()) {
block + = "/*\n" ;
block + = " " + header. toLatin1() + '\n' ;
block + = "*/\n" ;
block + = '\n' ;
}
if (field("protect" ). toBool()) {
block + = "#ifndef " + macroName + '\n' ;
block + = "#define " + macroName + '\n' ;
block + = '\n' ;
}
if (field("includeBase" ). toBool()) {
block + = "#include " + baseInclude + '\n' ;
block + = '\n' ;
}
block + = "class " + className;
if (! baseClass. isEmpty())
block + = " : public " + baseClass;
block + = '\n' ;
block + = "{\n" ;
/* qmake ignore Q_OBJECT */
if (field("qobjectMacro" ). toBool()) {
block + = " Q_OBJECT\n" ;
block + = '\n' ;
}
block + = "public:\n" ;
if (field("qobjectCtor" ). toBool()) {
block + = " " + className + "(QObject *parent = 0);\n" ;
} else if (field("qwidgetCtor" ). toBool()) {
block + = " " + className + "(QWidget *parent = 0);\n" ;
} else if (field("defaultCtor" ). toBool()) {
block + = " " + className + "();\n" ;
if (field("copyCtor" ). toBool()) {
block + = " " + className + "(const " + className + " &other);\n" ;
block + = '\n' ;
block + = " " + className + " &operator=" + "(const " + className
+ " &other);\n" ;
}
}
block + = "};\n" ;
if (field("protect" ). toBool()) {
block + = '\n' ;
block + = "#endif\n" ;
}
QFile headerFile(outputDir + '/' + header);
if (! headerFile. open(QFile :: WriteOnly | QFile :: Text)) {
QMessageBox :: warning(0 , QObject :: tr("Simple Wizard" ),
QObject :: tr("Cannot write file %1:\n%2" )
. arg(headerFile. fileName())
. arg(headerFile. errorString()));
return ;
}
headerFile. write(block);
block. clear();
if (field("comment" ). toBool()) {
block + = "/*\n" ;
block + = " " + implementation. toLatin1() + '\n' ;
block + = "*/\n" ;
block + = '\n' ;
}
block + = "#include \"" + header. toLatin1() + "\"\n" ;
block + = '\n' ;
if (field("qobjectCtor" ). toBool()) {
block + = className + "::" + className + "(QObject *parent)\n" ;
block + = " : " + baseClass + "(parent)\n" ;
block + = "{\n" ;
block + = "}\n" ;
} else if (field("qwidgetCtor" ). toBool()) {
block + = className + "::" + className + "(QWidget *parent)\n" ;
block + = " : " + baseClass + "(parent)\n" ;
block + = "{\n" ;
block + = "}\n" ;
} else if (field("defaultCtor" ). toBool()) {
block + = className + "::" + className + "()\n" ;
block + = "{\n" ;
block + = " // missing code\n" ;
block + = "}\n" ;
if (field("copyCtor" ). toBool()) {
block + = "\n" ;
block + = className + "::" + className + "(const " + className
+ " &other)\n" ;
block + = "{\n" ;
block + = " *this = other;\n" ;
block + = "}\n" ;
block + = '\n' ;
block + = className + " &" + className + "::operator=(const "
+ className + " &other)\n" ;
block + = "{\n" ;
if (! baseClass. isEmpty())
block + = " " + baseClass + "::operator=(other);\n" ;
block + = " // missing code\n" ;
block + = " return *this;\n" ;
block + = "}\n" ;
}
}
QFile implementationFile(outputDir + '/' + implementation);
if (! implementationFile. open(QFile :: WriteOnly | QFile :: Text)) {
QMessageBox :: warning(0 , QObject :: tr("Simple Wizard" ),
QObject :: tr("Cannot write file %1:\n%2" )
. arg(implementationFile. fileName())
. arg(implementationFile. errorString()));
return ;
}
implementationFile. write(block);
QDialog :: accept();
}
IntroPage:: IntroPage(QWidget * parent)
: QWizardPage (parent)
{
setTitle(tr("Introduction" ));
setPixmap(QWizard :: WatermarkPixmap, QPixmap (":/images/watermark1.png" ));
label = new QLabel (tr("This wizard will generate a skeleton C++ class "
"definition, including a few functions. You simply "
"need to specify the class name and set a few "
"options to produce a header file and an "
"implementation file for your new C++ class." ));
label- > setWordWrap(true );
QVBoxLayout * layout = new QVBoxLayout ;
layout- > addWidget(label);
setLayout(layout);
}
ClassInfoPage:: ClassInfoPage(QWidget * parent)
: QWizardPage (parent)
{
setTitle(tr("Class Information" ));
setSubTitle(tr("Specify basic information about the class for which you "
"want to generate skeleton source code files." ));
setPixmap(QWizard :: LogoPixmap, QPixmap (":/images/logo1.png" ));
classNameLabel = new QLabel (tr("&Class name:" ));
classNameLineEdit = new QLineEdit ;
classNameLabel- > setBuddy(classNameLineEdit);
baseClassLabel = new QLabel (tr("B&ase class:" ));
baseClassLineEdit = new QLineEdit ;
baseClassLabel- > setBuddy(baseClassLineEdit);
qobjectMacroCheckBox = new QCheckBox (tr("Generate Q_OBJECT ¯o" ));
groupBox = new QGroupBox (tr("C&onstructor" ));
qobjectCtorRadioButton = new QRadioButton (tr("&QObject-style constructor" ));
qwidgetCtorRadioButton = new QRadioButton (tr("Q&Widget-style constructor" ));
defaultCtorRadioButton = new QRadioButton (tr("&Default constructor" ));
copyCtorCheckBox = new QCheckBox (tr("&Generate copy constructor and "
"operator=" ));
defaultCtorRadioButton- > setChecked(true );
connect(defaultCtorRadioButton, & QAbstractButton :: toggled,
copyCtorCheckBox, & QWidget :: setEnabled);
registerField("className*" , classNameLineEdit);
registerField("baseClass" , baseClassLineEdit);
registerField("qobjectMacro" , qobjectMacroCheckBox);
registerField("qobjectCtor" , qobjectCtorRadioButton);
registerField("qwidgetCtor" , qwidgetCtorRadioButton);
registerField("defaultCtor" , defaultCtorRadioButton);
registerField("copyCtor" , copyCtorCheckBox);
QVBoxLayout * groupBoxLayout = new QVBoxLayout ;
groupBoxLayout- > addWidget(qobjectCtorRadioButton);
groupBoxLayout- > addWidget(qwidgetCtorRadioButton);
groupBoxLayout- > addWidget(defaultCtorRadioButton);
groupBoxLayout- > addWidget(copyCtorCheckBox);
groupBox- > setLayout(groupBoxLayout);
QGridLayout * layout = new QGridLayout ;
layout- > addWidget(classNameLabel, 0 , 0 );
layout- > addWidget(classNameLineEdit, 0 , 1 );
layout- > addWidget(baseClassLabel, 1 , 0 );
layout- > addWidget(baseClassLineEdit, 1 , 1 );
layout- > addWidget(qobjectMacroCheckBox, 2 , 0 , 1 , 2 );
layout- > addWidget(groupBox, 3 , 0 , 1 , 2 );
setLayout(layout);
}
CodeStylePage:: CodeStylePage(QWidget * parent)
: QWizardPage (parent)
{
setTitle(tr("Code Style Options" ));
setSubTitle(tr("Choose the formatting of the generated code." ));
setPixmap(QWizard :: LogoPixmap, QPixmap (":/images/logo2.png" ));
commentCheckBox = new QCheckBox (tr("&Start generated files with a "
"comment" ));
commentCheckBox- > setChecked(true );
protectCheckBox = new QCheckBox (tr("&Protect header file against multiple "
"inclusions" ));
protectCheckBox- > setChecked(true );
macroNameLabel = new QLabel (tr("&Macro name:" ));
macroNameLineEdit = new QLineEdit ;
macroNameLabel- > setBuddy(macroNameLineEdit);
includeBaseCheckBox = new QCheckBox (tr("&Include base class definition" ));
baseIncludeLabel = new QLabel (tr("Base class include:" ));
baseIncludeLineEdit = new QLineEdit ;
baseIncludeLabel- > setBuddy(baseIncludeLineEdit);
connect(protectCheckBox, & QAbstractButton :: toggled,
macroNameLabel, & QWidget :: setEnabled);
connect(protectCheckBox, & QAbstractButton :: toggled,
macroNameLineEdit, & QWidget :: setEnabled);
connect(includeBaseCheckBox, & QAbstractButton :: toggled,
baseIncludeLabel, & QWidget :: setEnabled);
connect(includeBaseCheckBox, & QAbstractButton :: toggled,
baseIncludeLineEdit, & QWidget :: setEnabled);
registerField("comment" , commentCheckBox);
registerField("protect" , protectCheckBox);
registerField("macroName" , macroNameLineEdit);
registerField("includeBase" , includeBaseCheckBox);
registerField("baseInclude" , baseIncludeLineEdit);
QGridLayout * layout = new QGridLayout ;
layout- > setColumnMinimumWidth(0 , 20 );
layout- > addWidget(commentCheckBox, 0 , 0 , 1 , 3 );
layout- > addWidget(protectCheckBox, 1 , 0 , 1 , 3 );
layout- > addWidget(macroNameLabel, 2 , 1 );
layout- > addWidget(macroNameLineEdit, 2 , 2 );
layout- > addWidget(includeBaseCheckBox, 3 , 0 , 1 , 3 );
layout- > addWidget(baseIncludeLabel, 4 , 1 );
layout- > addWidget(baseIncludeLineEdit, 4 , 2 );
setLayout(layout);
}
void CodeStylePage:: initializePage()
{
QString className = field("className" ). toString();
macroNameLineEdit- > setText(className. toUpper() + "_H" );
QString baseClass = field("baseClass" ). toString();
includeBaseCheckBox- > setChecked(! baseClass. isEmpty());
includeBaseCheckBox- > setEnabled(! baseClass. isEmpty());
baseIncludeLabel- > setEnabled(! baseClass. isEmpty());
baseIncludeLineEdit- > setEnabled(! baseClass. isEmpty());
QRegularExpression rx("Q[A-Z].*" );
if (baseClass. isEmpty()) {
baseIncludeLineEdit- > clear();
} else if (rx. match(baseClass). hasMatch()) {
baseIncludeLineEdit- > setText('<' + baseClass + '>' );
} else {
baseIncludeLineEdit- > setText('"' + baseClass. toLower() + ".h\"" );
}
}
OutputFilesPage:: OutputFilesPage(QWidget * parent)
: QWizardPage (parent)
{
setTitle(tr("Output Files" ));
setSubTitle(tr("Specify where you want the wizard to put the generated "
"skeleton code." ));
setPixmap(QWizard :: LogoPixmap, QPixmap (":/images/logo3.png" ));
outputDirLabel = new QLabel (tr("&Output directory:" ));
outputDirLineEdit = new QLineEdit ;
outputDirLabel- > setBuddy(outputDirLineEdit);
headerLabel = new QLabel (tr("&Header file name:" ));
headerLineEdit = new QLineEdit ;
headerLabel- > setBuddy(headerLineEdit);
implementationLabel = new QLabel (tr("&Implementation file name:" ));
implementationLineEdit = new QLineEdit ;
implementationLabel- > setBuddy(implementationLineEdit);
registerField("outputDir*" , outputDirLineEdit);
registerField("header*" , headerLineEdit);
registerField("implementation*" , implementationLineEdit);
QGridLayout * layout = new QGridLayout ;
layout- > addWidget(outputDirLabel, 0 , 0 );
layout- > addWidget(outputDirLineEdit, 0 , 1 );
layout- > addWidget(headerLabel, 1 , 0 );
layout- > addWidget(headerLineEdit, 1 , 1 );
layout- > addWidget(implementationLabel, 2 , 0 );
layout- > addWidget(implementationLineEdit, 2 , 1 );
setLayout(layout);
}
void OutputFilesPage:: initializePage()
{
QString className = field("className" ). toString();
headerLineEdit- > setText(className. toLower() + ".h" );
implementationLineEdit- > setText(className. toLower() + ".cpp" );
outputDirLineEdit- > setText(QDir :: toNativeSeparators(QDir :: tempPath()));
}
ConclusionPage:: ConclusionPage(QWidget * parent)
: QWizardPage (parent)
{
setTitle(tr("Conclusion" ));
setPixmap(QWizard :: WatermarkPixmap, QPixmap (":/images/watermark2.png" ));
label = new QLabel ;
label- > setWordWrap(true );
QVBoxLayout * layout = new QVBoxLayout ;
layout- > addWidget(label);
setLayout(layout);
}
void ConclusionPage:: initializePage()
{
QString finishText = wizard()- > buttonText(QWizard :: FinishButton);
finishText. remove('&' );
label- > setText(tr("Click %1 to generate the class skeleton." )
. arg(finishText));
}