Drop no-longer-used migration docs

This commit is contained in:
Matthias Clasen 2011-01-02 23:57:03 -05:00
parent cf752786f3
commit 83f5e4868c
14 changed files with 0 additions and 2105 deletions

View File

@ -1,64 +0,0 @@
<?xml version="1.0"?>
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
"http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" [
]>
<chapter id="gtk-migrating-ClientSideWindows">
<title>Migrating to client-side windows</title>
<para>
In version 2.18, GDK has been changed to use client-side windows. This
means that there is no longer a 1-1 correspondence between #GdkWindows
and windows in the underlying window system. In particular, it is no
longer correct to assume that each window has an associated XID.
Code that makes this assumption can sometimes be fixed by calling
gdk_window_ensure_native() on the windows in question.
Calling gdk_x11_window_get_xid() (or GDK_WINDOW_XID()) from the
X11-specific API on a non-native window will explicitly call
gdk_window_ensure_native(), so old code using this will continue to
work. A small gotcha is that the GDK_WINDOW_XID() call is no longer a
trivial accessor for the XID of the window, and thus must not be called
from another thread without taking locking precautions.
</para>
<para>
GDK looks for the <envar>GDK_NATIVE_WINDOWS</envar> environment variable
and makes all windows native if it is set. It also tries to be more
compatible with the way prior versions worked in some other ways.
</para>
<para>
Some applications assume that they can just operate on the X windows
corresponding to their GDK windows without ever telling GDK. One
example that we've seen is changing the child window stacking order
using XRestackWindows(). Fixing this properly requires to fix the code
to use GDK functions to achieve whatever it is trying to achieve.
To make this easier in the case of stacking order changes, we've added
a gdk_window_restack() function.
</para>
<para>
One change that can cause problems for some applications is that GDK
is more aggressive about optimizing away expose events. Code that does
more than just repainting exposed areas in response to expose events
may be affected by this.
</para>
<para>
Problems can also occur when using cairo for drawing. One thing that can
go wrong is clip handling. You may not use cairo_reset_clip() on a
cairo_t on a cairo context created via gdk_cairo_create() or passed to
the GtkWidget::draw signal.
</para>
<para>
Due to a weird API in XClearArea the gdk_window_clear_area() call handled
a specified width or height of zero to mean "to end of window" for
non-double-buffered drawing. This has been changed to be consistent with
the docs and what happens in the double-buffered case. All code in GTK+
that relied on this has been fixed, but it is possible (although unlikely)
that third party applications rely on this. If you need to do this, just
implement it yourself using gdk_drawable_get_size().
</para>
</chapter>

View File

@ -1,98 +0,0 @@
<?xml version="1.0"?>
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
"http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" [
]>
<chapter id="gtk-migrating-GtkAboutDialog">
<title>Migrating from GnomeAbout to GtkAboutDialog</title>
<para>
Since version 2.6, GTK+ provides the #GtkAboutDialog widget as a
replacement for the <structname>GnomeAbout</structname> dialog in
the libgnomeui library.
</para>
<para>
#GtkAboutDialog supports all features found in <structname>GnomeAbout</structname>.
The <structname>GtkAboutDialog</structname> API is bigger, since it follows
the GTK+ policy to have getters and setters for all widget properties,
but it isn't much more complex than <structname>GnomeAbout</structname>.
</para>
<para>
To convert an application that uses <structname>GnomeAbout</structname> to
<structname>GtkAboutDialog</structname>, as a first step, replace calls
like
<informalexample><programlisting>
const gchar *documentors[] = {
"Documenter 1",
"Documenter 2",
NULL
};
const gchar *documentors[] = {
"Author 1",
"Author 2",
NULL
};
GtkWidget *about = gnome_about_new ("GNOME Test Program", VERSION,
"(C) 1998-2001 The Free Software Foundation",
"Program to display GNOME functions.",
authors,
documenters,
_("translator-credits"),
"logo.png");
</programlisting></informalexample>
by something like
<informalexample><programlisting>
GdkPixbuf *logo = gdk_pixbuf_new_from_file ("logo.png", NULL);
GtkWidget *about = g_object_new (GTK_TYPE_ABOUT_DIALOG,
"name", "GNOME Test Program",
"version", VERSION,
"copyright", "(C) 1998-2001 The Free Software Foundation",
"comments", "Program to display GNOME functions.",
"authors", authors,
"documenters", documenters,
"translator-credits", _("translator-credits"),
"logo", logo,
NULL);
g_object_unref (pixbuf);
</programlisting></informalexample>
If the g_object_new() construction scares you, you can also use
gtk_about_dialog_new() to construct the dialog and then use the
setters for the individual properties.
</para>
<para>
Once you are done with the initial conversion, you may want to look into
using some of the features of <structname>GtkAboutDialog</structname>
which are not present in <structname>GnomeAbout</structname>.
<itemizedlist>
<listitem><para>
You can specify license information with the
#GtkAboutDialog:license property
</para></listitem>
<listitem><para>
You can add separate credits for artists with the
#GtkAboutDialog:artists property
</para></listitem>
<listitem><para>
You can add a pointer to the website of your application, using the
#GtkAboutDialog:website and #GtkAboutDialog:website-label properties.
</para></listitem>
<listitem><para>
If your credits contain email addresses or URLs, you can turn them
into clickable links using gtk_about_dialog_set_email_hook() and
gtk_about_dialog_set_url_hook().
</para></listitem>
</itemizedlist>
</para>
</chapter>
<!--
Local variables:
mode: sgml
sgml-parent-document: ("gtk-docs.sgml" "book" "part" "chapter")
End:
-->

View File

@ -1,445 +0,0 @@
<?xml version="1.0"?>
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
"http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" [
]>
<chapter id="gtk-migrating-GtkAction">
<chapterinfo>
<author>
<firstname>Federico</firstname>
<surname>Mena-Quintero</surname>
<affiliation>
<address>
<email>federico@ximian.com</email>
</address>
</affiliation>
</author>
</chapterinfo>
<title>Migrating from old menu and toolbar systems to GtkAction</title>
<para>
Prior to GTK+ 2.4, there were several APIs in use to create menus
and toolbars. GTK+ itself included #GtkItemFactory, which was
historically used in the GIMP; libgnomeui provided the gnome-ui
set of macros; libbonoboui provided a complex mechanism to do menu
merging across embedded components. GTK+ 2.4 includes a system
for creating menus and toolbars, with merging of items, based
around the #GtkAction mechanism.
</para>
<section id="actions-and-action-groups">
<title>Actions and Action Groups</title>
<para>
A #GtkAction represents an operation that the user can perform from
the menus and toolbars of an application. It is similar to "verbs"
in other menu systems. A #GtkAction has a name, which is its identifier,
and it can have several widgets that represent it in the user interface.
For example, an action for <symbol>EditCopy</symbol> can have a menu item
as well as a toolbar button associated to it. If there is nothing selected
in the document, the application can simply de-sensitize the
<symbol>EditCopy</symbol> action; this will cause both the menu
item and the toolbar button to be de-sensitized automatically.
Similarly, whenever the user selects the menu item or the
toolbar button associated to the <symbol>EditCopy</symbol>
action, the corresponding #GtkAction object will emit an
"activate" signal.
</para>
<para>
#GtkActionGroup is simply a group of #GtkAction objects. An
application may want to have several groups: one for global
actions such as "new document", "about", and "exit"; then one
group for each open document with actions specific to the
document, such as "cut", "copy", "paste", and "print".
</para>
<para>
Normal actions are simply commands, such as
<symbol>FileSave</symbol> or <symbol>EditCopy</symbol>.
Toggle actions can be active or inactive, such as
<symbol>FormatBold</symbol> or <symbol>ViewShowRulers</symbol>.
Radio actions define a set of items for which one and only one
can be active at a time, for example, {
<symbol>ViewHighQuality</symbol>,
<symbol>ViewNormalQuality</symbol>,
<symbol>ViewLowQuality</symbol> }.
</para>
</section>
<section id="ui-manager">
<title>User Interface Manager Object</title>
<para>
#GtkUIManager is an object that can construct menu and toolbar widgets
from an XML description. These widgets are in turn associated to
corresponding actions and action groups.
</para>
<para>
#GtkUIManager supports merging of menus and toolbars for applications
that have multiple components, each with separate sets of commands.
For example, a word processor that can embed images may want to have
toolbar buttons for Bold and Italic when the cursor is on a text
block, but Crop and Brightness/Contrast buttons when the cursor
is on an image. These actions, which change depending on the
state of the application, can be merged and de-merged from a
#GtkUIManager as appropriate.
</para>
</section>
<section id="migrating-gnomeuiinfo">
<title>Migrating from GnomeUIInfo</title>
<para>
Prior to GTK+ 2.4, some applications used the GnomeUIInfo
mechanism from
<filename>&lt;libgnomeui/gnome-app-helper.h&gt;</filename> to
define their menus and toolbars. With it, a program decleres an
array of <structname>GnomeUIInfo</structname> structures, which
contain information for menu or toolbar items such as their
label, icon, and accelerator key. Then, one calls
gnome_app_fill_menu() or gnome_app_fill_toolbar(), or one of the
related functions, to create the appropriate widgets based on
these structures.
</para>
<para>
A downside of this API is that the same structures are used to
pass back pointers to the widgets that got created. This means
that the structures cannot simply be kept around if the program
requires multiple instances of the user interface (e.g. several
windows); each new invocation of gnome_app_fill_menu() would
overwrite the widget fields of the structures.
</para>
<para>
Another disadvantage is that there is no automatic way to
synchronize the state of related controls. If there are toolbar
toogle buttons for "Bold", "Italic", "Underline", and also
corresponding menu items under "Format/Bold", etc., one has to
synchronize their toggled states by hand whenever the user
selects any one of them.
</para>
<para>
Finally, there is no way to do menu and toolbar merging for
applications that require embedded components.
</para>
<para>
To convert an application that uses GnomeUIInfo into the new
GtkAction mechanism, you need to do several things:
</para>
<orderedlist>
<listitem>
<para>
Separate your existing GnomeUIInfo entries into normal
actions, toggle actions, and radio actions, and then create
a separate array of #GtkActionEntry structures
for each group. This will allow you to create the necessary
#GtkActionGroup objects. Note that this does not describe
the actual "shape" that your menus and toolbars will have;
it simply defines the set of commands that will appear in them.
</para>
</listitem>
<listitem>
<para>
Create an XML description of your menus and toolbars for use
with #GtkUIManager. This defines the actual shape of the menus
and toolbars.
</para>
</listitem>
<listitem>
<para>
Port the code that uses gnome-app and gnome-app-helper to
#GtkAction and #GtkUIManager.
</para>
</listitem>
<listitem>
<para>
If your GnomeUIInfo entries use GNOME_APP_PIXMAP_DATA or
GNOME_APP_PIXMAP_FILENAME for pixmaps, you have to create a
#GtkIconFactory, add it to the list of default factories, then
create a #GtkIconSet for each of your own icons. Add the sets to
the factory, and use the id in the #GtkActionEntry like a regular
GTK+ stock id.
</para>
</listitem>
</orderedlist>
<example id="gnomeuiinfo-example">
<title>GnomeUIInfo Example</title>
<para>
The following code shows a declaration of a simple menu bar to
be used with gnome_app_fill_menu() or similar. The menu hierarchy i
looks like this:
</para>
<itemizedlist>
<listitem>
<para><guimenu>File</guimenu></para>
<simplelist>
<member><guimenuitem>Open</guimenuitem></member>
<member><guimenuitem>&mdash;</guimenuitem></member>
<member><guimenuitem>Exit</guimenuitem></member>
</simplelist>
</listitem>
<listitem>
<para><guimenu>View</guimenu></para>
<simplelist>
<member><guimenuitem>Zoom In</guimenuitem></member>
<member><guimenuitem>Zoom Out</guimenuitem></member>
<member><guimenuitem>&mdash;</guimenuitem></member>
<member><guimenuitem>[ ] Full Screen</guimenuitem></member>
<member><guimenuitem>&mdash;</guimenuitem></member>
<member><guimenuitem>( ) High Quality</guimenuitem></member>
<member><guimenuitem>( ) Normal Quality</guimenuitem></member>
<member><guimenuitem>( ) Low Quality</guimenuitem></member>
</simplelist>
</listitem>
</itemizedlist>
<programlisting>
static GnomeUIInfo file_menu_items[] = {
{ GNOME_APP_UI_ITEM, "_Open", "Open a file",
open_callback, NULL, NULL, GNOME_APP_PIXMAP_STOCK, GTK_STOCK_OPEN,
'o', GDK_CONTROL_MASK, NULL },
{ GNOME_APP_UI_SEPARATOR },
{ GNOME_APP_UI_ITEM, "E_xit", "Exit the program",
exit_callback, NULL, NULL, GNOME_APP_PIXMAP_STOCK, GTK_STOCK_QUIT,
'q', GDK_CONTROL_MASK, NULL},
{ GNOME_APP_UI_ENDOFINFO }
};
static GnomeUIInfo view_radio_items[] = {
{ GNOME_APP_UI_ITEM, "_High Quality", "Display images in high quality, slow mode",
high_quality_callback, NULL, NULL, GNOME_APP_PIXMAP_FILENAME, "high-quality.png",
0, 0, NULL },
{ GNOME_APP_UI_ITEM, "_Normal Quality", "Display images in normal quality",
normal_quality_callback, NULL, NULL, GNOME_APP_PIXMAP_FILENAME, "normal-quality.png",
0, 0, NULL },
{ GNOME_APP_UI_ITEM, "_Low Quality", "Display images in low quality, fast mode",
low_quality_callback, NULL, NULL, GNOME_APP_PIXMAP_FILENAME, "low-quality.png",
0, 0, NULL },
{ GNOME_APP_UI_ENDOFINFO }
};
static GnomeUIInfo view_menu_items[] = {
{ GNOME_APP_UI_ITEM, "Zoom _In", "Zoom into the image",
zoom_in_callback, NULL, NULL, GNOME_APP_PIXMAP_STOCK, GTK_STOCK_ZOOM_IN,
GDK_PLUS, 0, NULL },
{ GNOME_APP_UI_ITEM, "Zoom _Out", "Zoom away from the image",
zoom_out_callback, NULL, NULL, GNOME_APP_PIXMAP_STOCK, GTK_STOCK_ZOOM_OUT,
GDK_MINUS, 0, NULL },
{ GNOME_APP_UI_SEPARATOR },
{ GNOME_APP_UI_TOGGLEITEM, "_Full Screen", "Switch between full screen and windowed mode",
full_screen_callback, NULL, NULL, GNOME_APP_PIXMAP_NONE, NULL,
GDK_F11, 0, NULL },
{ GNOME_APP_UI_SEPARATOR },
{ GNOME_APP_UI_RADIOITEMS, NULL, NULL, view_radio_items },
{ GNOME_APP_UI_ENDOFINFO }
};
static GnomeUIInfo menubar[] = {
{ GNOME_APP_UI_SUBTREE, "_File", NULL, file_menu_items },
{ GNOME_APP_UI_SUBTREE, "_View", NULL, view_menu_items },
{ GNOME_APP_UI_ENDOFINFO }
}
</programlisting>
</example>
<example id="gnomeuiinfo-action-entries">
<title><structname>GtkActionEntry</structname> Structures</title>
<para>
The following code is the set of actions that are present in
the <link linkend="gnomeuiinfo-example">previous
example</link>. Note that the toggle and radio entries are
separate from normal actions. Also, note that #GtkActionEntry
structures take key names in the format of gtk_accelerator_parse()
rather than key values plus modifiers; you will have to convert these
values by hand. For example, %GDK_F11 with no modifiers is equivalent
to a key name of <literal>"F11"</literal>. Likewise, <literal>"o"</literal>
with %GDK_CONTROL_MASK is equivalent to <literal>"&lt;ontrol&gt;O"</literal>.
</para>
<programlisting>
/* Normal items */
static const GtkActionEntry entries[] = {
{ "FileMenu", NULL, "_File" },
{ "ViewMenu", NULL, "_View" },
{ "Open", GTK_STOCK_OPEN, "_Open", "&lt;control&gt;O", "Open a file", open_action_callback },
{ "Exit", GTK_STOCK_QUIT, "E_xit", "&lt;control&gt;Q", "Exit the program", exit_action_callback },
{ "ZoomIn", GTK_STOCK_ZOOM_IN, "Zoom _In", "plus", "Zoom into the image", zoom_in_action_callback },
{ "ZoomOut", GTK_STOCK_ZOOM_OUT, "Zoom _Out", "minus", "Zoom away from the image", zoom_out_action_callback },
};
/* Toggle items */
static const GtkToggleActionEntry toggle_entries[] = {
{ "FullScreen", NULL, "_Full Screen", "F11", "Switch between full screen and windowed mode", full_screen_action_callback, FALSE }
};
/* Radio items */
static const GtkRadioActionEntry radio_entries[] = {
{ "HighQuality", "my-stock-high-quality", "_High Quality", NULL, "Display images in high quality, slow mode", 0 },
{ "NormalQuality", "my-stock-normal-quality", "_Normal Quality", NULL, "Display images in normal quality", 1 },
{ "LowQuality", "my-stock-low-quality", "_Low Quality", NULL, "Display images in low quality, fast mode", 2 }
};
</programlisting>
</example>
<example id="gnomeuiinfo-xml">
<title>XML Description</title>
<para>
After extracting the actions, you will need to create an XML
description of the actual layout of your menus and toolbars
for use with #GtkUIManager. The following code shows a simple
menu bar that corresponds to the <link linkend="gnomeuiinfo-example">previous
example</link>. Note that the <guimenu>File</guimenu> and
<guimenu>View</guimenu> menus have their names specified in
the <link linkend="gnomeuiinfo-action-entries">action
entries</link>, not in the XML itself. This is because the
XML description only contains <emphasis>identifiers</emphasis>
for the items in the GUI, rather than human-readable names.
</para>
<programlisting>
static const char *ui_description =
"&lt;ui&gt;"
" &lt;menubar name='MainMenu'&gt;"
" &lt;menu action='FileMenu'&gt;"
" &lt;menuitem action='Open'/&gt;"
" &lt;menuitem action='Exit'/&gt;"
" &lt;/menu&gt;"
" &lt;menu action='ViewMenu'&gt;"
" &lt;menuitem action='ZoomIn'/&gt;"
" &lt;menuitem action='ZoomOut'/&gt;"
" &lt;separator/&gt;"
" &lt;menuitem action='FullScreen'/&gt;"
" &lt;separator/&gt;"
" &lt;menuitem action='HighQuality'/&gt;"
" &lt;menuitem action='NormalQuality'/&gt;"
" &lt;menuitem action='LowQuality'/&gt;"
" &lt;/menu&gt;"
" &lt;/menubar&gt;"
"&lt;/ui&gt;";
</programlisting>
</example>
<example id="gnomeuiinfo-code">
<title>Creating the Menu Bar</title>
<para>
In this last example, we will create a #GtkActionGroup based on the
<link linkend="gnomeuiinfo-action-entries">action entries</link>
we created above. We will then create a #GtkUIManager with the <link
linkend="gnomeuiinfo-xml">XML description</link> of the menu
layout. We will also extract the accelerator group and the
widgets from the #GtkUIManager put them into a window.
</para>
<programlisting>
GtkWidget *window;
GtkWidget *vbox;
GtkWidget *menubar;
GtkActionGroup *action_group;
GtkUIManager *ui_manager;
GtkAccelGroup *accel_group;
GError *error;
register_my_stock_icons (<!-- -->);
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
vbox = gtk_vbox_new (FALSE, 0);
gtk_container_add (GTK_CONTAINER (window), vbox);
action_group = gtk_action_group_new ("MenuActions");
gtk_action_group_add_actions (action_group, entries, G_N_ELEMENTS (entries), window);
gtk_action_group_add_toggle_actions (action_group, toggle_entries, G_N_ELEMENTS (toggle_entries), window);
gtk_action_group_add_radio_actions (action_group, radio_entries, G_N_ELEMENTS (radio_entries), 0, radio_action_callback, window);
ui_manager = gtk_ui_manager_new (<!-- -->);
gtk_ui_manager_insert_action_group (ui_manager, action_group, 0);
accel_group = gtk_ui_manager_get_accel_group (ui_manager);
gtk_window_add_accel_group (GTK_WINDOW (window), accel_group);
error = NULL;
if (!gtk_ui_manager_add_ui_from_string (ui_manager, ui_description, -1, &amp;error))
{
g_message ("building menus failed: %s", error-&gt;message);
g_error_free (error);
exit (EXIT_FAILURE);
}
menubar = gtk_ui_manager_get_widget (ui_manager, "/MainMenu");
gtk_box_pack_start (GTK_BOX (vbox), menubar, FALSE, FALSE, 0);
gtk_widget_show_all (window);
</programlisting>
</example>
<example id="gnomeuiinfo-icons">
<title>Registering the icons</title>
<para>
Here we show how the register_my_stock_icons() function
used in the previous example could look like.
</para>
<programlisting>
static struct {
gchar *filename;
gchar *stock_id;
} stock_icons[] = {
{ "high-quality.png", "my-stock-high-quality" },
{ "normal-quality.png", "my-stock-normal-quality" },
{ "low-quality.png", "my-stock-low-quality" },
};
static gint n_stock_icons = G_N_ELEMENTS (stock_icons);
static void
register_my_stock_icons (void)
{
GtkIconFactory *icon_factory;
GtkIconSet *icon_set;
GtkIconSource *icon_source;
gint i;
icon_factory = gtk_icon_factory_new (<!-- -->);
for (i = 0; i &lt; n_stock_icons; i++)
{
icon_set = gtk_icon_set_new (<!-- -->);
icon_source = gtk_icon_source_new (<!-- -->);
gtk_icon_source_set_filename (icon_source, stock_icons[i].filename);
gtk_icon_set_add_source (icon_set, icon_source);
gtk_icon_source_free (icon_source);
gtk_icon_factory_add (icon_factory, stock_icons[i].stock_id, icon_set);
gtk_icon_set_unref (icon_set);
}
gtk_icon_factory_add_default (icon_factory);
g_object_unref (icon_factory);
}
</programlisting>
</example>
</section>
</chapter>
<!--
Local variables:
mode: sgml
sgml-parent-document: ("gtk-docs.sgml" "book" "part" "chapter")
End:
-->

View File

@ -1,178 +0,0 @@
<?xml version="1.0"?>
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
"http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" [
]>
<chapter id="gtk-migrating-GtkAssistant">
<chapterinfo>
<author>
<firstname>Carlos</firstname>
<surname>Garnacho</surname>
<affiliation>
<address>
<email>carlosg@gnome.org</email>
</address>
</affiliation>
</author>
</chapterinfo>
<title>Migrating from GnomeDruid to GtkAssistant</title>
<para>
Since version 2.10, GTK+ provides the GtkAssistant widget as a replacement
for the <structname>GnomeDruid</structname> widget in the libgnomeui
library.
</para>
<para>
Conceptually, both <structname>GtkAssistant</structname> and
<structname>GnomeDruid</structname> do the same task, but there are
several areas where the API has been completely redesigned, so this
chapter covers the main changes between both widgets.
</para>
<section id="inserting-pages">
<title>Inserting pages</title>
<para>
<structname>GnomeDruid</structname> was implemented as a container for
<structname>GnomeDruidPage</structname> abstract objects, which are
implemented by the <structname>GnomeDruidPageEdge</structname> and
<structname>GnomeDruidPageStandard</structname> widgets. Instead,
<structname>GtkAssistant</structname> allows any widget to be a page,
and implements per-page settings (such as page type or title) as
child properties. So instead of:
</para>
<programlisting>
/* Page 1 */
page = gnome_druid_page_edge_new (GNOME_EDGE_START);
gnome_druid_page_edge_set_test (GNOME_DRUID_PAGE_EDGE (page),
"Welcome to the assistant, it will make your life easier");
gtk_widget_show (page);
gnome_druid_append_page (GNOME_DRUID (druid), GNOME_DRUID_PAGE (page));
/* Page 2 */
page = gnome_druid_page_standard_new ();
gtk_container_add (GTK_CONTAINER (GNOME_DRUID_PAGE_STANDARD (page)->vbox,
create_page1 ());
gtk_widget_show_all (page);
gnome_druid_append_page (GNOME_DRUID (druid), GNOME_DRUID_PAGE (page));
/* Page 3 */
page = gnome_druid_page_edge_new (GNOME_EDGE_FINISH);
gnome_druid_page_edge_set_test (GNOME_DRUID_PAGE_EDGE (page),
"Now you are done, your life is easier");
gtk_widget_show (page);
gnome_druid_append_page (GNOME_DRUID (druid), GNOME_DRUID_PAGE (page));
</programlisting>
<para>
You have to write:
</para>
<programlisting>
gtk_assistant_append_page (GTK_ASSISTANT (assistant),
gtk_label_new ("Welcome to the assistant, it will make your life easier"));
gtk_assistant_append_page (GTK_ASSISTANT (assistant),
create_page1 ());
gtk_assistant_append_page (GTK_ASSISTANT (assistant),
gtk_label_new ("Now you are done, your life is easier");
</programlisting>
</section>
<section id="decorating-the-assistant-pages">
<title>Decorating the assistant pages</title>
<para>
To decorate your assistant pages, <structname>GtkAssistant</structname> provides similar functions
to <structname>GnomeDruid</structname>, so you have to transform code like this:
</para>
<programlisting>
gnome_druid_page_edge_set_title (GNOME_DRUID_PAGE_EDGE (page), "Welcome");
gnome_druid_page_edge_set_logo (GNOME_DRUID_PAGE_EDGE (page), logo_pixbuf);
gnome_druid_page_edge_set_watermark (GNOME_DRUID_PAGE_EDGE (page), watermark_pixbuf);
</programlisting>
<para>
Into this:
</para>
<programlisting>
gtk_assistant_set_page_title (GTK_ASSISTANT (assistant), page_widget, "Welcome");
gtk_assistant_set_page_header_image (GTK_ASSISTANT (assistant), page_widget, logo_pixbuf);
gtk_assistant_set_page_side_image (GTK_ASSISTANT (assistant), page_widget, watermark_pixbuf);
</programlisting>
<para>
Where page_widget is the widget used as a page.
</para>
</section>
<section id="setting-the-page-flow">
<title>Setting the page flow</title>
<para>
Here is the area where <structname>GtkAssistant</structname> and <structname>GnomeDruid</structname>
differ the most. While <structname>GnomeDruid</structname> used the "next" and "back" signals from the
<structname>GnomeDruidPage</structname>, <structname>GtkAssistant</structname> uses the following
techniques:
</para>
<itemizedlist>
<listitem>
<para>gtk_assistant_set_forward_page_func (): Allows to define a GtkAssistantPageFunc to let the
assistant know which will be the following page given the current page.</para>
</listitem>
<listitem>
<para>gtk_assistant_set_page_complete (): Lets the assistant know whether the specified page is complete
or not, updating buttons state accordingly.</para>
</listitem>
<listitem>
<para>gtk_assistant_set_page_type (): Lets the assistant know the page role and update the buttons
state accordingly. Pages can have the following roles:</para>
<simplelist>
<member>Intro</member>
<member>Content</member>
<member>Progress</member>
<member>Confirmation</member>
<member>Summary</member>
</simplelist>
</listitem>
</itemizedlist>
<para>
A sample GtkAssistantPageFunc could look like this:
</para>
<programlisting>
static gint
forward_page_function (gint current_page,
gpointer data)
{
switch (current_page)
{
case 0:
return 1;
case 1:
if (check_page1_data ())
return 2;
else
return 3;
case 2:
return 3;
default:
return -1;
}
}
</programlisting>
</section>
</chapter>
<!--
Local variables:
mode: sgml
sgml-parent-document: ("gtk-docs.sgml" "book" "part" "chapter")
End:
-->

View File

@ -1,102 +0,0 @@
<?xml version="1.0"?>
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
"http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" [
]>
<chapter id="gtk-migrating-GtkBuilder">
<title>Migrating from libglade to GtkBuilder</title>
<para>
Since version 2.12, GTK+ provides #GtkBuilder to construct
user interfaces from XML descriptions, similar to the functionality
provided by #GladeXML in the libglade library.
</para>
<para>
A good way to start a migration from libglade to GtkBuilder is using
<application>glade3</application> to convert your .glade file.
If your code uses the @root parameter of glade_xml_new(),
you can use gtk_builder_add_objects_from_file() to construct only certain
objects from a GtkBuilder file.
</para>
<para>
Alternatively, GTK+ also offers the
<link linkend="gtk-builder-convert">gtk-builder-convert</link> script you can use
to do the conversion; in which case you should be careful to inspect the output
and make sure you didn't lose any data.
</para>
<table pgwide="1" frame="topbot">
<title>Step-by-step instructions for porting code from libglade to GtkBuilder</title>
<tgroup cols="2" colsep="0" rowsep="0">
<thead>
<row><entry>libglade</entry><entry>GtkBuilder</entry></row>
</thead>
<tbody>
<row>
<entry><![CDATA[#include <glade/glade.h>]]></entry>
<entry>not needed</entry>
</row>
<row>
<entry><screen>GladeXML*</screen></entry>
<entry><screen>GtkBuilder*</screen></entry>
</row>
<row>
<entry><screen>glade_xml_new (FILE, "first_widget", NULL)</screen></entry>
<entry>
<screen>
GError* error = NULL;
GtkBuilder* builder = gtk_builder_new (<!-- -->);
if (!gtk_builder_add_from_file (builder, FILE, &amp;error))
{
g_warning ("Couldn't load builder file: &percnt;s", error->message);
g_error_free (error);
}
</screen>
</entry>
</row>
<row>
<entry><screen>glade_xml_get_widget (gxml, “widget_name”)</screen></entry>
<entry><screen>GTK_WIDGET (gtk_builder_get_object (builder, “widget_name”))</screen></entry>
</row>
<row>
<entry><screen>glade_get_widget_name (widget)</screen></entry>
<entry><screen>gtk_widget_get_name (widget)</screen></entry>
</row>
<row>
<entry><screen>glade_xml_get_widget_prefix (gxml, “prefix”)</screen></entry>
<entry>can be emulated by <literal>gtk_builder_get_objects (builder)</literal> together with manual filtering. It returns a GSList* instead of a GList* though.</entry>
</row>
</tbody>
</tgroup>
</table>
<para>
While GtkBuilder strives to be a complete replacement for
libglade, there are a number of areas where it is currently
still behind libglade:
<itemizedlist>
<listitem><para>
GtkBuilder supports context information in translatable
properties in a slightly different way than libglade.
Intltool does not yet support this; see
<ulink url="http://bugzilla.gnome.org/show_bug.cgi?id=454894">bug
454894</ulink> for the current status of intltool support for
GtkBuilder files. Thankfully, context in translations is a
rarely used feature, and if you are not using it, intltools
glade format support works just fine for GtkBuilder files.
</para></listitem>
<listitem><para>
While libglade can often tolerate multiple widgets having the
same id in a glade file, GtkBuilder will not accept duplicate
object ids. Both <application>gtk-builder-convert</application>
and the GtkBuilder parser emit warnings when they see
duplicate ids.
</para></listitem>
</itemizedlist>
</para>
</chapter>

View File

@ -1,54 +0,0 @@
<?xml version="1.0"?>
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
"http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" [
]>
<chapter id="gtk-migrating-GtkColorButton">
<title>Migrating from GnomeColorPicker to GtkColorButton</title>
<para>
Since version 2.6, GTK+ provides the #GtkColorButton
widget as a replacement for the <structname>GnomeColorPicker</structname>
widget in the libgnomeui library.
</para>
<para>
Porting an application from <structname>GnomeColorPicker</structname> to
<structname>GtkColorButton</structname> is very simple.
<structname>GtkColorButton</structname> doesn't support dithering
(since it is rarely needed on modern hardware), and it doesn't have
setters and getters to set the color from floating point or integer
components. So instead of
<informalexample><programlisting>
guint red, green, blue, alpha;
/* ... */
gnome_color_picker_set_i8 (color_picker, red, green, blue, alpha);
</programlisting></informalexample>
you have to write
<informalexample><programlisting>
GdkColor color;
color.red = red &lt;&lt; 8;
color.green = green &lt;&lt; 8;
color.blue = blue &lt;&lt; 8;
gtk_color_button_set_color (color_picker, &amp;color);
gtk_color_button_set_alpha (color_picker, alpha &lt;&lt; 8);
</programlisting></informalexample>
and similarly for the setters taking other number formats. For
<function>gnome_color_picker_set_i16()</function> no conversion is needed,
for <function>gnome_color_picker_set_d()</function>, you need to convert
the color components like this:
<informalexample><programlisting>
color.red = (guint16) (red * 65535.0 + 0.5);
color.green = (guint16) (green * 65535.0 + 0.5);
color.blue = (guint16) (blue * 65535.0 + 0.5);
</programlisting></informalexample>
</para>
</chapter>
<!--
Local variables:
mode: sgml
sgml-parent-document: ("gtk-docs.sgml" "book" "part" "chapter")
End:
-->

View File

@ -1,213 +0,0 @@
<?xml version="1.0"?>
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
"http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" [
]>
<chapter id="gtk-migrating-GtkComboBox">
<title>Migrating from GtkOptionMenu and GtkCombo to GtkComboBox and
GtkComboBoxEntry</title>
<para>
Prior to 2.4, GTK+ offered two widgets for the task of selecting one
item from a list of options. #GtkOptionMenu presents the list of
options as a menu while #GtkCombo presents them in a Windows-style list
popup. The only difference between the two is that a #GtkCombo allows to
manually edit the selected value, while the #GtkOptionMenu does not.
</para>
<para>
In GTK+ 2.4, a unified API for list selection was introduced, with
#GtkComboBox for the non-editable case and #GtkComboBoxEntry for the
editable case.
The selection of the display style &mdash; menu or list &mdash;
is no longer done at the API level, but has been made themeable via
the style property #GtkComboBox:appears-as-list.
</para>
<section id="migrating-GtkOptionMenu">
<title>Migrating from GtkOptionMenu to GtkComboBox</title>
<para>
Here is an example of a simple, but typical use of
#GtkOptionMenu<!---->:
<informalexample><programlisting>
GtkWidget *option_menu, *menu, *menu_item;
option_menu = gtk_option_menu_new (<!-- -->);
menu = gtk_menu_new (<!-- -->);
menu_item = gtk_menu_item_new_with_label ("First Item");
gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item);
gtk_widget_show (menu_item);
menu_item = gtk_menu_item_new_with_label ("Second Item");
gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item);
gtk_widget_show (menu_item);
menu_item = gtk_menu_item_new_with_label ("Third Item");
gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item);
gtk_widget_show (menu_item);
gtk_option_menu_set_menu (GTK_OPTION_MENU (option_menu), menu);
</programlisting></informalexample>
In order to react to the user's selection, connect to the #GtkOptionMenu::changed
signal on the option menu and use gtk_option_menu_get_history()
to retrieve the index of the selected item.
</para>
<para>
And here is how it would be done with a #GtkComboBox<!---->:
<informalexample><programlisting>
GtkWidget *combo_box;
combo_box = gtk_combo_box_new_text (<!-- -->);
gtk_combo_box_append_text (GTK_COMBO_BOX (combo_box), "First Item");
gtk_combo_box_append_text (GTK_COMBO_BOX (combo_box), "Second Item");
gtk_combo_box_append_text (GTK_COMBO_BOX (combo_box), "Third Item");
</programlisting></informalexample>
In order to react to the user's selection, connect to the
#GtkComboBox::changed signal and use gtk_combo_box_get_active()
to retrieve the index of the selected item.
</para>
<para>
A slightly more complex example involving images:
<informalexample><programlisting>
GtkWidget *option_menu, *menu, *menu_item;
option_menu = gtk_option_menu_new (<!-- -->);
menu = gtk_menu_new (<!-- -->);
menu_item = gtk_image_menu_item_new_with_label ("First Item");
gtk_image_menu_item_set_image (gtk_image_new_from_pixbuf (pixbuf1));
gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item);
gtk_widget_show (menu_item);
menu_item = gtk_image_menu_item_new_with_label ("Second Item");
gtk_image_menu_item_set_image (gtk_image_new_from_pixbuf (pixbuf2));
gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item);
gtk_widget_show (menu_item);
menu_item = gtk_image_menu_item_new_with_label ("Third Item");
gtk_image_menu_item_set_image (gtk_image_new_from_pixbuf (pixbuf3));
gtk_menu_shell_append (GTK_MENU_SHELL (menu), menu_item);
gtk_widget_show (menu_item);
gtk_option_menu_set_menu (GTK_OPTION_MENU (option_menu), menu);
</programlisting></informalexample>
</para>
<para>
can be done using a #GtkComboBox as follows:
<informalexample><programlisting>
GtkListStore *store;
GtkTreeIter iter;
GtkCellRenderer *renderer;
GtkWidget *combo_box;
store = gtk_list_store_new (2, GDK_TYPE_PIXBUF, G_TYPE_STRING);
gtk_list_store_append (store, &amp;iter);
gtk_list_store_set (store, &amp;iter, 0, pixbuf1, 1, "First Item", -1);
gtk_list_store_append (store, &amp;iter);
gtk_list_store_set (store, &amp;iter, 0, pixbuf2, 1, "Second Item", -1);
gtk_list_store_append (store, &amp;iter);
gtk_list_store_set (store, &amp;iter, 0, pixbuf3, 1, "Third Item", -1);
combo_box = gtk_combo_box_new_with_model (GTK_TREE_MODEL (store));
renderer = gtk_cell_renderer_pixbuf_new (<!-- -->);
gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo_box), renderer, FALSE);
gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (combo_box), renderer,
"pixbuf", 0,
NULL);
renderer = gtk_cell_renderer_text_new (<!-- -->);
gtk_cell_layout_pack_start (GTK_CELL_LAYOUT (combo_box), renderer, TRUE);
gtk_cell_layout_set_attributes (GTK_CELL_LAYOUT (combo_box), renderer,
"text", 1,
NULL);
</programlisting></informalexample>
</para>
</section>
<section id="migrating-GtkCombo">
<title>Migrating from GtkCombo to GtkComboBoxEntry</title>
<para>
Here is an example of a simple, but typical use of a #GtkCombo<!---->:
<informalexample><programlisting>
GtkWidget *combo;
GList *items = NULL;
items = g_list_append (items, "First Item");
items = g_list_append (items, "Second Item");
items = g_list_append (items, "Third Item");
combo = gtk_combo_new (<!-- -->);
gtk_combo_set_popdown_strings (GTK_COMBO (combo), items);
</programlisting></informalexample>
In order to react to the user's selection, connect to the #GtkCombo::changed
signal on the combo and use
<literal>gtk_entry_get_text (GTK_ENTRY (combo->entry))</literal>
to retrieve the selected text.
</para>
<para>
And here is how it would be done using #GtkComboBoxEntry<!---->:
<informalexample><programlisting>
combo_box = gtk_combo_box_entry_new_text (<!-- -->);
gtk_combo_box_append_text (GTK_COMBO_BOX (combo_box), "First Item");
gtk_combo_box_append_text (GTK_COMBO_BOX (combo_box), "Second Item");
gtk_combo_box_append_text (GTK_COMBO_BOX (combo_box), "Third Item");
</programlisting></informalexample>
In order to react to the user's selection, connect to the #GtkComboBox::changed
signal on the combo and use
<literal>gtk_entry_get_text (GTK_ENTRY (GTK_BIN (combo_box)->child))</literal>
to retrieve the selected text.
</para>
</section>
<section id="new-features-GtkComboBox">
<title>New features</title>
<para>
The new widgets have more to offer than a mere combination of the
features of #GtkOptionMenu and #GtkCombo. Notable new features
include:
<variablelist>
<varlistentry>
<term>Grid mode</term>
<listitem><para>Sometimes it is preferable to display the available
options not in a linear list, but in a grid. A typical example
would be a "color combo" where the individual items are small
square color swatches. The new widgets support gridded display
with the functions
gtk_combo_box_set_wrap_width(),
gtk_combo_box_set_row_span_column() and
gtk_combo_box_set_column_span_column().
</para></listitem>
</varlistentry>
<varlistentry>
<term>Display of icons</term>
<listitem><para>An often-heard complaint about #GtkOptionMenu is that
the icons which appear in the image menu items in its menu are not
displayed in the button showing the selected item. This limitation
has been removed in #GtkComboBox; the selected item appears in the
same way as the options in the popup.
</para></listitem>
</varlistentry>
<varlistentry>
<term>Full tree model power</term>
<listitem><para>
Since the new widgets are built around the same models that are
used for #GtkTreeView, all of the powerful machinery of tree models
and cell renderers can be used.
</para></listitem>
</varlistentry>
</variablelist>
</para>
</section>
</chapter>
<!--
Local variables:
mode: sgml
sgml-parent-document: ("gtk-docs.sgml" "book" "part" "chapter")
End:
-->

View File

@ -1,141 +0,0 @@
<?xml version="1.0"?>
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
"http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" [
]>
<chapter id="gtk-migrating-entry-icons">
<title>Migrating from SexyIconEntry to GtkEntry</title>
<para>
GTK+ 2.16 supports showing icons inside a #GtkEntry, similar to
SexyIconEntry. Porting from SexyIconEntry to GtkEntry is relatively
straightforward. The main difference between the two APIs is that
SexyIconEntry uses #GtkImage widgets in a somewhat awkward way as
storage vehicles for icons, while GtkEntry allows to specify icons
via pixbufs, stock ids, icon names or #GIcons. So, if your code uses
e.g.:
<informalexample><programlisting>
image = gtk_image_new_from_stock (GTK_STOCK_NEW, GTK_ICON_SIZE_MENU);
sexy_icon_entry_set_icon (entry, SEXY_ICON_ENTRY_PRIMARY, image);
</programlisting></informalexample>
you can get rid of the @image, and directly write:
<informalexample><programlisting>
gtk_entry_set_icon_from_stock (entry, GTK_ENTRY_ICON_PRIMARY, GTK_STOCK_NEW);
</programlisting></informalexample>
</para>
<para>
The signals SexyIconEntry::icon-pressed and SexyIconEntry::icon-released
have been renamed to #GtkEntry::icon-press and #GtkEntry::icon-release
to avoid problems due to signal name clashes. Also, the signature of the
signals has changed from
<informalexample><programlisting>
void (*icon_pressed) (SexyIconEntry *entry,
SexyIconEntryPosition icon_pos,
int button)
</programlisting></informalexample>
to
<informalexample><programlisting>
void (*icon_press) (GtkEntry *entry,
GtkEntryIconPosition icon_pos,
GdkEventButton *event)
</programlisting></informalexample>
The new signature has the advantage that the signal handler can use
the timestamp of the event, e.g. for passing it to gtk_menu_popup().
When adapting an existing signal handler to the new signature, you
should note that the button number is easily available as @event->button,
as shown in the following example:
<informalexample><programlisting>
static void
icon_pressed_cb (SexyIconEntry *entry,
SexyIconEntryPosition position,
int button,
gpointer data)
{
GtkMenu *menu = data;
if (position == SEXY_ICON_ENTRY_PRIMARY)
gtk_menu_popup (GTK_MENU (menu), NULL, NULL, NULL, NULL,
button, GDK_CURRENT_TIME);
}
</programlisting></informalexample>
can be ported as:
<informalexample><programlisting>
static void
icon_press_cb (GtkEntry *entry,
GtkEntryIconPosition position,
GdkEventButton *event,
gpointer data)
{
GtkMenu *menu = data;
if (position == GTK_ENTRY_ICON_PRIMARY)
gtk_menu_popup (GTK_MENU (menu), NULL, NULL, NULL, NULL,
event->button, event->time);
}
</programlisting></informalexample>
</para>
<para>
Another difference is that SexyIconEntry offers manual control of
the icon prelighting, via sexy_icon_entry_set_icon_highlight().
#GtkEntry prelights automatically when appropriate, depending on
whether the icon is activatable and sensitive. You should make
sure that your icons are properly marked as activatable or nonactivatable
and sensitive or insensitive:
<itemizedlist>
<listitem><para>
Sensitive, but non-activatable icons are
good for purely informational purposes.
</para></listitem>
<listitem><para>
Icons should be marked as insensitive if the
function that they trigger is currently not available.
</para></listitem>
</itemizedlist>
</para>
<para>
GtkEntry has no direct equivalent of the special-purpose function
sexy_icon_entry_add_clear_button(). If you need this functionality,
the following code works:
<informalexample><programlisting>
static void
icon_pressed_cb (GtkEntry *entry,
gint position,
GdkEventButton *event,
gpointer data)
{
if (position == GTK_ENTRY_ICON_SECONDARY)
gtk_entry_set_text (entry, "");
}
static void
text_changed_cb (GtkEntry *entry,
GParamSpec *pspec,
GtkWidget *button)
{
gboolean has_text;
has_text = gtk_entry_get_text_length (entry) > 0;
gtk_entry_set_icon_sensitive (entry,
GTK_ENTRY_ICON_SECONDARY,
has_text);
}
/* ... */
/* Set up the clear icon */
gtk_entry_set_icon_from_stock (GTK_ENTRY (entry),
GTK_ENTRY_ICON_SECONDARY,
GTK_STOCK_CLEAR);
g_signal_connect (entry, "icon-press",
G_CALLBACK (icon_pressed_cb), NULL);
g_signal_connect (entry, "notify::text",
G_CALLBACK (text_changed_cb), find_button);
/* ... */
</programlisting></informalexample>
</para>
</chapter>

View File

@ -1,163 +0,0 @@
<?xml version="1.0"?>
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
"http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" [
]>
<chapter id="gtk-migrating-GtkFileChooser">
<chapterinfo>
<author>
<firstname>Federico</firstname>
<surname>Mena-Quintero</surname>
<affiliation>
<address>
<email>federico@ximian.com</email>
</address>
</affiliation>
</author>
</chapterinfo>
<title>Migrating from GtkFileSelection to GtkFileChooser</title>
<para>
#GtkFileChooser, starting with GTK+ 2.4, is the new set of APIs for file
selection widgets and dialogs. Previous versions of GTK+ used #GtkFileSelection,
which has numerous problems.
</para>
<para>
#GtkFileChooser is an abstract interface that can be implemented by widgets
that perform file selection tasks. Two widgets in GTK+ implement this
interface: #GtkFileChooserDialog and #GtkFileChooserWidget. Most applications
simply need to use #GtkFileChooserDialog, which is a dialog box that allows the
user to select existing files for opening them, or to pick new filenames for
saving documents. #GtkFileChooserWidget is for special applications that need to
embed a file selection widget inside a larger window. In the context of GTK+,
#GtkFileChooserDialog is simply a #GtkDialog box with a #GtkFileChooserWidget.
inside.
</para>
<section id="gtkfilechooser-creating">
<title>Creating a GtkFileChooserDialog</title>
<para>
To create a #GtkFileChooserDialog, you simply call gtk_file_chooser_dialog_new().
This function is similar to gtk_dialog_new() in that it takes parameters for the
title of the dialog box and its transient parent, as well as its
buttons. In addition, it takes in an argument that determines
whether the file chooser dialog will be used for opening
existing files or for saving to a possibly new file.
</para>
<para>
Please see <xref linkend="gtkfilechooser-typical-usage"/> for
how to create a simple file chooser dialog and extract the
selected filename from it.
</para>
</section>
<section id="gtkfilechooser-selection-modes">
<title>Selection Modes</title>
<para>
#GtkFileChooser can be used in two modes, to select a single file at a
time or to select a set of more than one file. To set this, use
gtk_file_chooser_set_select_multiple(). In single-selection
mode, you can use gtk_file_chooser_get_filename() to get a file
name from the local file system or gtk_file_chooser_get_uri() to
get a full-formed URI. In multiple-selection mode, you can use
gtk_file_chooser_get_filenames() to get a #GSList of filename strings, or
gtk_file_chooser_get_uris() to get a list of URI strings.
</para>
<para>
Also, you can configure #GtkFileChooser to select files
or folders. Consider a backup program that needs to let the
user select a folder that will be backed up along with its
subfolders. To configure whether #GtkFileChooser is used to select
files or folders, use gtk_file_chooser_set_action(). In
addition, this lets you configure whether the file chooser will
be used to select existing files or folders (e.g. for
"File/Open"), or to type in new filenames (for
"File/Save&nbsp;As...").
</para>
</section>
<section id="gtkfilechooser-installing-preview">
<title>Installing a Preview widget</title>
<para>
Many applications need to have a preview facility within their
file chooser dialogs. Previous to GTK+ 2.4, one needed to
access the #GtkFileSelection widget hierarchy directly to hook in
a preview widget. With #GtkFileChooser, there is a
dedicated API to do this.
</para>
<para>
Please see the <link linkend="gtkfilechooser-preview">section on
creating preview widgets</link> for more information.
</para>
</section>
<section id="gtkfilechooser-installing-extra-widgets">
<title>Installing Extra Widgets</title>
<para>
Some applications need to install extra widgets in a file
chooser. For example, an application may want to provide a
toggle button to give the user the option of opening a file
read-only.
</para>
<para>
Please see the <link linkend="gtkfilechooser-extra">section on
creating extra widgets</link> for more information.
</para>
</section>
<section id="gtkfilechooser-new-features">
<title>New features</title>
<para>
New features in #GtkFileChooser include the following:
</para>
<itemizedlist>
<listitem>
<para>
Ability to select URIs rather than just local files. You
must use a #GtkFileSystem implementation that supports this,
for example the gnome-vfs backend.
</para>
</listitem>
<listitem>
<para>
Present a list of application-specific shortcut folders.
For example, a paint program may want to add a shortcut for
its <filename>/usr/share/paint_program/Clipart</filename>
folder.
</para>
</listitem>
<listitem>
<para>
Define custom filters so that not all the files in a folder
are listed. For example, you could filter out backup files,
or show only image files.
</para>
</listitem>
</itemizedlist>
<para>
To see how to use these features, please consult the #GtkFileChooser
reference documentation.
</para>
</section>
</chapter>
<!--
Local variables:
mode: sgml
sgml-parent-document: ("gtk-docs.sgml" "book" "part" "chapter")
End:
-->

View File

@ -1,153 +0,0 @@
<?xml version="1.0"?>
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
"http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" [
]>
<chapter id="gtk-migrating-GtkIconView">
<title>Migrating from GnomeIconList to GtkIconView</title>
<para>
Since version 2.6, GTK+ provides the #GtkIconView widget. It is similar in
functionality to the <structname>GnomeIconList</structname> widget in the
libgnomeui library, both widgets provide a way to lay out named icons in
a grid. The distinctive feature of the GTK+ widget is that it follows the
model-view pattern, allowing it to share the actual data (i.e. the names
and images of the icons) with other views.
</para>
<para>
#GtkIconView currently doesn't support some features found in
<structname>GnomeIconList</structname>. Icons can not be positioned freely,
the spacing is not customizable, and it is not possible to edit the names of
icons.
</para>
<para>
To convert an application that uses <structname>GnomeIconList</structname>
to #GtkIconView, the first step is to organize your data in a #GtkTreeModel.
<structname>GnomeIconList</structname> lets you directly insert data with
gnome_icon_list_insert() and gnome_icon_list_insert_pixbuf() and their
append variants. So, if you previously had a function to fill your icon
list similar to this one:
<informalexample><programlisting>
void
fill_icon_list (GnomeIconList *icon_list)
{
gnome_icon_list_append (icon_list, "file1.png", "Icon 1");
gnome_icon_list_append (icon_list, "file2.png", "Icon 2");
/* more icons ... */
}
</programlisting></informalexample>
you will have to create a tree model, attach your icon view to it, and
fill the model:
<informalexample><programlisting>
enum {
PIXBUF_COLUMN,
TEXT_COLUMN,
/* you can have more columns here, e.g */
DATA_COLUMN
};
void
fill_model (GtkListStore *store)
{
GtkTreeIter iter;
GdkPixbuf *pixbuf;
gtk_list_store_append (store, &amp;iter);
pixbuf = gdk_pixbuf_new_from_file ("file1.png", NULL);
gtk_list_store_set (store, &amp;iter, PIXBUF_COLUMN, pixbuf, TEXT_COLUMN, "Icon 1", -1);
g_object_unref (pixbuf);
gtk_list_store_append (store, &amp;iter);
pixbuf = gdk_pixbuf_new_from_file ("file2.png", NULL);
gtk_list_store_set (store, &amp;iter, PIXBUF_COLUMN, pixbuf, TEXT_COLUMN, "Icon 2", -1);
g_object_unref (pixbuf);
/* more icons ... */
}
int
main (int argc, char *argv[])
{
GtkWidget *icon_view;
GtkListStore *store;
gtk_init (&amp;argc, &amp;argv);
/* do other initialization... */
/* construct the GtkIconView */
icon_view = gtk_icon_view_new (<!-- -->);
store = gtk_list_store_new (3, GDK_TYPE_PIXBUF, G_TYPE_STRING, G_TYPE_POINTER);
gtk_icon_view_set_pixbuf_column (GTK_ICON_VIEW (icon_view), PIXBUF_COLUMN);
gtk_icon_view_set_text_column (GTK_ICON_VIEW (icon_view), TEXT_COLUMN);
gtk_icon_view_set_model (GTK_ICON_VIEW (icon_view), GTK_TREE_MODEL (store));
fill_model (store);
/* ... */
}
</programlisting></informalexample>
This example uses a #GtkListStore as model, but part of the elegance of the
model-view pattern is that you can easily use another tree model implementation,
or even write your own custom tree model.
</para>
<para>
Your application may make use of extra data attached to the icons in the
<structname>GnomeIconList</structname> via gnome_icon_list_set_icon_data() and
gnome_icon_list_get_icon_data(). With #GtkIconView such data is most
conveniently stored in an extra column in the tree model, so you would
call a function like
<informalexample><programlisting>
void
set_icon_data (GtkIconView *icon_view,
gint idx,
gpointer data)
{
GtkTreeModel *model;
GtkTreeIter iter;
model = gtk_icon_view_get_model (icon_view);
if (gtk_tree_model_iter_nth_child (model, &amp;iter, NULL, idx))
gtk_list_store_set (GTK_LIST_STORE (model), &amp;iter,
DATA_COLUMN, data, -1);
}
</programlisting></informalexample>
assuming that your tree model has a <literal>DATA_COLUMN</literal> of type
%G_TYPE_POINTER.
</para>
<para>
There is a number of minor API differences between
<structname>GnomeIconList</structname> and
<structname>GtkIconView</structname>:
<itemizedlist>
<listitem><para>
<type>GnomeIconListMode</type> is replaced by the
<link linkend="GtkIconView--orientation">orientation</link>
property of <structname>GtkIconView</structname>
</para></listitem>
<listitem><para>
<structname>GtkIconView</structname> can not be frozen in the same
way as <structname>GnomeIconList</structname> can with
gnome_icon_list_freeze() and gnome_icon_list_thaw(). Instead you can
replace the whole model of a <structname>GtkIconView</structname>,
instead of doing many small changes to the existing model.
</para></listitem>
</itemizedlist>
</para>
</chapter>
<!--
Local variables:
mode: sgml
sgml-parent-document: ("gtk-docs.sgml" "book" "part" "chapter")
End:
-->

View File

@ -1,24 +0,0 @@
<?xml version="1.0"?>
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
"http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" [
]>
<chapter id="gtk-migrating-label-links">
<title>Migrating from SexyUrlLabel to GtkLabel</title>
<para>
GTK+ 2.18 supports showing links inside a #GtkLabel, similar to
SexyUrlLabel. Porting from SexyUrlLabel to GtkLabel is relatively
straightforward. GtkLabel accepts links in the markup using the
same HTML <tag>a</tag> notation that SexyUrlLabel uses. In addition
to the href attribute, GtkLabel accepts a title attribute that
is displayed as a tooltip on the link. Instead of
sexy_url_label_set_markup(), just call gtk_label_set_markup().
</para>
<para>
One difference between the two APIs is that the ::url-activated signal
from SexyUrlLabel has been replaced by the #GtkLabel::activate-link
signal. The need for connecting to this signal is greatly reduced,
since GtkLabel has a default handler that calls gtk_show_uri().
</para>
</chapter>

View File

@ -1,81 +0,0 @@
<?xml version="1.0"?>
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
"http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" [
]>
<chapter id="gtk-migrating-GtkLinkButton">
<title>Migrating from GnomeHRef to GtkLinkButton</title>
<para>
Since version 2.10, GTK+ provides the #GtkLinkButton widget as a
replacement for the <structname>GnomeHRef</structname> widget
in the libgnomeui library.
</para>
<para>
Porting an application from <structname>GnomeHRef</structname> to
#GtkLinkButton is very simple. #GtkLinkButton does not have a
default action for #GtkButton::clicked signal. So instead of simply
creating the widget
<informalexample><programlisting>
GtkWidget *button;
button = gnome_href_new (url, "");
</programlisting></informalexample>
you will have to handle the activation of the #GtkLinkButton, using
the ::clicked signal for instance
<informalexample><programlisting>
static void
link_button_clicked_cb (GtkWidget *widget,
gpointer data)
{
const gchar *link;
link = gtk_link_button_get_uri (GTK_LINK_BUTTON (widget));
open_browser_at_url (link);
}
/* ... */
GtkWidget *button;
button = gtk_link_button_new (url);
g_signal_connect (button, "clicked",
G_CALLBACK (link_button_clicked_cb), NULL);
</programlisting></informalexample>
If you have more than one #GtkLinkButton instead of connecting
a signal to each one, you can use a "hook function" which will be
called whenever a user activates a link button
<informalexample><programlisting>
static void
link_button_hook (GtkLinkButton *button,
const gchar *link,
gpointer user_data)
{
open_browser_at_url (link);
}
/* ... */
GtkWidget *button1 = gtk_link_button_new (uri1);
GtkWidget *button2 = gtk_link_button_new (uri2);
gtk_link_button_set_uri_hook (link_button_hook, NULL, NULL);
</programlisting></informalexample>
</para>
<para>
Starting with GTK+ 2.16, it is no longer necessary to set up a uri hook
manually, since GTK+ now defaults to calling gtk_show_uri() if no uri
hook has been set.
</para>
</chapter>
<!--
Local variables:
mode: sgml
sgml-parent-document: ("gtk-docs.sgml" "book" "part" "chapter")
End:
-->

View File

@ -1,323 +0,0 @@
<?xml version="1.0"?>
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
"http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" [
]>
<chapter id="gtk-migrating-GtkRecentChooser">
<chapterinfo>
<author>
<firstname>Emmanuele</firstname>
<lastname>Bassi</lastname>
<affiliation>
<address>
<email>ebassi@gmail.com</email>
</address>
</affiliation>
</author>
</chapterinfo>
<title>Migrating from EggRecent to GtkRecentChooser</title>
<para>
Since version 2.10, GTK+ provides a way of handling the recently used
documents. It is similar to the code that has lived inside the libegg
library and has been incorporated by many applications. The GTK+ version
aims to completely replace that code, and offers many distinctive features
that improve the registration and visualization of the recently used
documents, such as:
</para>
<para>
<itemizedlist>
<listitem><para>
Better performances while reading and writing the list of recently used
files
</para></listitem>
<listitem><para>
More meta-data available for each recent document, like the
applications that have registered a document inside the list, the last
time and the number of times the same application did register a
document inside the list, an optional user readable name and
description of the document
</para></listitem>
<listitem><para>
Improved the ability to sort and filter the documents, also using
custom sorting and filtering functions
</para></listitem>
<listitem><para>
New widgets for displaying the list, and better integration with
current #GtkFileChooser and #GtkUIManager widgets
</para></listitem>
</itemizedlist>
</para>
<section id="gtkrecent-manager">
<title>Managing the Recently Used Documents</title>
<para>
#GtkRecentManager is used to manage the Recently Used Documents. To
create a new #GtkRecentManager, you simply call gtk_recent_manager_new().
Like the <structname>EggRecentModel</structname> inside EggRecent, the
#GtkRecentManager loads the list of the recent documents and notifies
you of changes inside the list.
</para>
<para>
Usually, instead of creating a new #GtkRecentManager each time you
need it, you'll want to use the gtk_recent_manager_get_default()
function.
</para>
<para>
To add a document to the list, you can use gtk_recent_manager_add_item(),
like:
<informalexample><programlisting>
GtkRecentManager *manager;
manager = gtk_recent_manager_new (<!-- -->);
if (!gtk_recent_manager_add_item (manager, document_uri))
{
/* warn about the error */
}
g_object_unref (manager);
</programlisting></informalexample>
The gtk_recent_manager_add_item() function will try and guess some of the
meta-data associated to a URI. If you know some of meta-data about the
document yourself, set the desired fields of a #GtkRecentData structure
and pass it to the gtk_recent_manager_add_full() function instead:
<informalexample><programlisting>
GtkRecentManager *manager;
GtkRecentData *recent_data;
manager = gtk_recent_manager_new (<!-- -->);
recent_data = g_new0 (GtkRecentData, 1);
/* the user visible name of the document (maybe its title); should
* be preferred when displaying the item into the list
*/
recent_data-&gt;display_name = document_name;
/* the MIME type is mandatory */
recent_data-&gt;mime_type = document_mime_type;
/* the name of the application that is registering the document
* (also mandatory); usually, the same name you used with
* the g_set_application_name (<!-- -->) function.
*/
recent_data-&amp;app_name = APP_NAME;
/* the command to open a file; the %u string will be automagically
* expanded to the document's URI when getting the application's
* command line from the GtkRecentInfo object with
* gtk_recent_info_get_application_info (<!-- -->)
*/
recent_data-&amp;app_exec = g_strjoin (" ", g_get_prgname (<!-- -->), "--open-file", "%u", NULL);
if (!gtk_recent_manager_add_full (manager, document_uri, recent_data))
{
/* warn about the error */
}
g_free (recent_data-&gt;app_exec);
g_free (recent_data);
g_object_unref (manager);
</programlisting></informalexample>
</para>
<para>
Getting the list of items is also similar to
<structname>EggRecentModel</structname>; the GtkRecentInfo data is
allocated at look up time in order not to waste memory keeping it
around, so you must remember to free the data inside the list and then
the list itself when you are done using it:
<informalexample><programlisting>
GtkRecentManager *manager;
GList *recent_items, *l;
manager = gtk_recent_manager_get_default(<!-- -->);
recent_items = gtk_recent_manager_get_items (manager);
for (l = recent_items; l != NULL; l = l-&gt;next)
{
GtkRecentInfo *recent_info = l-&gt;data;
do_something_with_the_item (recent_info);
}
/* free everything and the list */
g_list_foreach (recent_items, (GFunc) gtk_recent_info_unref, NULL);
g_list_free (recent_items);
</programlisting></informalexample>
You can also look up a single item:
<informalexample><programlisting>
GtkRecentInfo *recent_info;
GError *error = NULL;
recent_info = gtk_recent_manager_lookup_item (manager, document_uri, &amp;error);
if (error)
{
display_error (error);
g_error_free (error);
}
else
{
do_something_with_the_item (recent_info);
gtk_recent_info_unref (recent_info);
}
</programlisting></informalexample>
The #GtkRecentInfo is a reference counted boxed type, and it holds all
the meta-data of a recently used document, like its display name, its
description, the list of each application that has registered the
document or the list of groups to which the document belong.
</para>
</section> <!-- gtkrecent-manager -->
<section id="gtkrecent-chooser">
<title>Displaying the Recently Used Documents</title>
<para>
Displaying the Recently Used Documents list is handled by any widget
implementing the #GtkRecentChooser interface. These widgets also handle
the sorting and filtering of the list; they will create their own
#GtkRecentManager objects by default:
<informalexample><programlisting>
GtkWidget *chooser;
gint response;
/* create a new dialog with the recently used documents list shown
* using a GtkTreeView widget
*/
chooser = gtk_recent_chooser_dialog_new ("Recent Documents",
parent_window,
GTK_STOCK_CLOSE, GTK_RESPONSE_CANCEL,
GTK_STOCK_OPEN, GTK_RESPONSE_OK,
NULL);
/* set the sorting order to "most recently used first" */
gtk_recent_chooser_set_sort_type (GTK_RECENT_CHOOSER (chooser), GTK_RECENT_SORT_MRU);
response = gtk_dialog_run (GTK_DIALOG (chooser));
if (response == GTK_RESPONSE_OK)
{
GtkRecentInfo *info;
info = gtk_recent_chooser_get_current_item (GTK_RECENT_CHOOSER (chooser));
do_something_with_the_item (info);
gtk_recent_info_unref (info);
}
gtk_widget_destroy (chooser);
</programlisting></informalexample>
</para>
</section> <!-- gtkrecent-chooser -->
<section id="gtkrecent-advanced">
<title>Advanced usage</title>
<para>
The #GtkRecentChooser widgets might display items sorted and filtered,
either with already supplied or custom sorting and filtering functions.
The biggest difference from the <structname>EggRecentView</structname>
widgets in EggRecent is that the #GtkRecentChooser widgets will use
their own copy of the list and will apply the sorting and filtering
functions only on the copy; this allows the creation of many viewers
with a single controller, like using many #GtkTreeView with a single
#GtkTreeModel instance.
</para>
<para>
Available sorting methods are:
<informalexample><programlisting>
/* no sorting */
gtk_recent_chooser_set_sort_type (GTK_RECENT_CHOOSER (chooser), GTK_RECENT_SORT_NONE);
/* most recently used first */
gtk_recent_chooser_set_sort_type (GTK_RECENT_CHOOSER (chooser), GTK_RECENT_SORT_MRU);
/* most recently used last */
gtk_recent_chooser_set_sort_type (GTK_RECENT_CHOOSER (chooser), GTK_RECENT_SORT_LRU);
</programlisting></informalexample>
You can create your own sorting function, and the use the
GTK_RECENT_SORT_CUSTOM method:
<informalexample><programlisting>
/* custom sorting function, based on the registration count
* (most used first)
*/
static void
sort_by_usage_count (GtkRecentInfo *a,
GtkRecentInfo *b,
gpointer data)
{
gint count_a, count_b;
count_a = count_b = 0;
if (gtk_recent_info_has_application (a, APP_NAME))
gtk_recent_info_get_application_info (a, APP_NAME, NULL, &amp;count_a, NULL);
if (gtk_recent_info_has_application (b, APP_NAME))
gtk_recent_info_get_application_info (b, APP_NAME, NULL, &amp;count_b, NULL);
return count_a &lt; count_b;
}
...
/* set custom sorting and set the custom sorting function */
gtk_recent_chooser_set_sort_type (GTK_RECENT_CHOOSER (chooser),
GTK_RECENT_SORT_CUSTOM);
gtk_recent_chooser_set_sort_func (GTK_RECENT_CHOOSER,
sort_by_usage_count,
NULL, /* sort function data */
NULL /* destroy notify for the data */);
</programlisting></informalexample>
</para>
<para>
Filtering is done using the #GtkRecentFilter object, similar to the
#GtkFileFilter object used by the #GtkFileChooser widgets. The
#GtkRecentFilter object has a set of pre-defined options based on the
meta-data exposed by the #GtkRecentInfo object. It also allows custom
filtering function:
<informalexample><programlisting>
GtkRecentFilter *filter;
filter = gtk_recent_filter_new (<!-- -->);
/* set the user visible name of the filter */
gtk_recent_filter_set_name (filter, "Since Last Month");
/* set the maximum age of a recently used document */
gtk_recent_filter_set_age (filter, 31);
/* the chooser takes the ownership of the object */
gtk_recent_chooser_add_filter (GTK_RECENT_CHOOSER (chooser), filter);
/* set the currently used filter */
gtk_recent_chooser_set_filter (GTK_RECENT_CHOOSER (chooser), filter);
filter = gtk_recent_filter_new (<!-- -->);
gtk_recent_filter_set_name (filter, "Every text file");
gtk_recent_filter_set_mime_type (filter, "text/plain");
gtk_recent_chooser_add_filter (GTK_RECENT_CHOOSER (chooser), filter);
</programlisting></informalexample>
The #GtkRecentChooserWidget and #GtkRecentChooserDialog widgets allow
multiple filters and the selection of an appropriate one; the
#GtkRecentChooserMenu widget allows just a single filter object.
</para>
</section> <!-- gtkrecent-advanced -->
</chapter>
<!--
Local variables:
mode: sgml
sgml-parent-document: ("gtk-docs.sgml" "book" "part" "chapter")
End:
-->

View File

@ -1,66 +0,0 @@
<?xml version="1.0"?>
<!DOCTYPE chapter PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
"http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" [
]>
<chapter id="gtk-migrating-tooltips">
<title>Migrating from GtkTooltips to GtkTooltip</title>
<para>
GTK+ 2.12 brings a completely new tooltip implementation which
allows many things that were not possible with the old
#GtkTooltips interface. The new possibilities are explained
in more detail in the section about #GtkTooltip.
</para>
<para>
A number of complications of the old API have been removed:
<itemizedlist>
<listitem><para>
Tooltips can not be grouped anymore. The old tooltips
API allowed this by using multiple #GtkTooltips objects.
We believe that the timeout behaviour of the new tooltips
implementation is better and makes it unnecessary to use
grouping as a way to overcome shortcomings of the
fast-tooltips mode.
</para></listitem>
<listitem><para>
Timeouts can not be set individually anymore. Instead
there are settings #GtkSettings:gtk-tooltip-timeout,
#GtkSettings:gtk-tooltip-browse-timeout and
#GtkSettings:gtk-tooltip-browse-mode-timeout to influence
the behaviour of tooltips globally.
</para></listitem>
</itemizedlist>
</para>
<para>
Here is an example of setting a tooltip on a widget with the old API:
<informalexample><programlisting>
GtkTooltips *tooltips = gtk_tooltips_new ();
gtk_tooltips_set_tip (tooltips, widget, "Some tips", NULL);
</programlisting></informalexample>
</para>
<para>
Using the new tooltips API, it is no longer necessary to create
an object:
<informalexample><programlisting>
gtk_widget_set_tooltip_text (widget, "Some tips");
</programlisting></informalexample>
</para>
<para>
Similarly, setting a tooltip on a #GtkToolItem gets
simplified from
<informalexample><programlisting>
gtk_tool_item_set_tooltip (toolitem, toolbar->tooltips, "tool tip", NULL);
</programlisting></informalexample>
to
<informalexample><programlisting>
gtk_tool_item_set_tooltip_text (toolitem, text);
</programlisting></informalexample>
</para>
</chapter>