Commit 3ed06437 authored by Sven Neumann's avatar Sven Neumann Committed by Sven Neumann
Browse files

app/gui/tips-dialog.c added support for simple text markup.

2002-02-26  Sven Neumann  <sven@gimp.org>

	* app/gui/tips-dialog.c
	* app/gui/tips-parser.c: added support for simple text markup.

	* tips/gimp-tips.xml.in: document and use the new markup tags.
parent d9c23318
2002-02-26 Sven Neumann <sven@gimp.org>
* app/gui/tips-dialog.c
* app/gui/tips-parser.c: added support for simple text markup.
* tips/gimp-tips.xml.in: document and use the new markup tags.
2002-02-26 Michael Natterer <mitch@gimp.org>
 
* app/app_procs.c: make absolute paths out of relative ones
......
......@@ -38,6 +38,7 @@
#include "libgimp/gimpintl.h"
static void tips_set_labels (GimpTip *tip);
static void tips_dialog_destroy (GtkWidget *widget,
gpointer data);
static void tips_show_previous (GtkWidget *widget,
......@@ -61,14 +62,13 @@ static gint old_show_tips = 0;
GtkWidget *
tips_dialog_create (void)
{
GtkWidget *vbox;
GtkWidget *vbox2;
GtkWidget *hbox;
GtkWidget *bbox;
GtkWidget *button;
GdkPixbuf *wilber;
GimpTip *tip;
gchar *filename;
GtkWidget *vbox;
GtkWidget *vbox2;
GtkWidget *hbox;
GtkWidget *bbox;
GtkWidget *button;
GdkPixbuf *wilber;
gchar *filename;
if (!tips)
{
......@@ -84,7 +84,7 @@ tips_dialog_create (void)
if (error)
{
tips = g_list_prepend (tips,
gimp_tip_new (_("The GIMP tips file could not be parsed correctly!"), error->message));
gimp_tip_new (_("<b>The GIMP tips file could not be parsed correctly!</b>"), error->message));
g_error_free (error);
}
}
......@@ -131,17 +131,13 @@ tips_dialog_create (void)
gtk_box_pack_start (GTK_BOX (hbox), vbox2, TRUE, TRUE, 0);
gtk_widget_show (vbox2);
tip = (GimpTip *) current_tip->data;
welcome_label = gtk_label_new (tip->welcome);
welcome_label = gtk_label_new (NULL);
gtk_label_set_justify (GTK_LABEL (welcome_label), GTK_JUSTIFY_LEFT);
gtk_label_set_line_wrap (GTK_LABEL (welcome_label), TRUE);
gtk_misc_set_alignment (GTK_MISC (welcome_label), 0.5, 0.5);
gtk_box_pack_start (GTK_BOX (vbox2), welcome_label, FALSE, FALSE, 0);
if (tip->welcome)
gtk_widget_show (welcome_label);
thetip_label = gtk_label_new (tip->thetip);
thetip_label = gtk_label_new (NULL);
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);
......@@ -230,6 +226,8 @@ tips_dialog_create (void)
gimp_standard_help_func,
"dialogs/tip_of_the_day.html");
tips_set_labels (current_tip->data);
return tips_dialog;
}
......@@ -270,8 +268,8 @@ tips_set_labels (GimpTip *tip)
else
gtk_widget_hide (welcome_label);
gtk_label_set_text (GTK_LABEL (welcome_label), tip->welcome);
gtk_label_set_text (GTK_LABEL (thetip_label), tip->thetip);
gtk_label_set_markup (GTK_LABEL (welcome_label), tip->welcome);
gtk_label_set_markup (GTK_LABEL (thetip_label), tip->thetip);
}
static void
......
......@@ -38,7 +38,7 @@ typedef enum
TIPS_IN_TIP,
TIPS_IN_WELCOME,
TIPS_IN_THETIP,
TIPS_UNKNOWN
TIPS_IN_UNKNOWN
} TipsParserState;
typedef enum
......@@ -56,6 +56,7 @@ struct _TipsParser
TipsParserState last_known_state;
const gchar *locale;
TipsParserLocaleState locale_state;
gint markup_depth;
gint unknown_depth;
GString *value;
......@@ -83,6 +84,10 @@ static void tips_parser_error (GMarkupParseContext *context,
GError *error,
gpointer user_data);
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,
......@@ -262,7 +267,15 @@ tips_parser_start_element (GMarkupParseContext *context,
case TIPS_IN_WELCOME:
case TIPS_IN_THETIP:
case TIPS_UNKNOWN:
if (strcmp (element_name, "b" ) == 0 ||
strcmp (element_name, "big") == 0 ||
strcmp (element_name, "tt" ) == 0)
tips_parser_start_markup (parser, element_name);
else
tips_parser_start_unknown (parser);
break;
case TIPS_IN_UNKNOWN:
tips_parser_start_unknown (parser);
break;
}
......@@ -287,28 +300,37 @@ tips_parser_end_element (GMarkupParseContext *context,
break;
case TIPS_IN_TIP:
parser->state = TIPS_IN_TIPS;
parser->tips = g_list_prepend (parser->tips, parser->current_tip);
parser->current_tip = NULL;
parser->state = TIPS_IN_TIPS;
break;
case TIPS_IN_WELCOME:
tips_parser_set_by_locale (parser, &parser->current_tip->welcome);
parser->state = TIPS_IN_TIP;
if (parser->markup_depth == 0)
{
tips_parser_set_by_locale (parser, &parser->current_tip->welcome);
g_string_assign (parser->value, "");
parser->state = TIPS_IN_TIP;
}
else
tips_parser_end_markup (parser, element_name);
break;
case TIPS_IN_THETIP:
tips_parser_set_by_locale (parser, &parser->current_tip->thetip);
parser->state = TIPS_IN_TIP;
break;
if (parser->markup_depth == 0)
{
tips_parser_set_by_locale (parser, &parser->current_tip->thetip);
g_string_assign (parser->value, "");
parser->state = TIPS_IN_TIP;
}
else
tips_parser_end_markup (parser, element_name);
break;
case TIPS_UNKNOWN:
case TIPS_IN_UNKNOWN:
tips_parser_end_unknown (parser);
break;
}
g_string_assign (parser->value, "");
}
static void
......@@ -331,7 +353,8 @@ tips_parser_characters (GMarkupParseContext *context,
/* strip tabs, newlines and adjacent whitespace */
for (i = 0; i < text_len; i++)
{
if (text[i] != ' ' && text[i] != '\t' && text[i] != '\n')
if (text[i] != ' ' &&
text[i] != '\t' && text[i] != '\n' && text[i] != '\r')
g_string_append_c (parser->value, text[i]);
else if (parser->value->len > 0 &&
parser->value->str[parser->value->len - 1] != ' ')
......@@ -354,20 +377,38 @@ tips_parser_error (GMarkupParseContext *context,
g_warning ("%s: %s", parser->filename, error->message);
}
static void
tips_parser_start_markup (TipsParser *parser,
const gchar *markup_name)
{
parser->markup_depth++;
g_string_append_printf (parser->value, "<%s>", markup_name);
}
static void
tips_parser_end_markup (TipsParser *parser,
const gchar *markup_name)
{
g_assert (parser->markup_depth > 0);
parser->markup_depth--;
g_string_append_printf (parser->value, "</%s>", markup_name);
}
static void
tips_parser_start_unknown (TipsParser *parser)
{
if (parser->unknown_depth == 0)
parser->last_known_state = parser->state;
parser->state = TIPS_UNKNOWN;
parser->state = TIPS_IN_UNKNOWN;
parser->unknown_depth++;
}
static void
tips_parser_end_unknown (TipsParser *parser)
{
g_assert (parser->unknown_depth > 0 && parser->state == TIPS_UNKNOWN);
g_assert (parser->unknown_depth > 0 && parser->state == TIPS_IN_UNKNOWN);
parser->unknown_depth--;
......
......@@ -38,6 +38,7 @@
#include "libgimp/gimpintl.h"
static void tips_set_labels (GimpTip *tip);
static void tips_dialog_destroy (GtkWidget *widget,
gpointer data);
static void tips_show_previous (GtkWidget *widget,
......@@ -61,14 +62,13 @@ static gint old_show_tips = 0;
GtkWidget *
tips_dialog_create (void)
{
GtkWidget *vbox;
GtkWidget *vbox2;
GtkWidget *hbox;
GtkWidget *bbox;
GtkWidget *button;
GdkPixbuf *wilber;
GimpTip *tip;
gchar *filename;
GtkWidget *vbox;
GtkWidget *vbox2;
GtkWidget *hbox;
GtkWidget *bbox;
GtkWidget *button;
GdkPixbuf *wilber;
gchar *filename;
if (!tips)
{
......@@ -84,7 +84,7 @@ tips_dialog_create (void)
if (error)
{
tips = g_list_prepend (tips,
gimp_tip_new (_("The GIMP tips file could not be parsed correctly!"), error->message));
gimp_tip_new (_("<b>The GIMP tips file could not be parsed correctly!</b>"), error->message));
g_error_free (error);
}
}
......@@ -131,17 +131,13 @@ tips_dialog_create (void)
gtk_box_pack_start (GTK_BOX (hbox), vbox2, TRUE, TRUE, 0);
gtk_widget_show (vbox2);
tip = (GimpTip *) current_tip->data;
welcome_label = gtk_label_new (tip->welcome);
welcome_label = gtk_label_new (NULL);
gtk_label_set_justify (GTK_LABEL (welcome_label), GTK_JUSTIFY_LEFT);
gtk_label_set_line_wrap (GTK_LABEL (welcome_label), TRUE);
gtk_misc_set_alignment (GTK_MISC (welcome_label), 0.5, 0.5);
gtk_box_pack_start (GTK_BOX (vbox2), welcome_label, FALSE, FALSE, 0);
if (tip->welcome)
gtk_widget_show (welcome_label);
thetip_label = gtk_label_new (tip->thetip);
thetip_label = gtk_label_new (NULL);
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);
......@@ -230,6 +226,8 @@ tips_dialog_create (void)
gimp_standard_help_func,
"dialogs/tip_of_the_day.html");
tips_set_labels (current_tip->data);
return tips_dialog;
}
......@@ -270,8 +268,8 @@ tips_set_labels (GimpTip *tip)
else
gtk_widget_hide (welcome_label);
gtk_label_set_text (GTK_LABEL (welcome_label), tip->welcome);
gtk_label_set_text (GTK_LABEL (thetip_label), tip->thetip);
gtk_label_set_markup (GTK_LABEL (welcome_label), tip->welcome);
gtk_label_set_markup (GTK_LABEL (thetip_label), tip->thetip);
}
static void
......
......@@ -38,7 +38,7 @@ typedef enum
TIPS_IN_TIP,
TIPS_IN_WELCOME,
TIPS_IN_THETIP,
TIPS_UNKNOWN
TIPS_IN_UNKNOWN
} TipsParserState;
typedef enum
......@@ -56,6 +56,7 @@ struct _TipsParser
TipsParserState last_known_state;
const gchar *locale;
TipsParserLocaleState locale_state;
gint markup_depth;
gint unknown_depth;
GString *value;
......@@ -83,6 +84,10 @@ static void tips_parser_error (GMarkupParseContext *context,
GError *error,
gpointer user_data);
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,
......@@ -262,7 +267,15 @@ tips_parser_start_element (GMarkupParseContext *context,
case TIPS_IN_WELCOME:
case TIPS_IN_THETIP:
case TIPS_UNKNOWN:
if (strcmp (element_name, "b" ) == 0 ||
strcmp (element_name, "big") == 0 ||
strcmp (element_name, "tt" ) == 0)
tips_parser_start_markup (parser, element_name);
else
tips_parser_start_unknown (parser);
break;
case TIPS_IN_UNKNOWN:
tips_parser_start_unknown (parser);
break;
}
......@@ -287,28 +300,37 @@ tips_parser_end_element (GMarkupParseContext *context,
break;
case TIPS_IN_TIP:
parser->state = TIPS_IN_TIPS;
parser->tips = g_list_prepend (parser->tips, parser->current_tip);
parser->current_tip = NULL;
parser->state = TIPS_IN_TIPS;
break;
case TIPS_IN_WELCOME:
tips_parser_set_by_locale (parser, &parser->current_tip->welcome);
parser->state = TIPS_IN_TIP;
if (parser->markup_depth == 0)
{
tips_parser_set_by_locale (parser, &parser->current_tip->welcome);
g_string_assign (parser->value, "");
parser->state = TIPS_IN_TIP;
}
else
tips_parser_end_markup (parser, element_name);
break;
case TIPS_IN_THETIP:
tips_parser_set_by_locale (parser, &parser->current_tip->thetip);
parser->state = TIPS_IN_TIP;
break;
if (parser->markup_depth == 0)
{
tips_parser_set_by_locale (parser, &parser->current_tip->thetip);
g_string_assign (parser->value, "");
parser->state = TIPS_IN_TIP;
}
else
tips_parser_end_markup (parser, element_name);
break;
case TIPS_UNKNOWN:
case TIPS_IN_UNKNOWN:
tips_parser_end_unknown (parser);
break;
}
g_string_assign (parser->value, "");
}
static void
......@@ -331,7 +353,8 @@ tips_parser_characters (GMarkupParseContext *context,
/* strip tabs, newlines and adjacent whitespace */
for (i = 0; i < text_len; i++)
{
if (text[i] != ' ' && text[i] != '\t' && text[i] != '\n')
if (text[i] != ' ' &&
text[i] != '\t' && text[i] != '\n' && text[i] != '\r')
g_string_append_c (parser->value, text[i]);
else if (parser->value->len > 0 &&
parser->value->str[parser->value->len - 1] != ' ')
......@@ -354,20 +377,38 @@ tips_parser_error (GMarkupParseContext *context,
g_warning ("%s: %s", parser->filename, error->message);
}
static void
tips_parser_start_markup (TipsParser *parser,
const gchar *markup_name)
{
parser->markup_depth++;
g_string_append_printf (parser->value, "<%s>", markup_name);
}
static void
tips_parser_end_markup (TipsParser *parser,
const gchar *markup_name)
{
g_assert (parser->markup_depth > 0);
parser->markup_depth--;
g_string_append_printf (parser->value, "</%s>", markup_name);
}
static void
tips_parser_start_unknown (TipsParser *parser)
{
if (parser->unknown_depth == 0)
parser->last_known_state = parser->state;
parser->state = TIPS_UNKNOWN;
parser->state = TIPS_IN_UNKNOWN;
parser->unknown_depth++;
}
static void
tips_parser_end_unknown (TipsParser *parser)
{
g_assert (parser->unknown_depth > 0 && parser->state == TIPS_UNKNOWN);
g_assert (parser->unknown_depth > 0 && parser->state == TIPS_IN_UNKNOWN);
parser->unknown_depth--;
......
......@@ -8,7 +8,10 @@
<!-- Tips in this file have been contributed by Zachary Beane, Mo Oishi, -->
<!-- Raphael Quinet, Sven Neumann, Carey Bunks and other people on the -->
<!-- gimp mailing lists and newsgroup (comp.graphics.apps.gimp). -->
<!-- -->
<!-- The tips parser supports a very basic markup language. You may use -->
<!-- the tag b to specify bold text, big to increase the font size and -->
<!-- tt to switch to a monospace font. -->
<!-- -->
<!-- The first tip should be a welcome message, because this is the -->
......@@ -17,7 +20,7 @@
<tip level="start">
<_welcome>
Welcome to the GIMP !
<big>Welcome to The GIMP !</big>
</_welcome>
<_thetip>
Nearly all image operations are performed by right-clicking
......@@ -52,7 +55,7 @@
<tip level="beginner">
<_thetip>
When you save an image to work on it again later, try using XCF,
the GIMP's native file format (use the file extension &quot;.xcf&quot;).
the GIMP's native file format (use the file extension <tt>.xcf</tt>).
This preserves the layers and every aspect of your work-in-progress.
Once a project is completed, you can save it as JPEG, PNG, GIF, ...
</_thetip>
......@@ -96,16 +99,16 @@
<tip level="intermediate">
<_thetip>
When using a drawing tool (Paintbrush, Airbrush, or Pencil),
Shift-click will draw a straight line from your last drawing
point to your current cursor position. If you also press Ctrl,
<tt>Shift</tt>-click will draw a straight line from your last drawing
point to your current cursor position. If you also press <tt>Ctrl</tt>,
the line will be constrained to 15 degree angles.
</_thetip>
</tip>
<tip level="intermediate">
<_thetip>
The file selection dialog box has command-line completion with
Tab, just like the shell. Type part of a filename, hit tab, and voila!
It's completed.
<tt>Tab</tt>, just like the shell. Type part of a filename, hit
<tt>Tab</tt>, and voila! It's completed.
</_thetip>
</tip>
<tip level="intermediate">
......@@ -117,8 +120,8 @@
</tip>
<tip level="intermediate">
<_thetip>
You can use the middle mouse button to pan around
the image, if it's larger than its display window.
You can use the middle mouse button to pan around the image, if it's
larger than its display window.
</_thetip>
</tip>
<tip level="intermediate">
......@@ -130,7 +133,7 @@
</tip>
<tip level="intermediate">
<_thetip>
You can drag a layer from the &quot;Layers, Channels and Paths&quot;
You can drag a layer from the <i>Layers, Channels and Paths</i>
dialog and drop it onto the toolbox. This will create a new image
containing only that layer.
</_thetip>
......@@ -145,24 +148,25 @@
</tip>
<tip level="intermediate">
<_thetip>
The GIMP supports gzip compression on the fly. Just add
&quot;.gz&quot; (or &quot;.bz2&quot;, if you have bzip2 installed) to
the filename and your image will be saved compressed. Of course loading
compressed images works too.
The GIMP supports gzip compression on the fly. Just add <tt>.gz</tt>
(or <tt>.bz2</tt>, if you have bzip2 installed) to the filename and
your image will be saved compressed. Of course loading compressed
images works too.
</_thetip>
</tip>
<tip level="intermediate">
<_thetip>
Pressing and holding the Shift key before making a selection allows
you to add to the current selection instead of replacing it. Using
Ctrl before making a selection subtracts from the current one.
Pressing and holding the <tt>Shift</tt> key before making a selection
allows you to add to the current selection instead of replacing it.
Using <tt>Ctrl</tt> before making a selection subtracts from the
current one.
</_thetip>
</tip>
<tip level="intermediate">
<_thetip>
You can press or release the Shift and Ctrl keys while you are
making a selection in order to constrain it to a perfect square
or circle, or to have it centered on its starting point.
You can press or release the <tt>Shift</tt> and <tt>Ctrl</tt> keys
while you are making a selection in order to constrain it to a perfect
square or circle, or to have it centered on its starting point.
</_thetip>
</tip>
<tip level="intermediate">
......@@ -212,8 +216,8 @@
<tip level="advanced">
<_thetip>
If your screen is too cluttered, you can press Tab multiple times
in an image window to hide or show the toolbox and other dialogs.
If your screen is too cluttered, you can press <tt>Tab</tt> multiple
times in an image window to hide or show the toolbox and other dialogs.
</_thetip>
</tip>
<tip level="advanced">
......@@ -224,43 +228,43 @@
</tip>
<tip level="advanced">
<_thetip>
Shift-click on the eye icon in the Layers dialog to hide all
layers but that one. Shift-click again to show all layers.
<tt>Shift</tt>-click on the eye icon in the Layers dialog to hide all
layers but that one. <tt>Shift</tt>-click again to show all layers.
</_thetip>
</tip>
<tip level="advanced">
<_thetip>
Ctrl-click on the layer mask's preview in the Layers dialog
<tt>Ctrl</tt>-click on the layer mask's preview in the Layers dialog
toggles the effect of the layer mask.
</_thetip>
</tip>
<tip level="advanced">
<_thetip>
Alt-click on the layer mask's preview in the Layers dialog
<tt>Alt</tt>-click on the layer mask's preview in the Layers dialog
toggles viewing the mask directly.
</_thetip>
</tip>
<tip level="advanced">
<_thetip>
You can use Alt-Tab to cycle through all layers in an image
(if your window manager doesn't trap those keys...).
You can use <tt>Alt</tt>-<tt>Tab</tt> to cycle through all layers in
an image (if your window manager doesn't trap those keys...).
</_thetip>
</tip>
<tip level="advanced">
<_thetip>
Shift-click with the Bucket Fill tool to have it use
<tt>Shift</tt>-click with the Bucket Fill tool to have it use
the background color instead of the foreground color.
</_thetip>
</tip>
<tip level="advanced">
<_thetip>
Control-drag with the Transform tool in rotation mode
<tt>Ctrl</tt>-drag with the Transform tool in rotation mode
will constrain the rotation to 15 degree angles.
</_thetip>
</tip>
<tip level="advanced">
<_thetip>
You can adjust and re-place a selection by using Alt-drag.
You can adjust and re-place a selection by using <tt>Alt</tt>-drag.
</_thetip>
</tip>
<tip level="advanced">
......@@ -268,15 +272,16 @@
If your fonts turn out blocky, that's because they're not scalable
fonts. Most X servers support scalable Type 1 Postscript fonts.
Download and install them. Some font servers allow you to use
TrueType (.ttf) fonts, which are also scalable.
TrueType (<tt>.ttf</tt>) fonts, which are also scalable.
</_thetip>
</tip>
<tip level="advanced">
<_thetip>
To create a perfect circle, hold Shift while doing an ellipse select. To
place a circle precisely, drag horizontal and vertical guides tangent to
the circle you want to select, place your cursor at the intersection
of the guides, and the resulting selection will just touch the guides.
To create a perfect circle, hold <tt>Shift</tt> while doing an ellipse
select. To place a circle precisely, drag horizontal and vertical guides
tangent to the circle you want to select, place your cursor at the
intersection of the guides, and the resulting selection will just touch
the guides.