2ccf8cac43e18e8e8304d71ae6bedac77fd9f89f
[profile/ivi/qtbase.git] / examples / widgets / doc / icons.qdoc
1 /****************************************************************************
2 **
3 ** Copyright (C) 2012 Nokia Corporation and/or its subsidiary(-ies).
4 ** Contact: http://www.qt-project.org/
5 **
6 ** This file is part of the documentation of the Qt Toolkit.
7 **
8 ** $QT_BEGIN_LICENSE:FDL$
9 ** GNU Free Documentation License
10 ** Alternatively, this file may be used under the terms of the GNU Free
11 ** Documentation License version 1.3 as published by the Free Software
12 ** Foundation and appearing in the file included in the packaging of
13 ** this file.
14 **
15 ** Other Usage
16 ** Alternatively, this file may be used in accordance with the terms
17 ** and conditions contained in a signed written agreement between you
18 ** and Nokia.
19 **
20 **
21 **
22 **
23 **
24 ** $QT_END_LICENSE$
25 **
26 ****************************************************************************/
27
28 /*!
29     \example widgets/icons
30     \title Icons Example
31
32     The Icons example shows how QIcon can generate pixmaps reflecting
33     an icon's state, mode and size. These pixmaps are generated from
34     the set of pixmaps made available to the icon, and are used by Qt
35     widgets to show an icon representing a particular action.
36
37     \image icons-example.png Screenshot of the Icons example
38
39     Contents:
40
41     \tableofcontents
42
43     \section1 QIcon Overview
44
45     The QIcon class provides scalable icons in different modes and
46     states. An icon's state and mode are depending on the intended use
47     of the icon. Qt currently defines four modes:
48
49     \table
50     \header \li Mode \li Description
51     \row
52     \li QIcon::Normal
53     \li Display the pixmap when the user is not interacting with the
54        icon, but the functionality represented by the icon is
55        available.
56     \row
57     \li QIcon::Active
58     \li Display the pixmap when the functionality represented by the
59        icon is available and the user is interacting with the icon,
60        for example, moving the mouse over it or clicking it.
61     \row
62     \li QIcon::Disabled
63     \li Display the pixmap when the functionality represented by
64        the icon is not available.
65     \row
66     \li QIcon::Selected
67     \li Display the pixmap when the icon is selected.
68     \endtable
69
70     QIcon's states are QIcon::On and QIcon::Off, which will display
71     the pixmap when the widget is in the respective state. The most
72     common usage of QIcon's states are when displaying checkable tool
73     buttons or menu entries (see QAbstractButton::setCheckable() and
74     QAction::setCheckable()). When a tool button or menu entry is
75     checked, the QIcon's state is \l{QIcon::}{On}, otherwise it's
76     \l{QIcon::}{Off}. You can, for example, use the QIcon's states to
77     display differing pixmaps depending on whether the tool button or
78     menu entry is checked or not.
79
80     A QIcon can generate smaller, larger, active, disabled, and
81     selected pixmaps from the set of pixmaps it is given. Such
82     pixmaps are used by Qt widgets to show an icon representing a
83     particular action.
84
85     \section1 Overview of the Icons Application
86
87     With the Icons application you get a preview of an icon's
88     generated pixmaps reflecting its different states, modes and size.
89
90     When an image is loaded into the application, it is converted into
91     a pixmap and becomes a part of the set of pixmaps available to the
92     icon. An image can be excluded from this set by checking off the
93     related checkbox. The application provides a sub directory
94     containing sets of images explicitly designed to illustrate how Qt
95     renders an icon in different modes and states.
96
97     The application allows you to manipulate the icon size with some
98     predefined sizes and a spin box. The predefined sizes are style
99     dependent, but most of the styles have the same values: Only the
100     Macintosh style differ by using 32 pixels, instead of 16 pixels,
101     for toolbar buttons. You can navigate between the available styles
102     using the \uicontrol View menu.
103
104     \image icons-view-menu.png Screenshot of the View menu
105
106     The \uicontrol View menu also provide the option to make the application
107     guess the icon state and mode from an image's file name. The \uicontrol
108     File menu provide the options of adding an image and removing all
109     images. These last options are also available through a context
110     menu that appears if you press the right mouse button within the
111     table of image files. In addition, the \uicontrol File menu provide an
112     \uicontrol Exit option, and the \uicontrol Help menu provide information about
113     the example and about Qt.
114
115     \image icons_find_normal.png Screenshot of the Find Files
116
117     The screenshot above shows the application with one image file
118     loaded. The \uicontrol {Guess Image Mode/State} is enabled and the
119     style is Plastique.
120
121     When QIcon is provided with only one available pixmap, that
122     pixmap is used for all the states and modes. In this case the
123     pixmap's icon mode is set to normal, and the generated pixmaps
124     for the normal and active modes will look the same. But in
125     disabled and selected mode, Qt will generate a slightly different
126     pixmap.
127
128     The next screenshot shows the application with an additional file
129     loaded, providing QIcon with two available pixmaps. Note that the
130     new image file's mode is set to disabled. When rendering the \uicontrol
131     Disabled mode pixmaps, Qt will now use the new image. We can see
132     the difference: The generated disabled pixmap in the first
133     screenshot is slightly darker than the pixmap with the originally
134     set disabled mode in the second screenshot.
135
136     \image icons_find_normal_disabled.png Screenshot of the Find Files
137
138     When Qt renders the icon's pixmaps it searches through the set of
139     available pixmaps following a particular algorithm. The algorithm
140     is documented in QIcon, but we will describe some particular cases
141     below.
142
143     \image icons_monkey_active.png Screenshot of the Find Files
144
145     In the screenshot above, we have set \c monkey_on_32x32 to be an
146     Active/On pixmap and \c monkey_off_64x64 to be Normal/Off. To
147     render the other six mode/state combinations, QIcon uses the
148     search algorithm described in the table below:
149
150     \table 100%
151     \header \li{2,1} Requested Pixmap \li {8,1} Preferred Alternatives (mode/state)
152     \header \li Mode \li State \li 1  \li 2 \li 3 \li 4 \li 5 \li 6 \li 7 \li 8
153     \row \li{1,2} Normal \li Off \li \b N0 \li A0 \li N1 \li A1 \li D0 \li S0 \li D1 \li S1
154     \row \li On \li N1 \li \b A1 \li N0 \li A0 \li D1 \li S1 \li D0 \li S0
155     \row \li{1,2} Active \li Off \li A0 \li \b N0 \li A1 \li N1 \li D0 \li S0 \li D1 \li S1
156     \row \li On \li \b A1 \li N1 \li A0 \li N0 \li D1 \li S1 \li D0 \li S0
157     \row \li{1,2} Disabled \li Off \li D0 \li \b {N0'} \li A0' \li D1 \li N1' \li A1' \li S0' \li S1'
158     \row \li On \li D1 \li N1' \li \b {A1'} \li D0 \li N0' \li A0' \li S1' \li S0'
159     \row \li{1,2} Selected \li Off \li S0 \li \b {N0''} \li A0'' \li S1 \li N1'' \li A1'' \li D0'' \li D1''
160     \row \li On \li S1 \li N1'' \li \b {A1''} \li S0 \li N0'' \li A0'' \li D1'' \li D0''
161     \endtable
162
163     In the table, "0" and "1" stand for Off" and "On", respectively.
164     Single quotes indicates that QIcon generates a disabled ("grayed
165     out") version of the pixmap; similarly, double quuote indicate
166     that QIcon generates a selected ("blued out") version of the
167     pixmap.
168
169     The alternatives used in the screenshot above are shown in bold.
170     For example, the Disabled/Off pixmap is derived by graying out
171     the Normal/Off pixmap (\c monkey_off_64x64).
172
173     In the next screenshots, we loaded the whole set of monkey
174     images. By checking or unchecking file names from the image list,
175     we get different results:
176
177     \table
178     \row
179     \li \inlineimage icons_monkey.png Screenshot of the Monkey Files
180     \li \inlineimage icons_monkey_mess.png Screenshot of the Monkey Files
181     \endtable
182
183     For any given mode/state combination, it is possible to specify
184     several images at different resolutions. When rendering an
185     icon, QIcon will automatically pick the most suitable image
186     and scale it down if necessary. (QIcon never scales up images,
187     because this rarely looks good.)
188
189     The screenshots below shows what happens when we provide QIcon
190     with three images (\c qt_extended_16x16.png, \c qt_extended_32x32.png, \c
191     qt_extended_48x48.png) and try to render the QIcon at various
192     resolutions:
193
194     \table
195     \row
196     \li
197     \li \inlineimage icons_qt_extended_8x8.png Qt Extended icon at 8 x 8
198     \li \inlineimage icons_qt_extended_16x16.png Qt Extended icon at 16 x 16
199     \li \inlineimage icons_qt_extended_17x17.png Qt Extended icon at 17 x 17
200     \row
201     \li
202     \li 8 x 8
203     \li \b {16 x 16}
204     \li 17 x 17
205     \row
206     \li \inlineimage icons_qt_extended_32x32.png Qt Extended icon at 32 x 32
207     \li \inlineimage icons_qt_extended_33x33.png Qt Extended icon at 33 x 33
208     \li \inlineimage icons_qt_extended_48x48.png Qt Extended icon at 48 x 48
209     \li \inlineimage icons_qt_extended_64x64.png Qt Extended icon at 64 x 64
210     \row
211     \li \b {32 x 32}
212     \li 33 x 33
213     \li \b {48 x 48}
214     \li 64 x 64
215     \endtable
216
217     For sizes up to 16 x 16, QIcon uses \c qt_extended_16x16.png and
218     scales it down if necessary. For sizes between 17 x 17 and 32 x
219     32, it uses \c qt_extended_32x32.png. For sizes above 32 x 32, it uses
220     \c qt_extended_48x48.png.
221
222     \section1 Line-by-Line Walkthrough
223
224     The Icons example consists of four classes:
225
226     \list
227     \li \c MainWindow inherits QMainWindow and is the main application
228        window.
229     \li \c IconPreviewArea is a custom widget that displays all
230        combinations of states and modes for a given icon.
231     \li \c IconSizeSpinBox is a subclass of QSpinBox that lets the
232        user enter icon sizes (e.g., "48 x 48").
233     \li \c ImageDelegate is a subclass of QItemDelegate that provides
234        comboboxes for letting the user set the mode and state
235        associated with an image.
236     \endlist
237
238     We will start by reviewing the \c IconPreviewArea class before we
239     take a look at the \c MainWindow class. Finally, we will review the
240     \c IconSizeSpinBox and \c ImageDelegate classes.
241
242     \section2 IconPreviewArea Class Definition
243
244     An \c IconPreviewArea widget consists of a group box containing a grid of
245     QLabel widgets displaying headers and pixmaps.
246
247     \image icons_preview_area.png Screenshot of IconPreviewArea.
248
249     \snippet widgets/icons/iconpreviewarea.h 0
250
251     The \c IconPreviewArea class inherits QWidget. It displays the
252     generated pixmaps corresponding to an icon's possible states and
253     modes at a given size.
254
255     We need two public functions to set the current icon and the
256     icon's size. In addition the class has three private functions: We
257     use the \c createHeaderLabel() and \c createPixmapLabel()
258     functions when constructing the preview area, and we need the \c
259     updatePixmapLabels() function to update the preview area when
260     the icon or the icon's size has changed.
261
262     The \c NumModes and \c NumStates constants reflect \l{QIcon}'s
263     number of currently defined modes and states.
264
265     \section2 IconPreviewArea Class Implementation
266
267     \snippet widgets/icons/iconpreviewarea.cpp 0
268
269     In the constructor we create the labels displaying the headers and
270     the icon's generated pixmaps, and add them to a grid layout.
271
272     When creating the header labels, we make sure the enums \c
273     NumModes and \c NumStates defined in the \c .h file, correspond
274     with the number of labels that we create. Then if the enums at
275     some point are changed, the \c Q_ASSERT() macro will alert that this
276     part of the \c .cpp file needs to be updated as well.
277
278     If the application is built in debug mode, the \c Q_ASSERT()
279     macro will expand to
280
281     \snippet doc/src/snippets/code/doc_src_examples_icons.cpp 0
282
283     In release mode, the macro simply disappear. The mode can be set
284     in the application's \c .pro file. One way to do so is to add an
285     option to \c qmake when building the application:
286
287     \snippet doc/src/snippets/code/doc_src_examples_icons.qdoc 1
288
289     or
290
291     \snippet doc/src/snippets/code/doc_src_examples_icons.qdoc 2
292
293     Another approach is to add this line directly to the \c .pro
294     file.
295
296     \snippet widgets/icons/iconpreviewarea.cpp 1
297     \codeline
298     \snippet widgets/icons/iconpreviewarea.cpp 2
299
300     The public \c setIcon() and \c setSize() functions change the icon
301     or the icon size, and make sure that the generated pixmaps are
302     updated.
303
304     \snippet widgets/icons/iconpreviewarea.cpp 3
305     \codeline
306     \snippet widgets/icons/iconpreviewarea.cpp 4
307
308     We use the \c createHeaderLabel() and \c createPixmapLabel()
309     functions to create the preview area's labels displaying the
310     headers and the icon's generated pixmaps. Both functions return
311     the QLabel that is created.
312
313     \snippet widgets/icons/iconpreviewarea.cpp 5
314
315     We use the private \c updatePixmapLabel() function to update the
316     generated pixmaps displayed in the preview area.
317
318     For each mode, and for each state, we retrieve a pixmap using the
319     QIcon::pixmap() function, which generates a pixmap corresponding
320     to the given state, mode and size.
321
322     \section2 MainWindow Class Definition
323
324     The \c MainWindow widget consists of three main elements: an
325     images group box, an icon size group box and a preview area.
326
327     \image icons-example.png Screenshot of the Icons example
328
329     \snippet widgets/icons/mainwindow.h 0
330
331     The MainWindow class inherits from QMainWindow. We reimplement the
332     constructor, and declare several private slots:
333
334     \list
335     \li The \c about() slot simply provides information about the example.
336     \li The \c changeStyle() slot changes the application's GUI style and
337        adjust the style dependent size options.
338     \li The \c changeSize() slot changes the size of the preview area's icon.
339     \li The \c changeIcon() slot updates the set of pixmaps available to the
340        icon displayed in the preview area.
341     \li The \c addImage() slot allows the user to load a new image into the
342        application.
343     \endlist
344
345     In addition we declare several private functions to simplify the
346     constructor.
347
348     \section2 MainWindow Class Implementation
349
350     \snippet widgets/icons/mainwindow.cpp 0
351
352     In the constructor we first create the main window's central
353     widget and its child widgets, and put them in a grid layout. Then
354     we create the menus with their associated entries and actions.
355
356     Before we resize the application window to a suitable size, we set
357     the window title and determine the current style for the
358     application. We also enable the icon size spin box by clicking the
359     associated radio button, making the current value of the spin box
360     the icon's initial size.
361
362     \snippet widgets/icons/mainwindow.cpp 1
363
364     The \c about() slot displays a message box using the static
365     QMessageBox::about() function. In this example it displays a
366     simple box with information about the example.
367
368     The \c about() function looks for a suitable icon in four
369     locations: It prefers its parent's icon if that exists. If it
370     doesn't, the function tries the top-level widget containing
371     parent, and if that fails, it tries the active window. As a last
372     resort it uses the QMessageBox's Information icon.
373
374     \snippet widgets/icons/mainwindow.cpp 2
375
376     In the \c changeStyle() slot we first check the slot's
377     parameter. If it is false we immediately return, otherwise we find
378     out which style to change to, i.e. which action that triggered the
379     slot, using the QObject::sender() function.
380
381     This function returns the sender as a QObject pointer. Since we
382     know that the sender is a QAction object, we can safely cast the
383     QObject. We could have used a C-style cast or a C++ \c
384     static_cast(), but as a defensive programming technique we use a
385     \l qobject_cast(). The advantage is that if the object has the
386     wrong type, a null pointer is returned. Crashes due to null
387     pointers are much easier to diagnose than crashes due to unsafe
388     casts.
389
390     \snippet widgets/icons/mainwindow.cpp 3
391     \snippet widgets/icons/mainwindow.cpp 4
392
393     Once we have the action, we extract the style name using
394     QAction::data(). Then we create a QStyle object using the static
395     QStyleFactory::create() function.
396
397     Although we can assume that the style is supported by the
398     QStyleFactory: To be on the safe side, we use the \c Q_ASSERT()
399     macro to check if the created style is valid before we use the
400     QApplication::setStyle() function to set the application's GUI
401     style to the new style. QApplication will automatically delete
402     the style object when a new style is set or when the application
403     exits.
404
405     The predefined icon size options provided in the application are
406     style dependent, so we need to update the labels in the icon size
407     group box and in the end call the \c changeSize() slot to update
408     the icon's size.
409
410     \snippet widgets/icons/mainwindow.cpp 5
411
412     The \c changeSize() slot sets the size for the preview area's
413     icon.
414
415     To determine the new size we first check if the spin box is
416     enabled. If it is, we extract the extent of the new size from the
417     box. If it's not, we search through the predefined size options,
418     extract the QStyle::PixelMetric and use the QStyle::pixelMetric()
419     function to determine the extent. Then we create a QSize object
420     based on the extent, and use that object to set the size of the
421     preview area's icon.
422
423     \snippet widgets/icons/mainwindow.cpp 12
424
425     The first thing we do when the \c addImage() slot is called, is to
426     show a file dialog to the user. The easiest way to create a file
427     dialog is to use QFileDialog's static functions. Here we use the
428     \l {QFileDialog::getOpenFileNames()}{getOpenFileNames()} function
429     that will return one or more existing files selected by the user.
430
431     For each of the files the file dialog returns, we add a row to the
432     table widget. The table widget is listing the images the user has
433     loaded into the application.
434
435     \snippet widgets/icons/mainwindow.cpp 13
436     \snippet widgets/icons/mainwindow.cpp 14
437
438     We retrieve the image name using the QFileInfo::baseName()
439     function that returns the base name of the file without the path,
440     and create the first table widget item in the row. Then we add the
441     file's complete name to the item's data. Since an item can hold
442     several information pieces, we need to assign the file name a role
443     that will distinguish it from other data. This role can be Qt::UserRole
444     or any value above it.
445
446     We also make sure that the item is not editable by removing the
447     Qt::ItemIsEditable flag. Table items are editable by default.
448
449     \snippet widgets/icons/mainwindow.cpp 15
450     \snippet widgets/icons/mainwindow.cpp 16
451     \snippet widgets/icons/mainwindow.cpp 17
452
453     Then we create the second and third items in the row making the
454     default mode Normal and the default state Off. But if the \uicontrol
455     {Guess Image Mode/State} option is checked, and the file name
456     contains "_act", "_dis", or "_sel", the modes are changed to
457     Active, Disabled, or Selected. And if the file name contains
458     "_on", the state is changed to On. The sample files in the
459     example's \c images subdirectory respect this naming convension.
460
461     \snippet widgets/icons/mainwindow.cpp 18
462     \snippet widgets/icons/mainwindow.cpp 19
463
464     In the end we add the items to the associated row, and use the
465     QTableWidget::openPersistentEditor() function to create
466     comboboxes for the mode and state columns of the items.
467
468     Due to the connection between the table widget's \l
469     {QTableWidget::itemChanged()}{itemChanged()} signal and the \c
470     changeIcon() slot, the new image is automatically converted into a
471     pixmap and made part of the set of pixmaps available to the icon
472     in the preview area. So, corresponding to this fact, we need to
473     make sure that the new image's check box is enabled.
474
475     \snippet widgets/icons/mainwindow.cpp 6
476     \snippet widgets/icons/mainwindow.cpp 7
477
478     The \c changeIcon() slot is called when the user alters the set
479     of images listed in the QTableWidget, to update the QIcon object
480     rendered by the \c IconPreviewArea.
481
482     We first create a QIcon object, and then we run through the
483     QTableWidget, which lists the images the user has loaded into the
484     application.
485
486     \snippet widgets/icons/mainwindow.cpp 8
487     \snippet widgets/icons/mainwindow.cpp 9
488     \snippet widgets/icons/mainwindow.cpp 10
489
490     We also extract the image file's name using the
491     QTableWidgetItem::data() function. This function takes a
492     Qt::DataItemRole as an argument to retrieve the right data
493     (remember that an item can hold several pieces of information)
494     and returns it as a QVariant. Then we use the
495     QVariant::toString() function to get the file name as a QString.
496
497     To create a pixmap from the file, we need to first create an
498     image and then convert this image into a pixmap using
499     QPixmap::fromImage(). Once we have the final pixmap, we add it,
500     with its associated mode and state, to the QIcon's set of
501     available pixmaps.
502
503     \snippet widgets/icons/mainwindow.cpp 11
504
505     After running through the entire list of images, we change the
506     icon of the preview area to the one we just created.
507
508     \snippet widgets/icons/mainwindow.cpp 20
509
510     In the \c removeAllImages() slot, we simply set the table widget's
511     row count to zero, automatically removing all the images the user
512     has loaded into the application. Then we update the set of pixmaps
513     available to the preview area's icon using the \c changeIcon()
514     slot.
515
516     \image icons_images_groupbox.png Screenshot of the images group box
517
518     The \c createImagesGroupBox() function is implemented to simplify
519     the constructor. The main purpose of the function is to create a
520     QTableWidget that will keep track of the images the user has
521     loaded into the application.
522
523     \snippet widgets/icons/mainwindow.cpp 21
524
525     First we create a group box that will contain the table widget.
526     Then we create a QTableWidget and customize it to suit our
527     purposes.
528
529     We call QAbstractItemView::setSelectionMode() to prevent the user
530     from selecting items.
531
532     The QAbstractItemView::setItemDelegate() call sets the item
533     delegate for the table widget. We create a \c ImageDelegate that
534     we make the item delegate for our view.
535
536     The QItemDelegate class can be used to provide an editor for an item view
537     class that is subclassed from QAbstractItemView. Using a delegate
538     for this purpose allows the editing mechanism to be customized and
539     developed independently from the model and view.
540
541     In this example we derive \c ImageDelegate from QItemDelegate.
542     QItemDelegate usually provides line editors, while our subclass
543     \c ImageDelegate, provides comboboxes for the mode and state
544     fields.
545
546     \snippet widgets/icons/mainwindow.cpp 22
547     \snippet widgets/icons/mainwindow.cpp 23
548
549     Then we customize the QTableWidget's horizontal header, and hide
550     the vertical header.
551
552     \snippet widgets/icons/mainwindow.cpp 24
553     \snippet widgets/icons/mainwindow.cpp 25
554
555     At the end, we connect the QTableWidget::itemChanged() signal to
556     the \c changeIcon() slot to ensuret that the preview area is in
557     sync with the image table.
558
559     \image icons_size_groupbox.png Screenshot of the icon size group box
560
561     The \c createIconSizeGroupBox() function is called from the
562     constructor. It creates the widgets controlling the size of the
563     preview area's icon.
564
565     \snippet widgets/icons/mainwindow.cpp 26
566
567     First we create a group box that will contain all the widgets;
568     then we create the radio buttons and the spin box.
569
570     The spin box is not a regular QSpinBox but an \c IconSizeSpinBox.
571     The \c IconSizeSpinBox class inherits QSpinBox and reimplements
572     two functions: QSpinBox::textFromValue() and
573     QSpinBox::valueFromText(). The \c IconSizeSpinBox is designed to
574     handle icon sizes, e.g., "32 x 32", instead of plain integer
575     values.
576
577     \snippet widgets/icons/mainwindow.cpp 27
578
579     Then we connect all of the radio buttons
580     \l{QRadioButton::toggled()}{toggled()} signals and the spin box's
581     \l {QSpinBox::valueChanged()}{valueChanged()} signal to the \c
582     changeSize() slot to make sure that the size of the preview
583     area's icon is updated whenever the user changes the icon size.
584     In the end we put the widgets in a layout that we install on the
585     group box.
586
587     \snippet widgets/icons/mainwindow.cpp 28
588
589     In the \c createActions() function we create and customize all the
590     actions needed to implement the functionality associated with the
591     menu entries in the application.
592
593     In particular we create the \c styleActionGroup based on the
594     currently available GUI styles using
595     QStyleFactory. QStyleFactory::keys() returns a list of valid keys,
596     typically including "windows", "motif", "cde", and
597     "plastique". Depending on the platform, "windowsxp" and
598     "macintosh" may be available.
599
600     We create one action for each key, and adds the action to the
601     action group. Also, for each action, we call QAction::setData()
602     with the style name. We will retrieve it later using
603     QAction::data().
604
605     \snippet widgets/icons/mainwindow.cpp 29
606
607     In the \c createMenu() function, we add the previously created
608     actions to the \uicontrol File, \uicontrol View and \uicontrol Help menus.
609
610     The QMenu class provides a menu widget for use in menu bars,
611     context menus, and other popup menus. We put each menu in the
612     application's menu bar, which we retrieve using
613     QMainWindow::menuBar().
614
615     \snippet widgets/icons/mainwindow.cpp 30
616
617     QWidgets have a \l{QWidget::contextMenuPolicy}{contextMenuPolicy}
618     property that controls how the widget should behave when the user
619     requests a context menu (e.g., by right-clicking). We set the
620     QTableWidget's context menu policy to Qt::ActionsContextMenu,
621     meaning that the \l{QAction}s associated with the widget should
622     appear in its context menu.
623
624     Then we add the \uicontrol{Add Image} and \uicontrol{Remove All Images}
625     actions to the table widget. They will then appear in the table
626     widget's context menu.
627
628     \snippet widgets/icons/mainwindow.cpp 31
629
630     In the \c checkCurrentStyle() function we go through the group of
631     style actions, looking for the current GUI style.
632
633     For each action, we first extract the style name using
634     QAction::data(). Since this is only a QStyleFactory key (e.g.,
635     "macintosh"), we cannot compare it directly to the current
636     style's class name. We need to create a QStyle object using the
637     static QStyleFactory::create() function and compare the class
638     name of the created QStyle object with that of the current style.
639     As soon as we are done with a QStyle candidate, we delete it.
640
641     For all QObject subclasses that use the \c Q_OBJECT macro, the
642     class name of an object is available through its
643     \l{QObject::metaObject()}{meta-object}.
644
645     We can assume that the style is supported by
646     QStyleFactory, but to be on the safe side we use the \c
647     Q_ASSERT() macro to make sure that QStyleFactory::create()
648     returned a valid pointer.
649
650     \section2 IconSizeSpinBox Class Definition
651
652     \snippet widgets/icons/iconsizespinbox.h 0
653
654     The \c IconSizeSpinBox class is a subclass of QSpinBox. A plain
655     QSpinBox can only handle integers. But since we want to display
656     the spin box's values in a more sophisticated way, we need to
657     subclass QSpinBox and reimplement the QSpinBox::textFromValue()
658     and QSpinBox::valueFromText() functions.
659
660     \image icons_size_spinbox.png Screenshot of the icon size spinbox
661
662     \section2 IconSizeSpinBox Class Implementation
663
664     \snippet widgets/icons/iconsizespinbox.cpp 0
665
666     The constructor is trivial.
667
668     \snippet widgets/icons/iconsizespinbox.cpp 2
669
670     QSpinBox::textFromValue() is used by the spin box whenever it
671     needs to display a value. The default implementation returns a
672     base 10 representation of the \c value parameter.
673
674     Our reimplementation returns a QString of the form "32 x 32".
675
676     \snippet widgets/icons/iconsizespinbox.cpp 1
677
678     The QSpinBox::valueFromText() function is used by the spin box
679     whenever it needs to interpret text typed in by the user. Since
680     we reimplement the \c textFromValue() function we also need to
681     reimplement the \c valueFromText() function to interpret the
682     parameter text and return the associated int value.
683
684     We parse the text using a regular expression (a QRegExp). We
685     define an expression that matches one or several digits,
686     optionally followed by whitespace, an "x" or the times symbol,
687     whitespace and one or several digits again.
688
689     The first digits of the regular expression are captured using
690     parentheses. This enables us to use the QRegExp::cap() or
691     QRegExp::capturedTexts() functions to extract the matched
692     characters. If the first and second numbers of the spin box value
693     differ (e.g., "16 x 24"), we use the first number.
694
695     When the user presses \uicontrol Enter, QSpinBox first calls
696     QSpinBox::valueFromText() to interpret the text typed by the
697     user, then QSpinBox::textFromValue() to present it in a canonical
698     format (e.g., "16 x 16").
699
700     \section2 ImageDelegate Class Definition
701
702     \snippet widgets/icons/imagedelegate.h 0
703
704     The \c ImageDelegate class is a subclass of QItemDelegate. The
705     QItemDelegate class provides display and editing facilities for
706     data items from a model. A single QItemDelegate object is
707     responsible for all items displayed in a item view (in our case,
708     a QTableWidget).
709
710     A QItemDelegate can be used to provide an editor for an item view
711     class that is subclassed from QAbstractItemView. Using a delegate
712     for this purpose allows the editing mechanism to be customized and
713     developed independently from the model and view.
714
715     \snippet widgets/icons/imagedelegate.h 1
716
717     The default implementation of QItemDelegate creates a QLineEdit.
718     Since we want the editor to be a QComboBox, we need to subclass
719     QItemDelegate and reimplement the QItemDelegate::createEditor(),
720     QItemDelegate::setEditorData() and QItemDelegate::setModelData()
721     functions.
722
723     \snippet widgets/icons/imagedelegate.h 2
724
725     The \c emitCommitData() slot is used to emit the
726     QImageDelegate::commitData() signal with the appropriate
727     argument.
728
729     \section2 ImageDelegate Class Implementation
730
731     \snippet widgets/icons/imagedelegate.cpp 0
732
733     The constructor is trivial.
734
735     \snippet widgets/icons/imagedelegate.cpp 1
736
737     The default QItemDelegate::createEditor() implementation returns
738     the widget used to edit the item specified by the model and item
739     index for editing. The parent widget and style option are used to
740     control the appearance of the editor widget.
741
742     Our reimplementation create and populate a combobox instead of
743     the default line edit. The contents of the combobox depends on
744     the column in the table for which the editor is requested. Column
745     1 contains the QIcon modes, whereas column 2 contains the QIcon
746     states.
747
748     In addition, we connect the combobox's \l
749     {QComboBox::activated()}{activated()} signal to the \c
750     emitCommitData() slot to emit the
751     QAbstractItemDelegate::commitData() signal whenever the user
752     chooses an item using the combobox. This ensures that the rest of
753     the application notices the change and updates itself.
754
755     \snippet widgets/icons/imagedelegate.cpp 2
756
757     The QItemDelegate::setEditorData() function is used by
758     QTableWidget to transfer data from a QTableWidgetItem to the
759     editor. The data is stored as a string; we use
760     QComboBox::findText() to locate it in the combobox.
761
762     Delegates work in terms of models, not items. This makes it
763     possible to use them with any item view class (e.g., QListView,
764     QListWidget, QTreeView, etc.). The transition between model and
765     items is done implicitly by QTableWidget; we don't need to worry
766     about it.
767
768     \snippet widgets/icons/imagedelegate.cpp 3
769
770     The QItemDelegate::setEditorData() function is used by QTableWidget
771     to transfer data back from the editor to the \l{QTableWidgetItem}.
772
773     \snippet widgets/icons/imagedelegate.cpp 4
774
775     The \c emitCommitData() slot simply emit the
776     QAbstractItemDelegate::commitData() signal for the editor that
777     triggered the slot. This signal must be emitted when the editor
778     widget has completed editing the data, and wants to write it back
779     into the model.
780 */