forked from qt-creator/qt-creator
Signed-off-by: Abhishek Patil <abhishek.patil@vcreatelogic.com> Merge-request: 145 Reviewed-by: con <qtc-committer@nokia.com>
668 lines
22 KiB
Plaintext
668 lines
22 KiB
Plaintext
/*!
|
||
\page project-file-wizard.html
|
||
\title 8. Project/File Wizards
|
||
|
||
New projects in Qt Creator can be created by clicking on the "File -> New" menu item and selecting the required project
|
||
type. Shown below is the new project dialog box.
|
||
|
||
\inlineimage qtc-newprojectdialog-8.png
|
||
|
||
|
||
In this chapter we will learn how to add new project types into the dialog box above.
|
||
|
||
\section1 8.1 Core::IWizard interface
|
||
|
||
Qt Creator provides a Core::IWizard interface that can be implemented to support new project types. The interface is
|
||
defined as follows in \bold {src/plugins/coreplugin/dialogs/iwizard.h}.
|
||
|
||
\code
|
||
class CORE_EXPORT IWizard : public QObject
|
||
{
|
||
Q_OBJECT
|
||
|
||
public:
|
||
enum Kind {FileWizard,ClassWizard,ProjectWizard};
|
||
virtual Kind kind() const = 0;
|
||
virtual QIcon icon() const = 0;
|
||
virtual QString description() const = 0;
|
||
virtual QString name() const = 0;
|
||
virtual QString category() const = 0;
|
||
virtual QString trCategory() const = 0;
|
||
virtual QStringList runWizard(const QString &path, QWidget *parent) = 0;
|
||
};
|
||
|
||
\endcode
|
||
|
||
Qt Creator supports the following types of new entities
|
||
\list
|
||
\o File
|
||
\o Class
|
||
\o Project
|
||
\endlist
|
||
|
||
\bold {Core::IWizard} has to be implemented to support any of the above project types.
|
||
|
||
\section2 8.1.1 Sample implementation of Core::IWizard
|
||
Let's implement the \bold {IWizard} interface to support a new project type called "Custom Project". The idea is to see the
|
||
new project type listed in the new project wizard that shows up on clicking "File -> New".
|
||
|
||
\section3 Step 1: Implementing the Core::IWizard interface
|
||
Lets create a class called \bold {CustomProjectWizard} and subclass it from \bold {Core::IWizard}.
|
||
|
||
\code
|
||
class CustomProjectWizard : public Core::IWizard
|
||
{
|
||
public:
|
||
CustomProjectWizard() { }
|
||
~CustomProjectWizard() { }
|
||
Core::IWizard::Kind kind() const;
|
||
QIcon icon() const;
|
||
QString description() const;
|
||
QString name() const;
|
||
QString category() const;
|
||
QString trCategory() const;
|
||
QStringList runWizard(const QString &path, QWidget *parent);
|
||
};
|
||
|
||
\endcode
|
||
|
||
Below we will discuss the implementation of each of the functions.
|
||
|
||
\bold{The kind()} function should be implemented to return the type of "new" project we support in our implementation of
|
||
\bold {IWizard}. Valid values are \bold {FileWizard},\bold{ClassWizard} and \bold {ProjectWizard}. In our implementation we return
|
||
\bold{ProjectWizard}.
|
||
|
||
\code
|
||
Core::IWizard::Kind CustomProjectWizard::kind() const
|
||
{
|
||
return IWizard::ProjectWizard;
|
||
}
|
||
\endcode
|
||
|
||
The \bold{icon()} implementation must return an icon to use against the project type in the New project dialog box. In our
|
||
implementation we return the Qt Creator icon itself.
|
||
|
||
\code
|
||
QIcon CustomProjectWizard::icon() const
|
||
{
|
||
return qApp->windowIcon();
|
||
}
|
||
\endcode
|
||
|
||
The \bold {description()},\bold {name()} and \bold {category()} methods must return some meta data of the new project/file/class
|
||
type we are providing in the \bold {IWizard} implementation.
|
||
|
||
\code
|
||
QString CustomProjectWizard::description() const
|
||
{
|
||
return "A custom project";
|
||
}
|
||
|
||
QString CustomProjectWizard::name() const
|
||
{
|
||
return "CustomProject";
|
||
}
|
||
|
||
QString CustomProjectWizard::category() const
|
||
{
|
||
return "FooCompanyInc";
|
||
}
|
||
\endcode
|
||
|
||
The \bold{trCategory()} method should be implemented to return a translated category string. This is the name that is
|
||
shown on the "New.." dialog box.
|
||
|
||
\code
|
||
QString CustomProjectWizard::trCategory() const
|
||
{
|
||
return tr("FooCompanyInc");
|
||
}
|
||
\endcode
|
||
|
||
If the user selects the "CustomProject" category supported by our implementation of \bold{IWizard} and selects Ok in the
|
||
"New.." dialog box; then the \bold{runWizard()} method is called. This method must be implemented to show a dialog box
|
||
or \bold{QWizard}, ask questions from the user about the new project/file/class being created and return a list of newly
|
||
created files. In our implementation of the \bold{IWizard} we will return an empty string list.
|
||
|
||
\code
|
||
QStringList CustomProjectWizard::runWizard(const QString &path, QWidget *parent)
|
||
{
|
||
Q_UNUSED(path);
|
||
Q_UNUSED(parent);
|
||
QMessageBox::information(parent, "Custom Wizard Dialog", "Hi there!");
|
||
return QStringList();
|
||
}
|
||
\endcode
|
||
|
||
\section3 Step 2: Providing the wizard from a plugin
|
||
We implement a custom-project plugin using the same means as described in Chapter 2. The only change is in the
|
||
\bold{initialize()} method implementation of the plugin.
|
||
|
||
\code
|
||
bool CustomProjectPlugin::initialize(const QStringList& args, QString *errMsg)
|
||
{
|
||
Q_UNUSED(args);
|
||
Q_UNUSED(errMsg);
|
||
addAutoReleasedObject(new CustomProjectWizard);
|
||
return true;
|
||
}
|
||
\endcode
|
||
|
||
|
||
\section3 Step 3: Testing the plugin
|
||
Upon compiling the plugin and restarting Qt Creator, we can notice the new project type in the "New.." dialog box. Take
|
||
a look at the screenshot below.
|
||
|
||
\inlineimage qtc-testplugin-8.png
|
||
|
||
\section1 8.2 Predefined IWizard implementation - Core::BaseFileWizard
|
||
|
||
Qt Creator's core provides a default implementation of the \bold{IWizard} interface in the form of the
|
||
\bold {Core::BaseFileWizard} class. This class implements provides default implementation of all the methods in the
|
||
\bold {IWizard} interface and adds some virtual methods of its own. To make use of the class, we need to subclass from it and
|
||
implement one or more methods.
|
||
|
||
\section2 8.2.1 Core::GeneratedFile and Core::GeneratedFiles
|
||
|
||
Normally a new wizard (\bold{IWizard} implementation) is implemented to allow the user to provide some hints and have
|
||
one or more files automatically generated. The \bold{Core::GeneratedFile} helps abstract each of the files that need
|
||
generation. We will learn later on that within subclasses of \bold{Core::BaseFileWizard}, we create an instance of
|
||
\bold{Core::GeneratedFile} for each file that is automatically generated.
|
||
|
||
The \bold{Core::GeneratedFile} class is defined as follows in \bold{coreplugin/basefilewizard.h}
|
||
|
||
\code
|
||
class GeneratedFile
|
||
{
|
||
public:
|
||
GeneratedFile();
|
||
explicit GeneratedFile(const QString &path);
|
||
GeneratedFile(const GeneratedFile &);
|
||
GeneratedFile &operator=(const GeneratedFile &);
|
||
~GeneratedFile();
|
||
|
||
QString path() const;
|
||
void setPath(const QString &p);
|
||
|
||
QString contents() const;
|
||
void setContents(const QString &c);
|
||
|
||
QString editorKind() const;
|
||
void setEditorKind(const QString &k);
|
||
|
||
bool write(QString *errorMessage) const;
|
||
|
||
private:
|
||
QSharedDataPointer<GeneratedFilePrivate> m_d;
|
||
};
|
||
|
||
typedef QList<GeneratedFile> GeneratedFiles;
|
||
|
||
\endcode
|
||
|
||
Files that need to be generated by subclasses of \bold {Core::BaseFileWizard} are represented by the
|
||
\bold {Core::GeneratedFile} class. The class contains three key properties of a file that needs generation
|
||
|
||
\list 1
|
||
\o Name of the file (with its absolute path).
|
||
\o The kind of editor needed for editing the file. Some valid values for editor kind are
|
||
\list a
|
||
\o \bold{CppEditor::Constants::CPPEDITOR_KIND}
|
||
\o \bold{GenericProjectManager::Constants::PROJECT_KIND}
|
||
\o \bold{Git::Constants:: GIT_COMMAND_LOG_EDITOR_KIND}
|
||
\o \bold {Git::Constants:: C_GIT_COMMAND_LOG_EDITOR}
|
||
\endlist
|
||
\o Contents of the file.
|
||
\endlist
|
||
|
||
Suppose that we wanted to generate a C++ source file with the following contents
|
||
|
||
\code
|
||
#include <iostream>
|
||
int main()
|
||
{
|
||
cout << "Hello World\n";
|
||
return 0;
|
||
}
|
||
\endcode
|
||
|
||
We would use \bold{Core::GeneratedFile} for generating the above contents as follows
|
||
\code
|
||
#include <coreplugin/basefilewizard.h>
|
||
#include <cppeditor/cppeditorconstants.h>
|
||
|
||
Core::GeneratedFile genFile("C:/Path/To/Source.cpp");
|
||
genFile.setEditorKind(CppEditor::Constants::CPPEDITOR_KIND);
|
||
genFile.setContents(
|
||
"#include <iostream>\n"
|
||
"\n"
|
||
"int main()\n"
|
||
"{\n"
|
||
" cout << \"Hello World\n\";\n"
|
||
" \n"
|
||
" return 0;\n"
|
||
"}
|
||
);
|
||
genFile.write();
|
||
|
||
\endcode
|
||
|
||
\section2 8.2.2 The "Item Model" class wizard
|
||
|
||
Suppose that we wanted to provide a new class wizard that helps automatically generate the skeleton of an item model
|
||
based on few hints like
|
||
\list
|
||
\o Model Class Name
|
||
\o Base Class Name (can be \bold {QAbstractItemModel},\bold QAbstractListModel and
|
||
\bold{QAbstractTableModel})
|
||
\o Header file name and
|
||
\o Source file name
|
||
\endlist
|
||
|
||
Lets implement a plugin that will provide the new "Item Model" class wizard in Qt Creator.
|
||
|
||
\section3 Step 1: Design the class wizard page
|
||
Lets design a simple page in Qt Designer that accepts hints as described above.
|
||
|
||
\inlineimage qtc-designer-8.png
|
||
|
||
|
||
The design is saved as ModelNamePage.ui.
|
||
\section3 Step 2: Implement the class wizard page
|
||
|
||
Lets import the UI in a Qt/C++ and provide easy to use methods to help fetch information from the page. First we design
|
||
a structure that captures all the "item model" class hints.
|
||
|
||
\code
|
||
struct ModelClassParameters
|
||
{
|
||
QString className;
|
||
QString headerFile;
|
||
QString sourceFile;
|
||
QString baseClass;
|
||
QString path;
|
||
};
|
||
|
||
\endcode
|
||
|
||
Next we declare a wizard page class that imports the UI designed in the previous step and provides methods to access
|
||
the hints provided by the user in the page.
|
||
|
||
\code
|
||
#include <QWizardPage>
|
||
#include "ui_ModelNamePage.h"
|
||
class ModelNamePage : public QWizardPage
|
||
{
|
||
Q_OBJECT
|
||
|
||
public:
|
||
ModelNamePage(QWidget* parent=0);
|
||
~ModelNamePage();
|
||
void setPath(const QString& path);
|
||
ModelClassParameters parameters() const;
|
||
private slots:
|
||
void on_txtModelClass_textEdited(const QString& txt);
|
||
|
||
private:
|
||
Ui::ModelNamePage ui;
|
||
QString path;
|
||
};
|
||
\endcode
|
||
|
||
The constructor and destructor are straight forward and easy to understand.
|
||
|
||
\code
|
||
ModelNamePage::ModelNamePage(QWidget* parent)
|
||
:QWizardPage(parent)
|
||
{
|
||
setTitle("Enter model class information");
|
||
setSubTitle("The header and source file names will be derived from the class name");
|
||
ui.setupUi(this);
|
||
}
|
||
|
||
ModelNamePage::~ModelNamePage()
|
||
{
|
||
}
|
||
\endcode
|
||
The \bold{setPath()} method basically stores the path in the private variable.
|
||
|
||
\code
|
||
void ModelNamePage::setPath(const QString& path)
|
||
{
|
||
this->path = path;
|
||
}
|
||
\endcode
|
||
|
||
The \bold{on_txtModelClass_textEdited()} slot computes the header and source file names based on the
|
||
classname.
|
||
|
||
\code
|
||
void ModelNamePage::on_txtModelClass_textEdited(const QString& txt)
|
||
{
|
||
ui.txtHeaderFile->setText(txt + ".h");
|
||
ui.txtImplFile->setText(txt + ".cpp");
|
||
}
|
||
\endcode
|
||
|
||
Finally the \bold{parameters()} method returns all the hints entered by the user in a ModelClassParameters
|
||
instance.
|
||
|
||
\code
|
||
ModelClassParameters ModelNamePage::parameters() const
|
||
{
|
||
ModelClassParameters params;
|
||
params.className = ui.txtModelClass->text();
|
||
params.headerFile = ui.txtHeaderFile->text();
|
||
|
||
params.sourceFile = ui.txtImplFile->text();
|
||
params.baseClass = ui.cmbBaseClass->currentText();
|
||
params.path = path;
|
||
return params;
|
||
}
|
||
\endcode
|
||
|
||
\section3 Step 3: Subclass Core::BaseFileWizard
|
||
|
||
The\bold {Core::BaseFileWizard} class is defined as follows in \bold{coreplugin/basefilewizard.h}
|
||
|
||
\code
|
||
class CORE_EXPORT BaseFileWizard : public IWizard
|
||
{
|
||
public:
|
||
virtual ~BaseFileWizard();
|
||
|
||
// IWizard
|
||
virtual Kind kind() const;
|
||
virtual QIcon icon() const;
|
||
virtual QString description() const;
|
||
virtual QString name() const;
|
||
virtual QString category() const;
|
||
virtual QString trCategory() const;
|
||
virtual QStringList runWizard(const QString &path, QWidget *parent);
|
||
|
||
protected:
|
||
typedef QList<QWizardPage *> WizardPageList;
|
||
explicit BaseFileWizard(const BaseFileWizardParameters ¶meters,QObject *parent = 0);
|
||
|
||
virtual QWizard *createWizardDialog(QWidget *parent,const QString &defaultPath,
|
||
const WizardPageList &extensionPages) const = 0;
|
||
|
||
virtual GeneratedFiles generateFiles(const QWizard *w,QString *errorMessage) const = 0;
|
||
|
||
virtual bool postGenerateFiles(const GeneratedFiles &l,QString *errorMessage);
|
||
};
|
||
\endcode
|
||
|
||
\underline {\bold{Note: Some methods from the actual BaseFileWizard class are not shown here.}}
|
||
|
||
The \bold{BaseFileWizard} class implements the \bold{IWizard} interface and offers three new functions
|
||
|
||
\list
|
||
\o \bold{createWizardDialog} - This function can be over-ridden by subclasses to provide a wizard that the
|
||
\bold{runWizard()} method is supposed to show.
|
||
\list
|
||
\o The \bold{parent} parameter should be used as the parent widget of the returned QWizard
|
||
\o The \bold{defaultPath} parameter should be the default location for generated files
|
||
\o The \bold{extensionPages} parameter lists out all the pages that should be shown in the wizard by default.
|
||
\endlist
|
||
\o \bold{generateFiles} - This method is called after the user is done with the wizard. Implementations of this
|
||
method must create the required files as instances of \bold{Core::GeneratedFile} class.
|
||
|
||
\o \bold{postGenerateFiles} - This method is called after \bold{generateFiles()} returns. The default
|
||
implementation opens the newly generated files; however subclasses can choose to do anything they want.
|
||
\endlist
|
||
|
||
We subclass the BaseFileWizard as follows for our "item model" wizard
|
||
|
||
\code
|
||
#include <coreplugin/basefilewizard.h>
|
||
class ModelClassWizard : public Core::BaseFileWizard
|
||
{
|
||
Q_OBJECT
|
||
|
||
public:
|
||
ModelClassWizard(const Core::BaseFileWizardParameters ¶meters,
|
||
QObject *parent = 0);
|
||
~ModelClassWizard();
|
||
|
||
QWizard *createWizardDialog(QWidget *parent,
|
||
const QString &defaultPath,
|
||
|
||
const WizardPageList &extensionPages) const;
|
||
|
||
Core::GeneratedFiles generateFiles(const QWizard *w,
|
||
QString *errorMessage) const;
|
||
|
||
private:
|
||
QString readFile(const QString& fileName,
|
||
const QMap<QString,QString>& replacementMap) const;
|
||
};
|
||
|
||
\endcode
|
||
|
||
The constructor and destructor methods are straight forward and easy to understand.
|
||
|
||
\code
|
||
ModelClassWizard::ModelClassWizard(
|
||
const Core::BaseFileWizardParameters ¶meters,QObject *parent)
|
||
: Core::BaseFileWizard(parameters, parent)
|
||
{
|
||
}
|
||
|
||
ModelClassWizard::~ModelClassWizard()
|
||
{
|
||
}
|
||
\endcode
|
||
|
||
The \bold{createWizardDialog()} method is implemented to create a \bold{QWizard} with its first page as the
|
||
\bold{ModelNamePage} class implemented step 2. Other default pages are added as usual.
|
||
|
||
\code
|
||
QWizard* ModelClassWizard::createWizardDialog(
|
||
QWidget *parent,
|
||
const QString &defaultPath,
|
||
const WizardPageList &extensionPages) const
|
||
{
|
||
// Create a wizard
|
||
QWizard* wizard = new QWizard(parent);
|
||
wizard->setWindowTitle("Model Class Wizard");
|
||
|
||
// Make our page as first page
|
||
ModelNamePage* page = new ModelNamePage(wizard);
|
||
int pageId = wizard->addPage(page);
|
||
wizard->setProperty("_PageId_", pageId);
|
||
page->setPath(defaultPath);
|
||
|
||
// Now add the remaining pages
|
||
foreach (QWizardPage *p, extensionPages)
|
||
wizard->addPage(p);
|
||
return wizard;
|
||
}
|
||
\endcode
|
||
|
||
The \bold{readFile()} method is implemented to read a file and return its contents as a string. Before returning the file<6C>s
|
||
contents as string, the function uses the replacement table passed as second parameter to fix the string.
|
||
|
||
\code
|
||
QString ModelClassWizard::readFile(const QString& fileName, const QMap<QString,QString>&
|
||
replacementMap) const
|
||
{
|
||
QFile file(fileName);
|
||
file.open(QFile::ReadOnly);
|
||
QString retStr = file.readAll();
|
||
QMap<QString,QString>::const_iterator it = replacementMap.begin();
|
||
QMap<QString,QString>::const_iterator end = replacementMap.end();
|
||
|
||
while(it != end)
|
||
{
|
||
retStr.replace(it.key(), it.value());
|
||
++it;
|
||
}
|
||
return retStr;
|
||
}
|
||
\endcode
|
||
|
||
Suppose we have a file (\bold{sample.txt}) whose contents are as follows
|
||
|
||
\code
|
||
#ifndef {{UPPER_CLASS_NAME}}_H
|
||
#define {{UPPER_CLASS_NAME}}_H
|
||
#include <{{BASE_CLASS_NAME}}>
|
||
struct {{CLASS_NAME}}Data;
|
||
|
||
class {{CLASS_NAME}} : public {{BASE_CLASS_NAME}}
|
||
{
|
||
Q_OBJECT
|
||
|
||
public:
|
||
{{CLASS_NAME}}(QObject* parent=0);
|
||
~{{CLASS_NAME}}();
|
||
int rowCount(const QModelIndex& parent) const;
|
||
QVariant data(const QModelIndex& index, int role) const;
|
||
|
||
private:
|
||
{{CLASS_NAME}}Data* d;
|
||
};
|
||
|
||
#endif // {{UPPER_CLASS_NAME}}_H
|
||
\endcode
|
||
|
||
Lets say we wanted to replace the hints in {{xyz}} with something more appropriate, we could use the following code
|
||
snippet.
|
||
|
||
\code
|
||
QMap<QString,QString> replacementMap;
|
||
replacementMap["{{UPPER_CLASS_NAME}}"] = "LIST_MODEL";
|
||
replacementMap["{{BASE_CLASS_NAME}}"] = "QAbstractListModel";
|
||
replacementMap["{{CLASS_NAME}}"] = "ListModel";
|
||
QString contents = readFile("Sample.txt", replacementTable);
|
||
\endcode
|
||
|
||
When the above code is executed, the contents string will contain
|
||
|
||
\code
|
||
#ifndef LIST_MODEL_H
|
||
#define LIST_MODEL_H
|
||
#include <QAbstractListModel>
|
||
struct ListModelData;
|
||
|
||
class ListModel : public QAbstractListModel
|
||
{
|
||
Q_OBJECT
|
||
|
||
public:
|
||
ListModel(QObject* parent=0);
|
||
~ListModel();
|
||
int rowCount(const QModelIndex& parent) const;
|
||
QVariant data(const QModelIndex& index, int role) const;
|
||
|
||
private:
|
||
ListModelData* d;
|
||
};
|
||
#endif // LIST_MODEL_H
|
||
\endcode
|
||
|
||
Seems like magic isnt it? ?. We create similar "template" header and source files for item, list and table model classes
|
||
and create a resource for use in our project.
|
||
|
||
Now, lets look at the implementation of the \bold{generateFiles()} method. This method basically creates two
|
||
\bold{Core::GeneratedFile} instances and populates them with appropriate data before returning them in a list.
|
||
|
||
|
||
\code
|
||
Core::GeneratedFiles ModelClassWizard::generateFiles(
|
||
const QWizard *w,QString *errorMessage) const
|
||
{
|
||
Q_UNUSED(errorMessage);
|
||
Core::GeneratedFiles ret;
|
||
int pageId = w->property("_PageId_").toInt();
|
||
ModelNamePage* page = qobject_cast<ModelNamePage*>(w->page(pageId));
|
||
|
||
if(!page)
|
||
return ret;
|
||
ModelClassParameters params = page->parameters();
|
||
QMap<QString,QString> replacementMap;
|
||
|
||
replacementMap["{{UPPER_CLASS_NAME}}"] = params.className.toUpper();
|
||
replacementMap["{{BASE_CLASS_NAME}}"] = params.baseClass;
|
||
replacementMap["{{CLASS_NAME}}"] = params.className;
|
||
replacementMap["{{CLASS_HEADER}}"] = QFileInfo(params.headerFile).fileName();
|
||
|
||
Core::GeneratedFile headerFile(params.path + "/" + params.headerFile);
|
||
headerFile.setEditorKind(CppEditor::Constants::CPPEDITOR_KIND);
|
||
|
||
Core::GeneratedFile sourceFile(params.path + "/" + params.sourceFile);
|
||
sourceFile.setEditorKind(CppEditor::Constants::CPPEDITOR_KIND);
|
||
|
||
if(params.baseClass == "QAbstractItemModel")
|
||
{
|
||
headerFile.setContents(readFile(":/CustomProject/ItemModelHeader", replacementMap) );
|
||
sourceFile.setContents(readFile(":/CustomProject/ItemModelSource", replacementMap) );
|
||
}
|
||
|
||
else if(params.baseClass == "QAbstractTableModel")
|
||
{
|
||
headerFile.setContents(readFile(":/CustomProject/TableModelHeader", replacementMap) );
|
||
sourceFile.setContents(readFile(":/CustomProject/TableModelSource", replacementMap) );
|
||
}
|
||
|
||
else if(params.baseClass == "QAbstractListModel")
|
||
{
|
||
headerFile.setContents(readFile(":/CustomProject/ListModelHeader", replacementMap) );
|
||
sourceFile.setContents(readFile(":/CustomProject/ListModelSource", replacementMap) );
|
||
}
|
||
|
||
ret << headerFile << sourceFile;
|
||
return ret;
|
||
}
|
||
|
||
\endcode
|
||
|
||
\section3 Step 4: Implementing the plugin
|
||
|
||
We implement the item model wizard plugin using the same means as described in Chapter 2. The only change is in the
|
||
\bold {initialize()} method implementation of the plugin.
|
||
|
||
\code
|
||
bool ItemModelWizard::initialize(const QStringList& args, QString *errMsg)
|
||
{
|
||
Q_UNUSED(args);
|
||
Q_UNUSED(errMsg);
|
||
Core::BaseFileWizardParameters params;
|
||
params.setKind(Core::IWizard::ClassWizard);
|
||
params.setIcon(qApp->windowIcon());
|
||
params.setDescription("Generates an item-model class");
|
||
params.setName("Item Model");
|
||
params.setCategory("FooCompany");
|
||
params.setTrCategory(tr("FooCompany"));
|
||
addAutoReleasedObject(new ModelClassWizard(params, this));
|
||
return true;
|
||
}
|
||
\endcode
|
||
|
||
\section3 Step 5: Testing the plugin
|
||
|
||
|
||
Upon compiling the plugin and restarting Qt Creator, we can notice the new project type in the "New.." dialog box. The
|
||
following screenshots showcase the wizard that was just implemented.
|
||
|
||
\inlineimage qtc-newitemmodel-8.png
|
||
|
||
|
||
Upon selecting the "Item Model" class wizard, we can see the ModelNamePage in a custom wizard.
|
||
|
||
\inlineimage qtc-customwizardone-8.png
|
||
|
||
|
||
We enter the appropriate details and click "Next" Qt Creator then shows us a built-in page to allow addition of the
|
||
newly generated files into the current project.
|
||
|
||
\inlineimage qtc-customwizardtwo-8.png
|
||
|
||
|
||
Upon clicking "Finish", we can notice the newly generated files in the editor.
|
||
|
||
\inlineimage qtc-editor-8.png
|
||
|
||
*/
|