~canonical-dx-team/ubuntu/maverick/gtk+2.0/menuproxy

« back to all changes in this revision

Viewing changes to docs/reference/gtk/migrating-GtkAction.sgml

  • Committer: Bazaar Package Importer
  • Author(s): Sebastien Bacher
  • Date: 2007-05-04 12:24:25 UTC
  • mfrom: (1.1.21 upstream)
  • Revision ID: james.westby@ubuntu.com-20070504122425-0m8midgzrp40y8w2
Tags: 2.10.12-1ubuntu1
* Sync with Debian
* New upstream version:
  Fixed bugs:
  - 379414 file chooser warnings when changing path in the entry
  - 418585 GtkFileChooserDefault sizing code is not DPI independent
  - 419568 Crash in search if start with special letter
  - 435062 build dies with icon cache validation
  - 379399 Segfault to call gtk_print_operation_run twice.
  - 387889 cups backend has problems when there are too many printers
  - 418531 invalid read to gtkicontheme.c gtk_icon_theme_lookup_icon...
  - 423916 crash in color scheme code
  - 424042 Segmentation fault while quickly pressing Alt+arrows
  - 415260 Protect against negative indices when setting values in G...
  - 419171 XGetVisualInfo() may not set nxvisuals
  - 128852 Gdk cursors don't look good on win32
  - 344657 Ctrl-H doesn't toggle "Show Hidden Files" setting
  - 345345 PrintOperation::paginate is not emitted for class handler
  - 347567 GtkPrintOperation::end-print is not emitted if it's cance...
  - 369112 gtk_ui_manager_add_ui should accept unnamed separator
  - 392015 Selected menu item invisible on Windows Vista
  - 399253 MS-Windows Theme Bottom Tab placement rendering glitches
  - 399425 gtk_input_dialog_fill_axes() adds child to gtkscrolledwin...
  - 403251 [patch] little memory leak in GtkPrintJob
  - 403267 [patch] memory leak in GtkPageSetupUnixDialog
  - 403470 MS-Windows Theme tab placement other than on top leaks a ...
  - 404506 Windows system fonts that have multi-byte font names cann...
  - 405089 Incorrect window placement for GtkEventBox private window
  - 405515 Minor leak in gtkfilesystemmodel.c
  - 405539 gdk_pixbuf_save() for PNG saver can return FALSE without ...
  - 415681 gdk_window_clear_area includes an extra line and column o...
  - 418219 GtkRecentChooser should apply filter before sorting and c...
  - 418403 Scroll to printer after selecting it from settings
  - 421985 _gtk_print_operation_platform_backend_launch_preview
  - 421990 gtk_print_job_get_surface
  - 421993 gtk_print_operation_init
  - 423064 Conditional jump or move depends on uninitialised value(s...
  - 423722 Fix printing header in gtk-demo
  - 424168 gtk_print_operation_run on async preview
  - 425655 Don't install gtk+-unix-print-2.0.pc on non-UNIX platforms
  - 425786 GDK segfaults if XineramaQueryScreens fails
  - 428665 Lpr Backend gets stuck in infinite loop during gtk_enumer...
  - 429902 GtkPrintOperation leaks cairo contextes
  - 431997 First delay of GdkPixbufAnimationIter is wrong
  - 433242 Inconsistent scroll arrow position calculations
  - 433972 Placing gtk.Expander inside a gtk.TextView() changes gtk....
  - 434261 _gtk_toolbar_elide_underscores incorrectly handles some s...
  - 383354 ctrl-L should make 'Location' entry disappear
  - 418673 gtk_recent_manager_add_item
  - 429732 gtk_accel_group_finalize accesses invalid memory
  - 435028 WM_CLIENT_LEADER is wrong on the leader_window
  - 431067 Background of the header window is not updated
  - 338843 add recent files support inside the ui manager
  - 148535 add drop shadow to menus, tooltips, etc. under Windows XP
* debian/control.in:
  - Conflicts on ubuntulooks (<= 0.9.11-1)
* debian/patches/15_default-fallback-icon-theme.patch:
  - patch from Debian, fallback on gnome icon theme

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
<chapter id="gtk-migrating-GtkAction">
 
2
  <chapterinfo>
 
3
    <author>
 
4
      <firstname>Federico</firstname>
 
5
      <surname>Mena-Quintero</surname>
 
6
      <affiliation>
 
7
        <address>
 
8
          <email>federico@ximian.com</email>
 
9
        </address>
 
10
      </affiliation>
 
11
    </author>
 
12
  </chapterinfo>
 
13
 
 
14
  <title>Migrating from old menu and toolbar systems to GtkAction</title>
 
15
 
 
16
  <para>
 
17
    Prior to GTK+ 2.4, there were several APIs in use to create menus
 
18
    and toolbars.  GTK+ itself included #GtkItemFactory, which was
 
19
    historically used in the GIMP; libgnomeui provided the gnome-ui
 
20
    set of macros; libbonoboui provided a complex mechanism to do menu
 
21
    merging across embedded components.  GTK+ 2.4 includes a system
 
22
    for creating menus and toolbars, with merging of items, based
 
23
    around the #GtkAction mechanism.
 
24
  </para>
 
25
 
 
26
  <section id="actions-and-action-groups">
 
27
    <title>Actions and Action Groups</title>
 
28
 
 
29
    <para>
 
30
      A #GtkAction represents an operation that the user can perform from 
 
31
      the menus and toolbars of an application.  It is similar to "verbs" 
 
32
      in other menu systems.  A #GtkAction has a name, which is its identifier, 
 
33
      and it can have several widgets that represent it in the user interface.  
 
34
      For example, an action for <symbol>EditCopy</symbol> can have a menu item 
 
35
      as well as a toolbar button associated to it.  If there is nothing selected
 
36
      in the document, the application can simply de-sensitize the
 
37
      <symbol>EditCopy</symbol> action; this will cause both the menu
 
38
      item and the toolbar button to be de-sensitized automatically.
 
39
      Similarly, whenever the user selects the menu item or the
 
40
      toolbar button associated to the <symbol>EditCopy</symbol>
 
41
      action, the corresponding #GtkAction object will emit an
 
42
      "activate" signal.
 
43
    </para>
 
44
 
 
45
    <para>
 
46
      #GtkActionGroup is simply a group of #GtkAction objects.  An
 
47
      application may want to have several groups:  one for global
 
48
      actions such as "new document", "about", and "exit"; then one
 
49
      group for each open document with actions specific to the
 
50
      document, such as "cut", "copy", "paste", and "print".
 
51
    </para>
 
52
 
 
53
    <para>
 
54
      Normal actions are simply commands, such as
 
55
      <symbol>FileSave</symbol> or <symbol>EditCopy</symbol>.  Toggle
 
56
      actions can be active or inactive, such as
 
57
      <symbol>FormatBold</symbol> or <symbol>ViewShowRulers</symbol>.
 
58
      Radio actions define a set of items for which one and only one
 
59
      can be active at a time, for example, {
 
60
      <symbol>ViewHighQuality</symbol>,
 
61
      <symbol>ViewNormalQuality</symbol>,
 
62
      <symbol>ViewLowQuality</symbol> }.
 
63
    </para>
 
64
  </section>
 
65
 
 
66
  <section id="ui-manager">
 
67
    <title>User Interface Manager Object</title>
 
68
 
 
69
    <para>
 
70
      #GtkUIManager is an object that can construct menu and toolbar widgets 
 
71
      from an XML description.  These widgets are in turn associated to
 
72
      corresponding actions and action groups.
 
73
    </para>
 
74
 
 
75
    <para>
 
76
      #GtkUIManager supports merging of menus and toolbars for applications 
 
77
      that have multiple components, each with separate sets of commands.  
 
78
      For example, a word processor that can embed images may want to have
 
79
      toolbar buttons for Bold and Italic when the cursor is on a text
 
80
      block, but Crop and Brightness/Contrast buttons when the cursor
 
81
      is on an image.  These actions, which change depending on the
 
82
      state of the application, can be merged and de-merged from a
 
83
      #GtkUIManager as appropriate.
 
84
    </para>
 
85
  </section>
 
86
 
 
87
  <section id="migrating-gnomeuiinfo">
 
88
    <title>Migrating from GnomeUIInfo</title>
 
89
 
 
90
    <para>
 
91
      Prior to GTK+ 2.4, some applications used the GnomeUIInfo
 
92
      mechanism from
 
93
      <filename>&lt;libgnomeui/gnome-app-helper.h&gt;</filename> to
 
94
      define their menus and toolbars.  With it, a program decleres an
 
95
      array of <structname>GnomeUIInfo</structname> structures, which
 
96
      contain information for menu or toolbar items such as their
 
97
      label, icon, and accelerator key.  Then, one calls
 
98
      gnome_app_fill_menu() or gnome_app_fill_toolbar(), or one of the
 
99
      related functions, to create the appropriate widgets based on
 
100
      these structures.
 
101
    </para>
 
102
 
 
103
    <para>
 
104
      A downside of this API is that the same structures are used to
 
105
      pass back pointers to the widgets that got created.  This means
 
106
      that the structures cannot simply be kept around if the program
 
107
      requires multiple instances of the user interface (e.g. several
 
108
      windows); each new invocation of gnome_app_fill_menu() would overwrite the
 
109
      widget fields of the structures.
 
110
    </para>
 
111
 
 
112
    <para>
 
113
      Another disadvantage is that there is no automatic way to
 
114
      synchronize the state of related controls.  If there are toolbar
 
115
      toogle buttons for "Bold", "Italic", "Underline", and also
 
116
      corresponding menu items under "Format/Bold", etc., one has to
 
117
      synchronize their toggled states by hand whenever the user
 
118
      selects any one of them.
 
119
    </para>
 
120
 
 
121
    <para>
 
122
      Finally, there is no way to do menu and toolbar merging for
 
123
      applications that require embedded components.
 
124
    </para>
 
125
 
 
126
    <para>
 
127
      To convert an application that uses GnomeUIInfo into the new
 
128
      GtkAction mechanism, you need to do several things:
 
129
    </para>
 
130
 
 
131
    <orderedlist>
 
132
      <listitem>
 
133
        <para>
 
134
          Separate your existing GnomeUIInfo entries into normal
 
135
          actions, toggle actions, and radio actions, and then create
 
136
          a separate array of #GtkActionEntry structures
 
137
          for each group.  This will allow you to create the necessary
 
138
          #GtkActionGroup objects.  Note that this does not describe the actual
 
139
          "shape" that your menus and toolbars will have; it simply
 
140
          defines the set of commands that will appear in them.
 
141
        </para>
 
142
      </listitem>
 
143
      <listitem>
 
144
        <para>
 
145
          Create an XML description of your menus and toolbars for use
 
146
          with #GtkUIManager.  This defines the actual shape of the menus and toolbars.
 
147
        </para>
 
148
      </listitem>
 
149
      <listitem>
 
150
        <para>
 
151
          Port the code that uses gnome-app and gnome-app-helper to
 
152
          #GtkAction and #GtkUIManager.
 
153
        </para>
 
154
      </listitem>
 
155
      <listitem>
 
156
       <para>
 
157
         If your GnomeUIInfo entries use GNOME_APP_PIXMAP_DATA or 
 
158
         GNOME_APP_PIXMAP_FILENAME for pixmaps, you have to create a 
 
159
         #GtkIconFactory, add it to the list of default factories, then create a 
 
160
         #GtkIconSet for each of your own icons. Add the sets to the factory, and 
 
161
         use the id in the #GtkActionEntry like a regular GTK+ stock id.
 
162
       </para>
 
163
      </listitem>
 
164
    </orderedlist>
 
165
 
 
166
    <example id="gnomeuiinfo-example">
 
167
      <title>GnomeUIInfo Example</title>
 
168
 
 
169
      <para>
 
170
        The following code shows a declaration of a simple menu bar to
 
171
        be used with gnome_app_fill_menu() or similar.  The menu hierarchy looks 
 
172
        like this:
 
173
      </para>
 
174
 
 
175
      <itemizedlist>
 
176
        <listitem>
 
177
          <para><guimenu>File</guimenu></para>
 
178
          <simplelist>
 
179
            <member><guimenuitem>Open</guimenuitem></member>
 
180
            <member><guimenuitem>&mdash;</guimenuitem></member>
 
181
            <member><guimenuitem>Exit</guimenuitem></member>
 
182
          </simplelist>
 
183
        </listitem>
 
184
 
 
185
        <listitem>
 
186
          <para><guimenu>View</guimenu></para>
 
187
          <simplelist>
 
188
            <member><guimenuitem>Zoom In</guimenuitem></member>
 
189
            <member><guimenuitem>Zoom Out</guimenuitem></member>
 
190
            <member><guimenuitem>&mdash;</guimenuitem></member>
 
191
            <member><guimenuitem>[ ] Full Screen</guimenuitem></member>
 
192
            <member><guimenuitem>&mdash;</guimenuitem></member>
 
193
            <member><guimenuitem>( ) High Quality</guimenuitem></member>
 
194
            <member><guimenuitem>( ) Normal Quality</guimenuitem></member>
 
195
            <member><guimenuitem>( ) Low Quality</guimenuitem></member>
 
196
          </simplelist>
 
197
        </listitem>
 
198
      </itemizedlist>
 
199
 
 
200
      <programlisting>
 
201
static GnomeUIInfo file_menu_items[] = {
 
202
  { GNOME_APP_UI_ITEM, "_Open", "Open a file",
 
203
    open_callback, NULL, NULL, GNOME_APP_PIXMAP_STOCK, GTK_STOCK_OPEN,
 
204
    'o', GDK_CONTROL_MASK, NULL },
 
205
  { GNOME_APP_UI_SEPARATOR },
 
206
  { GNOME_APP_UI_ITEM, "E_xit", "Exit the program",
 
207
    exit_callback, NULL, NULL, GNOME_APP_PIXMAP_STOCK, GTK_STOCK_QUIT,
 
208
    'q', GDK_CONTROL_MASK, NULL},
 
209
  { GNOME_APP_UI_ENDOFINFO }
 
210
};
 
211
 
 
212
static GnomeUIInfo view_radio_items[] = {
 
213
  { GNOME_APP_UI_ITEM, "_High Quality", "Display images in high quality, slow mode",
 
214
    high_quality_callback, NULL, NULL, GNOME_APP_PIXMAP_FILENAME, "high-quality.png",
 
215
    0, 0, NULL },
 
216
  { GNOME_APP_UI_ITEM, "_Normal Quality", "Display images in normal quality",
 
217
    normal_quality_callback, NULL, NULL, GNOME_APP_PIXMAP_FILENAME, "normal-quality.png",
 
218
    0, 0, NULL },
 
219
  { GNOME_APP_UI_ITEM, "_Low Quality", "Display images in low quality, fast mode",
 
220
    low_quality_callback, NULL, NULL, GNOME_APP_PIXMAP_FILENAME, "low-quality.png",
 
221
    0, 0, NULL },
 
222
  { GNOME_APP_UI_ENDOFINFO }
 
223
};
 
224
 
 
225
static GnomeUIInfo view_menu_items[] = {
 
226
  { GNOME_APP_UI_ITEM, "Zoom _In", "Zoom into the image",
 
227
    zoom_in_callback, NULL, NULL, GNOME_APP_PIXMAP_STOCK, GTK_STOCK_ZOOM_IN,
 
228
    GDK_PLUS, 0, NULL },
 
229
  { GNOME_APP_UI_ITEM, "Zoom _Out", "Zoom away from the image",
 
230
    zoom_out_callback, NULL, NULL, GNOME_APP_PIXMAP_STOCK, GTK_STOCK_ZOOM_OUT,
 
231
    GDK_MINUS, 0, NULL },
 
232
  { GNOME_APP_UI_SEPARATOR },
 
233
  { GNOME_APP_UI_TOGGLEITEM, "_Full Screen", "Switch between full screen and windowed mode",
 
234
    full_screen_callback, NULL, NULL, GNOME_APP_PIXMAP_NONE, NULL,
 
235
    GDK_F11, 0, NULL },
 
236
  { GNOME_APP_UI_SEPARATOR },
 
237
  { GNOME_APP_UI_RADIOITEMS, NULL, NULL, view_radio_items },
 
238
  { GNOME_APP_UI_ENDOFINFO }
 
239
};
 
240
 
 
241
static GnomeUIInfo menubar[] = {
 
242
  { GNOME_APP_UI_SUBTREE, "_File", NULL, file_menu_items },
 
243
  { GNOME_APP_UI_SUBTREE, "_View", NULL, view_menu_items },
 
244
  { GNOME_APP_UI_ENDOFINFO }
 
245
}
 
246
      </programlisting>
 
247
    </example>
 
248
 
 
249
    <example id="gnomeuiinfo-action-entries">
 
250
      <title><structname>GtkActionEntry</structname> Structures</title>
 
251
 
 
252
      <para>
 
253
        The following code is the set of actions that are present in
 
254
        the <link linkend="gnomeuiinfo-example">previous
 
255
        example</link>.  Note that the toggle and radio entries are
 
256
        separate from normal actions.  Also, note that #GtkActionEntry 
 
257
        structures take key names in the format of gdk_accelerator_parse() 
 
258
        rather than key values plus modifiers; you will have to convert these
 
259
        values by hand.  For example, %GDK_F11 with no modifiers is equivalent 
 
260
        to a key name of <literal>"F11"</literal>.  Likewise, <literal>"o"</literal>
 
261
        with %GDK_CONTROL_MASK is equivalent to <literal>"&lt;ontrol&gt;O"</literal>.
 
262
      </para>
 
263
 
 
264
      <programlisting>
 
265
/* Normal items */
 
266
static const GtkActionEntry entries[] = {
 
267
  { "FileMenu", NULL, "_File" },
 
268
  { "ViewMenu", NULL, "_View" },
 
269
  { "Open", GTK_STOCK_OPEN, "_Open", "&lt;control&gt;O", "Open a file", open_action_callback },
 
270
  { "Exit", GTK_STOCK_QUIT, "E_xit", "&lt;control&gt;Q", "Exit the program", exit_action_callback },
 
271
  { "ZoomIn", GTK_STOCK_ZOOM_IN, "Zoom _In", "plus", "Zoom into the image", zoom_in_action_callback },
 
272
  { "ZoomOut", GTK_STOCK_ZOOM_OUT, "Zoom _Out", "minus", "Zoom away from the image", zoom_out_action_callback },
 
273
};
 
274
 
 
275
/* Toggle items */
 
276
static const GtkToggleActionEntry toggle_entries[] = {
 
277
  { "FullScreen", NULL, "_Full Screen", "F11", "Switch between full screen and windowed mode", full_screen_action_callback, FALSE }
 
278
};
 
279
 
 
280
/* Radio items */
 
281
static const GtkRadioActionEntry radio_entries[] = {
 
282
  { "HighQuality", "my-stock-high-quality", "_High Quality", NULL, "Display images in high quality, slow mode", 0 },
 
283
  { "NormalQuality", "my-stock-normal-quality", "_Normal Quality", NULL, "Display images in normal quality", 1 },
 
284
  { "LowQuality", "my-stock-low-quality", "_Low Quality", NULL, "Display images in low quality, fast mode", 2 }
 
285
};
 
286
      </programlisting>
 
287
    </example>
 
288
 
 
289
    <example id="gnomeuiinfo-xml">
 
290
      <title>XML Description</title>
 
291
 
 
292
      <para>
 
293
        After extracting the actions, you will need to create an XML
 
294
        description of the actual layout of your menus and toolbars
 
295
        for use with #GtkUIManager. The following code shows a simple 
 
296
        menu bar that corresponds to the <link linkend="gnomeuiinfo-example">previous
 
297
        example</link>.  Note that the <guimenu>File</guimenu> and
 
298
        <guimenu>View</guimenu> menus have their names specified in
 
299
        the <link linkend="gnomeuiinfo-action-entries">action
 
300
        entries</link>, not in the XML itself.  This is because the
 
301
        XML description only contains <emphasis>identifiers</emphasis>
 
302
        for the items in the GUI, rather than human-readable names.
 
303
      </para>
 
304
 
 
305
      <programlisting>
 
306
static const char *ui_description =
 
307
"&lt;ui&gt;"
 
308
"  &lt;menubar name='MainMenu'&gt;"
 
309
"    &lt;menu action='FileMenu'&gt;"
 
310
"      &lt;menuitem action='Open'/&gt;"
 
311
"      &lt;menuitem action='Exit'/&gt;"
 
312
"    &lt;/menu&gt;"
 
313
"    &lt;menu action='ViewMenu'&gt;"
 
314
"      &lt;menuitem action='ZoomIn'/&gt;"
 
315
"      &lt;menuitem action='ZoomOut'/&gt;"
 
316
"      &lt;separator/&gt;"
 
317
"      &lt;menuitem action='FullScreen'/&gt;"
 
318
"      &lt;separator/&gt;"
 
319
"      &lt;menuitem action='HighQuality'/&gt;"
 
320
"      &lt;menuitem action='NormalQuality'/&gt;"
 
321
"      &lt;menuitem action='LowQuality'/&gt;"
 
322
"    &lt;/menu&gt;"
 
323
"  &lt;/menubar&gt;"
 
324
"&lt;/ui&gt;";
 
325
      </programlisting>
 
326
    </example>
 
327
 
 
328
    <example id="gnomeuiinfo-code">
 
329
      <title>Creating the Menu Bar</title>
 
330
 
 
331
      <para>
 
332
        In this last example, we will create a #GtkActionGroup based on the
 
333
        <link linkend="gnomeuiinfo-action-entries">action entries</link> 
 
334
        we created above.  We will then create a #GtkUIManager with the <link
 
335
        linkend="gnomeuiinfo-xml">XML description</link> of the menu
 
336
        layout.  We will also extract the accelerator group and the
 
337
        widgets from the #GtkUIManager put them into a window.
 
338
      </para>
 
339
 
 
340
      <programlisting>
 
341
GtkWidget *window;
 
342
GtkWidget *vbox;
 
343
GtkWidget *menubar;
 
344
GtkActionGroup *action_group;
 
345
GtkUIManager *ui_manager;
 
346
GtkAccelGroup *accel_group;
 
347
GError *error;
 
348
 
 
349
register_my_stock_icons (<!-- -->);
 
350
 
 
351
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
 
352
 
 
353
vbox = gtk_vbox_new (FALSE, 0);
 
354
gtk_container_add (GTK_CONTAINER (window), vbox);
 
355
 
 
356
action_group = gtk_action_group_new ("MenuActions");
 
357
gtk_action_group_add_actions (action_group, entries, G_N_ELEMENTS (entries), window);
 
358
gtk_action_group_add_toggle_actions (action_group, toggle_entries, G_N_ELEMENTS (toggle_entries), window);
 
359
gtk_action_group_add_radio_actions (action_group, radio_entries, G_N_ELEMENTS (radio_entries), 0, radio_action_callback, window);
 
360
 
 
361
ui_manager = gtk_ui_manager_new (<!-- -->);
 
362
gtk_ui_manager_insert_action_group (ui_manager, action_group, 0);
 
363
 
 
364
accel_group = gtk_ui_manager_get_accel_group (ui_manager);
 
365
gtk_window_add_accel_group (GTK_WINDOW (window), accel_group);
 
366
 
 
367
error = NULL;
 
368
if (!gtk_ui_manager_add_ui_from_string (ui_manager, ui_description, -1, &amp;error))
 
369
  {
 
370
    g_message ("building menus failed: %s", error-&gt;message);
 
371
    g_error_free (error);
 
372
    exit (EXIT_FAILURE);
 
373
  }
 
374
 
 
375
menubar = gtk_ui_manager_get_widget (ui_manager, "/MainMenu");
 
376
gtk_box_pack_start (GTK_BOX (vbox), menubar, FALSE, FALSE, 0);
 
377
 
 
378
gtk_widget_show_all (window);
 
379
      </programlisting>
 
380
    </example>
 
381
 
 
382
    <example id="gnomeuiinfo-icons">
 
383
      <title>Registering the icons</title>
 
384
 
 
385
      <para>
 
386
        Here we show how the register_my_stock_icons() function
 
387
        used in the previous example could look like.
 
388
      </para>
 
389
 
 
390
      <programlisting>
 
391
static struct { 
 
392
  gchar *filename;
 
393
  gchar *stock_id;
 
394
} stock_icons[] = {
 
395
  { "high-quality.png", "my-stock-high-quality" },
 
396
  { "normal-quality.png", "my-stock-normal-quality" },
 
397
  { "low-quality.png", "my-stock-low-quality" },
 
398
};
 
399
 
 
400
static gint n_stock_icons = G_N_ELEMENTS (stock_icons);
 
401
 
 
402
static void
 
403
register_my_stock_icons (void)
 
404
{
 
405
   GtkIconFactory *icon_factory;
 
406
   GtkIconSet *icon_set; 
 
407
   GtkIconSource *icon_source;
 
408
   gint i;
 
409
 
 
410
   icon_factory = gtk_icon_factory_new (<!-- -->);
 
411
   
 
412
   for (i = 0; i &lt; n_stock_icons; i++) 
 
413
    {
 
414
      icon_set = gtk_icon_set_new (<!-- -->);
 
415
      icon_source = gtk_icon_source_new (<!-- -->);
 
416
      gtk_icon_source_set_filename (icon_source, stock_icons[i].filename);
 
417
      gtk_icon_set_add_source (icon_set, icon_source);
 
418
      gtk_icon_source_free (icon_source);
 
419
      gtk_icon_factory_add (icon_factory, stock_icons[i].stock_id, icon_set);
 
420
      gtk_icon_set_unref (icon_set);
 
421
    }
 
422
 
 
423
   gtk_icon_factory_add_default (icon_factory); 
 
424
 
 
425
   g_object_unref (icon_factory);
 
426
}
 
427
      </programlisting>
 
428
    </example>
 
429
 
 
430
  </section>
 
431
 
 
432
</chapter>
 
433
 
 
434
<!--
 
435
Local variables:
 
436
mode: sgml
 
437
sgml-parent-document: ("gtk-docs.sgml" "book" "part" "chapter")
 
438
End:
 
439
-->