aboutsummaryrefslogtreecommitdiffstats
path: root/doc/pluginhowto
diff options
context:
space:
mode:
authorAbhishek Patil <abhishek.patil@vcreatelogic.com>2010-06-21 15:27:59 +0200
committercon <qtc-committer@nokia.com>2010-06-21 17:32:15 +0200
commitabcb9358c26c240c409df15300507a90aef37f48 (patch)
tree56f03e33746d3c9186b4a8b0f93565d149263c2c /doc/pluginhowto
parentcdbe93285bee1d88518d9b002a908392f9c6bafb (diff)
Qt Creator Plugin HOWTO documentation first and second cut
Signed-off-by: Abhishek Patil <abhishek.patil@vcreatelogic.com> Merge-request: 145 Reviewed-by: con <qtc-committer@nokia.com>
Diffstat (limited to 'doc/pluginhowto')
-rw-r--r--doc/pluginhowto/adv-find-filter.qdoc7
-rw-r--r--doc/pluginhowto/classic.css102
-rw-r--r--doc/pluginhowto/editor-type.qdoc998
-rw-r--r--doc/pluginhowto/find-filter.qdoc549
-rw-r--r--doc/pluginhowto/find-support.qdoc6
-rw-r--r--doc/pluginhowto/first-plugin.qdoc327
-rw-r--r--doc/pluginhowto/images/qtc-aboutplugin-2.pngbin0 -> 56448 bytes
-rw-r--r--doc/pluginhowto/images/qtc-codeeffect-4.pngbin0 -> 61008 bytes
-rw-r--r--doc/pluginhowto/images/qtc-compiledplugin-2.pngbin0 -> 49905 bytes
-rw-r--r--doc/pluginhowto/images/qtc-configwidget-9.pngbin0 -> 15191 bytes
-rw-r--r--doc/pluginhowto/images/qtc-customeditor-10.pngbin0 -> 60409 bytes
-rw-r--r--doc/pluginhowto/images/qtc-customwizardone-8.pngbin0 -> 18830 bytes
-rw-r--r--doc/pluginhowto/images/qtc-customwizardtwo-8.pngbin0 -> 18804 bytes
-rw-r--r--doc/pluginhowto/images/qtc-designer-8.pngbin0 -> 102978 bytes
-rw-r--r--doc/pluginhowto/images/qtc-dirview-6.pngbin0 -> 67766 bytes
-rw-r--r--doc/pluginhowto/images/qtc-donothingleft-5.pngbin0 -> 36162 bytes
-rw-r--r--doc/pluginhowto/images/qtc-donothingright-5.pngbin0 -> 39347 bytes
-rw-r--r--doc/pluginhowto/images/qtc-editor-10.pngbin0 -> 67409 bytes
-rw-r--r--doc/pluginhowto/images/qtc-editor-8.pngbin0 -> 61442 bytes
-rw-r--r--doc/pluginhowto/images/qtc-editortabs-10.pngbin0 -> 63919 bytes
-rw-r--r--doc/pluginhowto/images/qtc-fileformat-10.pngbin0 -> 73251 bytes
-rw-r--r--doc/pluginhowto/images/qtc-finddialog-9.pngbin0 -> 35625 bytes
-rw-r--r--doc/pluginhowto/images/qtc-firstnavigation-6.pngbin0 -> 66435 bytes
-rw-r--r--doc/pluginhowto/images/qtc-help-5.pngbin0 -> 35528 bytes
-rw-r--r--doc/pluginhowto/images/qtc-helpdonothing-5.pngbin0 -> 53023 bytes
-rw-r--r--doc/pluginhowto/images/qtc-htmleditor-10.pngbin0 -> 60409 bytes
-rw-r--r--doc/pluginhowto/images/qtc-ieditor-10.pngbin0 -> 59839 bytes
-rw-r--r--doc/pluginhowto/images/qtc-installedplugin-2.pngbin0 -> 88408 bytes
-rw-r--r--doc/pluginhowto/images/qtc-loggermode-13.pngbin0 -> 63276 bytes
-rw-r--r--doc/pluginhowto/images/qtc-loggermodewidget-13.pngbin0 -> 48289 bytes
-rw-r--r--doc/pluginhowto/images/qtc-loggerpage-13.pngbin0 -> 35852 bytes
-rw-r--r--doc/pluginhowto/images/qtc-menubar-5.pngbin0 -> 32068 bytes
-rw-r--r--doc/pluginhowto/images/qtc-menuitem-10.pngbin0 -> 23686 bytes
-rw-r--r--doc/pluginhowto/images/qtc-menuitemposition-5.pngbin0 -> 50230 bytes
-rw-r--r--doc/pluginhowto/images/qtc-menuresponse-5.pngbin0 -> 62385 bytes
-rw-r--r--doc/pluginhowto/images/qtc-modes-13.pngbin0 -> 63245 bytes
-rw-r--r--doc/pluginhowto/images/qtc-nevigationwidget-4.pngbin0 -> 28158 bytes
-rw-r--r--doc/pluginhowto/images/qtc-newitemmodel-8.pngbin0 -> 30007 bytes
-rw-r--r--doc/pluginhowto/images/qtc-newmode-13.pngbin0 -> 63747 bytes
-rw-r--r--doc/pluginhowto/images/qtc-newprojectdialog-8.pngbin0 -> 29979 bytes
-rw-r--r--doc/pluginhowto/images/qtc-objectlist-4.pngbin0 -> 21695 bytes
-rw-r--r--doc/pluginhowto/images/qtc-options-5.pngbin0 -> 27809 bytes
-rw-r--r--doc/pluginhowto/images/qtc-options-7.pngbin0 -> 28604 bytes
-rw-r--r--doc/pluginhowto/images/qtc-options-keyboard-5.pngbin0 -> 28617 bytes
-rw-r--r--doc/pluginhowto/images/qtc-plaintextedit-10.pngbin0 -> 56294 bytes
-rw-r--r--doc/pluginhowto/images/qtc-plugindirectory-2.pngbin0 -> 46002 bytes
-rw-r--r--doc/pluginhowto/images/qtc-pluginmanager-4.pngbin0 -> 11739 bytes
-rw-r--r--doc/pluginhowto/images/qtc-progressbar-11.pngbin0 -> 64348 bytes
-rw-r--r--doc/pluginhowto/images/qtc-search-9.pngbin0 -> 93028 bytes
-rw-r--r--doc/pluginhowto/images/qtc-searchprogress-11.pngbin0 -> 60921 bytes
-rw-r--r--doc/pluginhowto/images/qtc-secondnavigation-6.pngbin0 -> 74820 bytes
-rw-r--r--doc/pluginhowto/images/qtc-testplugin-7.pngbin0 -> 20483 bytes
-rw-r--r--doc/pluginhowto/images/qtc-testplugin-8.pngbin0 -> 30046 bytes
-rw-r--r--doc/pluginhowto/images/qtc-testplugin-9.pngbin0 -> 11637 bytes
-rw-r--r--doc/pluginhowto/images/qtc-title-10.pngbin0 -> 18461 bytes
-rw-r--r--doc/pluginhowto/location-filter.qdoc6
-rw-r--r--doc/pluginhowto/menu.qdoc304
-rw-r--r--doc/pluginhowto/mode.qdoc537
-rw-r--r--doc/pluginhowto/nav-widget.qdoc171
-rw-r--r--doc/pluginhowto/pref-pane.qdoc205
-rw-r--r--doc/pluginhowto/progress.qdoc111
-rw-r--r--doc/pluginhowto/project-file-wizard.qdoc667
-rw-r--r--doc/pluginhowto/qtc-arch.qdoc329
-rw-r--r--doc/pluginhowto/qtc-project-plugin.qdoc6
-rw-r--r--doc/pluginhowto/qtcreator-compile.qdoc25
-rw-r--r--doc/pluginhowto/qtcreator-pluginhowto.qdoc28
-rw-r--r--doc/pluginhowto/qtcreator-pluginhowto.qdocconf221
-rw-r--r--doc/pluginhowto/vcs.qdoc6
68 files changed, 4605 insertions, 0 deletions
diff --git a/doc/pluginhowto/adv-find-filter.qdoc b/doc/pluginhowto/adv-find-filter.qdoc
new file mode 100644
index 00000000000..52c133851fc
--- /dev/null
+++ b/doc/pluginhowto/adv-find-filter.qdoc
@@ -0,0 +1,7 @@
+/*!
+ \page adv-find-filter.html
+ \title 15.Adding "advanced" find filter
+
+ This page needs to be written still!
+
+ */
diff --git a/doc/pluginhowto/classic.css b/doc/pluginhowto/classic.css
new file mode 100644
index 00000000000..400ee71168c
--- /dev/null
+++ b/doc/pluginhowto/classic.css
@@ -0,0 +1,102 @@
+h3.fn,span.fn
+{
+ margin-left: 1cm;
+ text-indent: -1cm;
+}
+
+a:link
+{
+ color: #004faf;
+ text-decoration: none
+}
+
+a:visited
+{
+ color: #672967;
+ text-decoration: none
+}
+
+td.postheader
+{
+ font-family: sans-serif
+}
+
+tr.address
+{
+ font-family: sans-serif
+}
+
+body
+{
+ background: #ffffff;
+ color: black
+}
+
+table tr.odd {
+ background: #f0f0f0;
+ color: black;
+}
+
+table tr.even {
+ background: #e4e4e4;
+ color: black;
+}
+
+table.annotated th {
+ padding: 3px;
+ text-align: left
+}
+
+table.annotated td {
+ padding: 3px;
+}
+
+table tr pre
+{
+ padding-top: none;
+ padding-bottom: none;
+ padding-left: none;
+ padding-right: none;
+ border: none;
+ background: none
+}
+
+tr.qt-style
+{
+ background: #a2c511;
+ color: black
+}
+
+body pre
+{
+ padding: 0.2em;
+ border: #e7e7e7 1px solid;
+ background: #f1f1f1;
+ color: black
+}
+
+span.preprocessor, span.preprocessor a
+{
+ color: darkblue;
+}
+
+span.comment
+{
+ color: darkred;
+ font-style: italic
+}
+
+span.string,span.char
+{
+ color: darkgreen;
+}
+
+.subtitle
+{
+ font-size: 0.8em
+}
+
+.small-subtitle
+{
+ font-size: 0.65em
+}
diff --git a/doc/pluginhowto/editor-type.qdoc b/doc/pluginhowto/editor-type.qdoc
new file mode 100644
index 00000000000..d877d39bf27
--- /dev/null
+++ b/doc/pluginhowto/editor-type.qdoc
@@ -0,0 +1,998 @@
+/*!
+ \page editor-type.html
+ \title 10. Adding editor type
+
+ At the very basic level Qt Creator is a text editor. On top of supporting editing of text files, Qt Creator also allows users
+ to edit UI (Qt Designer) files, QRC (Resource) files, PRO/PRI (Project) files and EXE/DLL/SO (Binary) files.
+
+ \inlineimage qtc-editor-10.png
+
+
+ In this chapter we will understand how to provide editors for custom file formats, specifically the HTML file format.
+ When we are done, we will be able to load HTML files from the local file system and view/edit them.
+
+ \inlineimage qtc-fileformat-10.png
+
+ \section1 10.1 Core Classes and Interfaces
+
+ To support a new editor type, we need to
+ \list
+ \o Implement a plugin \bold {(Core::IPlugin} implementation) class that exposes an "editor factory". Chapter 2 in this
+ document provides a detailed description on creating plugins by implementing the \bold {Core::IPlugin interface}.
+
+ \o Implement the editor factory, \bold {Core::IEditorFactory}, interface. This interface implementation provides
+ methods to help create instances of "editor" object for a specified mime-type.
+ \o Implement the editor, \bold {Core::IEditor}, interface. This interface implementation provides a widget that helps
+ edit a file type (for example: HTML, ODF etc). Editors must provide access to the "file" that it is currently being
+ shown or edited.
+ \o Implement the file, \bold{Core::IFile}, interface to help customize the loading and saving of data into disk files.
+
+ \endlist
+
+ In the following subsections, we will take a look at each of the above mentioned core interfaces.
+
+ \section2 10.1.1 The Core::IFile interface
+
+ This interface abstracts file operations from the user-interface point of view. It provides virtual methods to load and
+ save files, given a file name. It also helps in understanding the mime-type of file and value of certain flags like “modified”
+ and "read-only". The \bold{Core::IFile} interface is declared as follows in src/plugins/coreplugin/ifile.h
+
+ \code
+ namespace Core
+ {
+ class IFile : public QObject
+ {
+ Q_OBJECT
+
+ public:
+ enum ReloadBehavior { AskForReload, ReloadAll, ReloadPermissions, ReloadNone };
+ IFile(QObject *parent = 0) : QObject(parent) {}
+ virtual ~IFile() {}
+ virtual bool save(const QString &fileName = QString()) = 0;
+ virtual QString fileName() const = 0;
+ virtual QString defaultPath() const = 0;
+ virtual QString suggestedFileName() const = 0;
+ virtual QString mimeType() const = 0;
+ virtual bool isModified() const = 0;
+ virtual bool isReadOnly() const = 0;
+ virtual bool isSaveAsAllowed() const = 0;
+ virtual void modified(ReloadBehavior *behavior) = 0;
+ virtual void checkPermissions() {}
+
+ signals:
+ void changed();
+ };
+ } // namespace Core
+
+ \endcode
+
+ You may be wondering: "Why go for another interface called \bold {IFile} when we already have a class called \bold {QFile} that
+ provides the exact same functionality?" Good point. The responses to this question are listed below
+
+ \list
+ \o \bold {IFile} has to take care of loading contents of a filename into an editor \bold {(Core::IEditor} interface discussed
+ next). \bold {QFile} on the other hand simply loads contents into a \bold {QByteArray}.
+
+ \o \bold {IFile} has to emit the \bold {modified()} signal when the user edits the contents of the file in the editor, but the
+ actual disk-file contents have not been modified. \bold {QFile} emits the \bold {bytesWritten()} signal only when the
+ disk-file contents have been modified.
+
+ \o \bold {IFile} has to handle how a modified file, on the disk, is reloaded. \bold {QFile} on the other-hand doesn’t need to
+ handle this.
+ \endlist
+
+ We will learn more about implementing the \bold {Core::IFile} interface in a future section.
+
+ \section2 10.1.2 The Core::IEditor interface
+ Implementations of the \bold {Core::IEditor} interface provide editors for different types of files. It is declared as follows
+ in src/plugins/coreplugin/editormanager/ieditor.h.
+
+ \code
+ namespace Core
+ {
+ class IContext : public QObject
+ {
+ Q_OBJECT
+
+ public:
+ IContext(QObject *parent = 0) : QObject(parent) {}
+ virtual ~IContext() {}
+ virtual QList<int> context() const = 0;
+ virtual QWidget *widget() = 0;
+ virtual QString contextHelpId() const { return QString(); }
+ };
+
+ class IEditor : public IContext
+ {
+ Q_OBJECT
+
+ public:
+ IEditor(QObject *parent = 0) : IContext(parent) {}
+ virtual ~IEditor() {}
+ virtual bool createNew(const QString &contents = QString()) = 0;
+ virtual bool open(const QString &fileName = QString()) = 0;
+ virtual IFile *file() = 0;
+ virtual const char *kind() const = 0;
+ virtual QString displayName() const = 0;
+ virtual void setDisplayName(const QString &title) = 0;
+ virtual bool duplicateSupported() const = 0;
+ virtual IEditor *duplicate(QWidget *parent) = 0;
+ virtual QByteArray saveState() const = 0;
+ virtual bool restoreState(const QByteArray &state) = 0;
+ virtual int currentLine() const { return 0; }
+ virtual int currentColumn() const { return 0; }
+ virtual bool isTemporary() const = 0;
+ virtual QToolBar *toolBar() = 0;
+
+ signals:
+ void changed();
+ };
+ } // namespace Core
+
+ \endcode
+
+ The \bold {Core::IEditor} interface primary provides access to
+ \list
+ \o An \underline{editor widget}\bold{ (Core::IEditor::widget()} method) that Qt Creator can use to display contents of the
+ file being edited.
+
+ \o The file \bold {(Core::IEditor::file() } method), which is a \bold {Core::IFile} implementation, that Qt Creator
+ can use to trigger the loading and saving of data from disk-files.
+
+ \o An optional custom toolbar that Qt Creator can show whenever the editor becomes active.
+
+ \o The current position of the edit-cursor within the file \bold {(Core::IEditor::currentLine()} and
+ \bold {Core::IEditor::currentColumn())}
+
+ \o The name that needs to be displayed in the \underline{open-files combo box}.
+ \endlist
+
+ Take a look at the following screenshot to get a better understanding.
+
+ \inlineimage qtc-ieditor-10.png
+
+
+ We will understand more about implementing the \bold {Core::IEditor} interface in a future section.
+
+
+ \section2 10.1.3 The Core::IEditorFactory interface
+
+ Implementations of \bold {Core::IEditorFactory} interface provide methods to create instances of Core::IEditor
+ for a supported mime-type. It is declared as follows in src/plugins/coreplugin/editormanager/ieditorfactory.h.
+
+ \code
+ namespace Core
+ {
+ class IFileFactory : public QObject
+ {
+ Q_OBJECT
+
+ public:
+ IFileFactory(QObject *parent = 0) : QObject(parent) {}
+ virtual ~IFileFactory() {}
+ virtual QStringList mimeTypes() const = 0;
+ virtual QString kind() const = 0;
+ virtual Core::IFile *open(const QString &fileName) = 0;
+ };
+
+ class IEditorFactory : public Core::IFileFactory
+ {
+ Q_OBJECT
+
+ public:
+ IEditorFactory(QObject *parent = 0) : IFileFactory(parent) {}
+ virtual ~IEditorFactory() {}
+ virtual IEditor *createEditor(QWidget *parent) = 0;
+ };
+ } // namespace Core
+
+ \endcode
+
+ The \bold {IEditorFactory::mimeType()} method should be implemented to return the mime-type supported by the
+ editor for which the factory is implemented. The \bold {IEditorFactory::createEditor()} method should be
+ implemented to actually create a concrete editor and return the same.
+
+ \section2 10.1.4 The Core::MimeDatabase class
+
+ The \bold {Core::MimeDatabase} class keeps track of all the mime-types supported by Qt Creator. It also helps figure out
+ the mime-type of a given file. Take the following code for example:
+
+ \code
+ #include <coreplugin/mimedatabase.h>
+ Core::ICore* core = Core::ICore::instance();
+ Core::MimeDatabase* mdb = core->mimeDatabase();
+ Core::MimeType type1 = mdb->findByFile( QFileInfo("C:/Temp/sample.html") );
+
+ qDebug("File Type for sample.html = %s", qPrintable(type1.type()));
+ Core::MimeType type2 = mdb->findByFile( QFileInfo("C:/Temp/TextEdit/Main.cpp") );
+
+ qDebug("File Type for Main.cpp = %s", qPrintable(type2.type()));
+ Core::MimeType type3 = mdb->findByFile( QFileInfo("C:/Temp/TextEdit/TextEdit.pro") );
+
+ qDebug("File Type for TextEdit.pro = %s", qPrintable(type3.type()));
+ \endcode
+
+ When the above code is compiled and executed, we get the following as output.
+ \code
+ File Type for sample.html = text/plain
+ File Type for Main.cpp = text/x-c++src
+ File Type for TextEdit.pro = text/plain
+ \endcode
+
+ The \bold { Core::MimeDatabase } uses filename suffix, glob patterns and "magic" matchers to figure out the mime-type of
+ a given filename. At this point however, lets not dig into how the mime-database manages to figure out the mime-type
+ from a filename; it is enough if we know that mime-type discovery is possible.
+
+ The \bold Core::IEditorFactory interface, as described in the previous section, provides an editor \bold{(Core::IEditor}
+ implementation) for a specific mime-type. The following points help us understand how Qt Creator manages to pick the
+ appropriate \bold {Core::IEditorFactory} for a given filename.
+
+ \list 1
+ \o User selects File -> Open and chooses a file to open
+
+ \o Qt Creator uses \bold {Core::MimeDatabase} to figure out the mime-type of the selected file
+
+ \o Qt Creator runs through all \bold {Core::IEditorFactory} implementations and picks the editor-factory that
+ supports the mime-type evaluated in step 2
+
+ \o Qt Creator asks the selected editor factory to create an editor (Core::IEditor implementation)
+
+ \o The widget returned by \bold {Core::IEditor::widget()} is then shown in the workspace area of the mainwindow
+
+ \o The \bold {Core::IEditor::open()} method is then called to open the file selected in step 1.
+
+ \endlist
+
+ \section2 10.1.5 Adding a new mime-type
+
+ If we wanted to support a new editor type, then we need to register the mime-type supported by the new editor with
+ the \bold {Core::MimeDatabase}. Several mechanisms can be used to register a new mime-type. In this chapter we will
+ learn the simplest way to register a new mime-type from an XML file.
+ Suppose that we wanted to register the \bold {text/html} mime-type and associate it with \bold {*.html} filenames. We create an XML
+ file as and save it as \bold {text-html-mimetype.xml}.
+
+ \code
+ <?xml version="1.0" encoding="UTF-8"?>
+ <mime-info xmlns='http://www.freedesktop.org/standards/shared-mime-info'>
+ <mime-type type="text/html">
+ <sub-class-of type="text/plain"/>
+ <comment>HTML File</comment>
+ <glob pattern="*.html"/>
+ </mime-type>
+ </mime-info>
+ \endcode
+
+ We then register the mime-type described in the XML file (above) using the
+ \bold {Core::MimeDatabase::addMimeTypes()} method. Take a look at the code snippet below
+
+ \code
+ Core::ICore* core = Core::ICore::instance();
+ Core::MimeDatabase* mdb = core->mimeDatabase();
+ QString errMsg;
+ bool success = mdb->addMimeTypes("text-html-mimetype.xml", errMsg);
+ \endcode
+
+ Once registered, Qt Creator will begin to map all *.html filenames to text/plain mime-type.
+
+ \section1 10.2 Providing a HTML Editor in Qt Creator
+
+ Let's implement a plugin for Qt Creator that provides support for viewing and editing HTML files. The following
+ screenshots show the expected results.
+
+ The user select a HTML file to open using the standard File -> Open menuitem.
+
+ \inlineimage qtc-menuitem-10.png
+
+
+ Upon selecting a HTML file, Qt Creator will show a custom editor as shown below.
+
+
+ \inlineimage qtc-customeditor-10.png
+
+
+ Notice that the editor has two tabs called "Preview" and "Source" at the bottom edge.
+
+
+ \inlineimage qtc-editortabs-10.png
+
+
+ Clicking on the "Source" tab shows the HTML code in a \bold { QPlainTextEdit} widget.
+
+ \inlineimage qtc-plaintextedit-10.png
+
+
+ Users can edit the HTML in this tab, and when he moves back to the "preview" tab the changes are reflected. Users can
+ continue to make use of File -> Save menu item to save changes to the HTML file.
+
+ For achieving the above we implement the following classes
+
+ \table
+ \header
+ \o Class
+ \o Interface\\Baseclass
+ \o Description
+
+ \row
+ \o \c{HtmlEditorWidget}
+ \o \bold {QTabWidget}
+ \o Provides a tab widget with two tabs, one for showing the
+ HTML preview and other for showing the HTML code.
+
+ \row
+ \o \c{HtmlFile}
+ \o \bold {Core::IFile}
+ \o Implements the \bold {IFile} interface for the file shown in
+ \bold {HtmlEditorWidget}.
+ \row
+ \o \c {HtmlEditor}
+ \o \bold {Core::IEditor}
+ \o Implements the \bold{IEditor} interface for managing the
+ \bold{HtmlEditorWidget} and hooking up an \bold{IFile} with it.
+ \row
+ \o \c {HtmlEditorFactory}
+ \o \bold {Core::IEditorFactory}
+ \o Implements the \bold{IEditorFactory} interface for creating
+ instances of \bold{IEditor} for the "text/html" mime-type.
+
+ \row
+ \o \c {HtmlEditorPlugin}
+ \o \bold {Core::IPlugin }
+ \o Implements the \bold{IPlugin} interface for hooking all of the
+ above into Qt Creator.
+ \endtable
+
+ For every html file there is an instance each of \bold{HtmlEditorWidget},\bold{HtmlFile} and \bold{HtmlEditor} handling the
+ loading, editing and saving functionality. In our implementation we provide mechanisms to help establish association
+ between instances of the above classes that handle the same file.
+
+ \section2 10.2.1 Implementing the HTML Editor Widget
+ By default, Qt Creator uses a plain-text editor widget to display the contents of the HTML file being edited. We would
+ like to offer a tabbed widget as editor. One of the tabs shows the HTML preview, the other shows the HTML code. The
+ class \bold {HtmlEditorWidget} is our editor; and it is declared as follows.
+
+ \code
+ struct HtmlEditorWidgetData;
+ class HtmlEditorWidget : public QTabWidget
+ {
+ Q_OBJECT
+
+ public:
+ HtmlEditorWidget(QWidget* parent = 0);
+ ~HtmlEditorWidget();
+ void setContent(const QByteArray& ba, const QString& path=QString());
+ QByteArray content() const;
+ QString title() const;
+
+ protected slots:
+ void slotCurrentTabChanged(int tab);
+ void slotContentModified();
+
+ signals:
+ void contentModified();
+ void titleChanged(const QString&);
+
+ private:
+ HtmlEditorWidgetData* d;
+ };
+ \endcode
+
+ The constructor basically creates two different views from \bold{QWebView} and \bold {QPlainTextEdit} and adds them as tabs
+ at the bottom position of the tab widget. We will learn about the signal-slot connections later.
+
+ \code
+ HtmlEditorWidget::HtmlEditorWidget(QWidget* parent):QTabWidget(parent)
+ {
+ d = new HtmlEditorWidgetData;
+ d->webView = new QWebView;
+ d->textEdit = new QPlainTextEdit;
+
+ addTab(d->webView, "Preview");
+ addTab(d->textEdit, "Source");
+
+ setTabPosition(QTabWidget::South);
+ setTabShape(QTabWidget::Triangular);
+
+ d->textEdit->setFont( QFont("Courier", 12) );
+ connect(this, SIGNAL(currentChanged(int)),this, SLOT(slotCurrentTabChanged(int)));
+ connect(d->textEdit, SIGNAL(textChanged()),this, SLOT(slotContentModified()));
+ connect(d->webView, SIGNAL(titleChanged(QString)),this, SIGNAL(titleChanged(QString)));
+ d->modified = false;
+ }
+ \endcode
+
+
+ The destructor does nothing other than deleting the private \bold{"d"} object.
+
+ \code
+ HtmlEditorWidget::~HtmlEditorWidget()
+ {
+ delete d;
+ }
+ \endcode
+
+ The setContent method simply sets the contents of html file to \bold{webView} and \bold {textEdit}.
+
+ \code
+ void HtmlEditorWidget::setContent(const QByteArray& ba, const QString& path)
+ {
+ if(path.isEmpty())
+ d->webView->setHtml(ba);
+ else
+ d->webView->setHtml(ba, "file:///" + path);
+ d->textEdit->setPlainText(ba);
+ d->modified = false;
+ d->path = path;
+ }
+ \endcode
+
+ The \bold {content} method returns the contents of the \bold {textEdit}.
+
+ \code
+ QByteArray HtmlEditorWidget::content() const
+ {
+ QString htmlText = d->textEdit->toPlainText();
+ return htmlText.toAscii();
+ }
+ \endcode
+
+ The \bold {title()} method returns the title from the webView. The string returned from this method will be used in the
+ open-file combo box.
+
+ \inlineimage qtc-title-10.png
+
+ \code
+ QString HtmlEditorWidget::title() const
+ {
+ return d->webView->title();
+ }
+ \endcode
+
+ The following connection made in the constructor of \bold {HtmlEditorWidget} makes sure that when the user moves from
+ "source" to "preview" tab, the HTML content viewed in the preview tab is updated.
+
+ \code
+ connect(this, SIGNAL(currentChanged(int)),this, SLOT(slotCurrentTabChanged(int)));
+
+ void HtmlEditorWidget::slotCurrentTabChanged(int tab)
+ {
+ if(tab == 0 && d->modified)
+ setContent( content(), d->path );
+ }
+ \endcode
+
+
+ Following connection makes sure that \bold {setContentModified()} slot is called whenever user edits the html source.
+ The slot \bold {setContentModified()} simply sets modified to true and emits the signal "contentModified" We will
+ know the usability of this signal later in the section while understanding \bold {HtmlFile} class.
+
+ \code
+ connect(d->textEdit, SIGNAL(textChanged()), this, SLOT(slotContentModified()));
+
+ void HtmlEditorWidget::slotContentModified()
+ {
+ d->modified = true;
+ emit contentModified();
+ }
+ \endcode
+
+ Following connection simply emits \bold {titleChanged()} signal on title change of \bold {webView}. We will know more about
+ this signal later.
+
+ \code
+ connect(d->webView, SIGNAL(titleChanged(QString)),this, SIGNAL(titleChanged(QString)));
+ \endcode
+
+ \section2 10.2.2 Implementing the Core::IFile interface
+
+ We implement the \bold {Core::IFile} interface in the \bold {HtmlFile} class. Apart from implementing the pure virtual
+ functions from \bold {IFile} (introduced in section 5.1.1); the \bold {HtmlFile} class has methods to get/set the modified flag
+ which indicates the modification status of the file contents.
+
+ \code
+ struct HtmlFileData;
+ class HtmlFile : public Core::IFile
+ {
+ Q_OBJECT
+
+ public:
+ HtmlFile(HtmlEditor* editor, HtmlEditorWidget* editorWidget);
+ ~HtmlFile();
+ void setModified(bool val=true);
+ // Declare all the virtual functions from IFile here..
+ protected slots:
+ void modified() { setModified(true); }
+ private:
+ HtmlFileData* d;
+ };
+
+ struct HtmlFileData
+ {
+ HtmlFileData(): mimeType(HtmlEditorConstants::C_HTMLEDITOR_MIMETYPE),editorWidget(0), editor(0), modified(false) { }
+ const QString mimeType;
+ HtmlEditorWidget* editorWidget;
+ HtmlEditor* editor;
+ QString fileName;
+ bool modified;
+ };
+
+ \endcode
+
+ In the constructor implementation is simple. It establishes the association between an instance of \bold {HtmlFile} with the
+ corresponding \bold {HtmlEditor} and the \bold {HtmlEditorWidget} instances.
+
+ \code
+
+ HtmlFile::HtmlFile(HtmlEditor* editor, HtmlEditorWidget* editorWidget): Core::IFile(editor)
+ {
+ d = new HtmlFileData;
+ d->editor = editor;
+ d->editorWidget = editorWidget;
+ }
+ \endcode
+
+ The destructor does nothing other than deleting the private \bold {"d"} object.
+
+ \code
+ HtmlFile::~HtmlFile()
+ {
+ delete d;
+ }
+ \endcode
+
+ The \bold {setModified()} function stores the modification flag and emits the \bold {changed()} signal.
+
+ \code
+
+ void HtmlFile::setModified(bool val)
+ {
+ if(d->modified == val)
+ return;
+ d->modified = val;
+ emit changed();
+ }
+
+ bool HtmlFile::isModified() const
+ {
+ return d->modified;
+ }
+
+ \endcode
+
+ Returns the mime-type handled by this class.
+
+ \code
+
+ QString HtmlFile::mimeType() const
+ {
+ return d->mimeType;
+ }
+ \endcode
+
+ The save method is called when file->save action (Ctrl+s) is triggered. This saves the contents of \bold {HtmlEditorWidget}
+ (the contents shown by plain text editor) in the file as shown below. The modified flag is set to false after the contents
+ are saved into the file.
+
+
+ \code
+ bool HtmlFile::save(const QString &fileName)
+ {
+ QFile file(fileName);
+ if(file.open(QFile::WriteOnly))
+ {
+ d->fileName = fileName;
+ QByteArray content = d->editorWidget->content();
+ file.write(content);
+ setModified(false);
+ return true;
+ }
+ return false;
+ }
+ \endcode
+
+ The \bold {open} method is called when file->open action is triggered. This opens the file and calls the setContent()
+ method of \bold {HtmlEditorWidget}. The display name is set to the title of the html file.
+
+ \code
+ bool HtmlFile::open(const QString &fileName)
+ {
+ QFile file(fileName);
+ if(file.open(QFile::ReadOnly))
+ {
+ d->fileName = fileName;
+ QString path = QFileInfo(fileName).absolutePath();
+ d->editorWidget->setContent(file.readAll(), path);
+ d->editor->setDisplayName(d->editorWidget->title());
+ return true;
+ }
+ return false;
+ }
+
+ \endcode
+
+ The following methods implement the "filename" property.
+
+ \code
+ void HtmlFile::setFilename(const QString& filename)
+ {
+ d->fileName = filename;
+ }
+
+ QString HtmlFile::fileName() const
+ {
+ return d->fileName;
+ }
+ \endcode
+
+ We implement the \bold {defaultPath()},\bold { suggestedFileName()},\bold {fileFilter()} and fileExtension()
+ methods to do nothing at the moment.
+
+ \code
+ QString HtmlFile::defaultPath() const
+ {
+ return QString();
+ }
+
+ QString HtmlFile::suggestedFileName() const
+ {
+ return QString();
+ }
+
+ QString HtmlFile::fileFilter() const
+ {
+ return QString();
+ }
+
+ QString HtmlFile::fileExtension() const
+ {
+ return QString();
+ }
+ \endcode
+
+ Since we want to edit the file, we return false in \bold {isReadOnly()} method and true from \bold {isSaveAsAllowed()}
+ method.
+
+ \code
+ bool HtmlFile::isReadOnly() const
+ {
+ return false;
+ }
+
+ bool HtmlFile::isSaveAsAllowed() const
+ {
+ return true;
+ }
+ \endcode
+
+ The \bold {modified()} function has to be implemented to customize the way in which the Html editor should handle
+ reloading of a modified file. This function is called if a html-file was modified outside of Qt Creator, while it is being
+ edited. For now we do nothing.
+
+ \code
+ void HtmlFile::modified(ReloadBehavior* behavior)
+ {
+ Q_UNUSED(behavior);
+ }
+ \endcode
+
+ \section2 10.2.3 Implementing the Core::IEditor interface
+
+ The \bold {HtmlEditor} class implements \bold {IEditor} interface to provide an editor widget for html (*.html) files and
+ associate a \bold {HtmlFile} instance with it.
+
+
+ \code
+ #include <coreplugin/editormanager/ieditor.h>
+ struct HtmlEditorData;
+ class HtmlEditor : public Core::IEditor
+ {
+ Q_OBJECT
+
+ public:
+ HtmlEditor(HtmlEditorWidget* editorWidget);
+ ~HtmlEditor();
+
+ bool createNew(const QString& contents = QString());
+ QString displayName() const;
+
+ IEditor* duplicate(QWidget* parent);
+ bool duplicateSupported() const;
+ Core::IFile* file();
+
+
+ bool isTemporary() const;
+ const char* kind() const;
+ bool open(const QString& fileName = QString()) ;
+ bool restoreState(const QByteArray& state);
+ QByteArray saveState() const;
+ void setDisplayName(const QString &title);
+ QToolBar* toolBar();
+
+ // From Core::IContext
+ QWidget* widget();
+ QList<int> context() const;
+
+ protected slots:
+ void slotTitleChanged(const QString& title)
+ { setDisplayName(title); }
+
+ private:
+ HtmlEditorData* d;
+ };
+
+ \endcode
+
+ \bold {HtmlEditorData} holds object of \bold {HtmlEditorWidget} and \bold {HtmlFile}. displayName is used as visual
+ description of the document.
+
+ \code
+ struct HtmlEditorData
+ {
+ HtmlEditorData() : editorWidget(0), file(0) { }
+ HtmlEditorWidget* editorWidget;
+ QString displayName;
+ HtmlFile* file;
+ QList<int> context;
+ };
+ \endcode
+
+ The constructor creates initializes itself on an \bold {HtmlEditorWidget}. It creates an \bold {HtmlFile} instance so that its
+ association with \bold {HtmlEditor} and widget is set.
+
+ \code
+ HtmlEditor::HtmlEditor(HtmlEditorWidget* editorWidget): Core::IEditor(editorWidget)
+ {
+ d = new HtmlEditorData;
+ d->editorWidget = editorWidget;
+ d->file = new HtmlFile(this, editorWidget);
+ Core::UniqueIDManager* uidm = Core::UniqueIDManager::instance();
+ d->context << uidm->uniqueIdentifier(HtmlEditorConstants::C_HTMLEDITOR);
+
+ connect(d->editorWidget, SIGNAL(contentModified()),d->file,SLOT(modified()));
+ connect(d->editorWidget, SIGNAL(titleChanged(QString)),this,SLOT(slotTitleChanged(QString)));
+ connect(d->editorWidget, SIGNAL(contentModified()),this,SIGNAL(changed()));
+ }
+ \endcode
+
+ The destructor does nothing other than deleting the private \bold {'d'} object.
+
+ \code
+ HtmlEditor::~HtmlEditor()
+ {
+ delete d;
+ }
+ \endcode
+
+ The following functions are self explanatory.
+
+ \code
+ QWidget* HtmlEditor::widget()
+ {
+ return d->editorWidget;
+ }
+
+ QList<int> HtmlEditor::context() const
+ {
+ return d->context;
+ }
+
+ Core::IFile* HtmlEditor::file()
+ {
+ return d->file;
+ }
+ \endcode
+
+ The \bold {createNew()} method is implemented to reset the contents of the \bold {HtmlEditorWidget} and \bold {HtmlFile}
+ objects. For now we ignore the contents parameter.
+
+ \code
+ bool HtmlEditor::createNew(const QString& contents)
+ {
+ Q_UNUSED(contents);
+ d->editorWidget->setContent(QByteArray());
+ d->file->setFilename(QString());
+ return true;
+ }
+ \endcode
+
+ The \bold {open()} method causes the \bold {HtmlFile} to open a given filename. It is assumed that the filename is a HTML
+ filename.
+
+ \code
+ bool HtmlEditor::open(const QString &fileName)
+ {
+ return d->file->open(fileName);
+ }
+
+ \endcode
+
+ The following method returns the \bold {'kind'} of the editor.
+
+ \code
+ namespace HtmlEditorConstants
+ {
+ const char* const C_HTMLEDITOR_MIMETYPE = "text/html";
+ const char* const C_HTMLEDITOR = "HTML Editor";
+ }
+
+ const char* HtmlEditor::kind() const
+ {
+ return HtmlEditorConstants::C_HTMLEDITOR;
+ }
+
+ \endcode
+
+ The string returned by \bold {displayName} is used in the open-file combobox. The following methods help set and fetch the
+ display name.
+
+ \code
+ QString HtmlEditor::displayName() const
+ {
+ return d->displayName;
+ }
+
+ void HtmlEditor::setDisplayName(const QString& title)
+ {
+ if(d->displayName == title)
+ return;
+ d->displayName = title;
+ emit changed();
+ }
+ \endcode
+
+ We implement the following methods to do nothing in this example.
+
+ \code
+ bool HtmlEditor::duplicateSupported() const
+ {
+ return false;
+ }
+
+ Core::IEditor* HtmlEditor::duplicate(QWidget* parent)
+ {
+ Q_UNUSED(parent);
+ return 0;
+ }
+
+ QByteArray HtmlEditor::saveState() const
+ {
+ return QByteArray();
+ }
+
+ bool HtmlEditor::restoreState(const QByteArray& state)
+ {
+ Q_UNUSED(state);
+ return false;
+ }
+
+ QToolBar* HtmlEditor::toolBar()
+ {
+ return 0;
+ }
+
+ bool HtmlEditor::isTemporary() const
+ {
+ return false;
+ }
+ \endcode
+
+ \section2 10.2.4 Implementing the Core::IEditorFactory interface
+
+ The \bold HtmlEditorFactory class implements the \bold Core::IEditorFactory interface; and is declared as follows.
+
+ \code
+ #include <coreplugin/editormanager/ieditorfactory.h>
+
+ struct HtmlEditorFactoryData;
+
+ class HtmlEditorFactory : public Core::IEditorFactory
+ {
+ Q_OBJECT
+
+ public:
+ HtmlEditorFactory(HtmlEditorPlugin* owner);
+ ~HtmlEditorFactory();
+ QStringList mimeTypes() const;
+ QString kind() const;
+ Core::IEditor* createEditor(QWidget* parent);
+ Core::IFile* open(const QString &fileName);
+
+ private:
+ HtmlEditorFactoryData* d;
+ };
+ \endcode
+
+ \bold {HtmlEditorFactoryData} structure holds the private data of the \bold {HtmlEditorFactory} class. Notice that the
+ constructor initializes the mime-types to \bold {HtmlEditorConstants::C_HTMLEDITOR_MYMETYPE}. It also
+ initializes the \bold {kind} of the editor. This kind should be same as \bold{kind} of \bold {HtmlEditor}.
+
+ \code
+ namespace HtmlEditorConstants
+ {
+ const char* const C_HTMLEDITOR_MIMETYPE = "text/html";
+ const char* const C_HTMLEDITOR = "HTML Editor";
+ }
+
+ struct HtmlEditorFactoryData
+ {
+ HtmlEditorFactoryData(): kind(HtmlEditorConstants::C_HTMLEDITOR)
+ {
+ mimeTypes << QString(HtmlEditorConstants::C_HTMLEDITOR_MIMETYPE);
+ }
+
+ QString kind;
+ QStringList mimeTypes;
+ };
+ \endcode
+
+ The following methods are self-explanatory.
+
+ \code
+ HtmlEditorFactory::HtmlEditorFactory(HtmlEditorPlugin* owner):Core::IEditorFactory(owner)
+ {
+ d = new HtmlEditorFactoryData;
+ }
+
+ HtmlEditorFactory::~HtmlEditorFactory()
+ {
+ delete d;
+ }
+
+ QStringList HtmlEditorFactory::mimeTypes() const
+ {
+ return d->mimeTypes;
+ }
+
+ QString HtmlEditorFactory::kind() const
+ {
+ return d->kind;
+ }
+ \endcode
+
+
+ The \bold {open()} method should be implemented to return the IFile that is currently handling the given filename. If there
+ are none, then a new editor for the file is created and it's IFile is returned. To fully understand this process take a
+ look at the implementation of \bold {Core::EditorManager::openEditor()} method.
+
+ \code
+ Core::IFile* HtmlEditorFactory::open(const QString& fileName)
+ {
+ Core::EditorManager* em = Core::EditorManager::instance();
+ Core::IEditor* iface = em->openEditor(fileName, d->kind);
+ return iface ? iface->file() : 0;
+ }
+ \endcode
+
+ This method creates and returns an instance of the \bold {HtmlEditor} class.
+
+ \code
+ Core::IEditor* HtmlEditorFactory::createEditor(QWidget* parent)
+ {
+ HtmlEditorWidget* editorWidget = new HtmlEditorWidget(parent);
+ return new HtmlEditor(editorWidget);
+ }
+ \endcode
+
+ \section2 10.2.5 Implementing the plugin
+
+ We implement the \bold {HtmlEditorPlugin} plugin class using the same means described in Chapter 2. The only change is
+ the \bold {initialize()} method implementation.
+
+ \code
+ bool HtmlEditorPlugin::initialize(const QStringList &arguments, QString* errMsg)
+ {
+ Q_UNUSED(arguments);
+ Core::ICore* core = Core::ICore::instance();
+ Core::MimeDatabase* mdb = core->mimeDatabase();
+ if(!mdb->addMimeTypes("text-html-mimetype.xml", errMsg))
+ return false;
+ addAutoReleasedObject(new HtmlEditorFactory(this));
+ return true;
+ }
+ \endcode
+
+ When the plugin is compiled and Qt Creator is (re)started; we will be able to load HTML files using the newly
+ implemented editor plugin.
+
+ \inlineimage qtc-htmleditor-10.png
+
+*/
diff --git a/doc/pluginhowto/find-filter.qdoc b/doc/pluginhowto/find-filter.qdoc
new file mode 100644
index 00000000000..907dd07f579
--- /dev/null
+++ b/doc/pluginhowto/find-filter.qdoc
@@ -0,0 +1,549 @@
+/*!
+ \page find-filter.html
+ \title 9. Find Filter
+
+ Qt Creator's find dialog box allows users to search for a text or regular expression in opened projects and unloaded disk
+ files. Clicking on "Edit -> Find/Replace -> Find Dialog" shows the find dialog box.
+
+ \inlineimage qtc-finddialog-9.png
+
+
+ In the find dialog box the "scope" and "configuration widget" are extensible. It is possible to add more items to the
+ scope combo box and against every item it is possible to provide a configuration widget that needs to be shown below.
+ Each item in the "scope" combo box is called "find filter" in Qt Creator lingo.
+
+ \section1 9.1 Find::IFindFilter interface
+ The \underline {find} plugin in Qt Creator exposes an interface called Find::IFindFilter. The interface is declared as follows in
+ the src/plugins/find/ifindfilter.h header.
+
+ \code
+ class FIND_EXPORT IFindFilter : public QObject
+ {
+ Q_OBJECT
+
+ public:
+ virtual ~IFindFilter() {}
+ virtual QString id() const = 0;
+ virtual QString name() const = 0;
+ virtual bool isEnabled() const = 0;
+ virtual QKeySequence defaultShortcut() const = 0;
+ virtual void findAll(const QString &txt, QTextDocument::FindFlags findFlags) = 0;
+ virtual QWidget *createConfigWidget() { return 0; }
+ virtual void writeSettings(QSettings *settings) { Q_UNUSED(settings); }
+ virtual void readSettings(QSettings *settings) { Q_UNUSED(settings); }
+
+ signals:
+ void changed();
+ };
+
+ \endcode
+
+ By implementing the \bold {IFindFilter} interface and adding an instance of it to the object pool, we will be able to add a
+ new find-filter; which means another entry in the "scope" combo box of the find dialog box.
+
+ \section1 9.2 Providing a custom filter
+
+ Suppose that we wanted to provide a custom filter that will allow us to look for files in the loaded projects that include a
+ given header. In the following steps we will understand how to write a find filter for this.
+
+ \section2 Step 1: Declaring the HeaderFilter class
+
+ We first begin by declaring a class called HeaderFilter that implements the Find::IFindFilter interface. The class
+ definition is as follows.
+ \code
+ #include <find/ifindfilter.h>
+ class HeaderFilter : public Find::IFindFilter
+ {
+ Q_OBJECT
+
+ public:
+ HeaderFilter();
+ ~HeaderFilter();
+ QString id() const;
+ QString name() const;
+ bool isEnabled() const;
+ QKeySequence defaultShortcut() const;
+ void findAll(const QString &txt,
+ QTextDocument::FindFlags findFlags);
+ QWidget *createConfigWidget();
+
+ private:
+ HeaderFilterData *d;
+ };
+ \endcode
+
+ \section2 Step 2: Implementing the HeaderFilter class
+
+ The constructor and destructors are currently empty. We will fill in more code as we progress with our understanding of
+ the \bold {IFindFilter} interface.
+
+ \code
+ struct HeaderFilterData
+ {
+
+ };
+
+ HeaderFilter:: HeaderFilter()
+ {
+ d = new HeaderFilterData;
+ }
+
+ HeaderFilter::~ HeaderFilter()
+ {
+ delete d;
+ }
+
+ \endcode
+ The \bold{id()} method should be implemented to return a unique identifier for the find filter.
+
+
+ \code
+ QString HeaderFilter::id() const
+ {
+ return "HeaderFilter";
+ }
+
+ \endcode
+
+ The \bold {name()} method should be implemented to return the string that gets shown in the "scope" combo box of the find
+ dialog box.
+
+ \code
+ QString HeaderFilter::name() const
+ {
+ return tr("Header Filter");
+ }
+ \endcode
+
+ The \bold {isEnabled()} method should be implemented to return whether the find filter is enabled or not. In our case we
+ would like to show the filter enabled if projects are loaded in Qt Creator, false otherwise. To fully understand the
+ implementation of the function, we must first study the \bold {ProjectExplorer} namespace. For now let's just return true
+ and revisit the function after learning about the \bold {ProjectExplorer} namespace.
+
+ \code
+ bool HeaderFilter::isEnabled() const
+ {
+ return true;
+ }
+ \endcode
+
+ The \bold{defaultShortcut()} method should be implemented to return a key-sequence that the user can use to launch
+ the find dialog box with the "header filter" selected in "cope". In our implementation we return an invalid keysequence.
+
+ \code
+ QKeySequence HeaderFilter::defaultShortcut() const
+ {
+ return QKeySequence();
+ }
+ \endcode
+
+ The \bold {createConfigWidget()} method should be implemented to return a configuration widget that gets shown at
+ the bottom edge of the find dialog box.
+
+
+ \inlineimage qtc-configwidget-9.png
+
+
+ For our header-filter; let's return a simple QLabel because we don't want to provide any configuration options.
+
+ \code
+ QWidget *HeaderFilter::createConfigWidget()
+ {
+ return (new QLabel("This is a header filter"));
+ }
+ \endcode
+
+ The \bold{findAll()} method should be implemented to perform the actual "find" or "search" operation. We need to
+ understand few key classes in the \bold {ProjectExplorer},\bold {TextEditor},\bold {Find }and \bold {Core::Utils} namespace before
+ attempting to implement the filter. For now implement the method to do nothing.
+
+ \code
+ void HeaderFilter::findAll(const QString &text,QTextDocument::FindFlags findFlags)
+ {
+ // Do nothing
+ }
+ \endcode
+
+
+ \section2 Step 3: Implementing the "header-filter" plugin.
+
+ We implement the header-filter plugin very similar to the \bold {DoNothingPlugin} class described in Chapter 2. Here we
+ only look at the implementation if the \bold {initialize()} method.
+
+ \code
+ bool HeaderFilterPlugin::initialize(const QStringList& args,QString *errMsg)
+ {
+ Q_UNUSED(args);
+ Q_UNUSED(errMsg);
+ addAutoReleasedObject(new HeaderFilter);
+ return true;
+ }
+ \endcode
+
+ \section2 Step 4: Testing the plugin
+ Upon compiling the plugin and restarting Qt Creator, we can notice the "Header Filter" item in the scope combo box of
+ the find dialog box.
+
+ \inlineimage qtc-testplugin-9.png
+
+
+ Currently no "finding" or "searching" is done by our plugin because we have not yet implemented the
+ \bold {HeaderFilter::findAll()} method.
+
+ \section1 9.3 The ProjectExplorer namespace
+
+ The \bold {ProjectExplorer} namespace comprises of classes and interfaces that make up the project management
+ system in Qt Creator. This namespace is provided by the \bold {projectexplorer} plugin. Support for project types are provided
+ by plugins. For example
+
+ \list
+ \o \bold {cmakeprojectmanager} plugin provides implementations of interfaces in \bold {ProjectExplorer} namespace for
+ supporting CMake projects
+ \o \bold {qt4projectmanager} plugin provides support for Qt 4 projects
+ \o \bold {qmlprojectmanager} plugin provides support for QML projects
+ \endlist
+
+ \table
+ \header
+ \o Class/Interface
+ \o Description
+
+ \row
+ \o \c {ProjectExplorer::IProjectManager}
+ \o This interface must be implemented to provide support for a kind of
+ project. Implementations of this interface help load projects into Qt
+ Creator.
+
+ \row
+ \o \c {ProjectExplorer::Project}
+ \o This interface describes a project in terms of
+ \list
+ \o A file (Core::IFile) that describes the project.
+ \o A Boolean flag describing whether the project builds an
+ application or library
+ \o Build steps (ProjectExplorer:: BuildStep) that
+ need to be performed in order to build and clean the project
+ \o Run configurations that need to be used for running the
+ project
+ \o The environment within which the project needs to be run
+ \o The root node in the project explorer panel
+ \o Include paths and macros to be used while building the project
+ \endlist
+
+ \row
+ \o \c {ProjectManager::}
+ \o This class is the implementation of the Core::IPlugin interface for the
+
+ \row
+ \o \c {ProjectExplorerPlugin}
+ \o project explorer plugin. Through this class we can
+ \list
+ \o gain access to all the open projects
+ \o gain access the current project
+ \o gain access to the currently selected node (file/folder) in the
+ project explorer panel
+ \o gain access to the build manager
+ \bold {(ProjectManager::BuildManager)}
+ \endlist
+ \endtable
+
+ \section2 9.3.1 Getting a list of open-projects
+
+ Using the \bold {ProjectManager::ProjectExplorerPlugin} class we can catch hold of all the open-projects in Qt
+ Creator. The following code snippet shows how to do that
+
+ \code
+ #include <extensionsystem/pluginmanager.h>
+ #include <projectexplorer/projectexplorer.h>
+
+ // Catch hold of the plugin-manager
+ ExtensionSystem::PluginManager* pm = ExtensionSystem::PluginManager::instance();
+
+ // Look for the ProjectExplorerPlugin object
+ ProjectExplorer::ProjectExplorerPlugin* projectExplorerPlugin
+ = pm->getObject<ProjectExplorer::ProjectExplorerPlugin>();
+
+ // Fetch a list of all open projects
+ QList<ProjectExplorer::Project*> projects = d->projectPlugin->session()->projects();
+
+ \endcode
+
+
+ From the projects list we can gain access to the project file and all the other (source, header, resource etc) files in the
+ project. To gain access to the project file(s) we can
+
+ \code
+ Q_FOREACH(ProjectExplorer::Project* project, projects)
+ {
+ QString name = project->name();
+ Core::IFile* projectFile = project->file();
+ // Do something with the above. For example:
+ qDebug("Project %s has project file as %s",
+ qPrintable(name),
+ qPrintable(projectFile->fileName()));
+ }
+ \endcode
+
+
+ While the above code snippet helps with fetching the project file (CMakeLists.txt, .pro etc..), it doesn't help us fetch all
+ the files associated with the project.
+
+ \section2 9.3.2 Getting a list of files
+
+ From the projects list we can get a string-list of all file names associated with the project using the following code
+ snippet.
+
+ \code
+ // Make a list of files in each project
+ QStringList files;
+
+ Q_FOREACH(ProjectManager::Project* project, projects)
+ files += project->files(Project::AllFiles);
+ \endcode
+
+ \section2 9.3.3 Enabling the HeaderFilter conditionally
+
+ Ideally the header-filter should be enabled only if there is atleast one open project. To make this happen, we upgrade
+ the HeaderFilter implementation as follows
+
+ \code
+ struct HeaderFilterData
+ {
+ ProjectExplorer::ProjectExplorerPlugin* projectExplorer()
+ {
+ if(m_projectPlugin)
+ return m_projectPlugin;
+
+ ExtensionSystem::PluginManager* pm = ExtensionSystem::PluginManager::instance();
+ m_projectPlugin = pm->getObject<ProjectExplorer::ProjectExplorerPlugin>();
+ return m_projectPlugin;
+ }
+
+ private:
+ ProjectExplorer::ProjectExplorerPlugin* m_projectPlugin;
+
+ };
+
+ bool HeaderFilter::isEnabled() const
+ {
+ QList<ProjectExplorer::Project*> projects = d->projectExplorer()->session()->projects();
+ if(projects.count())
+ return true;
+ return false;
+ }
+
+ \endcode
+
+ \section1 9.4 Searching in files
+
+ In the previous section we understood how to gain access to the file names of all files associated with open projects. We
+ are now in a position to search within files. Let's begin the implementation of the \bold {HeaderFilter::findAll()}
+ method, and understand more concepts as we progress.
+
+ \code
+ void HeaderFilter::findAll(const QString &text,QTextDocument::FindFlags findFlags)
+ {
+ // Fetch a list of all open projects
+ QList<Project*> projects = d->projectPlugin->session()->projects();
+
+ // Make a list of files in each project
+ QStringList files;
+ Q_FOREACH(Project* project, projects)
+ files += project->files(Project::AllFiles);
+
+ // Remove duplicates
+ files.removeDuplicates();
+
+ // Search for text in "files"
+ // ...
+ }
+ \endcode
+
+ The number of files that need to be searched can be varying. It may be as little as 1 and as high as 1000 or more! Hence
+ searching for something in files within the \bold {findAll()} method is a bad idea. If the \bold {findAll()} method takes too long
+ then it may cause Qt Creator to appear frozen until searching is finished.
+
+ The solution to this is
+ \list
+ \o We make use of QtConcurrent and spawn multiple threads to perform the actual searching
+ \o We initialize a QFutureWatcher on the QFuture returned by QtConcurrent to emit signals as and when
+ search results are generated
+ \o We catch the signals generated by QFutureWatcher and list search results as they come
+ \endlist
+
+ Qt Creator's core utils library provides a readymade function called \bold {findInFiles()} that looks for a string within a list
+ of files and returns a \bold {QFuture} to monitor search results. The function is declared as follows in src/libs/utils/filesearch.h
+
+ \code
+ namespace Core {
+ namespace Utils {
+
+ class FileSearchResult
+ {
+ public:
+ QString fileName;
+ int lineNumber;
+ QString matchingLine;
+ int matchStart;
+ int matchLength;
+ };
+
+ QFuture<FileSearchResult> findInFiles(const QString &searchTerm,const QStringList &files,
+ QTextDocument::FindFlags flags
+ );
+
+ QFuture<FileSearchResult> findInFilesRegExp(const QString &searchTerm,const QStringList &files,
+ QTextDocument::FindFlags flags
+ );
+
+ } // namespace Utils
+ } // namespace Core
+ \endcode
+
+ Lets now continue with the implementation of \bold {HeaderFilter::findAll()} by making use of the
+ \bold {findInFiles()} method.
+
+ \code
+ struct HeaderFilterData
+ {
+ QFutureWatcher<FileSearchResult> watcher;
+
+ ProjectExplorer::ProjectExplorerPlugin* projectExplorer() {
+ ...
+ }
+ };
+
+ HeaderFilter::HeaderFilter()
+ {
+ d->watcher.setPendingResultsLimit(1);
+ connect(&d->watcher, SIGNAL(resultReadyAt(int)),
+ this, SLOT(displayResult(int)));
+ }
+
+ void HeaderFilter::findAll(const QString &text,QTextDocument::FindFlags findFlags)
+ {
+ ....
+ // Remove duplicates
+ files.removeDuplicates();
+
+ // Begin searching
+ QString includeline = "#include <" + text + ">";
+ Find::SearchResult *result = d->searchResultWindow()->startNewSearch();
+
+ // Let the watcher monitor the search results
+ d->watcher.setFuture(QFuture<FileSearchResult>());
+ }
+
+ void HeaderFilter::displayResult(int index)
+ {
+ // TODO
+ }
+
+ \endcode
+
+ In the revised \bold {findAll()} implementation we make use of the \bold {findInFiles()} method to spawn multiple
+ background threads to do all the finding. As search results are generated, the \bold {displayResult(int)} slot is called. In
+ this slot we can now show search results to the user.
+
+
+ \section1 9.5 Showing search results
+
+ The "find" plugin provides an object of class \bold {Find::SearchResultWindow}. This class provides access to the widget
+ that displays search results.
+
+ \inlineimage qtc-search-9.png
+
+
+ We would like to show our search results in the "search result window" as well. To do so, we modify the
+ \bold {HeaderFilter} code as follows
+
+ \code
+ #include <find/searchresultwindow.h>
+ struct HeaderFilterData
+ {
+ // Method to search and return the search window
+
+ Find::SearchResultWindow* searchResultWindow()
+ {
+ if(m_searchResultWindow)
+ return m_searchResultWindow;
+
+ ExtensionSystem::PluginManager* pm = ExtensionSystem::PluginManager::instance();
+ m_searchResultWindow = pm->getObject<Find::SearchResultWindow>();
+ return m_searchResultWindow;
+ }
+
+ private:
+ Find::SearchResultWindow *m_searchResultWindow;
+ };
+
+ HeaderFilter::HeaderFilter()
+ {
+ // displayResult(int) is called when every a new
+ // search result is generated
+ connect(&d->watcher, SIGNAL(resultReadyAt(int)),this, SLOT(displayResult(int)));
+ }
+
+ void HeaderFilter::findAll(const QString &text,QTextDocument::FindFlags findFlags)
+ {
+ ...
+ //When result gets activated it invokes the openEditor function
+ connect(result, SIGNAL(activated(Find::SearchResultItem)),
+ this, SLOT(openEditor(Find::SearchResultItem)));
+
+ d->searchResultWindow()->popup(true);
+ d->watcher.setFuture(Utils::findInFiles(includeline, files, findFlags));
+ }
+
+ void HeaderFilter::displayResult(int index)
+ {
+ FileSearchResult result = d->watcher.future().resultAt(index);
+
+ d->searchResultWindow()->addResult(result.fileName,
+ result.lineNumber,
+ result.matchingLine,
+ result.matchStart,
+ result.matchLength);
+ }
+
+ void HeaderFilter::openEditor(const QString &fileName, int line, int column)
+ {
+ // TODO
+ }
+ \endcode
+
+ Whenever the user double clicks on the search results, the \bold {openEditor()} method is called. In that method we should
+ have Qt Creator open the corresponding file and mark the searched text.
+
+ \section1 9.6 Opening the searched files
+
+ Without going into too many details about the texteditor plugin, lets just take a look at the function that loads a named
+ file for us and moves the cursor to a specified location. The \bold {BaseTextEditor} class in the \bold {TextEditor} namespace
+ provides a static method called \bold {openEditorAt()} that serves our purpose.
+
+ \code
+ namespace TextEditor {
+ class BaseTextEditor : public QPlainTextEdit
+ {
+ public:
+ ....
+ static ITextEditor *openEditorAt(const QString &fileName,int line, int column = 0,
+ const QString &editorKind);
+ ....
+ };
+ } // TextEditor namespace
+ \endcode
+
+ We now update the \bold {HeaderFilter::openEditor()} slot as follows
+
+ \code
+ #include <texteditor/basetexteditor.h>
+ void HeaderFilter::openEditor(const Find::SearchResultItem &item)
+ {
+ TextEditor::BaseTextEditor::openEditorAt(item.fileName, item.lineNumber, item.index);
+ }
+ \endcode
+
+ With this the \bold {HeaderFilter} is now complete.
+
+*/
diff --git a/doc/pluginhowto/find-support.qdoc b/doc/pluginhowto/find-support.qdoc
new file mode 100644
index 00000000000..e377bb7f720
--- /dev/null
+++ b/doc/pluginhowto/find-support.qdoc
@@ -0,0 +1,6 @@
+/*!
+ \page find-support.html
+ \title 9.Find support
+
+ This page needs to be written still!
+*/
diff --git a/doc/pluginhowto/first-plugin.qdoc b/doc/pluginhowto/first-plugin.qdoc
new file mode 100644
index 00000000000..b00f6c31c5d
--- /dev/null
+++ b/doc/pluginhowto/first-plugin.qdoc
@@ -0,0 +1,327 @@
+/*!
+\page first-plugin.html
+ itle 2. First Plugin
+The best way to learn about writing Qt Creator plugins is to actually start by writing the very first plugin.
+
+There are two ways for writing plugins for Qt Creator:
+\list
+\o \l {Writing plugin inside the source tree.}
+\o \l {Writing plugin outside the source tree.}
+\endlist
+For Writing plugin in the any of the above mentioned way Qt Creator source scould have been compiled.
+
+Lets keep our goals very simple for this one. We are going to provide a plugin for Qt Creator that does nothing. The purpose behind
+this "Do nothing" plugin is to discover the basic classes in Qt Creator and to feel happy when our plugin shows up in the
+"plugin list"
+
+\inlineimage qtc-aboutplugin-2.png
+
+
+ arget {Writing plugin inside the source tree.}
+\section1 2.1 Create a plugin project in Qt Creator
+Create a folder called DoNothing in $$QT_CREATOR_ROOT/src/plugins directory. The entire source code of
+the plugin will be put into this directory.
+
+\bold {Note:}\underline {It may be possible to write and build Qt Creator plugins outside of its source tree, but it is
+much easier to write plugins within the source tree}.
+
+
+Lets first create the \c {DoNothing.pro} file with the following contents
+\code
+TEMPLATE = lib
+TARGET = DoNothing
+
+PROVIDER = FooCompanyInc
+
+include(../../qtcreatorplugin.pri)
+include(../../plugins/coreplugin/coreplugin.pri)
+
+HEADERS += DoNothingPlugin.h
+SOURCES += DoNothingPlugin.cpp
+OTHER_FILES += DoNothing.pluginspec
+\endcode
+
+The project file configures the following aspects of the plugin:
+\list 1
+\o Declares that DoNothing is a library. The output will be DoNothing.dll
+\o Configures DoNothing to make use of settings defined in qtcreatorplugin.pri
+\o Overrides the default destination directory to $$IDE_PLUGIN_PATH/FooCompanyInc. By default the value
+ will be to $$IDE_PLUGIN_PATH/Nokia
+\o Configures DoNothing to make use of settings defined in coreplugin.pri
+\o Provides information about the .h and .cpp files that make up the plugin
+\endlist
+
+\section1 2.2 Marking the plugin for build
+Edit the \c {$$QT_CREATOR_ROOT/src/plugins/plugins.pro } file and include the following lines at the end of
+the file and save the changes.
+
+\code
+SUBDIRS += plugin_DoNothing
+plugin_DoNothing.subdir = DoNothing
+\endcode
+
+The above lines make sure that the next time we build Qt Creator, the DoNothing plugin is compiled along with the rest
+of Qt Creator plugins.
+
+\section1 2.3 Implementing the plugin
+So far we have only written the project file and marked our plugin for compilation. We now do the actual
+implementation of the plugin. All plugins implement the IPlugin interface. Lets take a look at how the DoNothing plugin
+implements the interface and understand it in stages.
+
+In \c {$$QT_CREATOR_ROOT/src/plugins/DoNothing/DoNothingPluigin.h} enter the following code.
+\code
+#ifndef DONOTHINGPLUGIN_H
+#define DONOTHINGPLUGIN_H
+#include <extensionsystem/iplugin.h>
+
+class DoNothingPlugin : public ExtensionSystem::IPlugin
+{
+public:
+ DoNothingPlugin();
+ ~DoNothingPlugin();
+ void extensionsInitialized();
+ bool initialize(const QStringList & arguments, QString * errorString);
+ void shutdown();
+};
+#endif // DONOTHINGPLUGIN_H
+\endcode
+
+As you can see the DoNothingPlugin class implements the IPlugin interface and nothing else. Lets look at how the
+functions are implemented.
+
+\code
+#include "DoNothingPlugin.h"
+#include <QtPlugin>
+#include <QStringList>
+
+DoNothingPlugin::DoNothingPlugin()
+{
+ // Do nothing
+}
+
+DoNothingPlugin::~DoNothingPlugin()
+{
+ // Do notning
+}
+\endcode
+Apart from initializing local (non widget and non action) variables; the constructor and destructor don't do much else.
+\code
+
+bool DoNothingPlugin::initialize(const QStringList& args, QString *errMsg)
+{
+ Q_UNUSED(args);
+ Q_UNUSED(errMsg);
+ return true;
+}
+\endcode
+
+The \bold initialize() method is called when Qt Creator wants the plugin to initialize itself. This function is ideally used to
+initialize the internal state of the plugin and register actions/objects with Qt Creator. The function is called after all the
+dependencies of this plugin have been loaded.
+
+Since our plugin really does nothing, we return \bold {true} signifying that the initialization was successful. If the initialization
+was unsuccessful (for some wired reason); the \bold {errMsg} string should be set to a human readable error message.
+
+
+\code
+void DoNothingPlugin::extensionsInitialized()
+{
+ // Do nothing
+}
+\endcode
+
+The \bold extensionsInitialized() method is called after this plugin has been initialized (ie. after initialize() method has been
+called). This method is called on plugins that depend on this plugin first.
+\code
+void DoNothingPlugin::shutdown()
+{
+ // Do nothing
+}
+\endcode
+The \bold shutdown() method is called when the plugin is about to be unloaded.
+\code
+Q_EXPORT_PLUGIN(DoNothingPlugin)
+\endcode
+Finally we export the plugin class by making use of the \bold {Q_EXPORT_PLUGIN()} macro.
+
+\section1 2.4 Writing the pluginspec file
+
+Each plugin should accompany a pluginspec file that provides some meta data about the plugin. For our plugin the
+pluginspec file is as follows
+\code
+<plugin name="DoNothing" version="0.0.1">
+ <vendor>FooCompanyInc</vendor>
+ <copyright>(C) 2009-2010 FooCompanyInc Pvt. Ltd.</copyright>
+ <license>Do anything you want</license>
+ <description>A plugin that does nothing</description>
+ <url>http://www.FooCompanyInc.com</url>
+ <dependencyList>
+ <dependency name="Core"/>
+ </dependencyList>
+</plugin>
+\endcode
+The pluginspec file provides the following fields of information:
+
+\list 1
+\o Name of the plugin, which is also used as the name of the library file that provides the plugin implementation.
+ (In our case DoNothing.dll on Windows, libDoNothing.so on Unix)
+
+\o Version of the plugin
+
+\o Vendor name
+
+\o Copyright
+
+\o License text
+
+\o Description
+
+\o URL of the plugin vendor
+
+\o Dependency List provides all the plugins that this plugin depends on. Qt Creator ensures that dependencies
+ are loaded and initialized before this plugin.
+
+\endlist
+
+\bold {Note:}\underline {The pluginspec file should be in the same directory as the plugin's project file. Just to make things clear, the
+contents of the DoNothing plugin directory is as shown below}
+
+
+\inlineimage qtc-plugindirectory-2.png
+
+
+\section1 2.5 Compiling the plugin
+
+Open a command prompt and move to the Qt Creator build directory (the same build directory you created in the
+previous chapter). Execute the following commands
+\code
+qmake ..\qtcreator.pro -recursive
+nmake
+\endcode
+After nmake returns, you will notice a FooCompanyInc folder within plugins folder whose contents are shown in the image
+below.
+
+\inlineimage qtc-compiledplugin-2.png
+
+
+\section1 2.6 Check out the new plugin
+Launch (or relaunch) Qt Creator and notice that the "Installed Plugins" dialog box now reports that DoNothing plugin
+was infact loaded and initialized.
+
+
+\inlineimage qtc-installedplugin-2.png
+
+
+In the coming chapters we will learn to write more complicated plugins for Qt Creator.
+
+ arget {Writing plugin outside the source tree.}
+\section1 2.7 Building out-of-source plugins
+
+Thus far we have understood how to build plugins within the source tree of Qt Creator. It may not be practical for us to
+use the Qt Creator source tree for plugin development all the time. Suppose that you are the author of a specialized
+library (or application) and you want integrate your product into Qt Creator. Since you are a 3rd party developer you
+cannot expect to have your code in Qt Creator source tree all the time. In this section we will look at how to build
+plugins that are outside the Qt Creator source tree.
+
+\section2 2.7.1 The plugin project file
+
+The whole magic of out-of-source plugin builds lies in the project (.pro) file of your plugin. Lets the DoNothing plugin
+discussed in the previous section and modify (its ".pro" file) so that plugins can be built from a directory outside Qt
+Creator source.
+
+The following table lists out the directory structure
+
+ able
+\header
+\o Description
+\o Directory
+
+ \row
+ \o Qt Creator Source Code
+ \o C:\\Work\\QtCreator
+
+ \row
+ \o Qt Creator Build Directory
+ \o C:\\Work\\QtCreator\\build
+
+ \row
+ \o DoNothing Plugin Source
+ \o C:\\Work\\Research\\QtCreator\\Plugins\\DoNothing
+
+
+ This directory currently contains
+ \list
+ \o DoNothing.pluginspec
+ \o DoNothing.pro
+ \o DoNothingPlugin.cpp
+ \o DoNothingPlugin.h
+ \endlist
+\row
+\o Target plugin directory
+\o C:\\Work\\QtCreator\\build\\lib\\qtcreator\\plugins\\FooCompanyInc
+
+ \endtable
+
+Let's now modify the DoNothing.pro file in C:\\Work\\Research\\QtCreator\\Plugins\\DoNothing as follows.
+
+\code
+QTC_SOURCE = C:/Work/QtCreator/
+QTC_BUILD = C:/Work/QtCreator/build/
+
+TEMPLATE = lib
+TARGET = DoNothing
+
+IDE_SOURCE_TREE = $$QTC_SOURCE
+IDE_BUILD_TREE = $$QTC_BUILD
+
+PROVIDER = FooCompanyInc
+
+LIBS += -L$$IDE_PLUGIN_PATH/Nokia
+
+include($$QTC_SOURCE/src/qtcreatorplugin.pri)
+include($$QTC_SOURCE/src/plugins/coreplugin/coreplugin.pri)
+
+HEADERS = DoNothingPlugin.h
+SOURCES = DoNothingPlugin.cpp
+OTHER_FILES = DoNothingPlugin.pluginspec
+\endcode
+
+The \bold{QTC_SOURCE} and \bold {QTC_BUILD} variables in the project file point to the source and build directories of Qt Creator.
+If you prefer setting these as environment variables, then use \bold{$$(QTC_BUILD)} instead of \bold{$$QTC_BUILD} in the
+project file.
+
+The \bold {IDE_SOURCE_TREE} and \bold {IDE_BUILD_TREE} variables are used by qtcreatorplugin.pri to establish the include
+and library paths.
+
+The \bold {PROVIDER} and \bold {DESTDIR} directories must be set before including qtcreatorplugin.pri. This is because the variables
+will be provided default values are \bold {Nokia} and \bold {$$IDE_BUILD_TREE/lib/qtcreator/plugins/Nokia} otherwise.
+
+By default qtcreatorplugin.pri assumes that all the libs that a plugin may depend on are present inside the \bold {DESTDIR}. If
+our \bold {DESTDIR} is different from the default (Nokia) one, then we will need to explicitly set that. The remaining things are
+just the same.
+
+
+\section2 2.7.2 Compiling the plugin
+
+Once the project file has been created, we make use of the standard qmake and make commands to compile the plugin.
+
+\code
+C:\Work\Research\QtCreator\Plugins\DoNothing>qmake
+C:\Work\Research\QtCreator\Plugins\DoNothing>nmake
+
+Microsoft (R) Program Maintenance Utility Version 8.00.50727.762
+Copyright (C) Microsoft Corporation. All rights reserved.
+
+"C:\Program Files\Microsoft Visual Studio 8\VC\BIN\nmake.exe" -f Makefile.Debug
+Microsoft (R) Program Maintenance Utility Version 8.00.50727.762
+Copyright (C) Microsoft Corporation. All rights reserved.
+
+copy /y "DoNothing.pluginspec"
+"..\..\..\..\QtCreator\build\lib\qtcreator\plugins\FooCompanyInc\DoNothing.pluginspec"
+1 file(s) copied.
+........................................
+mt.exe -nologo -manifest "debug\DoNothingd.intermediate.manifest" -
+outputresource:..\..\..\..\QtCreator\build\lib\qtcreator\plugins\FooCompanyInc\DoNothingd.dll;2
+C:\Work\Research\QtCreator\Plugins\DoNothing>
+\endcode
+*/
diff --git a/doc/pluginhowto/images/qtc-aboutplugin-2.png b/doc/pluginhowto/images/qtc-aboutplugin-2.png
new file mode 100644
index 00000000000..ce048ec86c7
--- /dev/null
+++ b/doc/pluginhowto/images/qtc-aboutplugin-2.png
Binary files differ
diff --git a/doc/pluginhowto/images/qtc-codeeffect-4.png b/doc/pluginhowto/images/qtc-codeeffect-4.png
new file mode 100644
index 00000000000..d318c54223c
--- /dev/null
+++ b/doc/pluginhowto/images/qtc-codeeffect-4.png
Binary files differ
diff --git a/doc/pluginhowto/images/qtc-compiledplugin-2.png b/doc/pluginhowto/images/qtc-compiledplugin-2.png
new file mode 100644
index 00000000000..6dceac16043
--- /dev/null
+++ b/doc/pluginhowto/images/qtc-compiledplugin-2.png
Binary files differ
diff --git a/doc/pluginhowto/images/qtc-configwidget-9.png b/doc/pluginhowto/images/qtc-configwidget-9.png
new file mode 100644
index 00000000000..1c792ef74df
--- /dev/null
+++ b/doc/pluginhowto/images/qtc-configwidget-9.png
Binary files differ
diff --git a/doc/pluginhowto/images/qtc-customeditor-10.png b/doc/pluginhowto/images/qtc-customeditor-10.png
new file mode 100644
index 00000000000..585ae7a78a3
--- /dev/null
+++ b/doc/pluginhowto/images/qtc-customeditor-10.png
Binary files differ
diff --git a/doc/pluginhowto/images/qtc-customwizardone-8.png b/doc/pluginhowto/images/qtc-customwizardone-8.png
new file mode 100644
index 00000000000..3dc3c762934
--- /dev/null
+++ b/doc/pluginhowto/images/qtc-customwizardone-8.png
Binary files differ
diff --git a/doc/pluginhowto/images/qtc-customwizardtwo-8.png b/doc/pluginhowto/images/qtc-customwizardtwo-8.png
new file mode 100644
index 00000000000..a26a956dcfd
--- /dev/null
+++ b/doc/pluginhowto/images/qtc-customwizardtwo-8.png
Binary files differ
diff --git a/doc/pluginhowto/images/qtc-designer-8.png b/doc/pluginhowto/images/qtc-designer-8.png
new file mode 100644
index 00000000000..6d64ef3f06d
--- /dev/null
+++ b/doc/pluginhowto/images/qtc-designer-8.png
Binary files differ
diff --git a/doc/pluginhowto/images/qtc-dirview-6.png b/doc/pluginhowto/images/qtc-dirview-6.png
new file mode 100644
index 00000000000..464600008ea
--- /dev/null
+++ b/doc/pluginhowto/images/qtc-dirview-6.png
Binary files differ
diff --git a/doc/pluginhowto/images/qtc-donothingleft-5.png b/doc/pluginhowto/images/qtc-donothingleft-5.png
new file mode 100644
index 00000000000..96209198f8e
--- /dev/null
+++ b/doc/pluginhowto/images/qtc-donothingleft-5.png
Binary files differ
diff --git a/doc/pluginhowto/images/qtc-donothingright-5.png b/doc/pluginhowto/images/qtc-donothingright-5.png
new file mode 100644
index 00000000000..2e6869cea96
--- /dev/null
+++ b/doc/pluginhowto/images/qtc-donothingright-5.png
Binary files differ
diff --git a/doc/pluginhowto/images/qtc-editor-10.png b/doc/pluginhowto/images/qtc-editor-10.png
new file mode 100644
index 00000000000..4904077774c
--- /dev/null
+++ b/doc/pluginhowto/images/qtc-editor-10.png
Binary files differ
diff --git a/doc/pluginhowto/images/qtc-editor-8.png b/doc/pluginhowto/images/qtc-editor-8.png
new file mode 100644
index 00000000000..fc591208465
--- /dev/null
+++ b/doc/pluginhowto/images/qtc-editor-8.png
Binary files differ
diff --git a/doc/pluginhowto/images/qtc-editortabs-10.png b/doc/pluginhowto/images/qtc-editortabs-10.png
new file mode 100644
index 00000000000..0d5d36e114b
--- /dev/null
+++ b/doc/pluginhowto/images/qtc-editortabs-10.png
Binary files differ
diff --git a/doc/pluginhowto/images/qtc-fileformat-10.png b/doc/pluginhowto/images/qtc-fileformat-10.png
new file mode 100644
index 00000000000..3b3e767be61
--- /dev/null
+++ b/doc/pluginhowto/images/qtc-fileformat-10.png
Binary files differ
diff --git a/doc/pluginhowto/images/qtc-finddialog-9.png b/doc/pluginhowto/images/qtc-finddialog-9.png
new file mode 100644
index 00000000000..beb36797002
--- /dev/null
+++ b/doc/pluginhowto/images/qtc-finddialog-9.png
Binary files differ
diff --git a/doc/pluginhowto/images/qtc-firstnavigation-6.png b/doc/pluginhowto/images/qtc-firstnavigation-6.png
new file mode 100644
index 00000000000..7dbac0194b7
--- /dev/null
+++ b/doc/pluginhowto/images/qtc-firstnavigation-6.png
Binary files differ
diff --git a/doc/pluginhowto/images/qtc-help-5.png b/doc/pluginhowto/images/qtc-help-5.png
new file mode 100644
index 00000000000..b021977d6d7
--- /dev/null
+++ b/doc/pluginhowto/images/qtc-help-5.png
Binary files differ
diff --git a/doc/pluginhowto/images/qtc-helpdonothing-5.png b/doc/pluginhowto/images/qtc-helpdonothing-5.png
new file mode 100644
index 00000000000..f823e877c1f
--- /dev/null
+++ b/doc/pluginhowto/images/qtc-helpdonothing-5.png
Binary files differ
diff --git a/doc/pluginhowto/images/qtc-htmleditor-10.png b/doc/pluginhowto/images/qtc-htmleditor-10.png
new file mode 100644
index 00000000000..585ae7a78a3
--- /dev/null
+++ b/doc/pluginhowto/images/qtc-htmleditor-10.png
Binary files differ
diff --git a/doc/pluginhowto/images/qtc-ieditor-10.png b/doc/pluginhowto/images/qtc-ieditor-10.png
new file mode 100644
index 00000000000..7ba5448a7ae
--- /dev/null
+++ b/doc/pluginhowto/images/qtc-ieditor-10.png
Binary files differ
diff --git a/doc/pluginhowto/images/qtc-installedplugin-2.png b/doc/pluginhowto/images/qtc-installedplugin-2.png
new file mode 100644
index 00000000000..6385e7f56fe
--- /dev/null
+++ b/doc/pluginhowto/images/qtc-installedplugin-2.png
Binary files differ
diff --git a/doc/pluginhowto/images/qtc-loggermode-13.png b/doc/pluginhowto/images/qtc-loggermode-13.png
new file mode 100644
index 00000000000..d605f05a96a
--- /dev/null
+++ b/doc/pluginhowto/images/qtc-loggermode-13.png
Binary files differ
diff --git a/doc/pluginhowto/images/qtc-loggermodewidget-13.png b/doc/pluginhowto/images/qtc-loggermodewidget-13.png
new file mode 100644
index 00000000000..2fb60db3f36
--- /dev/null
+++ b/doc/pluginhowto/images/qtc-loggermodewidget-13.png
Binary files differ
diff --git a/doc/pluginhowto/images/qtc-loggerpage-13.png b/doc/pluginhowto/images/qtc-loggerpage-13.png
new file mode 100644
index 00000000000..1bdca41d051
--- /dev/null
+++ b/doc/pluginhowto/images/qtc-loggerpage-13.png
Binary files differ
diff --git a/doc/pluginhowto/images/qtc-menubar-5.png b/doc/pluginhowto/images/qtc-menubar-5.png
new file mode 100644
index 00000000000..2c4182dcf0e
--- /dev/null
+++ b/doc/pluginhowto/images/qtc-menubar-5.png
Binary files differ
diff --git a/doc/pluginhowto/images/qtc-menuitem-10.png b/doc/pluginhowto/images/qtc-menuitem-10.png
new file mode 100644
index 00000000000..7a55675cb9b
--- /dev/null
+++ b/doc/pluginhowto/images/qtc-menuitem-10.png
Binary files differ
diff --git a/doc/pluginhowto/images/qtc-menuitemposition-5.png b/doc/pluginhowto/images/qtc-menuitemposition-5.png
new file mode 100644
index 00000000000..5dbf3d3556c
--- /dev/null
+++ b/doc/pluginhowto/images/qtc-menuitemposition-5.png
Binary files differ
diff --git a/doc/pluginhowto/images/qtc-menuresponse-5.png b/doc/pluginhowto/images/qtc-menuresponse-5.png
new file mode 100644
index 00000000000..b610864fcb9
--- /dev/null
+++ b/doc/pluginhowto/images/qtc-menuresponse-5.png
Binary files differ
diff --git a/doc/pluginhowto/images/qtc-modes-13.png b/doc/pluginhowto/images/qtc-modes-13.png
new file mode 100644
index 00000000000..2e22406ef96
--- /dev/null
+++ b/doc/pluginhowto/images/qtc-modes-13.png
Binary files differ
diff --git a/doc/pluginhowto/images/qtc-nevigationwidget-4.png b/doc/pluginhowto/images/qtc-nevigationwidget-4.png
new file mode 100644
index 00000000000..1aadab3b41d
--- /dev/null
+++ b/doc/pluginhowto/images/qtc-nevigationwidget-4.png
Binary files differ
diff --git a/doc/pluginhowto/images/qtc-newitemmodel-8.png b/doc/pluginhowto/images/qtc-newitemmodel-8.png
new file mode 100644
index 00000000000..c453e616021
--- /dev/null
+++ b/doc/pluginhowto/images/qtc-newitemmodel-8.png
Binary files differ
diff --git a/doc/pluginhowto/images/qtc-newmode-13.png b/doc/pluginhowto/images/qtc-newmode-13.png
new file mode 100644
index 00000000000..d8f75db6118
--- /dev/null
+++ b/doc/pluginhowto/images/qtc-newmode-13.png
Binary files differ
diff --git a/doc/pluginhowto/images/qtc-newprojectdialog-8.png b/doc/pluginhowto/images/qtc-newprojectdialog-8.png
new file mode 100644
index 00000000000..dbf7e8dc892
--- /dev/null
+++ b/doc/pluginhowto/images/qtc-newprojectdialog-8.png
Binary files differ
diff --git a/doc/pluginhowto/images/qtc-objectlist-4.png b/doc/pluginhowto/images/qtc-objectlist-4.png
new file mode 100644
index 00000000000..e6327ea03e3
--- /dev/null
+++ b/doc/pluginhowto/images/qtc-objectlist-4.png
Binary files differ
diff --git a/doc/pluginhowto/images/qtc-options-5.png b/doc/pluginhowto/images/qtc-options-5.png
new file mode 100644
index 00000000000..7b4dcc29149
--- /dev/null
+++ b/doc/pluginhowto/images/qtc-options-5.png
Binary files differ
diff --git a/doc/pluginhowto/images/qtc-options-7.png b/doc/pluginhowto/images/qtc-options-7.png
new file mode 100644
index 00000000000..d96513d0201
--- /dev/null
+++ b/doc/pluginhowto/images/qtc-options-7.png
Binary files differ
diff --git a/doc/pluginhowto/images/qtc-options-keyboard-5.png b/doc/pluginhowto/images/qtc-options-keyboard-5.png
new file mode 100644
index 00000000000..6b21187c516
--- /dev/null
+++ b/doc/pluginhowto/images/qtc-options-keyboard-5.png
Binary files differ
diff --git a/doc/pluginhowto/images/qtc-plaintextedit-10.png b/doc/pluginhowto/images/qtc-plaintextedit-10.png
new file mode 100644
index 00000000000..77da1a97027
--- /dev/null
+++ b/doc/pluginhowto/images/qtc-plaintextedit-10.png
Binary files differ
diff --git a/doc/pluginhowto/images/qtc-plugindirectory-2.png b/doc/pluginhowto/images/qtc-plugindirectory-2.png
new file mode 100644
index 00000000000..1e758cbc5b5
--- /dev/null
+++ b/doc/pluginhowto/images/qtc-plugindirectory-2.png
Binary files differ
diff --git a/doc/pluginhowto/images/qtc-pluginmanager-4.png b/doc/pluginhowto/images/qtc-pluginmanager-4.png
new file mode 100644
index 00000000000..ef4301b0a83
--- /dev/null
+++ b/doc/pluginhowto/images/qtc-pluginmanager-4.png
Binary files differ
diff --git a/doc/pluginhowto/images/qtc-progressbar-11.png b/doc/pluginhowto/images/qtc-progressbar-11.png
new file mode 100644
index 00000000000..521b67eb715
--- /dev/null
+++ b/doc/pluginhowto/images/qtc-progressbar-11.png
Binary files differ
diff --git a/doc/pluginhowto/images/qtc-search-9.png b/doc/pluginhowto/images/qtc-search-9.png
new file mode 100644
index 00000000000..39d397364e2
--- /dev/null
+++ b/doc/pluginhowto/images/qtc-search-9.png
Binary files differ
diff --git a/doc/pluginhowto/images/qtc-searchprogress-11.png b/doc/pluginhowto/images/qtc-searchprogress-11.png
new file mode 100644
index 00000000000..54e7f4364fd
--- /dev/null
+++ b/doc/pluginhowto/images/qtc-searchprogress-11.png
Binary files differ
diff --git a/doc/pluginhowto/images/qtc-secondnavigation-6.png b/doc/pluginhowto/images/qtc-secondnavigation-6.png
new file mode 100644
index 00000000000..acf3a2881b2
--- /dev/null
+++ b/doc/pluginhowto/images/qtc-secondnavigation-6.png
Binary files differ
diff --git a/doc/pluginhowto/images/qtc-testplugin-7.png b/doc/pluginhowto/images/qtc-testplugin-7.png
new file mode 100644
index 00000000000..c04d8149630
--- /dev/null
+++ b/doc/pluginhowto/images/qtc-testplugin-7.png
Binary files differ
diff --git a/doc/pluginhowto/images/qtc-testplugin-8.png b/doc/pluginhowto/images/qtc-testplugin-8.png
new file mode 100644
index 00000000000..3fbcee58940
--- /dev/null
+++ b/doc/pluginhowto/images/qtc-testplugin-8.png
Binary files differ
diff --git a/doc/pluginhowto/images/qtc-testplugin-9.png b/doc/pluginhowto/images/qtc-testplugin-9.png
new file mode 100644
index 00000000000..9affcc4dbeb
--- /dev/null
+++ b/doc/pluginhowto/images/qtc-testplugin-9.png
Binary files differ
diff --git a/doc/pluginhowto/images/qtc-title-10.png b/doc/pluginhowto/images/qtc-title-10.png
new file mode 100644
index 00000000000..25f662ef111
--- /dev/null
+++ b/doc/pluginhowto/images/qtc-title-10.png
Binary files differ
diff --git a/doc/pluginhowto/location-filter.qdoc b/doc/pluginhowto/location-filter.qdoc
new file mode 100644
index 00000000000..88bd85680ad
--- /dev/null
+++ b/doc/pluginhowto/location-filter.qdoc
@@ -0,0 +1,6 @@
+/*!
+ \page location-filter.html
+ \title 14.Adding location filter
+
+ This page needs to be written still!
+*/
diff --git a/doc/pluginhowto/menu.qdoc b/doc/pluginhowto/menu.qdoc
new file mode 100644
index 00000000000..5a491819425
--- /dev/null
+++ b/doc/pluginhowto/menu.qdoc
@@ -0,0 +1,304 @@
+/*!
+\page menu.html
+\title 5. Adding menu and menu-items
+
+In this chapter we will understand how to add entries to existing menus in Qt Creator. We will also learn how to add new
+menu entries. Before moving ahead let's take a look at the menu bar in Qt Creator
+
+\inlineimage qtc-menubar-5.png
+
+
+The menu bar consists of the following set of default menus
+\list
+\o File
+ \list
+ \o New
+ \o Open
+ \o Recent Files
+ \endlist
+\o Edit
+ \list
+ \o Advanced
+ \endlist
+\o Tools
+\o Window
+ \list
+ \o Panes
+ \endlist
+\o Help
+\endlist
+
+\bold {Note:}\underline{Other menu items like Build and Debug come from plugins. They are not a part of the default menu set}.
+
+As Qt developers we know that the above menus are shown within a \bold {QMenuBar}; and that there is a \bold {QMenu} associated
+with each of the above menus.
+
+\section1 5.1 Core::ActionManager
+
+The main Qt Creator program is nothing but a plugin loader. All of the functionality provided by Qt Creator is provided
+by the plugins. The main plugin for Qt Creator is called "core" Without core, Qt Creator really doesn't have a personality
+
+One of the key components of the "core" is the \bold {ActionManager}.\bold {ActionManager} is responsible for registration of menus,
+menu-items and keyboard shortcuts. So if we wanted to add a new menu-item or menu, we would have to use
+\bold {ActionManager}. The coming subsections explain this better.
+
+To gain access to the \bold {ActionManager}, the following piece of code can be used.
+\code
+#include <coreplugin/actionmanager/actionmanager.h>
+#include <coreplugin/icore.h>
+Core::ActionManager* am = Core::ICore::instance()->actionManager();
+\endcode
+
+\section1 5.2 Core::ActionContainer
+
+ActionContianer represents menu or menubar in Qt Creator. Instances of ActionContainer are never created directly,
+instead they are accessed using ActionManager::createMenu(), ActionManager::createMenuBar() etc; but more on that
+later.
+There is an ActionContainer associated with each of the default menus in Qt Creator. Fetching ActionContainer for a
+given menu can be done using the following code snippet
+
+\code
+#include <coreplugin/coreconstants.h>
+#include <coreplugin/actionmanager/actionmanager.h>
+#include <coreplugin/icore.h>
+
+Core::ActionManager* am = Core::ICore::instance()->actionManager();
+Core::ActionContainer* ac = am->actionContainer( ID );
+\endcode
+The following table lists out the ID to use for each of the menus in Qt Creator. Each of the IDs are defined as \bold {const}
+\bold {char*} static variables within the \bold {Core} namespace.
+
+\table
+\header
+ \o Menu
+ \o ID
+\row
+ \o File
+ \o Core::Constants::M_FILE
+\row
+ \o File->New
+ \o Core::Constants::M_FILE_NEW
+\row
+ \o File->Open
+ \o Core::Constants::M_FILE_OPEN
+\row
+ \o Edit
+ \o Core::Constants::M_FILE_RECENTFILES
+\row
+ \o Edit->Advanced
+ \o Core::Constants::M_EDIT_ADVANCED
+\row
+ \o Tools
+ \o Core::Constants::M_TOOLS
+\row
+ \o Window
+ \o Core::Constants::M_WINDOW
+\row
+ \o Window Panes
+ \o Core::Constants::M_WINDOW_PANES
+\row
+ \o Help
+ \o Core::Constants::M_HELP
+\endtable
+
+So if we want to catch hold of the "Help" menu, we can use the code snippet as follows
+\code
+#include <coreplugin/coreconstants.h>
+#include <coreplugin/actionmanager/actionmanager.h>
+#include <coreplugin/icore.h>
+
+Core::ActionManager* am = Core::ICore::instance()->actionManager();
+Core::ActionContainer* ac = am->actionContainer( Core::Constants::M_HELP );
+\endcode
+
+\section1 5.3 Registering menu-items.
+
+The Core::Command class represents an action like a menu item, tool button, or shortcut. You don't create Command
+objects directly, instead use we use ActionManager::registerAction() to register an action and retrieve a Command. The
+Command object represents the user visible action and its properties.
+
+Shown below is the right way to add the "About DoNothing" menu-item from the DoNothing plugin.
+
+\code
+#include <coreplugin/coreconstants.h>
+#include <coreplugin/actionmanager/actionmanager.h>
+#include <coreplugin/actionmanager/command.h>
+#include <coreplugin/icore.h>
+#include <QKeySequence>
+
+bool DoNothingPlugin::initialize(const QStringList& args, QString *errMsg)
+{
+ Q_UNUSED(args);
+ Q_UNUSED(errMsg);
+
+ // Fetch the action manager
+ Core::ActionManager* am = Core::ICore::instance()->actionManager();
+
+ // Create a command for "About DoNothing".
+ Core::Command* cmd = am->registerAction(
+ new QAction(tr("About DoNothing"),this),
+ "DoNothingPlugin.AboutDoNothing",
+ QList<int>() <<Core::Constants::C_GLOBAL_ID
+ );
+
+ // Add the command to Help menu
+ am->actionContainer(Core::Constants::M_HELP)->addAction(cmd);
+ return true;
+}
+\endcode
+\bold {Warning:}\underline { ac->menu()->addAction("About DoNothing") should never be used when adding menu items to Qt Creator.}
+
+After compiling the changes, we can notice that the "About DoNothing" action shows up in the "Help" menu; but at the
+beginning.
+
+\inlineimage qtc-helpdonothing-5.png
+
+
+If the "About DoNothing" menu item is to be placed in between specified menu item the we will make a small update in the code block
+\code
+bool DoNothingPlugin::initialize(const QStringList& args, QString *errMsg)
+{
+ .....
+ // Add the command to Help menu
+ am->actionContainer(Core::Constants::M_HELP)->addAction(showCmd, Core::Constants::G_HELP_HELP);
+ return true;
+}
+\endcode
+
+The effect of the change in code can be seen in the image below.
+
+\inlineimage qtc-menuitemposition-5.png
+
+
+When added this way, we will be able to find the "About DoNothing" action in the "Keyboard Shortcuts" dialog box and
+also associate a keyboard shortcut with it.
+
+\inlineimage qtc-options-keyboard-5.png
+
+
+\section1 5.4 Responding to menu-items
+Since menu-items are QActions, we can connect to their triggered(bool) or toggled(bool) signal and respond to
+trigger/toggled events. The code below shows how to do this
+\code
+class DoNothingPlugin : public ExtensionSystem::IPlugin
+{
+ Q_OBJECT
+
+private slots:
+ void about();
+};
+
+bool DoNothingPlugin::initialize(const QStringList& args, QString *errMsg)
+{
+ ......
+ QAction *action = new QAction(tr("About DoNothing"),this);
+ Core::Command* cmd = am->registerAction(action,
+ "DoNothingPlugin.AboutDoNothing",
+ QList<int>() << 0);
+ ......
+ connect(action, SIGNAL(triggered(bool)), this, SLOT(about()));
+ return true;
+}
+
+void DoNothingPlugin::about()
+{
+ QMessageBox::information(0, "About DoNothing Plugin",
+ "Seriously dude, this plugin does nothing");
+}
+\endcode
+
+After compiling the changes and clicking on the "About DoNothing" menu-item, we can see the information dialog box
+as shown below.
+
+\inlineimage qtc-menuresponse-5.png
+
+
+If you wanted the message box to have the Qt Creator main window as its parent, then you can use the following code
+for the about() slot.
+
+\code
+void DoNothingPlugin::about()
+{
+ QMessageBox::information(Core::ICore::instance()->mainWindow(),
+ "About DoNothing Plugin",
+ "Seriously dude, this plugin does nothing");
+}
+\endcode
+
+\section1 5.5 Adding menus
+The procedure for adding menus is the same. Instead of creating a \bold {Core::Command}, we create a \bold {Core::ActionContainer}
+and add it to the \bold {MENU_BAR}. The following code snippet highlights the changes from our previous version.
+\code
+bool DoNothingPlugin::initialize(const QStringList& args, QString *errMsg)
+{
+ Q_UNUSED(args);
+ Q_UNUSED(errMsg);
+
+ // Fetch the action manager
+ Core::ActionManager* am = Core::ICore::instance()->actionManager();
+
+ // Create a DoNothing menu
+ Core::ActionContainer* ac = am->createMenu("DoNothingPlugin.DoNothingMenu");
+ ac->menu()->setTitle("DoNothing");
+
+ // Create a command for "About DoNothing".
+ QAction *action = new QAction(tr("About DoNothing",this));
+ Core::Command* cmd = am->registerAction(action,"DoNothingPlugin.AboutDoNothing",QList<int>() << 0);
+
+ // Add DoNothing menu to the menubar
+ am->actionContainer(Core::Constants::MENU_BAR)->addMenu(ac);
+
+ // Add the "About DoNothing" action to the DoNothing menu
+ ac->addAction(cmd);
+
+ // Connect the action
+ connect(action, SIGNAL(triggered(bool)), this, SLOT(about()));
+ return true;
+}
+\endcode
+After recompiling the changes, you will be able to notice the DoNothing menu as shown in the screenshot below.
+
+\inlineimage qtc-donothingleft-5.png
+
+\section1 5.6 Placing menus and menu-items
+It is possible to insert menus and menu-items anywhere you want. Shown below is a code snippet that inserts the
+"DoNothing" menu before the "Help" menu.
+\code
+bool DoNothingPlugin::initialize(const QStringList& args, QString *errMsg)
+{
+ Q_UNUSED(args);
+ Q_UNUSED(errMsg);
+
+ // Fetch the action manager
+ Core::ActionManager* am = Core::ICore::instance()->actionManager();
+
+ // Create a DoNothing menu
+ Core::ActionContainer* ac = am->createMenu("DoNothingPlugin.DoNothingMenu");
+ ac->menu()->setTitle("DoNothing");
+
+ // Create a command for "About DoNothing".
+ QAction *action = new QAction(tr("About DoNothing"),this);
+ Core::Command* cmd = am->registerAction(action,"DoNothingPlugin.AboutDoNothing",QList<int>() << 0);
+
+ // Insert the "DoNothing" menu between "Window" and "Help".
+ QMenu* windowMenu = am->actionContainer(Core::Constants::M_HELP)->menu();
+ QMenuBar* menuBar = am->actionContainer(Core::Constants::MENU_BAR)->menuBar();
+ menuBar->insertMenu(windowMenu->menuAction(), ac->menu());
+
+ // Add the "About DoNothing" action to the DoNothing menu
+ ac->addAction(cmd);
+
+ // Connect the action
+ connect(action, SIGNAL(triggered(bool)), this, SLOT(about()));
+ return true;
+}
+\endcode
+
+After compiling the changes, we can now notice that change in position of the "DoNothing" menu.
+
+\inlineimage qtc-donothingright-5.png
+
+
+You can use a similar technique for customizing the position of menu-items.
+
+*/
diff --git a/doc/pluginhowto/mode.qdoc b/doc/pluginhowto/mode.qdoc
new file mode 100644
index 00000000000..bf421e949a3
--- /dev/null
+++ b/doc/pluginhowto/mode.qdoc
@@ -0,0 +1,537 @@
+/*!
+\page mode.html
+\title 13. Adding a mode
+
+When we are working in Qt Creator then we in one of the six modes below.
+
+\list
+\o Welcome
+\o Edit
+\o Debug
+\o Project
+\o Help
+\o Output
+\endlist
+
+By selecting different modes in Qt creator we can quickly switch between different task spaces, such
+as editing, browsing the Qt Creator manual, setting up the build environment, etc.
+Different modes can be selected either by clicking on the mode selectors or through keyboard shortcuts.
+
+The following figure shows the mode selectors in the Qt Creator.
+
+\inlineimage qtc-modes-13.png
+
+
+Now in this chapter we are concerned about learning to add a new mode and a "LoggerMode" mode selector will be availble in Qt Creator.
+
+\section1 13.1 Core Classes and Interfaces
+
+To support a new mode we need to
+\list
+\o Implement a plugin \bold {(ExtensionSystem::IPlugin } implementation) class that exposes the new mode.Chapter 2 in this
+ document provides a detailed description on creating plugins by implementing the ExtensionSystem::IPlugin interface.
+\o Implement the \bold{(Core::IMode)} interface. This interface allows us to add a new mode in Qt creator
+\endlist
+
+
+\section2 Step 1. Core::IMode interface
+This interface abstracts the creation of a mode, adding an icon to the mode selector, setting the mode priority,
+setting a unique made name. The \bold {Core::IMode} interface is declared as follows in scr/plugins/coreplugin/imode.h
+\code
+namespace Core {
+
+ class CORE_EXPORT IMode : public IContext
+ {
+ Q_OBJECT
+
+ public:
+ IMode(QObject *parent = 0) : IContext(parent) {}
+ virtual ~IMode() {}
+
+ virtual QString name() const = 0;
+ virtual QIcon icon() const = 0;
+ virtual int priority() const = 0;
+ virtual const char *uniqueModeName() const = 0;
+ };
+} // namespace Core
+\endcode
+
+Notice that Core::IMode inherits Core::IContext. Core::IContext is an interface through which
+Qt Creator picks up the widget corresponding to the mode. The Core::IContext interface is declared
+as follows.
+
+\code
+namespace Core
+{
+
+ class CORE_EXPORT IContext : public QObject
+ {
+ Q_OBJECT
+
+ public:
+ IContext(QObject *parent = 0) : QObject(parent) {}
+ virtual ~IContext() {}
+
+ virtual QList<int> context() const = 0;
+ virtual QWidget *widget() = 0;
+ virtual QString contextHelpId() const { return QString(); }
+ };
+}
+\endcode
+
+\section1 13.2 Adding a new mode
+Lets add a mode to Qt Creator called "LoggerMode". LoggerMode allows the user (developer) to log the number of hours he/she
+has worked on a project. The following steps explain how the new mode "LoggerMode" is added.
+
+\section2 Step 1. Declaring the LoggerMode class
+We first begin by declaring a class called LoggerMode that implements the Core::IMode interface.
+The class definition is as follows.
+\code
+#include <coreplugin/imode.h>
+
+struct LoggerModeData;
+class LoggerMode : public Core::IMode
+{
+ Q_OBJECT
+
+public:
+ LoggerMode();
+ ~LoggerMode();
+
+ QString name() const;
+ QIcon icon() const;
+ int priority() const;
+ QWidget *widget();
+ const char *uniqueModeName() const;
+ QList<int> context() const;
+ void activated();
+ QString contextHelpId() const { return QLatin1String("Qt Creator"); }
+
+private:
+ LoggerModeData *d;
+};
+\endcode
+
+\section2 Step 2. Implementing the LoggerMode class
+Declaring the private variables of the LoggerMode class.
+\code
+struct LoggerModeData
+{
+ QWidget *m_widget;
+};
+\endcode
+The constructor creates a new blank widget just for now to get started with the mode.
+The constructor and the destructor are implemented as follows
+\code
+LoggerMode::LoggerMode()
+{
+ d = new LoggerModeData;
+ d->m_widget = new QWidget;
+}
+
+LoggerMode::~LoggerMode()
+{
+ delete d->m_widget;
+ delete d;
+}
+\endcode
+The \bold {name()} method returns a name for the new mode selector.
+\code
+QString LoggerMode::name() const
+{
+ return tr("LoggerMode");
+}
+\endcode
+
+The \bold {icon()} method returns a logo for the new mode selector.
+\code
+QIcon LoggerMode::icon() const
+{
+ return QIcon(QLatin1String(":/core/images/qtcreator_logo_32.png"));
+}
+\endcode
+
+The \bold {priority()} method is implemented to return a priority for the mode. Modes of higher
+priority are shown above modes of lower priority. The highest priority in Qt Creator is currently
+100 and is associated with the Welcome mode. We return 0 from LoggerMode, becasue we want this
+mode to appear at the end.
+\code
+int LoggerMode::priority() const
+{
+ return 0;
+}
+\endcode
+Thw \bold {widget()} method returns a widget to the new mode.
+\code
+QWidget* LoggerMode::widget()
+{
+ return d->m_widget;
+}
+\endcode
+
+The \bold {uniqueModeName()} returns the name of the mode to the "LoggerMode" Class.
+\code
+const char* LoggerMode::uniqueModeName() const
+{
+ return "LoggerMode" ;
+}
+\endcode
+The \bold {context()} method returns an empty list of integers to tne "LoggerMode" class.
+\code
+QList<int> LoggerMode::context() const
+{
+ return QList<int>();
+}
+\endcode
+
+\section2 Step 3. Implementing the "LoggerMode" plugin
+We implement the "LoggerMode" plugin very similar to the DoNothingPlugin class described in Chapter 2.
+Here we only look at the implementation of the initialize() method.
+\code
+bool LoggerModePlugin::initialize(const QStringList& args, QString *errMsg)
+{
+ Q_UNUSED(args);
+ Q_UNUSED(errMsg);
+
+ loggerMode = new LoggerMode;
+ addAutoReleasedObject(loggerMode);
+
+ return true;
+}
+\endcode
+\section2 Step 4. Testing the plugin.
+Upon compiling the plugin and restarting Qt Creator, we can notice the "LoggerMode" mode selector in the Qt creator.
+
+\inlineimage qtc-loggermode-13.png
+
+\section1 13.3 Adding Functionality to the "LoggerMode"
+The actual function of the "LoggerMode" is to log data in a text file about a project, such as progress , hours worked,
+description etc.
+
+\section2 Step 1. Modifying the "LoggerMode" Class
+
+To add the functionalities, the LoggerMode class is further modified.
+The code block is given as follows.
+
+\code
+struct LoggerModeData;
+class LoggerMode :public Core::IMode
+{
+ Q_OBJECT
+
+public:
+ LoggerMode();
+ ~LoggerMode();
+ ...
+ ...
+
+protected slots:
+ void addNewStackWidgetPage(const QString projectName);
+ void addItem();
+
+private:
+ ...
+};
+\endcode
+
+The constructor of the \bold {LoggerMode} class is modified as follows.
+\code
+LoggerMode::LoggerMode()
+{
+ d = new LoggerModeData;
+ d->m_widget = new QWidget;
+
+ //Current Projects Label and combobox widget are created.
+
+ d->currentProjectsLabel = new QLabel("Current projects :");
+ d->currentProjectsLabel->setFixedWidth(90);
+ d->currentProjectsCombobox = new QComboBox;
+ d->currentProjectsCombobox->setSizePolicy(QSizePolicy::Preferred,
+ QSizePolicy::Preferred);
+
+ //Add Projects Label and combobox widget are created.
+
+ d->addProjectLabel = new QLabel("Add Project :");
+ d->addProjectLabel->setAlignment(Qt::AlignRight);
+ d->addProjectComboBox = new QComboBox;
+ d->addProjectComboBox->setSizePolicy(QSizePolicy::Preferred,
+ QSizePolicy::Preferred);
+ d->addProjectComboBox->setEditable(true);
+
+ d->addToProjectButton = new QPushButton(tr("Add Project"));
+ d->addToProjectButton->setFixedWidth(80);
+
+ //Creating a horizontal Layout
+
+ QHBoxLayout *hLayout = new QHBoxLayout;
+ hLayout->addWidget(d->currentProjectsLabel);
+ hLayout->addWidget(d->currentProjectsCombobox);
+ hLayout->addWidget(d->addProjectLabel);
+ hLayout->addWidget(d->addProjectComboBox);
+ hLayout->addWidget(d->addToProjectButton);
+
+ //creating a stackedWidget
+
+ d->stackedWidget = new QStackedWidget;
+
+ //creating a vertical layout
+
+ QVBoxLayout* layout = new QVBoxLayout;
+ layout->addLayout(hLayout);
+ layout->addWidget(d->stackedWidget);
+
+ d->m_widget->setLayout(layout);
+
+ d->addProjectComboBox->addItem("Project 1");
+ d->addProjectComboBox->addItem("Project 2");
+ d->addProjectComboBox->addItem("Project 3");
+
+ connect(d->addToProjectButton,SIGNAL(clicked()),
+ this,SLOT(addItem()));
+
+ connect(d->currentProjectsCombobox, SIGNAL(currentIndexChanged(int)),
+ d->stackedWidget, SLOT(setCurrentIndex(int)));
+}
+
+\endcode
+
+Implementation of the \bold{addNewStackWidgetPage()} slot of \bold {LoggerMode} class
+\code
+void LoggerMode::addNewStackWidgetPage(const QString projectName)
+{
+ d->stackedWidget->addWidget(new LoggerModeWidget(projectName));
+}
+\endcode
+
+Implementation of the \bold{addItem()} slot of \bold {LoggerMode} class
+\code
+void LoggerMode::addItem()
+{
+ d->currentProjectsCombobox->addItem(d->addProjectComboBox->currentText());
+ addNewStackWidgetPage(d->currentProjectsCombobox->itemText(0));
+}
+\endcode
+
+The effect of the above block of code can be seen in the following image.
+
+\inlineimage qtc-loggerpage-13.png
+
+
+\section2 Step 2. Declaration of the "LoggerModeWidget" class
+Reffering to the above image, when ever we select a project from the \bold {Add Project} combobox and click
+\bold {Add Project} button a new project is added to the \bold {Current projects} list and and a corresponding
+\bold {LoggerModeWidget} is opened, for logging different informations about the project.
+The declaration of the \bold {LoggerModeWidget} class is shown in the following code block.
+
+ \code
+#include <QWidget>
+
+struct LoggerModeWidgetData;
+class LoggerModeWidget : public QWidget
+{
+ Q_OBJECT
+
+public:
+ LoggerModeWidget(const QString projectName, QWidget* parent = 0);
+ ~LoggerModeWidget();
+
+public slots:
+ void setProjectName(QString name);
+
+protected slots:
+ bool saveToFile();
+ void startTimeLog();
+ void endTimeLog();
+ void updateTime();
+
+private:
+ LoggerModeWidgetData* d;
+};
+\endcode
+
+\section2 Step 3. Implementing the "LoggerModeWidget" class
+Declaring the private member variables in the structure called \bold {LoggerModeWidgetData}
+\code
+struct LoggerModeWidgetData
+{
+ QLabel *progressLabel;
+ QLabel *hoursWorkedLabel;
+ QLabel *dateLabel;
+ QLabel *descriptionLabel;
+ QCalendarWidget *calendar;
+ QComboBox *progressComboBox;
+ QLineEdit *hoursWorkedLineEdit;
+ QPushButton *startTimerButton;
+ QPushButton *stopTimerButton;
+ QPushButton *saveButton;
+ QTimer *timer;
+ QTextEdit *textEdit;
+ QString projectName;
+ int totalTime;
+};
+\endcode
+Implementation of the constructor and destructor of the \bold {LoggerModeWidget} class
+\code
+LoggerModeWidget::LoggerModeWidget(const QString projectName, QWidget* parent)
+:QWidget(parent)
+{
+ d = new LoggerModeWidgetData;
+ d->projectName = projectName;
+ d->totalTime = 0;
+
+ QStringList percentList;
+ percentList <<"10%" <<"20%" <<"30%" <<"40%" <<"50%"
+ <<"60%" <<"70%" <<"80%" <<"90%" <<"100%" ;
+ d->progressLabel = new QLabel("Progress:");
+ d->hoursWorkedLabel = new QLabel("Hours Worked:");
+ d->dateLabel = new QLabel("Date:");
+ d->descriptionLabel = new QLabel("Description :");
+ d->hoursWorkedLineEdit = new QLineEdit;
+ d->hoursWorkedLineEdit->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
+ d->progressComboBox = new QComboBox;
+ d->progressComboBox->addItems(percentList);
+ d->progressComboBox->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
+ d->startTimerButton = new QPushButton(tr("Start Timer"));
+ d->startTimerButton->setFixedWidth(80);
+ d->stopTimerButton = new QPushButton(tr("Pause Timer"));
+ d->stopTimerButton->setFixedWidth(80);
+ d->stopTimerButton->setCheckable(true);
+ d->textEdit = new QTextEdit(this);
+ d->textEdit->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
+ d->calendar = new QCalendarWidget;
+ d->saveButton = new QPushButton(tr("Save To File"));
+ d->saveButton->setSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred);
+
+ QGroupBox *timeLoggerBox = new QGroupBox(tr("Time Logger"));
+
+ QGridLayout *gLayout = new QGridLayout;
+ gLayout->addWidget(d->dateLabel, 0, 0, 1, 1);
+ gLayout->addWidget(d->calendar, 1, 0, 1, 3);
+ gLayout->addWidget(d->progressLabel, 2, 0, 1, 1);
+ gLayout->addWidget(d->progressComboBox, 2, 1, 1, 1);
+ gLayout->addWidget(d->hoursWorkedLabel, 3, 0, 1, 1);
+ gLayout->addWidget(d->hoursWorkedLineEdit, 3, 1, 1, 1);
+ gLayout->addWidget(d->startTimerButton, 4, 1, 1, 1);
+ gLayout->addWidget(d->stopTimerButton, 4, 2, 1, 1);
+
+ timeLoggerBox->setLayout(gLayout);
+
+ d->timer = new QTimer(this);
+
+ // connection of SIGNALS and SLOTS
+
+ connect(d->timer, SIGNAL(timeout()), this, SLOT(updateTime()));
+ connect(d->startTimerButton,SIGNAL(clicked()),this,SLOT(startTimeLog()));
+ connect(d->stopTimerButton,SIGNAL(clicked()),this,SLOT(endTimeLog()));
+ connect(d->saveButton, SIGNAL(clicked()), this, SLOT(saveToFile()));
+
+ QVBoxLayout *vLayout = new QVBoxLayout;
+ vLayout->addWidget(d->descriptionLabel);
+ vLayout->addWidget(d->textEdit);
+
+ QHBoxLayout * hLayout = new QHBoxLayout;
+ hLayout->addWidget(timeLoggerBox);
+ hLayout->addLayout(vLayout);
+
+ QHBoxLayout *bLayout = new QHBoxLayout;
+ bLayout->addStretch(1);
+ bLayout->addWidget(d->saveButton);
+
+ QVBoxLayout *mainLayout = new QVBoxLayout(this);
+ mainLayout->addLayout(hLayout);
+ mainLayout->addLayout(bLayout);
+ mainLayout->addStretch(1);
+
+}
+
+LoggerModeWidget::~LoggerModeWidget()
+{
+ delete d;
+}
+
+\endcode
+
+The \bold {saveToFile()} slot is used by the "SaveTofile" button to save the contents of the "LoggerModeWidget" to a
+text file.
+\code
+bool LoggerModeWidget::saveToFile()
+{
+ QString fileName = QFileDialog::getSaveFileName(this);
+ if (fileName.isEmpty())
+ return false;
+
+ QFile file(fileName);
+ if (!file.open(QFile::WriteOnly | QFile::Text)) {
+ QMessageBox::critical(this, tr("Application"),
+ tr("Unable to open file %1 for writing :\n%2.")
+ .arg(fileName)
+ .arg(file.errorString()));
+ return false;
+ }
+
+ QTextStream out(&file);
+
+#ifndef QT_NO_CURSOR
+ QApplication::setOverrideCursor(Qt::WaitCursor);
+#endif
+ out << "Project name : " << d->projectName << "\n";
+ out << "Date : " << d->calendar->selectedDate().toString() << "\n";
+ out << "Progress : " << d->progressComboBox->currentText() << "\n";
+ out << "Duration : " << d->hoursWorkedLineEdit->text() << "\n\n";
+ out << "Description : " << d->textEdit->toPlainText();
+#ifndef QT_NO_CURSOR
+ QApplication::restoreOverrideCursor();
+#endif
+
+ return true;
+}
+\endcode
+The \bold {startTimeLog()} slot is used by the \bold {Start Timer} button to start the timer.
+\code
+void LoggerModeWidget::startTimeLog()
+{
+ d->totalTime = 0;
+ d->timer->start(1000);
+}
+\endcode
+
+The \bold {endTimeLog()} slot is used by the \bold (Pause Timer } button to pause and resume the timer.
+\code
+void LoggerModeWidget::endTimeLog()
+{
+ if(d->stopTimerButton->isChecked())
+ {
+ d->stopTimerButton->setText("Continue Timer");
+ d->timer->stop();
+ }
+ else
+ {
+ d->stopTimerButton->setText("Pause Timer");
+ d->timer->start(1000);
+ }
+}
+\endcode
+
+The \bold {updateTime()} slot is used to update the time.
+\code
+void LoggerModeWidget::updateTime()
+{
+ d->totalTime++;
+ QTime time(0,0,0);
+ time = time.addSecs(d->totalTime);
+ d->hoursWorkedLineEdit->setText(time.toString());
+}
+\endcode
+
+\section1 13.4 Testing the final LoggerMode plugin.
+
+\section2 Step 1. A "LoggerMode" mode selector can be seen int the Qt Creator.
+\inlineimage qtc-loggermode-13.png
+
+\section2 Step 2. A LoggerMode widget opens with options to "Add Projects"
+\inlineimage qtc-loggerpage-13.png
+
+\section2 Step 3. The "Add Project" button adds a project to the "Current Project list and opens the the "LoggerModeWidget"
+\inlineimage qtc-loggermodewidget-13.png
+
+*/
diff --git a/doc/pluginhowto/nav-widget.qdoc b/doc/pluginhowto/nav-widget.qdoc
new file mode 100644
index 00000000000..e1274bd0118
--- /dev/null
+++ b/doc/pluginhowto/nav-widget.qdoc
@@ -0,0 +1,171 @@
+/*!
+ \page nav-widget.html
+ \title 6. Adding Navigation Widget
+
+ Navigation panel in Qt Creator is the area where Project, File System, Bookmark and Open Documents siderbars are
+ shown. Sidebar is one of the widgets in the "Navigation Panel" Take a look at the marked area in the screenshot below.
+
+ \inlineimage qtc-firstnavigation-6.png
+
+
+ Qt Creator makes it possible for us to divide the navigation panel into windows and view more than one side bar at the
+ same time. Take a look at the screenshot below.
+
+
+ \inlineimage qtc-secondnavigation-6.png
+
+
+ In this chapter we will understand how to add a new side bar to Qt Creator.
+
+ \section1 6.1 Core::INavigationWidgetFactory interface
+
+ The Core of Qt Creator exposes an interface called Core::INavigationWidgetFactory. The interface is defined as follows in
+ plugins/corelib/inavigationwidgetfactory.h
+
+ \code
+ class CORE_EXPORT INavigationWidgetFactory : public QObject
+ {
+ Q_OBJECT
+
+ public:
+ INavigationWidgetFactory();
+ virtual ~INavigationWidgetFactory();
+ virtual QString displayName() = 0;
+ virtual QKeySequence activationSequence();
+ virtual NavigationView createWidget() = 0;
+ virtual void saveSettings(int position, QWidget *widget);
+ virtual void restoreSettings(int position, QWidget *widget);
+ };
+ \endcode
+
+ And NavigationView (the return type of createWidget()) is
+
+ \code
+ struct NavigationView
+ {
+ QWidget *widget;
+ QList<QToolButton *> doockToolBarWidgets;
+ };
+
+ \endcode
+
+ Plugins that provide a navigation siderbar (or widget) must implement this interface. In addition to implementing the
+ interface, the plugin has to use "expose" an instance of that interface using methods described in section 4.2.2.
+
+ \section1 6.2 Preparing a navigation sidebar (widget)
+
+ Suppose that we wanted to provide a Directory browser as a side bar widget from our plugin.
+
+ \section2 Step 1: Let's Implement FileSystemModel such that it will show only one column.
+
+ The Implementation of FileSystemModel is as follows:
+ \code
+ #include <QFileSystemModel>
+
+ class FileSystemModel : public QFileSystemModel
+ {
+ public:
+ FileSystemModel(QObject* parent=0);
+ ~FileSystemModel();
+ int columnCount(const QModelIndex &parent = QModelIndex()}const;
+ };
+ \endcode
+
+ General Constructor and Destructor
+ \code
+ FileSystemModel::FileSyatemModel(QObject *parent)
+ :QFileSystemModel(parent)
+ {
+ }
+
+ FileSystemModel::~FileSystemModel()
+ {
+ }
+ \endcode
+
+ Implement the virtual function columnCount to return only one column.
+
+ \code
+ int FileSystemModel::columnCount(const QModelIndex &parent)const
+ {
+ Q_UNUSED(parent)
+ return 1;
+ }
+ \endcode
+ With this FileSystemModel is ready.
+
+ \section2 Step 2: Implementing the INavigationWidgetFactory Interface
+ We implement the INavigationWidgetFactory interface in a class whose defination is as follows
+
+ \code
+ #include<coreplugin/inavigationwidgetfactory.h>
+
+ class DirNavigationFactory:: public Core::INavigationWidgetFactory
+ {
+ public:
+ DirNavigationFactory(){}
+ ~DirNavigationFactory(){}
+ Core::NavigationView createWidget();
+ QString displayName();
+ };
+
+ \endcode
+
+ The createWidget() method is implemented to return an instance of the QTreeView which uses
+ FileSystemModel that was explained in previous step.
+ \code
+ Core::NavigationView DirNavigationFactory::createWidget()
+ {
+ Core::NavigationView view;
+
+ // Create FileSystemModel and set the defauls path as home path
+ FileSystemModel* model = new FileSystemModel;
+ model->setRootPath(QDir::homePath());
+
+ // Create TreeView and set model
+ QTreeView* tree = new QTreeView;
+ tree->setModel(model);
+
+ view.widget = tree;
+
+ return view;
+ }
+ \endcode
+
+ The \bold {displayName()} method is implemented to return a descriptive name that Qt Creator should use for showing the
+ side-bar.
+
+ \code
+ QString DirNavigationFactory::displayName()
+ {
+ return "Dir View";
+ }
+ \endcode
+
+ With this the \bold {INavigationWidgetFactory} implementation is ready.
+
+ \section2 Step 3: Implementing the Dir-view plugin
+ We implement the Dir-view plugin class similar to the \bold {DoNothingPlugin} class described in Chapter 2. Hence, we only
+ describe the implementation of the initialize method of the \bold {DirModelPluginPlugin} class here.
+
+ \code
+ bool DirModelPluginPlugin::initialize(const QStringList& args, QString *errMsg)
+ {
+ Q_UNUSED(args);
+ Q_UNUSED(errMsg);
+ addAutoReleasedObject(new DirNavigationFactory);
+ return true;
+ }
+ \endcode
+
+ In the \bold {initialize()} method an instance of the \bold {INavigationWidgetFactory} implementation is created and added to the object
+ pool. Once the object is added to the pool, \bold {ExtensionSystem::PluginManager} emits the \bold {objectAdded()} signal, which is
+ then trapped by the Core of Qt Creator. The Core then makes use of our implementation of \bold {INavigationWidgetFactory}
+ interface and places an instance of DirExplorerSideBar in the navigation panel.
+
+ \section2 Step 4: Testing the plugin
+ Upon compiling the plugin and restarting Qt Creator, we can notice the "Dir View" side bar as shown below.
+
+ \inlineimage qtc-dirview-6.png
+
+*/
diff --git a/doc/pluginhowto/pref-pane.qdoc b/doc/pluginhowto/pref-pane.qdoc
new file mode 100644
index 00000000000..122134c462f
--- /dev/null
+++ b/doc/pluginhowto/pref-pane.qdoc
@@ -0,0 +1,205 @@
+/*!
+ \page pref-pane.html
+ \title 7. Adding Preferences Pane
+ Preferences dialog in Qt Creator is used to configure the Qt Creator settings. Since Qt Creator is just a plugin loader that
+ loads all the relevant plugins, the preferences dialog shows pages that configure plugins. You can get to it by clicking
+ Tools->Options.
+
+ \inlineimage qtc-options-7.png
+
+
+ Each plugin provides one or more options pages that get shown in the preferences dialog. In the following sub-sections
+ we will learn how to add our own pages to the dialog.
+
+ \section1 7.1 Core::IOptionsPage interface
+
+ The Core of Qt Creator exposes an interface called \bold{Core::IOptionsPage}. The interface is defined in
+ plugins/coreplugin/dialogs/ioptionspage.h.
+
+ \code
+ class CORE_EXPORT IOptionsPage : public QObject
+ {
+ Q_OBJECT
+
+ public:
+ IOptionsPage( *parent = 0) : QObject(parent) {}
+ virtual ~IOptionsPage() {}
+ virtual QString id() const = 0;
+ virtual QString trName() const = 0;
+ virtual QString category() const = 0;
+ virtual QString trCategory() const = 0;
+ virtual QWidget *createPage(QWidget *parent) = 0;
+ virtual void apply() = 0;
+ virtual void finish() = 0;
+ };
+ \endcode
+
+ By implementing the above interface and exposing an instance of it, we will be able to register new pages with the
+ preferences dialog.
+
+ \section1 7.2 Preparing the options-page
+ Let's implement a plugin that shows an options page that lists out all the open and modified files.
+
+ \section2 Step 1: Implementing the "modified file" list widget
+ The modified file list widget is simply a \bold{QListWidget} that shows all the modified files from the project manager. The
+ class declaration is as follows
+
+ \code
+ #include <QListWidget>
+ class ModifiedFileListWidget: public QListWidget
+ {
+ Q_OBJECT
+
+ public:
+ ModifiedFileListWidget(QWidget* parent=0);
+ ~ModifiedFileListWidget();
+ };
+ \endcode
+
+ Within the constructor we populate the list widget with names of the modified pages
+
+ \code
+ #include <coreplugin/filemanager.h>
+ #include <coreplugin/icore.h>
+ #include <coreplugin/ifile.h>
+
+ ModifiedFileListWidget::ModifiedFileListWidget(QWidget* parent):QListWidget(parent)
+ {
+ // Show the list of modified pages
+ Core::FileManager* fm = Core::ICore::instance()->fileManager();
+ QList<Core::IFile*> files = fm->modifiedFiles();
+
+ for(int i=0; i<files.count();i++)
+ this->addItem(files.at(i)->fileName());
+ }
+ \endcode
+
+ The destructor does nothing.
+
+ \code
+ ModifiedFileListerPage::~ModifiedFileListerPage()
+ {
+
+ }
+ \endcode
+
+ \section2 Step 2: Implementing the Core::IOptionsPage interface
+ We implement the \bold {Core::IOptionsPage} interface in a class called \bold {ModifiedFileLister}. The class declaration
+ is as follows
+
+ \code
+ #include <coreplugin/dialogs/ioptionspage.h>
+ class ModifiedFileLister : public Core::IOptionsPage
+ {
+ Q_OBJECT
+
+ public:
+ ModifiedFileLister(QObject *parent = 0);
+ ~ModifiedFileLister();
+ // IOptionsPage implementation
+ QString id() const;
+ QString trName() const;
+ QString category() const;
+ QString trCategory() const;
+ QWidget *createPage(QWidget *parent);
+ void apply();
+ void finish();
+ };
+ \endcode
+
+ The constructor and destructor are straightforward and easy to understand.
+
+ \code
+ ModifiedFileLister::ModifiedFileLister(QObject *parent): IOptionsPage(parent)
+ {
+
+ }
+
+ ModifiedFileLister::~ModifiedFileLister()
+ {
+
+ }
+ \endcode
+
+ The \bold{id()} method should be implemented to return a unique identifier for the options page provided by this class. The
+ string will be used internally to \underline{\bold{id}}entify the page.
+
+ \code
+ QString ModifiedFileLister::id() const
+ {
+ return "ModifiedFiles";
+ }
+ \endcode
+
+ The \bold {trName()} method should be implemented to return a translated string name that will be shown in the options
+ dialog.
+
+ \code
+ QString ModifiedFileLister::trName() const
+ {
+ return tr("Modified Files");
+ }
+ \endcode
+
+ The \bold{category()} and \bold{trCategory()} methods should be implemented to return the group under which we want to
+ show the page. The latter returns the translated version of the string returned by the former.
+
+ \code
+ QString ModifiedFileLister::category() const
+ {
+ return "Help";
+ }
+
+ QString ModifiedFileLister::trCategory() const
+ {
+ return tr("Help");
+ }
+ \endcode
+
+ The \bold{createPage()} method should be implemented to return a new instance of the page implemented in step 1.
+
+ \code
+ QWidget *ModifiedFileLister::createPage(QWidget *parent)
+ {
+ return new ModifiedFileListWidget(parent);
+ }
+ \endcode
+
+ The methods \bold {apply()} and \bold {finish()} can be implemented to accept the changes made by the user made on the
+ page. In our case we don't have any changes to accept, so we leave the methods empty.
+
+ \code
+ void ModifiedFileLister::apply()
+ {
+ // Do nothing
+ }
+
+ void ModifiedFileLister::finish()
+ {
+ // Do nothing
+ }
+ \endcode
+
+ \section2 Step 3: Implementing the modified-file-lister plugin
+
+ We implement the plugin class similar to the \bold {DoNothingPlugin} class described in Chapter 2. Hence, we only
+ describe the implementation of the initialize method of the \bold {ModifiedFileListerPlugin} class here.
+
+ \code
+ bool ModifiedFileListerPlugin::initialize(const QStringList& args, QString *errMsg)
+ {
+ Q_UNUSED(args);
+ Q_UNUSED(errMsg);
+ addAutoReleasedObject(new ModifiedFileLister);
+ return true;
+ }
+ \endcode
+
+ \section2 Step 4: Testing the plugin
+ Upon compiling the plugin and restarting Qt Creator, we can notice in the options dialog the newly added "Modified
+ Files" page.
+
+
+ \inlineimage qtc-testplugin-7.png
+
+ */
diff --git a/doc/pluginhowto/progress.qdoc b/doc/pluginhowto/progress.qdoc
new file mode 100644
index 00000000000..d65dd78f07d
--- /dev/null
+++ b/doc/pluginhowto/progress.qdoc
@@ -0,0 +1,111 @@
+/*!
+ \page progress.html
+ \title 11.Showing and reacting to progress information
+ The progress bars give us the information about the progress status of a current task.We can find
+ progress bar showing up in the Qt Creator window at the left side. Whenever a task is executed
+ a progress bar pops up showing the progress status until the task is completed.
+
+ \inlineimage qtc-progressbar-11.png
+
+ \section1 11.1 Creating a progress bar
+ First we will declare the methods required for implementing a "Progress Bar" widget and then we will attach the widget with "Header Filter" in "Find/Replace"
+ and see it working according to the search progress status.
+
+ \section2 Step 1. Modification of "HeaderFilter" class
+ The "HeaderFilter" class discussed in Chapter 9. is further modified.
+ So we will now declare the methods required for a "Progress Bar" in the following block of code.
+ \code
+ struct HeaderFilterData;
+ class HeaderFilter : public Find::IFindFilter
+ {
+ Q_OBJECT
+ public:
+ HeaderFilter();
+ ~HeaderFilter();
+ ...
+ QWidget *createProgressWidget();
+
+ private:
+ HeaderFilterData *d;
+ };
+ \endcode
+
+ Here \bold {createProgressWidget()} is not implemented from Find::IFindFilter. It is a custom function written within HeaderFilter class,
+ which takes up the onus of returning a progress display widget.
+
+ \section2 Step 2. Implementation of the "HeaderFilter" class
+ The private member variables of the \bold {HeaderFilter} class are declared in the structure \bold {HeaderFilterData}
+ \code
+ struct HeaderFilterData
+ {
+ QFutureWatcher<FileSearchResult> watcher;
+ QLabel *resultLabel;
+ ...
+ ...
+ };
+ \endcode
+ The \bold {constructor} and the \bold {destructor} are as follows.
+ \code
+ HeaderFilter::HeaderFilter()
+ {
+
+ d = new HeaderFilterProgressData;
+ d->watcher.setPendingResultsLimit(1);
+ d->resultLabel = 0 ;
+ ...
+ }
+
+ HeaderFilter::~HeaderFilter()
+ {
+ delete d;
+ }
+ \endcode
+
+ The \bold {findAll()} method is further modified to create a progress bar popup the bar while searching
+ is going on.
+ \code
+ void HeaderFilter::findAll(const QString &text,QTextDocument::FindFlags findFlags)
+ {
+ ...
+ ...
+ ...
+
+ //The "progress" is the instance of FutureProgress class.
+ //The "progress" is the pointer to the progress bar created
+ //Creates and shows the "progress" bar for searching task.
+ Core::FutureProgress *progress =
+ Core::ICore::instance()->progressManager()->addTask(d->watcher.future(),
+ "MySearch",
+ Find::Constants::TASK_SEARCH,
+ Core::ProgressManager::KeepOnFinish
+ );
+
+ progress->setWidget(createProgressWidget());
+ connect(progress, SIGNAL(clicked()), d->searchResultWindow(), SLOT(popup()));
+ }
+ \endcode
+
+ The \bold {createProgressWidget()} function creates the progress widget.It shows
+ the number of searched items found below and is placed below the progress bar.
+ \code
+ QWidget *HeaderFilter::createProgressWidget()
+ {
+ d->resultLabel = new QLabel;
+ d->resultLabel->setAlignment(Qt::AlignCenter);
+ QFont f = d->resultLabel->font();
+ f.setBold(true);
+ f.setPointSizeF(StyleHelper::sidebarFontSize());
+ d->resultLabel->setFont(f);
+ d->resultLabel->setPalette(StyleHelper::sidebarFontPalette(d->resultLabel->palette()));
+ d->resultLabel->setText(tr("%1 found").arg(d->searchResultWindow()->numberOfResults()));
+ return d->resultLabel;
+ }
+ \endcode
+
+ \section2 Step 3.Testing the plugin.
+ Now its the time to test the plugin. For searching we use our "HeaderFilter" and the searched result is shown in the
+ "Search Results" window and the progress bar pops up while searching.
+
+ \inlineimage qtc-searchprogress-11.png
+
+*/
diff --git a/doc/pluginhowto/project-file-wizard.qdoc b/doc/pluginhowto/project-file-wizard.qdoc
new file mode 100644
index 00000000000..69c663df8ac
--- /dev/null
+++ b/doc/pluginhowto/project-file-wizard.qdoc
@@ -0,0 +1,667 @@
+/*!
+ \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 &parameters,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 &parameters,
+ 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 &parameters,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’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
+
+ */
diff --git a/doc/pluginhowto/qtc-arch.qdoc b/doc/pluginhowto/qtc-arch.qdoc
new file mode 100644
index 00000000000..f33f2a36449
--- /dev/null
+++ b/doc/pluginhowto/qtc-arch.qdoc
@@ -0,0 +1,329 @@
+/*!
+ \page qtc-arch.html
+ \title 4. Qt Creator Architecture
+
+ Every large system has a well defined "system architecture" which if understood well makes it easy for us to find out
+ way in it. Qt Creator is no different. In this chapter we will understand the basic architecture of Qt Creator so that we
+ can continue our understanding of writing plugins.
+
+ \section1 4.1 Nuts and Bolts of Qt Creator
+
+ Qt Creator is Nokia's cross-platform IDE. Currently Qt Creator is mainly used for writing Qt/C++ code.
+ The core of Qt Creator is basically only a "plugin loader" All functionality is implemented in plugins.
+
+ \inlineimage qtc-pluginmanager-4.png
+
+
+ The core "personality"of Qt Creator is implemented in the \bold {Core Plugin (Core::ICore)}. We have already had a brush
+ with the core plugin in the previous chapter. In the rest of this document we will refer to "core plugin" as Core.
+ The plugin manager \bold{(ExtensionSystem::PluginManager)} provides simple means for plugin cooperation that
+ allow plugins to provide hooks for other plugin's extensions.
+
+ \section1 4.2 What exactly is a plugin?
+
+ At the most fundamental level plugin is a shared library (DLL file on Windows, SO file on Linux, DYLIB file on Mac). From
+ a developer's point of view plugin is a module that
+ \list 1
+ \o Implements the ExtensionSystem::IPlugin interface in a class. This class will be referred to as "Plugin Class" in the
+ rest of the document.
+ \o Exports the Plugin Class using the Q_EXPORT_PLUGIN macro
+ \o Provides a pluginspec file that provides some meta information about the plugin
+ \o Registers one or more objects that might be of some interest to other plugins
+ \o Searches for the availability of one or more objects registered by other plugins.
+ \endlist
+
+ We have already had some experience with the first three aspects listed above, but we have not touched upon the last
+ two.
+ \section2 4.2.1 What are registered objects?
+
+ objects are those that land up in the \bold {PluginManager's} object pool. The \bold {allObjects()} method in
+ \bold {PluginManager} returns the object pool as a list of QObject pointers. Shown below is the code that we can use to list
+ all objects in the object-pool in a \bold {QListWidget}.
+
+ \code
+ #include <extensionsystem/pluginmanager.h>
+
+ ExtensionSystem::PluginManager* pm = ExtensionSystem::PluginManager::instance();
+ QList<QObject*> objects = pm->allObjects();
+ QListWidget* listWidget = new QListWidget;
+
+ Q_FOREACH(QObject* obj, objects)
+ {
+ QString objInfo = QString("%1 (%2)").arg(obj->objectName()).arg(obj->metaObject()->className());
+ listWidget->addItem(objInfo);
+ }
+
+ listWidget->show();
+ \endcode
+ When such a list widget is constructed and shown; you will see a window as shown below.
+
+
+ \inlineimage qtc-objectlist-4.png
+
+
+ From the class names it is easy to picture the fact that each of those objects came from different plugins.
+
+ \bold {\underline {A registered object is an instance of QObject (or one of its subclasses) registered by a plugin and is available in the
+ object-pool for other plugins to make use of}}.
+
+ \section2 4.2.2 How to "register" an object from a plugin?
+ There are three ways to register an object from a plugin:
+
+ \list
+
+ \o \bold {IPlugin::addAutoReleasedObject(QObject*)}
+ \o \bold {IPlugin::addObject(QObject*)}
+ \o \bold {PluginManager::addObject(QObject*)}
+
+ \endlist
+
+
+ The \bold {IPlugin::addObject()} and \bold {IPlugin::addAutoReleasedObject()} essentially call the
+ \bold {PluginManager::addObject()} method. The \bold {IPlugin} methods are only provided for convenience. It is
+ recommended that plugins make use of the \bold {IPlugin} methods for adding objects.
+
+ The only difference between \bold {addAutoReleasedObject()} and \bold {addObject()} is that objects added using the
+ former method are automatically removed and deleted in the reverse order of registration when the plugin is destroyed.
+ At anytime plugins can make use of the \bold {IPlugin::removeObject(QObject*)} method to remove its object from
+ the object pool.
+
+ \section2 4.2.3 What objects to register?
+
+ Plugins can register just about any object. Normally objects that provide some sort of functionality used by other
+ plugin(s) are registered. Functionalities in Qt Creator are defined by means of interfaces. Listed below are some interfaces
+
+ \list
+
+ \o \bold {Core::INavigationWidgetFactory}
+ \o \bold {Core::IEditor}
+ \o \bold {Core::IOptionsPage}
+ \o \bold {Core::IWizard}
+
+ \endlist
+
+ \bold{\underline { C++ developers normally assume interfaces to be classes with all its functions are public pure
+ virtual functions. In Qt Creator interfaces are subclasses of QObject that offer one or more
+ methods are pure virtual}}.
+
+ If a plugin has objects that implement an interface, then such an object has to be registered. For example if a plugin
+ implements the \bold{INavigationWidgetFactory} interface in an object and registered it, the Core will automatically use that
+ object to show the widget provided by it as navigation widget. Take a look at the code snippet below. We provide a
+ simple \bold{QTableWidget} as navigation widget via an implementation of \bold {Core::INavigationWidgetFactory}.
+
+ \code
+ #include <coreplugin/inavigationwidgetfactory.h>
+
+ class NavWidgetFactory : public Core::INavigationWidgetFactory
+ {
+ public:
+ NavWidgetFactory();
+ ~NavWidgetFactory();
+ Core::NavigationView createWidget();
+ QString displayName();
+ };
+
+ #include <QTableWidget>
+
+ NavWidgetFactory::NavWidgetFactory() { }
+ NavWidgetFactory::~NavWidgetFactory() { }
+
+ Core::NavigationView NavWidgetFactory::createWidget()
+ {
+ Core::NavigationView view;
+ view.widget = new QTableWidget(50, 3);
+ }
+
+ QString NavWidgetFactory::displayName()
+ {
+ return "Spreadsheet";
+ }
+
+ bool MyPlugin::initialize(const QStringList& args, QString *errMsg)
+ {
+ Q_UNUSED(args);
+ Q_UNUSED(errMsg);
+ // Provide a navigation widget factory.
+ // Qt Creator's navigation widget will automatically
+ // hook to our INavigationWidgetFactory implementation, which
+ // is the NavWidgetFactory class, and show the QTableWidget
+ // created by it in the navigation panel.
+ addAutoReleasedObject(new NavWidgetFactory);
+ return true;
+ }
+ \endcode
+
+ The effect of the above code is
+
+ \inlineimage qtc-codeeffect-4.png
+
+ \section2 4.2.4 Becoming aware of registered objects
+
+ Whenever the \bold {PluginManager::addObject()} is used to add an object, it \bold{(PluginManager)} emits the
+ \bold {objectAdded(QObject*)} signal. This signal can be used within our applications to figure out the objects that got
+ added.
+
+ Obviously a plugin will begin receiving the signal only after it makes a connection to it. That happens only after the
+ plugin is initialized; which also means that the plugin will receive the \bold {objectAdded()} signal only for objects added
+ after the plugin was initialized.
+
+ Usually the slot that is connected to the objectAdded() signal will look for one or more known interfaces. Suppose that
+ your plugin is looking for the INavigationWidgetFactory interface, the slot connected to objectAdded() will be like the
+ one shown below.
+
+ \code
+ void Plugin::slotObjectAdded(QObject * obj)
+ {
+ INavigationWidgetFactory *factory = Aggregation::query<INavigationWidgetFactory>(obj);
+
+ if(factory)
+ {
+ // use it here...
+ }
+ }
+ \endcode
+
+ \section2 4.2.5 Searching for objects
+
+ Sometimes a plugin might want to search for an object in the application that offers some functionality. We already
+ know by now that
+
+ \list
+ \o \bold {PluginManager::allObjects()} returns the object pool as a \bold {QList<QObject*>}
+ \o Connecting to \bold {PluginManager::objectAdded()} signal helps in known objects as they get registered
+ \endlist
+
+ Using both of the above mentioned methods you can look for objects. Lets now understand yet another way to find
+ objects.
+
+ Suppose that you wanted to look for objects that implement the \bold {INavigationWidgetFactory} interface and show it in a
+ \bold {QListWidget}. You can make use of the \bold {PluginManager::getObjects<T>()} method for this purpose. The following code
+ snippet explains this
+
+ \code
+ ExtensionSystem::PluginManager* pm = ExtensionSystem::PluginManager::instance();
+ QList<Core::INavigationWidgetFactory*> objects = pm->getObjects<Core::INavigationWidgetFactory>();
+ QListWidget* listWidget = new QListWidget();
+
+ Q_FOREACH(Core::INavigationWidgetFactory* obj, objects)
+ {
+ QString objInfo = QString("%1 (%2)").arg(obj->displayName()).arg(obj->metaObject()->className());
+ listWidget->addItem(objInfo);
+ }
+ \endcode
+
+ When the list widget is shown you will notice that the navigation widgets are shown in the same order as they are
+ shown in the navigation combo box. Take a look at the screenshot below.
+
+ \inlineimage qtc-nevigationwidget-4.png
+
+
+ \section1 4.3 Aggregations
+
+ Aggregations are provided by the \bold {Aggregation} namespace. It adds functionality for "glueing" \bold {QObjects} of different
+ types together, so you can "cast" between them. Using the classes and methods in this namespace you can bundle
+ related objects into a single entity. Objects that are bundled into an aggregate can be "cast" from the aggregate into the
+ object class type.
+
+ \section2 4.3.1 Aggregations - the old fashioned way
+
+ Suppose that you wanted an object that provided implementations of two interfaces. Normally we would go about
+ coding the object like this.
+
+ \code
+ class Interface1
+ {
+ ....
+ };
+ Q_DECLARE_INTERFACE("Interface1", "Interface1");
+
+ class Interface2
+ {
+ ....
+ };
+ Q_DECLARE_INTERFACE("Interface2", "Interface2");
+
+ class Bundle : public QObject,public Interface1,public Interface2
+ {
+ Q_OBJECT(Interface1 Interface2)
+ ....
+ };
+ Bundle bundle;
+
+ \endcode
+
+ Now we can think of \bold {bundle} as an object that provides \bold {Interface1} and \bold {Interface2} implementations. We can
+ make use of casting operators on the bundle object to extract \bold{Interface1} and \bold {Interface2}.
+
+ \code
+ Interface1* iface1Ptr = qobject_cast<Interface1*>(&bundle);
+ Interface2* iface2Ptr = qobject_cast<Interface2*>(&bundle);
+ \endcode
+
+ \section2 4.3.2 Aggregations - the Qt Creator way
+
+ Qt Creator's Aggregation library offers a cleaner way to define interfaces and bundle them into a single object. Instances
+ of Aggregation::Aggregate can be created and objects can be added to it. Each of the objects added to the aggregation
+ can implement an interface. The following code snippet shows how to create an aggregation.
+
+ \code
+
+ #include <aggregation/aggregate.h>
+
+ class Interface1 : public QObject
+ {
+ Q_OBJECT
+
+ public:
+ Interface1() { }
+ ~Interface1() { }
+ };
+
+ class Interface2 : public QObject
+ {
+ Q_OBJECT
+
+ public:
+ Interface2() { }
+ ~Interface2() { }
+ };
+
+ Aggregation::Aggregate bundle;
+ bundle.add(new Interface1);
+ bundle.add(new Interface2);
+
+ \endcode
+
+ The aggregation instance "bundle" now conceptually contains implementations of two interfaces. To extract the
+ interfaces we can make use of the following code
+
+ \code
+ Interface1* iface1Ptr = Aggregation::query<Interface1>( &bundle );
+ Interface2* iface2Ptr = Aggregation::query<Interface2>( &bundle );
+ \endcode
+
+ With aggregation you can also several objects of the same interface into a single bundle. For example
+
+ \code
+ Aggregation::Aggregate bundle;
+ bundle.add(new Interface1);
+ bundle.add(new Interface2);
+ bundle.add(new Interface1);
+ bundle.add(new Interface1);
+ QList<Interface1*> iface1Ptrs = Aggregation::query_all<Interface1>( &bundle );
+ \endcode
+
+ Another key advantage of Aggregation is that, you can delete any one of the objects in the bundle to delete the whole
+ bundle. Example
+
+ \code
+ Aggregation::Aggregate* bundle = new Aggregation::Aggregate;
+ bundle->add(new Interface1);
+ bundle->add(new Interface2);
+ Interface1* iface1Ptr = Aggregation::query<Interface1>(bundle);
+ delete iface1Ptr;
+ // deletes the bundle and all objects in it
+ // same as delete bundle
+ \endcode
+
+ The use of aggregation will become clearer when we deal with real plugin examples in the coming chapters.
+*/
diff --git a/doc/pluginhowto/qtc-project-plugin.qdoc b/doc/pluginhowto/qtc-project-plugin.qdoc
new file mode 100644
index 00000000000..09fa8a39e80
--- /dev/null
+++ b/doc/pluginhowto/qtc-project-plugin.qdoc
@@ -0,0 +1,6 @@
+/*!
+ \page qtc-project-plugin.html
+ \title 3. Creating plugins using Qt Creator
+
+ This page needs to be written still!
+*/
diff --git a/doc/pluginhowto/qtcreator-compile.qdoc b/doc/pluginhowto/qtcreator-compile.qdoc
new file mode 100644
index 00000000000..678829196f0
--- /dev/null
+++ b/doc/pluginhowto/qtcreator-compile.qdoc
@@ -0,0 +1,25 @@
+/*!
+ \page qtcreator-compile.html
+ \title 1. Compiling Qt Creator
+
+To start with building Qt creator, you need to get the Qt Creator source. The Qt Creator source is avaiable
+from the following locations:
+\list
+\o Nokia Website: \l {http://qt.nokia.com/downloads}
+\o GIT Repository: \l {http://qt.gitorious.org/qt-creator}
+\endlist
+It is recommended that you build Qt Creator in a separate directory.
+
+The following steps will guide you to get Qt Creator source compiled:
+\list
+\o Step 1: Create "build" directory inside main source directory
+\o Step 2: Run qmake ../qtcreator.pro -recursive command to get makefile.
+\o Step 3: Finally run make (or mingw32-make or nmake, depending on your platform).
+\endlist
+After successful compilation, you should be able to find \bold {qtcreator.exe} inside \bold {build/bin} directory.
+You can now launch Qt Creator.
+
+\bold {Note:}\underline{It is important that you compile Qt Creator from its sources. Otherwise you wont be able to write
+and test plugins for Qt Creator}.
+
+*/
diff --git a/doc/pluginhowto/qtcreator-pluginhowto.qdoc b/doc/pluginhowto/qtcreator-pluginhowto.qdoc
new file mode 100644
index 00000000000..4cd182dba11
--- /dev/null
+++ b/doc/pluginhowto/qtcreator-pluginhowto.qdoc
@@ -0,0 +1,28 @@
+/*!
+ \page index.html
+ \title Qt Creator Plugin HOWTO
+
+ Qt Creator is not only a great developer tool, it is also a tool
+ can accomodate plugins to help......
+
+ Qt Creator plugin development can be understood by going through
+ the following chapters in this manual
+
+ \list 1
+ \o \l {qtcreator-compile.html} {Compiling Qt Creator}
+ \o \l {first-plugin.html} {First Plugin}
+ \o \l {qtc-project-plugin.html} {Creating plugins using Qt Creator}
+ \o \l {qtc-arch.html} {Qt Creator Architecture}
+ \o \l {menu.html} {Adding menu and menu-items}
+ \o \l {nav-widget.html} {Adding Navigation Widget}
+ \o \l {pref-pane.html} {Adding Preferences Pane}
+ \o \l {project-file-wizard.html} {Project/File Wizards}
+ \o \l {find-filter.html} {Find Filter}
+ \o \l {editor-type.html} {Adding editor type}
+ \o \l {progress.html} {Showing and reacting to progress information}
+ \o \l {vcs.html} {Implementing version control system}
+ \o \l {mode.html} {Adding a mode}
+ \o \l {location-filter.html} {Adding location filter}
+ \o \l {adv-find-filter.html} {Adding "advanced" find filter}
+ \endlist
+*/
diff --git a/doc/pluginhowto/qtcreator-pluginhowto.qdocconf b/doc/pluginhowto/qtcreator-pluginhowto.qdocconf
new file mode 100644
index 00000000000..fa083253237
--- /dev/null
+++ b/doc/pluginhowto/qtcreator-pluginhowto.qdocconf
@@ -0,0 +1,221 @@
+project = Qt Creator Plugin HOWTO API
+description = Qt Creator Plugin HOWTO Documentation
+
+language = Cpp
+
+sources.fileextensions = "*.qdoc"
+sourcedirs = .
+
+imagedirs = images
+
+indexes = $QTDIR/doc/html/qt.index
+
+outputdir = ./html
+base = file:./html
+versionsym = 1.3.1
+codeindent = 1
+tabsize = 4
+
+## compat.qdocconf
+alias.i = e
+alias.include = input
+
+macro.0 = "\\\\0"
+macro.b = "\\\\b"
+macro.n = "\\\\n"
+macro.r = "\\\\r"
+macro.i = "\\o"
+macro.i11 = "\\o{1,1}"
+macro.i12 = "\\o{1,2}"
+macro.i13 = "\\o{1,3}"
+macro.i14 = "\\o{1,4}"
+macro.i15 = "\\o{1,5}"
+macro.i16 = "\\o{1,6}"
+macro.i17 = "\\o{1,7}"
+macro.i18 = "\\o{1,8}"
+macro.i19 = "\\o{1,9}"
+macro.i21 = "\\o{2,1}"
+macro.i31 = "\\o{3,1}"
+macro.i41 = "\\o{4,1}"
+macro.i51 = "\\o{5,1}"
+macro.i61 = "\\o{6,1}"
+macro.i71 = "\\o{7,1}"
+macro.i81 = "\\o{8,1}"
+macro.i91 = "\\o{9,1}"
+macro.img = "\\image"
+macro.endquote = "\\endquotation"
+macro.relatesto = "\\relates"
+
+spurious = "Missing comma in .*" \
+ "Missing pattern .*"
+
+## macros.qdocconf
+macro.aring.HTML = "&aring;"
+macro.Auml.HTML = "&Auml;"
+macro.author = "\\bold{Author:}"
+macro.br.HTML = "<br />"
+macro.BR.HTML = "<br />"
+macro.aacute.HTML = "&aacute;"
+macro.eacute.HTML = "&eacute;"
+macro.iacute.HTML = "&iacute;"
+macro.gui = "\\bold"
+macro.hr.HTML = "<hr />"
+macro.key = "\\bold"
+macro.menu = "\\bold"
+macro.note = "\\bold{Note:}"
+macro.oslash.HTML = "&oslash;"
+macro.ouml.HTML = "&ouml;"
+macro.QA = "\\e{Qt Assistant}"
+macro.QD = "\\e{Qt Designer}"
+macro.QL = "\\e{Qt Linguist}"
+macro.QC = "\\e{Qt Creator}"
+macro.param = "\\e"
+macro.raisedaster.HTML = "<sup>*</sup>"
+macro.reg.HTML = "<sup>&reg;</sup>"
+macro.return = "Returns"
+macro.starslash = "\\c{*/}"
+macro.uuml.HTML = "&uuml;"
+macro.mdash.HTML = "&mdash;"
+
+## qt-cpp-ignore.qdocconf
+Cpp.ignoretokens = QAXFACTORY_EXPORT \
+ QDESIGNER_COMPONENTS_LIBRARY \
+ QDESIGNER_EXTENSION_LIBRARY \
+ QDESIGNER_SDK_LIBRARY \
+ QDESIGNER_SHARED_LIBRARY \
+ QDESIGNER_UILIB_LIBRARY \
+ QM_EXPORT_CANVAS \
+ QM_EXPORT_DNS \
+ QM_EXPORT_DOM \
+ QM_EXPORT_FTP \
+ QM_EXPORT_HTTP \
+ QM_EXPORT_ICONVIEW \
+ QM_EXPORT_NETWORK \
+ QM_EXPORT_OPENGL \
+ QM_EXPORT_SQL \
+ QM_EXPORT_TABLE \
+ QM_EXPORT_WORKSPACE \
+ QM_EXPORT_XML \
+ QT_ASCII_CAST_WARN \
+ QT_ASCII_CAST_WARN_CONSTRUCTOR \
+ QT_BEGIN_HEADER \
+ QT_DESIGNER_STATIC \
+ QT_END_HEADER \
+ QT_FASTCALL \
+ QT_WIDGET_PLUGIN_EXPORT \
+ Q_COMPAT_EXPORT \
+ Q_CORE_EXPORT \
+ Q_EXPLICIT \
+ Q_EXPORT \
+ Q_EXPORT_CODECS_CN \
+ Q_EXPORT_CODECS_JP \
+ Q_EXPORT_CODECS_KR \
+ Q_EXPORT_PLUGIN \
+ Q_GFX_INLINE \
+ Q_AUTOTEST_EXPORT \
+ Q_GUI_EXPORT \
+ Q_GUI_EXPORT_INLINE \
+ Q_GUI_EXPORT_STYLE_CDE \
+ Q_GUI_EXPORT_STYLE_COMPACT \
+ Q_GUI_EXPORT_STYLE_MAC \
+ Q_GUI_EXPORT_STYLE_MOTIF \
+ Q_GUI_EXPORT_STYLE_MOTIFPLUS \
+ Q_GUI_EXPORT_STYLE_PLATINUM \
+ Q_GUI_EXPORT_STYLE_POCKETPC \
+ Q_GUI_EXPORT_STYLE_SGI \
+ Q_GUI_EXPORT_STYLE_WINDOWS \
+ Q_GUI_EXPORT_STYLE_WINDOWSXP \
+ QHELP_EXPORT \
+ Q_INLINE_TEMPLATE \
+ Q_INTERNAL_WIN_NO_THROW \
+ Q_NETWORK_EXPORT \
+ Q_OPENGL_EXPORT \
+ Q_OUTOFLINE_TEMPLATE \
+ Q_SQL_EXPORT \
+ Q_SVG_EXPORT \
+ Q_SCRIPT_EXPORT \
+ Q_SCRIPTTOOLS_EXPORT \
+ Q_TESTLIB_EXPORT \
+ Q_TYPENAME \
+ Q_XML_EXPORT \
+ Q_XMLSTREAM_EXPORT \
+ Q_XMLPATTERNS_EXPORT \
+ QDBUS_EXPORT \
+ QT_BEGIN_NAMESPACE \
+ QT_BEGIN_INCLUDE_NAMESPACE \
+ QT_END_NAMESPACE \
+ QT_END_INCLUDE_NAMESPACE \
+ PHONON_EXPORT
+Cpp.ignoredirectives = Q_DECLARE_HANDLE \
+ Q_DECLARE_INTERFACE \
+ Q_DECLARE_METATYPE \
+ Q_DECLARE_OPERATORS_FOR_FLAGS \
+ Q_DECLARE_PRIVATE \
+ Q_DECLARE_PUBLIC \
+ Q_DECLARE_SHARED \
+ Q_DECLARE_TR_FUNCTIONS \
+ Q_DECLARE_TYPEINFO \
+ Q_DISABLE_COPY \
+ QT_FORWARD_DECLARE_CLASS \
+ Q_DUMMY_COMPARISON_OPERATOR \
+ Q_ENUMS \
+ Q_FLAGS \
+ Q_INTERFACES \
+ __attribute__ \
+ K_DECLARE_PRIVATE \
+ PHONON_OBJECT \
+ PHONON_HEIR
+
+## qt-html-templates.qdocconf
+HTML.stylesheets = classic.css
+HTML.postheader = "<table border=\"0\" cellpadding=\"0\" cellspacing=\"0\" width=\"100%\">\n" \
+ "<tr>\n" \
+ "<td align=\"left\" valign=\"top\" width=\"32\">" \
+ "<a href=\"http://www.trolltech.com/products/qt\"><img src=\"images/qt-logo.png\" align=\"left\" border=\"0\" /></a>" \
+ "</td>\n" \
+ "<td width=\"1\">&nbsp;&nbsp;</td>" \
+ "<td class=\"postheader\" valign=\"center\">" \
+ "<a href=\"index.html\">" \
+ "<font color=\"#004faf\">Home</font></a>&nbsp;&middot;" \
+ " <a href=\"namespaces.html\">" \
+ "<font color=\"#004faf\">All&nbsp;Namespaces</font></a>&nbsp;&middot;" \
+ " <a href=\"classes.html\">" \
+ "<font color=\"#004faf\">All&nbsp;Classes</font></a>&nbsp;&middot;" \
+ " <a href=\"mainclasses.html\">" \
+ "<font color=\"#004faf\">Main&nbsp;Classes</font></a>&nbsp;&middot;" \
+ " <a href=\"groups.html\">" \
+ "<font color=\"#004faf\">Grouped&nbsp;Classes</font></a>&nbsp;&middot;" \
+ " <a href=\"modules.html\">" \
+ "<font color=\"#004faf\">Modules</font></a>&nbsp;&middot;" \
+ " <a href=\"functions.html\">" \
+ "<font color=\"#004faf\">Functions</font></a>" \
+ "</td>\n" \
+ "<td align=\"right\" valign=\"top\" width=\"230\"></td></tr></table>"
+
+HTML.footer = "<p /><address><hr /><div align=\"center\">\n" \
+ "<table width=\"100%\" cellspacing=\"0\" border=\"0\"><tr class=\"address\">\n" \
+ "<td width=\"30%\" align=\"left\">Copyright &copy; 2010 Nokia Corporation " \
+ "and/or its subsidiary(-ies)</td>\n" \
+ "<td width=\"40%\" align=\"center\"><a href=\"trademarks.html\">Trademarks</a></td>\n" \
+ "<td width=\"30%\" align=\"right\"><div align=\"right\">Qt Creator Plugin HOWTO\\version</div></td>\n" \
+ "</tr></table></div></address>"
+
+## qt-defines.qdocconf
+defines = Q_QDOC \
+ QT_.*_SUPPORT \
+ QT_.*_LIB \
+ QT_COMPAT \
+ QT_KEYPAD_NAVIGATION \
+ QT3_SUPPORT \
+ Q_WS_.* \
+ Q_OS_.* \
+ Q_BYTE_ORDER \
+ QT_DEPRECATED \
+ Q_NO_USING_KEYWORD \
+ __cplusplus
+
+# Files not referenced in any qdoc file (last four needed by qtdemo)
+# See also qhp.Qt.extraFiles
+extraimages.HTML = qt-logo \
+ trolltech-logo
+
diff --git a/doc/pluginhowto/vcs.qdoc b/doc/pluginhowto/vcs.qdoc
new file mode 100644
index 00000000000..03be51a54ed
--- /dev/null
+++ b/doc/pluginhowto/vcs.qdoc
@@ -0,0 +1,6 @@
+/*!
+ \page vcs.html
+ \title 12.Implementing version control system
+
+ This page needs to be written still!
+*/