diff --git a/doc/api/api.pro b/doc/api/api.pro index cfa103dee7c204eb6970dbcad12735fc6a78a6e3..6cce0829112210b8b2f142623e62652fa71c595f 100644 --- a/doc/api/api.pro +++ b/doc/api/api.pro @@ -45,6 +45,7 @@ HELP_DEP_FILES = $$PWD/qtcreator-api.qdoc \ $$PWD/coding-style.qdoc \ $$PWD/external-tool-spec.qdoc \ $$PWD/qtcreator-dev.qdoc \ + $$PWD/qtcreator-dev-wizards.qdoc \ $$PWD/qtcreator-dev.qdocconf docs.name = CREATE API DOC diff --git a/doc/api/examples/webpagewizard/webpagewizard.cpp b/doc/api/examples/webpagewizard/webpagewizard.cpp new file mode 100644 index 0000000000000000000000000000000000000000..27b3b0e5821cb100bea521a9664c7af0c90b0e52 --- /dev/null +++ b/doc/api/examples/webpagewizard/webpagewizard.cpp @@ -0,0 +1,122 @@ +//! [0] +#include "webpagewizard.h" + +#include <utils/filewizarddialog.h> +#include <utils/qtcassert.h> + +#include <QtCore/QXmlStreamWriter> + +#include <QtGui/QGridLayout> +#include <QtGui/QLabel> +#include <QtGui/QLineEdit> +#include <QtGui/QPlainTextEdit> + +namespace MyPlugin { +namespace Internal { + +//! [1] +WebContentPageWizardPage::WebContentPageWizardPage(QWidget *parent) : + QWizardPage(parent), + m_titleLineEdit(new QLineEdit), + m_textEdit(new QPlainTextEdit), + m_complete(false) +{ + QGridLayout *layout = new QGridLayout(this); + QLabel *titleLabel = new QLabel(tr("&Title")); + layout->addWidget(titleLabel, 0, 0); + layout->addWidget(m_titleLineEdit, 0, 1); + QLabel *contentLabel = new QLabel(tr("&Content")); + layout->addWidget(contentLabel, 1, 0, 1, 1, Qt::AlignTop); + layout->addWidget(m_textEdit, 1, 1); + titleLabel->setBuddy(m_titleLineEdit); + contentLabel->setBuddy(m_textEdit); + setTitle(tr("Web Page Contents")); + + connect(m_titleLineEdit, SIGNAL(textChanged(QString)), this, SLOT(slotChanged())); + connect(m_textEdit, SIGNAL(textChanged()), this, SLOT(slotChanged())); +} + +QString WebContentPageWizardPage::title() const +{ + return m_titleLineEdit->text(); +} + +QString WebContentPageWizardPage::contents() const +{ + return m_textEdit->toPlainText(); +} + +void WebContentPageWizardPage::slotChanged() +{ + const bool completeNow = !m_titleLineEdit->text().isEmpty() + && m_textEdit->blockCount() > 0; + if (completeNow != m_complete) { + m_complete = completeNow; + emit completeChanged(); + } +} + +//! [1] //! [2] + +WebContentWizardDialog::WebContentWizardDialog(QWidget *parent) : + Utils::FileWizardDialog(parent), m_contentPage(new WebContentPageWizardPage) +{ + addPage(m_contentPage); +} + +//! [2] //! [3] + +WebPageWizard::WebPageWizard(const Core::BaseFileWizardParameters ¶meters, + QObject *parent) : + Core::BaseFileWizard(parameters, parent) +{ +} + +QWizard *WebPageWizard::createWizardDialog(QWidget *parent, + const QString &defaultPath, + const WizardPageList &extensionPages) const +{ + WebContentWizardDialog *dialog = new WebContentWizardDialog(parent); + dialog->setPath(defaultPath); + foreach (QWizardPage *p, extensionPages) + dialog->addPage(p); + return dialog; +} + +Core::GeneratedFiles + WebPageWizard::generateFiles(const QWizard *w, + QString *) const +{ + Core::GeneratedFiles files; + const WebContentWizardDialog *dialog = qobject_cast<const WebContentWizardDialog*>(w); + QTC_ASSERT(dialog, return files; ) + + const QString fileName = Core::BaseFileWizard::buildFileName(dialog->path(), dialog->fileName(), QLatin1String("html")); + + Core::GeneratedFile file(fileName); + + QString contents; + QXmlStreamWriter writer(&contents); + writer.setAutoFormatting(true); + writer.writeStartDocument(); + writer.writeStartElement(QLatin1String("html")); + writer.writeStartElement(QLatin1String("head")); + writer.writeTextElement(QLatin1String("title"), dialog->title()); + writer.writeEndElement(); // HEAD + writer.writeStartElement(QLatin1String("body")); + writer.writeTextElement(QLatin1String("h1"), dialog->title()); + writer.writeTextElement(QLatin1String("p"), dialog->contents()); + writer.writeEndElement(); // BODY + writer.writeEndElement(); // HTML + file.setAttributes(Core::GeneratedFile::OpenEditorAttribute); + file.setContents(contents); + files.push_back(file); + return files; +} + +//! [3] + +} // namespace Internal +} // namespace MyPlugin + +//! [0] diff --git a/doc/api/examples/webpagewizard/webpagewizard.h b/doc/api/examples/webpagewizard/webpagewizard.h new file mode 100644 index 0000000000000000000000000000000000000000..a34c228856728bf784b34739ead8ca2936084a48 --- /dev/null +++ b/doc/api/examples/webpagewizard/webpagewizard.h @@ -0,0 +1,76 @@ +//! [0] + +#ifndef WEBPAGEFILEWIZARD_H +#define WEBPAGEFILEWIZARD_H + +#include "basefilewizard.h" +#include "utils/filewizarddialog.h" + +#include <QtGui/QWizardPage> + +QT_BEGIN_NAMESPACE +class QLineEdit; +class QPlainTextEdit; +QT_END_NAMESPACE + +namespace MyPlugin { +namespace Internal { + +//! [1] +class WebContentPageWizardPage : public QWizardPage +{ + Q_OBJECT +public: + explicit WebContentPageWizardPage(QWidget *parent = 0); + + QString title() const; + QString contents() const; + + virtual bool isComplete() const { return m_complete; } + +private slots: + void slotChanged(); + +private: + QLineEdit *m_titleLineEdit; + QPlainTextEdit *m_textEdit; + bool m_complete; +}; + +//! [1] //! [2] + +class WebContentWizardDialog : public Utils::FileWizardDialog +{ + Q_OBJECT +public: + explicit WebContentWizardDialog(QWidget *parent = 0); + + QString title() const { return m_contentPage->title(); } + QString contents() const { return m_contentPage->contents(); } + +private: + WebContentPageWizardPage *m_contentPage; +}; + +//! [2] //! [3] + +class WebPageWizard : public Core::BaseFileWizard +{ +public: + explicit WebPageWizard(const Core::BaseFileWizardParameters ¶meters, + QObject *parent = 0); +protected: + virtual QWizard *createWizardDialog(QWidget *parent, + const QString &defaultPath, + const WizardPageList &extensionPages) const; + virtual Core::GeneratedFiles generateFiles(const QWizard *w, + QString *errorMessage) const; +}; + +//! [3] +} // namespace Internal +} // namespace MyPlugin + + +#endif // WEBPAGEFILEWIZARD_H +//! [0] diff --git a/doc/api/examples/webpagewizard/webpagewizardplugin.cpp b/doc/api/examples/webpagewizard/webpagewizardplugin.cpp new file mode 100644 index 0000000000000000000000000000000000000000..29720c50cf33741d9c802e03375981fae980b8a3 --- /dev/null +++ b/doc/api/examples/webpagewizard/webpagewizardplugin.cpp @@ -0,0 +1,13 @@ +//! [0] +bool MyPlugin::initialize(const QStringList &arguments, QString *errorMessage) +{ + Core::BaseFileWizardParameters p(IWizard::FileWizard); + p.setCategory(QLatin1String("P.web")); + p.setDisplayCategory(tr("Web")); + p.setDescription(tr("Creates a Web Page.")); + p.setDisplayName(tr("Web Page")); + p.setId(QLatin1String("A.WebPage")); + addAutoReleasedObject(new WebPageWizard(p)); +} + +//! [0] diff --git a/doc/api/qtcreator-dev-wizards.qdoc b/doc/api/qtcreator-dev-wizards.qdoc new file mode 100644 index 0000000000000000000000000000000000000000..30bbf22751705e29486b37904b06c216c0fb1c9d --- /dev/null +++ b/doc/api/qtcreator-dev-wizards.qdoc @@ -0,0 +1,249 @@ +/**************************************************************************** +** +** This file is part of Qt Creator +** +** Copyright (c) 2011 Nokia Corporation and/or its subsidiary(-ies). +** +** Contact: Nokia Corporation (info@qt.nokia.com) +** +** +** GNU Free Documentation License +** +** Alternatively, this file may be used under the terms of the GNU Free +** Documentation License version 1.3 as published by the Free Software +** Foundation and appearing in the file included in the packaging of this +** file. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +****************************************************************************/ + +/*! + \page qtcreator-dev-wizards.html + \title Creating Wizards in Code + + \section1 Introduction + + If the functionality provided by template-based + \l{http://doc.qt.nokia.com/qtcreator-snapshot/creator-project-wizards.html}{custom wizards} + is not sufficient for your case, you can write wizards in code. + + A wizard in Qt Creator is an instance of a class implementing + the Core::IWizard interface that is registered with ExtensionSystem::PluginManager. + + Implementing wizards requires: + \list + \o Deciding on a base class: + \list + \o Core::IWizard is a very generic interface that does + not make any assumption about what the wizard does and + what its UI looks like. + + \o Core::BaseFileWizard should be used for wizards that + generate files using a UI based on Utils::Wizard. + \endlist + + \o Providing a set of parameters that determine how the wizard shows up + in the list of wizards in the \gui{New File or Project} dialog. + + When deriving from Core::IWizard, virtual functions returning the + values have to be implemented. + + When deriving from Core::BaseFileWizard, a parameter class + Core::BaseFileWizardParameters needs to be passed to the constructor, + on which the parameters can be set. This allows for easy creation + of several wizard instances with slightly different parameters. + + \o Implementing the wizard UI + + Typically, this will be a class derived from Utils::Wizard. + Utils::Wizard extends QWizard with the functionality to show a progress + bar on the left. + + \o Implementing the wizard functionality + + When deriving from Core::BaseFileWizard, a list of Core::GeneratedFile + needs to be populated with the files and their contents. + \note The files are not actually written to the disk. This will be + done by Core::BaseFileWizard after performing overwrite checks and prompting + the user accordingly. + + \endlist + + \section2 Relevant Classes + + \table + \header + \o Class + \o Description + + \row + \o Core::IWizard + \o Qt Creator wizard interface, implementations of which are registered with + ExtensionSystem::PluginManager. + + \row + \o Core::BaseFileWizard + \o Inherits Core::IWizard and provides a base class for generating files with a UI + based on QWizard. + + \row + \o Core::BaseFileWizardParameters + \o Contains parameters for Core::BaseFileWizard. + + \row + \o Core::GeneratedFile + \o A file as produced by Core::BaseFileWizard, containing name, contents and some + attributes. + + \row + \o Utils::FileWizardPage + \o Introductory wizard page asking for file name and path. + + \row + \o Utils::FileWizardDialog + \o A wizard dialog presenting a Utils::FileWizardPage, which can be extended + by custom pages. + + \row + \o Utils::ProjectIntroPage + \o Introductory wizard page asking for project name and path. + + \row + \o ProjectExplorer::BaseProjectWizardDialog + \o Base class for project wizard dialogs, presenting + a Utils::ProjectIntroPage. + + \endtable + + \section2 Parameters + + The parameters listed below determine how the wizard shows up + in the list of wizards in the \gui{New File or Project} dialog. + + Wizards in Qt Creator are grouped by categories. + + \table + \header + \o Type + \o Parameter Name + \o Description + + \row + \o Core::IWizard::WizardKind + \o kind + \o Enumeration value that indicates the type of the wizard (project, class, file). + + \row + \o QIcon + \o icon + \o Icon to show. + + \row + \o QString + \o description + \o Descriptive text. + + \row + \o QString + \o displayName + \o Name to be shown in the list. + + \row + \o QString + \o id + \o Unique identifier for the wizard. It also determines the order within a category. + + \row + \o QString + \o category + \o Identifier of the category under which the wizard is to be listed. It also + determines the order of the categories. + \ + \row + \o QString + \o displayCategory + \o Description of the category. + \endtable + + \section1 Example + + \section2 Introduction + + In this example, we create a wizard + for writing HTML files consisting of a title and a paragraph, + making use of QXmlStreamWriter. + + For the UI, we use Utils::FileWizardDialog and extend it by a page + letting the user enter title and contents. + + In our BaseFileWizard implementation, we create the file contents + using QXmlStreamWriter. + + \section2 The WebContentPageWizardPage Class + + Let us start with the wizard page. We use a QLineEdit for the title + and a QPlainTextEdit for the content, arranged in a QGridLayout with + descriptive labels. + \note The QGridLayout was chosen to be able to accommodate the large + vertical span of the QPlainTextEdit. For standard controls, a + QFormLayout should be considered, which will lay out the labels + according to the platform guide lines. + + On top of that, we implement validation logic to ensure content is entered. + We implement QWizardPage::isComplete() to return true when both input widgets + have contents, enabling the \gui{Next} button. For this to happen + as the user enters text, we need to connect to the changed() signal of the + controls and emit QWizardPage::completeChanged() once the complete status changes. + + \snippet webpagewizard/webpagewizard.h 1 + + \snippet webpagewizard/webpagewizard.cpp 1 + + \section2 The WebContentWizardDialog Class + + The wizard dialog extends Utils::FileWizardDialog, which presents an + introductory page asking for file name and path. + We add our WebContentPageWizardPage after that. + + \snippet webpagewizard/webpagewizard.h 2 + + \snippet webpagewizard/webpagewizard.cpp 2 + + \section2 The WebContentWizard Class + + In our implementation of Core::BaseFileWizard, we overwrite + createWizardDialog() to return an instance of our WebContentWizardDialog, + initially set to the path passed in. We also add the extension pages + we receive. Extension pages are for example the wizard pages asking for + a project to add the files to and whether to add the files to a version control + system. + + In generateFiles(), we obtain the parameters from our wizard and populate + the list of Core::GeneratedFile with our file. To generate the contents, + we use QXmlStreamWriter. + + \snippet webpagewizard/webpagewizard.h 3 + + \snippet webpagewizard/webpagewizard.cpp 3 + + \section2 Plugin Registration + + In order for the wizard to be found by the \gui{New} dialog, we need to + register it with ExtensionSystem::PluginManager, which also takes care + of deleting it: + + \snippet webpagewizard/webpagewizardplugin.cpp 0 + + \section2 Complete Example Code + + Here is the complete code of \c webpagewizard.h: + \snippet webpagewizard/webpagewizard.h 0 + The complete code of \c webpagewizard.cpp looks as follows: + \snippet webpagewizard/webpagewizard.cpp 0 + + The registration of the wizard in the \c initialize() method + of a plugin looks like: + \snippet webpagewizard/webpagewizardplugin.cpp 0 +*/ diff --git a/doc/api/qtcreator-dev.qdoc b/doc/api/qtcreator-dev.qdoc index ee66c5557a26efd569d395d1ebba3495f5685dad..c11b7ecb9c3e63028d4c17eb3504b1173f511a43 100644 --- a/doc/api/qtcreator-dev.qdoc +++ b/doc/api/qtcreator-dev.qdoc @@ -80,7 +80,7 @@ \list \o \l{Creating Plugins} \o \l{Qt Creator Coding Rules} - \o \l{Wizards} + \o \l{Creating Wizards in Code} \o \l{User Interface Text Guidelines} \endlist diff --git a/doc/config/qtcreator-developer.qdocconf b/doc/config/qtcreator-developer.qdocconf index eac89aad7c051c3616046a439838ff241ec87817..343a06a8b98c37df630b73eb1cb9116c53e67aca 100644 --- a/doc/config/qtcreator-developer.qdocconf +++ b/doc/config/qtcreator-developer.qdocconf @@ -39,7 +39,7 @@ sources.fileextensions = "*.cpp *.qdoc" imagedirs = $SRCDIR/images $SRCDIR/templates/images outputdir = ../api/html -exampledirs = +exampledirs = ../api/examples indexes = qt.index include(compat.qdocconf)