Applied a slightly modified patch from Róman Joost as attached to bug

2008-08-04  Sven Neumann  <sven@gimp.org>

	Applied a slightly modified patch from Róman Joost as attached 
to
	bug #545963. This add links to the user manual to the tips 
dialog:

	* data/tips/gimp-tips.dtd
	* data/tips/gimp-tips.xml.in: add optional help IDs to the tips.

	* app/dialogs/tips-dialog.c

	* app/dialogs/tips-parser.[ch]: parse the help IDs from the tips
	file and show a "Learn more" link in the tips dialog.


svn path=/trunk/; revision=26361
This commit is contained in:
Sven Neumann 2008-08-04 13:56:07 +00:00 committed by Sven Neumann
parent 6f8f412fd4
commit 083c48d2d2
6 changed files with 162 additions and 73 deletions

View file

@ -1,3 +1,16 @@
2008-08-04 Sven Neumann <sven@gimp.org>
Applied a slightly modified patch from Róman Joost as attached to
bug #545963. This add links to the user manual to the tips dialog:
* data/tips/gimp-tips.dtd
* data/tips/gimp-tips.xml.in: add optional help IDs to the tips.
* app/dialogs/tips-dialog.c
* app/dialogs/tips-parser.[ch]: parse the help IDs from the tips
file and show a "Learn more" link in the tips dialog.
2008-08-03 Martin Nordholts <martinn@svn.gnome.org>
* app/display/gimpdisplayshell.c (gimp_display_shell_new): Center

View file

@ -36,24 +36,26 @@
#include "gimp-intl.h"
enum
{
RESPONSE_PREVIOUS = 1,
RESPONSE_NEXT = 2
};
static void tips_dialog_set_tip (GimpTip *tip);
static void tips_dialog_response (GtkWidget *dialog,
gint response);
static void tips_dialog_destroy (GtkWidget *widget,
gpointer data);
static void tips_dialog_set_tip (GimpTip *tip);
static void tips_dialog_response (GtkWidget *dialog,
gint response);
static void tips_dialog_destroy (GtkWidget *widget,
GimpGuiConfig *config);
static void more_button_clicked (GtkWidget *button,
Gimp *gimp);
static GtkWidget *tips_dialog = NULL;
static GtkWidget *thetip_label = NULL;
static GList *tips = NULL;
static GList *current_tip = NULL;
static GtkWidget *tips_dialog = NULL;
static GtkWidget *tip_label = NULL;
static GtkWidget *more_button = NULL;
static GList *tips = NULL;
static GList *current_tip = NULL;
GtkWidget *
@ -164,32 +166,47 @@ tips_dialog_create (Gimp *gimp)
gtk_box_pack_start (GTK_BOX (vbox), hbox, TRUE, TRUE, 0);
gtk_widget_show (hbox);
thetip_label = gtk_label_new (NULL);
gtk_label_set_selectable (GTK_LABEL (thetip_label), TRUE);
gtk_label_set_justify (GTK_LABEL (thetip_label), GTK_JUSTIFY_LEFT);
gtk_label_set_line_wrap (GTK_LABEL (thetip_label), TRUE);
gtk_misc_set_alignment (GTK_MISC (thetip_label), 0.5, 0.5);
gtk_box_pack_start (GTK_BOX (hbox), thetip_label, TRUE, TRUE, 0);
gtk_widget_show (thetip_label);
vbox = gtk_vbox_new (FALSE, 6);
gtk_box_pack_start (GTK_BOX (hbox), vbox, TRUE, TRUE, 0);
gtk_widget_show (vbox);
image = gtk_image_new_from_stock (GIMP_STOCK_INFO, GTK_ICON_SIZE_DIALOG);
gtk_misc_set_alignment (GTK_MISC (image), 0.5, 0.5);
gtk_misc_set_alignment (GTK_MISC (image), 0.5, 0.0);
gtk_box_pack_start (GTK_BOX (hbox), image, FALSE, FALSE, 0);
gtk_widget_show (image);
gtk_container_set_focus_chain (GTK_CONTAINER (hbox), NULL);
tip_label = gtk_label_new (NULL);
gtk_label_set_selectable (GTK_LABEL (tip_label), TRUE);
gtk_label_set_justify (GTK_LABEL (tip_label), GTK_JUSTIFY_LEFT);
gtk_label_set_line_wrap (GTK_LABEL (tip_label), TRUE);
gtk_misc_set_alignment (GTK_MISC (tip_label), 0.5, 0.0);
gtk_box_pack_start (GTK_BOX (vbox), tip_label, TRUE, TRUE, 0);
gtk_widget_show (tip_label);
hbox = gtk_hbox_new (FALSE, 0);
gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, FALSE, 0);
gtk_widget_show (hbox);
more_button = gtk_link_button_new_with_label ("http://docs.gimp.org/",
_("Learn more"));
gtk_widget_show (more_button);
gtk_box_pack_start (GTK_BOX (hbox), more_button, FALSE, FALSE, 0);
g_signal_connect (more_button, "clicked",
G_CALLBACK (more_button_clicked),
gimp);
tips_dialog_set_tip (current_tip->data);
return tips_dialog;
}
static void
tips_dialog_destroy (GtkWidget *widget,
gpointer data)
tips_dialog_destroy (GtkWidget *widget,
GimpGuiConfig *config)
{
GimpGuiConfig *config = GIMP_GUI_CONFIG (data);
/* the last-shown-tip is saved in sessionrc */
config->last_tip = g_list_position (tips, current_tip);
@ -227,5 +244,21 @@ tips_dialog_set_tip (GimpTip *tip)
{
g_return_if_fail (tip != NULL);
gtk_label_set_markup (GTK_LABEL (thetip_label), tip->thetip);
gtk_label_set_markup (GTK_LABEL (tip_label), tip->text);
/* set the URI to unset the "visited" state */
gtk_link_button_set_uri (GTK_LINK_BUTTON (more_button),
"http://docs.gimp.org/");
gtk_widget_set_sensitive (more_button, tip->help_id != NULL);
}
static void
more_button_clicked (GtkWidget *button,
Gimp *gimp)
{
GimpTip *tip = current_tip->data;
if (tip->help_id)
gimp_help (gimp, NULL, NULL, tip->help_id);
}

View file

@ -54,6 +54,7 @@ typedef struct
TipsParserState state;
TipsParserState last_known_state;
const gchar *locale;
const gchar *help_id;
TipsParserLocaleState locale_state;
gint markup_depth;
gint unknown_depth;
@ -63,33 +64,38 @@ typedef struct
} TipsParser;
static void tips_parser_start_element (GMarkupParseContext *context,
const gchar *element_name,
const gchar **attribute_names,
const gchar **attribute_values,
gpointer user_data,
GError **error);
static void tips_parser_end_element (GMarkupParseContext *context,
const gchar *element_name,
gpointer user_data,
GError **error);
static void tips_parser_characters (GMarkupParseContext *context,
const gchar *text,
gsize text_len,
gpointer user_data,
GError **error);
static void tips_parser_start_element (GMarkupParseContext *context,
const gchar *element_name,
const gchar **attribute_names,
const gchar **attribute_values,
gpointer user_data,
GError **error);
static void tips_parser_end_element (GMarkupParseContext *context,
const gchar *element_name,
gpointer user_data,
GError **error);
static void tips_parser_characters (GMarkupParseContext *context,
const gchar *text,
gsize text_len,
gpointer user_data,
GError **error);
static void tips_parser_start_markup (TipsParser *parser,
const gchar *markup_name);
static void tips_parser_end_markup (TipsParser *parser,
const gchar *markup_name);
static void tips_parser_start_unknown (TipsParser *parser);
static void tips_parser_end_unknown (TipsParser *parser);
static void tips_parser_parse_locale (TipsParser *parser,
const gchar **names,
const gchar **values);
static void tips_parser_set_by_locale (TipsParser *parser,
gchar **dest);
static void tips_parser_start_markup (TipsParser *parser,
const gchar *markup_name);
static void tips_parser_end_markup (TipsParser *parser,
const gchar *markup_name);
static void tips_parser_start_unknown (TipsParser *parser);
static void tips_parser_end_unknown (TipsParser *parser);
static gchar * tips_parser_parse_help_id (TipsParser *parser,
const gchar **names,
const gchar **values);
static void tips_parser_parse_locale (TipsParser *parser,
const gchar **names,
const gchar **values);
static void tips_parser_set_by_locale (TipsParser *parser,
gchar **dest);
static const GMarkupParser markup_parser =
@ -129,7 +135,7 @@ gimp_tip_new (const gchar *title,
va_end (args);
}
tip->thetip = g_string_free (str, FALSE);
tip->text = g_string_free (str, FALSE);
return tip;
}
@ -140,7 +146,9 @@ gimp_tip_free (GimpTip *tip)
if (! tip)
return;
g_free (tip->thetip);
g_free (tip->text);
g_free (tip->help_id);
g_slice_free (GimpTip, tip);
}
@ -230,9 +238,13 @@ tips_parser_start_element (GMarkupParseContext *context,
{
case TIPS_START:
if (strcmp (element_name, "gimp-tips") == 0)
parser->state = TIPS_IN_TIPS;
{
parser->state = TIPS_IN_TIPS;
}
else
tips_parser_start_unknown (parser);
{
tips_parser_start_unknown (parser);
}
break;
case TIPS_IN_TIPS:
@ -240,9 +252,14 @@ tips_parser_start_element (GMarkupParseContext *context,
{
parser->state = TIPS_IN_TIP;
parser->current_tip = g_slice_new0 (GimpTip);
parser->current_tip->help_id = tips_parser_parse_help_id (parser,
attribute_names,
attribute_values);
}
else
tips_parser_start_unknown (parser);
{
tips_parser_start_unknown (parser);
}
break;
case TIPS_IN_TIP:
@ -252,16 +269,22 @@ tips_parser_start_element (GMarkupParseContext *context,
tips_parser_parse_locale (parser, attribute_names, attribute_values);
}
else
tips_parser_start_unknown (parser);
{
tips_parser_start_unknown (parser);
}
break;
case TIPS_IN_THETIP:
if (strcmp (element_name, "b" ) == 0 ||
strcmp (element_name, "big") == 0 ||
strcmp (element_name, "tt" ) == 0)
tips_parser_start_markup (parser, element_name);
{
tips_parser_start_markup (parser, element_name);
}
else
tips_parser_start_unknown (parser);
{
tips_parser_start_unknown (parser);
}
break;
case TIPS_IN_UNKNOWN:
@ -297,7 +320,7 @@ tips_parser_end_element (GMarkupParseContext *context,
case TIPS_IN_THETIP:
if (parser->markup_depth == 0)
{
tips_parser_set_by_locale (parser, &parser->current_tip->thetip);
tips_parser_set_by_locale (parser, &parser->current_tip->text);
g_string_truncate (parser->value, 0);
parser->state = TIPS_IN_TIP;
}
@ -387,6 +410,23 @@ tips_parser_end_unknown (TipsParser *parser)
parser->state = parser->last_known_state;
}
static gchar *
tips_parser_parse_help_id (TipsParser *parser,
const gchar **names,
const gchar **values)
{
while (*names && *values)
{
if (strcmp (*names, "help") == 0 && **values)
return g_strdup (*values);
names++;
values++;
}
return NULL;
}
static void
tips_parser_parse_locale (TipsParser *parser,
const gchar **names,
@ -435,3 +475,4 @@ tips_parser_set_by_locale (TipsParser *parser,
break;
}
}

View file

@ -27,7 +27,8 @@ typedef struct _GimpTip GimpTip;
struct _GimpTip
{
gchar *thetip;
gchar *text;
gchar *help_id;
};

View file

@ -4,6 +4,7 @@
<!ELEMENT tip (thetip+)>
<!ATTLIST tip level (start|beginner|intermediate|advanced) #REQUIRED>
<!ATTLIST tip help CDATA #IMPLIED>
<!ENTITY % markup "(#PCDATA|b|big|tt)*">

View file

@ -20,20 +20,20 @@
pressing the F1 key at any time. This also works inside the menus.
</_thetip>
</tip>
<tip level="beginner">
<tip level="beginner" help="gimp-layer-dialog">
<_thetip>
GIMP uses layers to let you organize your image. Think of them
as a stack of slides or filters, such that looking through them you
see a composite of their contents.
</_thetip>
</tip>
<tip level="beginner">
<tip level="beginner" help="gimp-layer-menu">
<_thetip>
You can perform many layer operations by right-clicking on the text
label of a layer in the Layers dialog.
</_thetip>
</tip>
<tip level="beginner">
<tip level="beginner" help="gimp-file-save">
<_thetip>
When you save an image to work on it again later, try using XCF,
GIMP's native file format (use the file extension <tt>.xcf</tt>).
@ -41,14 +41,14 @@
Once a project is completed, you can save it as JPEG, PNG, GIF, ...
</_thetip>
</tip>
<tip level="beginner">
<tip level="beginner" help="gimp-image-flatten">
<_thetip>
Most plug-ins work on the current layer of the current image. In
some cases, you will have to merge all layers (Image→Flatten Image)
if you want the plug-in to work on the whole image.
</_thetip>
</tip>
<tip level="beginner">
<tip level="beginner" help="gimp-layer-alpha-add">
<_thetip>
If a layer's name in the Layers dialog is displayed in <b>bold</b>,
this layer doesn't have an alpha-channel. You can add an alpha-channel
@ -91,14 +91,14 @@
(or optionally hold <tt>Spacebar</tt> while you move the mouse).
</_thetip>
</tip>
<tip level="intermediate">
<tip level="intermediate" help="gimp-concepts-image-grid">
<_thetip>
Click and drag on a ruler to place a guide on an image. All
dragged selections will snap to the guides. You can remove
guides by dragging them off the image with the Move tool.
</_thetip>
</tip>
<tip level="intermediate">
<tip level="intermediate" help="gimp-file-new">
<_thetip>
You can drag a layer from the Layers dialog and drop it onto the
toolbox. This will create a new image containing only that layer.
@ -128,28 +128,28 @@
current one.
</_thetip>
</tip>
<tip level="intermediate">
<tip level="intermediate" help="gimp-selection-stroke">
<_thetip>
You can draw simple squares or circles using Edit→Stroke Selection.
It strokes the edge of your current selection. More complex shapes
can be drawn using the Path tool or with Filters→Render→Gfig.
</_thetip>
</tip>
<tip level="intermediate">
<tip level="intermediate" help="gimp-path-stroke">
<_thetip>
If you stroke a path (Edit→Stroke Path), the paint tools can
be used with their current settings. You can use the Paintbrush in
gradient mode or even the Eraser or the Smudge tool.
</_thetip>
</tip>
<tip level="intermediate">
<tip level="intermediate" help="gimp-using-paths">
<_thetip>
You can create and edit complex selections using the Path tool.
The Paths dialog allows you to work on multiple paths and to convert
them to selections.
</_thetip>
</tip>
<tip level="intermediate">
<tip level="intermediate" help="gimp-using-quickmask">
<_thetip>
You can use the paint tools to change the selection. Click on the
&quot;Quick Mask&quot; button at the bottom left of an image window.
@ -157,7 +157,7 @@
again to convert it back to a normal selection.
</_thetip>
</tip>
<tip level="intermediate">
<tip level="intermediate" help="gimp-channel-dialog">
<_thetip>
You can save a selection to a channel (Select→Save to Channel) and
then modify this channel with any paint tools. Using the buttons in
@ -208,7 +208,7 @@
an image (if your window manager doesn't trap those keys...).
</_thetip>
</tip>
<tip level="advanced">
<tip level="advanced" help="gimp-tool-bucket-fill">
<_thetip>
<tt>Ctrl</tt>-click with the Bucket Fill tool to have it use
the background color instead of the foreground color.
@ -216,7 +216,7 @@
sets the background color instead of the foreground color.
</_thetip>
</tip>
<tip level="advanced">
<tip level="advanced" help="gimp-tools-transform">
<_thetip>
<tt>Ctrl</tt>-drag with the Rotate tool will constrain the
rotation to 15 degree angles.