88433a5e2f35a3da6e485c9b2f208cf430b15b3f
[profile/ivi/qtbase.git] / examples / widgets / doc / src / plugandpaint.qdoc
1 /****************************************************************************
2 **
3 ** Copyright (C) 2012 Digia Plc and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/legal
5 **
6 ** This file is part of the documentation of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:FDL$
9 ** Commercial License Usage
10 ** Licensees holding valid commercial Qt licenses may use this file in
11 ** accordance with the commercial license agreement provided with the
12 ** Software or, alternatively, in accordance with the terms contained in
13 ** a written agreement between you and Digia.  For licensing terms and
14 ** conditions see http://qt.digia.com/licensing.  For further information
15 ** use the contact form at http://qt.digia.com/contact-us.
16 **
17 ** GNU Free Documentation License Usage
18 ** Alternatively, this file may be used under the terms of the GNU Free
19 ** Documentation License version 1.3 as published by the Free Software
20 ** Foundation and appearing in the file included in the packaging of
21 ** this file.  Please review the following information to ensure
22 ** the GNU Free Documentation License version 1.3 requirements
23 ** will be met: http://www.gnu.org/copyleft/fdl.html.
24 ** $QT_END_LICENSE$
25 **
26 ****************************************************************************/
27
28 /*!
29     \example tools/plugandpaint
30     \title Plug & Paint Example
31     \ingroup examples-widgets-tools
32
33     \brief The Plug & Paint example demonstrates how to write Qt
34     applications that can be extended through plugins.
35
36     \image plugandpaint.png Screenshot of the Plug & Paint example
37
38     A plugin is a dynamic library that can be loaded at run-time to
39     extend an application. Qt makes it possible to create custom
40     plugins and to load them using QPluginLoader. To ensure that
41     plugins don't get lost, it is also possible to link them
42     statically to the executable. The Plug & Paint example uses
43     plugins to support custom brushes, shapes, and image filters. A
44     single plugin can provide multiple brushes, shapes, and/or
45     filters.
46
47     If you want to learn how to make your own application extensible
48     through plugins, we recommend that you start by reading this
49     overview, which explains how to make an application use plugins.
50     Afterward, you can read the
51     \l{plugandpaintplugins/basictools}{Basic Tools} and
52     \l{plugandpaintplugins/extrafilters}{Extra Filters}
53     overviews, which show how to implement static and dynamic
54     plugins, respectively.
55
56     Plug & Paint consists of the following classes:
57
58     \list
59     \li \c MainWindow is a QMainWindow subclass that provides the menu
60        system and that contains a \c PaintArea as the central widget.
61     \li \c PaintArea is a QWidget that allows the user to draw using a
62        brush and to insert shapes.
63     \li \c PluginDialog is a dialog that shows information about the
64        plugins detected by the application.
65     \li \c BrushInterface, \c ShapeInterface, and \c FilterInterface are
66        abstract base classes that can be implemented by plugins to
67        provide custom brushes, shapes, and image filters.
68     \endlist
69
70     \section1 The Plugin Interfaces
71
72     We will start by reviewing the interfaces defined in \c
73     interfaces.h. These interfaces are used by the Plug & Paint
74     application to access extra functionality. They are implemented
75     in the plugins.
76
77
78     \snippet tools/plugandpaint/interfaces.h 0
79
80     The \c BrushInterface class declares four pure virtual functions.
81     The first pure virtual function, \c brushes(), returns a list of
82     strings that identify the brushes provided by the plugin. By
83     returning a QStringList instead of a QString, we make it possible
84     for a single plugin to provide multiple brushes. The other
85     functions have a \c brush parameter to identify which brush
86     (among those returned by \c brushes()) is used.
87
88     \c mousePress(), \c mouseMove(), and \c mouseRelease() take a
89     QPainter and one or two \l{QPoint}s, and return a QRect
90     identifying which portion of the image was altered by the brush.
91
92     The class also has a virtual destructor. Interface classes
93     usually don't need such a destructor (because it would make
94     little sense to \c delete the object that implements the
95     interface through a pointer to the interface), but some compilers
96     emit a warning for classes that declare virtual functions but no
97     virtual destructor. We provide the destructor to keep these
98     compilers happy.
99
100     \snippet tools/plugandpaint/interfaces.h 1
101
102     The \c ShapeInterface class declares a \c shapes() function that
103     works the same as \c{BrushInterface}'s \c brushes() function, and
104     a \c generateShape() function that has a \c shape parameter.
105     Shapes are represented by a QPainterPath, a data type that can
106     represent arbitrary 2D shapes or combinations of shapes. The \c
107     parent parameter can be used by the plugin to pop up a dialog
108     asking the user to specify more information.
109
110     \snippet tools/plugandpaint/interfaces.h 2
111
112     The \c FilterInterface class declares a \c filters() function
113     that returns a list of filter names, and a \c filterImage()
114     function that applies a filter to an image.
115
116     \snippet tools/plugandpaint/interfaces.h 4
117
118     To make it possible to query at run-time whether a plugin
119     implements a given interface, we must use the \c
120     Q_DECLARE_INTERFACE() macro. The first argument is the name of
121     the interface. The second argument is a string identifying the
122     interface in a unique way. By convention, we use a "Java package
123     name" syntax to identify interfaces. If we later change the
124     interfaces, we must use a different string to identify the new
125     interface; otherwise, the application might crash. It is therefore
126     a good idea to include a version number in the string, as we did
127     above.
128
129     The \l{plugandpaintplugins/basictools}{Basic Tools} plugin
130     and the \l{plugandpaintplugins/extrafilters}{Extra Filters}
131     plugin shows how to derive from \c BrushInterface, \c
132     ShapeInterface, and \c FilterInterface.
133
134     A note on naming: It might have been tempting to give the \c
135     brushes(), \c shapes(), and \c filters() functions a more generic
136     name, such as \c keys() or \c features(). However, that would
137     have made multiple inheritance impractical. When creating
138     interfaces, we should always try to give unique names to the pure
139     virtual functions.
140
141     \section1 The MainWindow Class
142
143     The \c MainWindow class is a standard QMainWindow subclass, as
144     found in many of the other examples (e.g.,
145     \l{mainwindows/application}{Application}). Here, we'll
146     concentrate on the parts of the code that are related to plugins.
147
148     \snippet tools/plugandpaint/mainwindow.cpp 4
149
150     The \c loadPlugins() function is called from the \c MainWindow
151     constructor to detect plugins and update the \uicontrol{Brush},
152     \uicontrol{Shapes}, and \uicontrol{Filters} menus. We start by handling static
153     plugins (available through QPluginLoader::staticInstances())
154
155     To the application that uses the plugin, a Qt plugin is simply a
156     QObject. That QObject implements plugin interfaces using multiple
157     inheritance.
158
159     \snippet tools/plugandpaint/mainwindow.cpp 5
160
161     The next step is to load dynamic plugins. We initialize the \c
162     pluginsDir member variable to refer to the \c plugins
163     subdirectory of the Plug & Paint example. On Unix, this is just a
164     matter of initializing the QDir variable with
165     QApplication::applicationDirPath(), the path of the executable
166     file, and to do a \l{QDir::cd()}{cd()}. On Windows and Mac OS X,
167     this file is usually located in a subdirectory, so we need to
168     take this into account.
169
170     \snippet tools/plugandpaint/mainwindow.cpp 6
171     \snippet tools/plugandpaint/mainwindow.cpp 7
172     \snippet tools/plugandpaint/mainwindow.cpp 8
173
174     We use QDir::entryList() to get a list of all files in that
175     directory. Then we iterate over the result using \l foreach and
176     try to load the plugin using QPluginLoader.
177
178     The QObject provided by the plugin is accessible through
179     QPluginLoader::instance(). If the dynamic library isn't a Qt
180     plugin, or if it was compiled against an incompatible version of
181     the Qt library, QPluginLoader::instance() returns a null pointer.
182
183     If QPluginLoader::instance() is non-null, we add it to the menus.
184
185     \snippet tools/plugandpaint/mainwindow.cpp 9
186
187     At the end, we enable or disable the \uicontrol{Brush}, \uicontrol{Shapes},
188     and \uicontrol{Filters} menus based on whether they contain any items.
189
190     \snippet tools/plugandpaint/mainwindow.cpp 10
191
192     For each plugin (static or dynamic), we check which interfaces it
193     implements using \l qobject_cast(). First, we try to cast the
194     plugin instance to a \c BrushInterface; if it works, we call the
195     private function \c addToMenu() with the list of brushes returned
196     by \c brushes(). Then we do the same with the \c ShapeInterface
197     and the \c FilterInterface.
198
199     \snippet tools/plugandpaint/mainwindow.cpp 3
200
201     The \c aboutPlugins() slot is called on startup and can be
202     invoked at any time through the \uicontrol{About Plugins} action. It
203     pops up a \c PluginDialog, providing information about the loaded
204     plugins.
205
206     \image plugandpaint-plugindialog.png Screenshot of the Plugin dialog
207
208
209     The \c addToMenu() function is called from \c loadPlugin() to
210     create \l{QAction}s for custom brushes, shapes, or filters and
211     add them to the relevant menu. The QAction is created with the
212     plugin from which it comes from as the parent; this makes it
213     convenient to get access to the plugin later.
214
215     \snippet tools/plugandpaint/mainwindow.cpp 0
216
217     The \c changeBrush() slot is invoked when the user chooses one of
218     the brushes from the \uicontrol{Brush} menu. We start by finding out
219     which action invoked the slot using QObject::sender(). Then we
220     get the \c BrushInterface out of the plugin (which we
221     conveniently passed as the QAction's parent) and we call \c
222     PaintArea::setBrush() with the \c BrushInterface and the string
223     identifying the brush. Next time the user draws on the paint
224     area, \c PaintArea will use this brush.
225
226     \snippet tools/plugandpaint/mainwindow.cpp 1
227
228     The \c insertShape() is invoked when the use chooses one of the
229     shapes from the \uicontrol{Shapes} menu. We retrieve the QAction that
230     invoked the slot, then the \c ShapeInterface associated with that
231     QAction, and finally we call \c ShapeInterface::generateShape()
232     to obtain a QPainterPath.
233
234     \snippet tools/plugandpaint/mainwindow.cpp 2
235
236     The \c applyFilter() slot is similar: We retrieve the QAction
237     that invoked the slot, then the \c FilterInterface associated to
238     that QAction, and finally we call \c
239     FilterInterface::filterImage() to apply the filter onto the
240     current image.
241
242     \section1 The PaintArea Class
243
244     The \c PaintArea class contains some code that deals with \c
245     BrushInterface, so we'll review it briefly.
246
247     \snippet tools/plugandpaint/paintarea.cpp 0
248
249     In \c setBrush(), we simply store the \c BrushInterface and the
250     brush that are given to us by \c MainWindow.
251
252     \snippet tools/plugandpaint/paintarea.cpp 1
253
254     In the \l{QWidget::mouseMoveEvent()}{mouse move event handler},
255     we call the \c BrushInterface::mouseMove() function on the
256     current \c BrushInterface, with the current brush. The mouse
257     press and mouse release handlers are very similar.
258
259     \section1 The PluginDialog Class
260
261     The \c PluginDialog class provides information about the loaded
262     plugins to the user. Its constructor takes a path to the plugins
263     and a list of plugin file names. It calls \c findPlugins()
264     to fill the QTreeWdiget with information about the plugins:
265
266     \snippet tools/plugandpaint/plugindialog.cpp 0
267
268     The \c findPlugins() is very similar to \c
269     MainWindow::loadPlugins(). It uses QPluginLoader to access the
270     static and dynamic plugins. Its helper function \c
271     populateTreeWidget() uses \l qobject_cast() to find out which
272     interfaces are implemented by the plugins:
273
274     \snippet tools/plugandpaint/plugindialog.cpp 1
275
276     \section1 Importing Static Plugins
277
278     The \l{plugandpaintplugins/basictools}{Basic Tools} plugin
279     is built as a static plugin, to ensure that it is always
280     available to the application. This requires using the
281     Q_IMPORT_PLUGIN() macro somewhere in the application (in a \c
282     .cpp file) and specifying the plugin in the \c .pro file.
283
284     For Plug & Paint, we have chosen to put Q_IMPORT_PLUGIN() in \c
285     main.cpp:
286
287     \snippet tools/plugandpaint/main.cpp 0
288
289     The argument to Q_IMPORT_PLUGIN() is the plugin's name, as
290     specified with Q_EXPORT_PLUGIN2() in the \l{Exporting the
291     Plugin}{plugin}.
292
293     In the \c .pro file, we need to specify the static library.
294     Here's the project file for building Plug & Paint:
295
296     \snippet tools/plugandpaint/plugandpaint.pro 0
297
298     The \c LIBS line variable specifies the library \c pnp_basictools
299     located in the \c ../plugandpaintplugins/basictools directory.
300     (Although the \c LIBS syntax has a distinct Unix flavor, \c qmake
301     supports it on all platforms.)
302
303     The \c CONFIG() code at the end is necessary for this example
304     because the example is part of the Qt distribution and Qt can be
305     configured to be built simultaneously in debug and in release
306     modes. You don't need to for your own plugin applications.
307
308     This completes our review of the Plug & Paint application. At
309     this point, you might want to take a look at the
310     \l{plugandpaintplugins/basictools}{Basic Tools} example
311     plugin.
312 */
313
314 /*!
315     \example tools/plugandpaintplugins/basictools
316     \title Plug & Paint Basic Tools Example
317
318     The Basic Tools example is a static plugin for the
319     \l{plugandpaint}{Plug & Paint} example. It provides a set
320     of basic brushes, shapes, and filters. Through the Basic Tools
321     example, we will review the four steps involved in writing a Qt
322     plugin:
323
324     \list 1
325     \li Declare a plugin class.
326     \li Implement the interfaces provided by the plugin.
327     \li Export the plugin using the Q_EXPORT_PLUGIN2() macro.
328     \li Build the plugin using an adequate \c .pro file.
329     \endlist
330
331     \section1 Declaration of the Plugin Class
332
333     \snippet tools/plugandpaintplugins/basictools/basictoolsplugin.h 0
334
335     We start by including \c interfaces.h, which defines the plugin
336     interfaces for the \l{plugandpaint}{Plug & Paint}
337     application. For the \c #include to work, we need to add an \c
338     INCLUDEPATH entry to the \c .pro file with the path to Qt's \c
339     examples/tools directory.
340
341     The \c BasicToolsPlugin class is a QObject subclass that
342     implements the \c BrushInterface, the \c ShapeInterface, and the
343     \c FilterInterface. This is done through multiple inheritance.
344     The \c Q_INTERFACES() macro is necessary to tell \l{moc}, Qt's
345     meta-object compiler, that the base classes are plugin
346     interfaces. Without the \c Q_INTERFACES() macro, we couldn't use
347     \l qobject_cast() in the \l{plugandpaint}{Plug & Paint}
348     application to detect interfaces.
349
350     \snippet tools/plugandpaintplugins/basictools/basictoolsplugin.h 2
351
352     In the \c public section of the class, we declare all the
353     functions from the three interfaces.
354
355     \section1 Implementation of the Brush Interface
356
357     Let's now review the implementation of the \c BasicToolsPlugin
358     member functions inherited from \c BrushInterface.
359
360     \snippet tools/plugandpaintplugins/basictools/basictoolsplugin.cpp 0
361
362     The \c brushes() function returns a list of brushes provided by
363     this plugin. We provide three brushes: \uicontrol{Pencil}, \uicontrol{Air
364     Brush}, and \uicontrol{Random Letters}.
365
366     \snippet tools/plugandpaintplugins/basictools/basictoolsplugin.cpp 1
367
368     On a mouse press event, we just call \c mouseMove() to draw the
369     spot where the event occurred.
370
371     \snippet tools/plugandpaintplugins/basictools/basictoolsplugin.cpp 2
372
373     In \c mouseMove(), we start by saving the state of the QPainter
374     and we compute a few variables that we'll need later.
375
376     \snippet tools/plugandpaintplugins/basictools/basictoolsplugin.cpp 3
377
378     Then comes the brush-dependent part of the code:
379
380     \list
381     \li If the brush is \uicontrol{Pencil}, we just call
382        QPainter::drawLine() with the current QPen.
383
384     \li If the brush is \uicontrol{Air Brush}, we start by setting the
385        painter's QBrush to Qt::Dense6Pattern to obtain a dotted
386        pattern. Then we draw a circle filled with that QBrush several
387        times, resulting in a thick line.
388
389     \li If the brush is \uicontrol{Random Letters}, we draw a random letter
390        at the new cursor position. Most of the code is for setting
391        the font to be bold and larger than the default font and for
392        computing an appropriate bounding rect.
393     \endlist
394
395     At the end, we restore the painter state to what it was upon
396     entering the function and we return the bounding rectangle.
397
398     \snippet tools/plugandpaintplugins/basictools/basictoolsplugin.cpp 4
399
400     When the user releases the mouse, we do nothing and return an
401     empty QRect.
402
403     \section1 Implementation of the Shape Interface
404
405     \snippet tools/plugandpaintplugins/basictools/basictoolsplugin.cpp 5
406
407     The plugin provides three shapes: \uicontrol{Circle}, \uicontrol{Star}, and
408     \uicontrol{Text...}. The three dots after \uicontrol{Text} are there because
409     the shape pops up a dialog asking for more information. We know
410     that the shape names will end up in a menu, so we include the
411     three dots in the shape name.
412
413     A cleaner but more complicated design would have been to
414     distinguish between the internal shape name and the name used in
415     the user interface.
416
417     \snippet tools/plugandpaintplugins/basictools/basictoolsplugin.cpp 6
418
419     The \c generateShape() creates a QPainterPath for the specified
420     shape. If the shape is \uicontrol{Text}, we pop up a QInputDialog to
421     let the user enter some text.
422
423     \section1 Implementation of the Filter Interface
424
425     \snippet tools/plugandpaintplugins/basictools/basictoolsplugin.cpp 7
426
427     The plugin provides three filters: \uicontrol{Invert Pixels}, \uicontrol{Swap
428     RGB}, and \uicontrol{Grayscale}.
429
430     \snippet tools/plugandpaintplugins/basictools/basictoolsplugin.cpp 8
431
432     The \c filterImage() function takes a filter name and a QImage as
433     parameters and returns an altered QImage. The first thing we do
434     is to convert the image to a 32-bit RGB format, to ensure that
435     the algorithms will work as expected. For example,
436     QImage::invertPixels(), which is used to implement the
437     \uicontrol{Invert Pixels} filter, gives counterintuitive results for
438     8-bit images, because they invert the indices into the color
439     table instead of inverting the color table's entries.
440
441     \section1 Exporting the Plugin
442
443     Whereas applications have a \c main() function as their entry
444     point, plugins need to contain exactly one occurrence of the
445     Q_EXPORT_PLUGIN2() macro to specify which class provides the
446     plugin:
447
448     \snippet tools/plugandpaintplugins/basictools/basictoolsplugin.cpp 9
449
450     This line may appear in any \c .cpp file that is part of the
451     plugin's source code.
452
453     \section1 The .pro File
454
455     Here's the project file for building the Basic Tools plugin:
456
457     \snippet tools/plugandpaintplugins/basictools/basictools.pro 0
458
459     The \c .pro file differs from typical \c .pro files in many
460     respects. First, it starts with a \c TEMPLATE entry specifying \c
461     lib. (The default template is \c app.) It also adds \c plugin to
462     the \c CONFIG variable. This is necessary on some platforms to
463     avoid generating symbolic links with version numbers in the file
464     name, which is appropriate for most dynamic libraries but not for
465     plugins.
466
467     To make the plugin a static plugin, all that is required is to
468     specify \c static in addition to \c plugin. The
469     \l{plugandpaintplugins/extrafilters}{Extra Filters} plugin,
470     which is compiled as a dynamic plugin, doesn't specify \c static
471     in its \c .pro file.
472
473     The \c INCLUDEPATH variable sets the search paths for global
474     headers (i.e., header files included using \c{#include <...>}).
475     We add Qt's \c examples/tools directory (strictly speaking,
476     \c{examples/tools/plugandpaintplugins/basictools/../..}) to the
477     list, so that we can include \c <plugandpaint/interfaces.h>.
478
479     The \c TARGET variable specifies which name we want to give the
480     target library. We use \c pnp_ as the prefix to show that the
481     plugin is designed to work with Plug & Paint. On Unix, \c lib is
482     also prepended to that name. On all platforms, a
483     platform-specific suffix is appended (e.g., \c .dll on Windows,
484     \c .a on Linux).
485
486     The \c CONFIG() code at the end is necessary for this example
487     because the example is part of the Qt distribution and Qt can be
488     configured to be built simultaneously in debug and in release
489     modes. You don't need to for your own plugins.
490 */
491
492 /*!
493     \example tools/plugandpaintplugins/extrafilters
494     \title Plug & Paint Extra Filters Example
495
496     The Extra Filters example is a plugin for the
497     \l{plugandpaint}{Plug & Paint} example. It provides a set
498     of filters in addition to those provided by the
499     \l{plugandpaintplugins/basictools}{Basic Tools} plugin.
500
501     Since the approach is identical to
502     \l{plugandpaintplugins/basictools}{Basic Tools}, we won't
503     review the code here. The only part of interest is the
504     \c .pro file, since Extra Filters is a dynamic plugin
505     (\l{plugandpaintplugins/basictools}{Basic Tools} is
506     linked statically into the Plug & Paint executable).
507
508     Here's the project file for building the Extra Filters plugin:
509
510     \snippet tools/plugandpaintplugins/extrafilters/extrafilters.pro 0
511
512     The \c .pro file differs from typical \c .pro files in many
513     respects. First, it starts with a \c TEMPLATE entry specifying \c
514     lib. (The default template is \c app.) It also adds \c plugin to
515     the \c CONFIG variable. This is necessary on some platforms to
516     avoid generating symbolic links with version numbers in the file
517     name, which is appropriate for most dynamic libraries but not for
518     plugins.
519
520     The \c INCLUDEPATH variable sets the search paths for global
521     headers (i.e., header files included using \c{#include <...>}).
522     We add Qt's \c examples/tools directory (strictly speaking,
523     \c{examples/tools/plugandpaintplugins/basictools/../..}) to the
524     list, so that we can include \c <plugandpaint/interfaces.h>.
525
526     The \c TARGET variable specifies which name we want to give the
527     target library. We use \c pnp_ as the prefix to show that the
528     plugin is designed to work with Plug & Paint. On Unix, \c lib is
529     also prepended to that name. On all platforms, a
530     platform-specific suffix is appended (e.g., \c .dll on Windows,
531     \c .so on Linux).
532
533     The \c DESTDIR variable specifies where we want to install the
534     plugin. We put it in Plug & Paint's \c plugins subdirectory,
535     since that's where the application looks for dynamic plugins.
536
537     The \c CONFIG() code at the end is necessary for this example
538     because the example is part of the Qt distribution and Qt can be
539     configured to be built simultaneously in debug and in release
540     modes. You don't need to for your own plugins.
541 */