~ubuntu-branches/ubuntu/jaunty/gimp/jaunty-security

« back to all changes in this revision

Viewing changes to app/display/gimpstatusbar.c

  • Committer: Bazaar Package Importer
  • Author(s): Daniel Holbach
  • Date: 2007-05-02 16:33:03 UTC
  • mfrom: (1.1.4 upstream)
  • Revision ID: james.westby@ubuntu.com-20070502163303-bvzhjzbpw8qglc4y
Tags: 2.3.16-1ubuntu1
* Resynchronized with Debian, remaining Ubuntu changes:
  - debian/rules: i18n magic.
* debian/control.in:
  - Maintainer: Ubuntu Core Developers <ubuntu-devel@lists.ubuntu.com>
* debian/patches/02_help-message.patch,
  debian/patches/03_gimp.desktop.in.in.patch,
  debian/patches/10_dont_show_wizard.patch: updated.
* debian/patches/04_composite-signedness.patch,
  debian/patches/05_add-letter-spacing.patch: dropped, used upstream.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* The GIMP -- an image manipulation program
2
 
 * Copyright (C) 1995 Spencer Kimball and Peter Mattis
 
1
/* GIMP - The GNU Image Manipulation Program Copyright (C) 1995
 
2
 * Spencer Kimball and Peter Mattis
3
3
 *
4
4
 * This program is free software; you can redistribute it and/or modify
5
5
 * it under the terms of the GNU General Public License as published by
18
18
 
19
19
#include "config.h"
20
20
 
 
21
#include <string.h>
 
22
 
21
23
#include <gtk/gtk.h>
22
24
 
 
25
#include "libgimpmath/gimpmath.h"
23
26
#include "libgimpwidgets/gimpwidgets.h"
24
27
 
25
28
#include "display-types.h"
26
29
 
27
30
#include "core/gimpimage.h"
28
31
#include "core/gimpunit.h"
29
 
#include "core/gimpmarshal.h"
30
32
#include "core/gimpprogress.h"
31
33
 
 
34
#include "widgets/gimpuimanager.h"
32
35
#include "widgets/gimpunitstore.h"
33
36
#include "widgets/gimpunitcombobox.h"
 
37
#include "widgets/gimpwidgets-utils.h"
34
38
 
35
39
#include "gimpdisplay.h"
36
40
#include "gimpdisplayshell.h"
41
45
#include "gimp-intl.h"
42
46
 
43
47
 
 
48
/* maximal width of the string holding the cursor-coordinates for
 
49
 * the status line
 
50
 */
 
51
#define CURSOR_LEN       256
 
52
 
 
53
#define MESSAGE_TIMEOUT  5000
 
54
 
 
55
 
44
56
typedef struct _GimpStatusbarMsg GimpStatusbarMsg;
45
57
 
46
58
struct _GimpStatusbarMsg
47
59
{
48
60
  guint  context_id;
 
61
  gchar *stock_id;
49
62
  gchar *text;
50
63
};
51
64
 
52
 
/* maximal width of the string holding the cursor-coordinates for
53
 
 * the status line
54
 
 */
55
 
#define CURSOR_LEN 256
56
 
 
57
 
 
58
 
static void     gimp_statusbar_class_init     (GimpStatusbarClass *klass);
59
 
static void     gimp_statusbar_init           (GimpStatusbar      *statusbar);
60
 
static void     gimp_statusbar_progress_iface_init (GimpProgressInterface *progress_iface);
 
65
 
 
66
static void     gimp_statusbar_progress_iface_init (GimpProgressInterface *iface);
 
67
 
 
68
static void     gimp_statusbar_finalize           (GObject           *object);
61
69
 
62
70
static void     gimp_statusbar_destroy            (GtkObject         *object);
63
71
 
72
80
static void     gimp_statusbar_progress_set_value (GimpProgress      *progress,
73
81
                                                   gdouble            percentage);
74
82
static gdouble  gimp_statusbar_progress_get_value (GimpProgress      *progress);
 
83
static void     gimp_statusbar_progress_pulse     (GimpProgress      *progress);
 
84
static gboolean gimp_statusbar_progress_message   (GimpProgress      *progress,
 
85
                                                   Gimp              *gimp,
 
86
                                                   GimpMessageSeverity severity,
 
87
                                                   const gchar       *domain,
 
88
                                                   const gchar       *message);
75
89
static void     gimp_statusbar_progress_canceled  (GtkWidget         *button,
76
90
                                                   GimpStatusbar     *statusbar);
77
91
 
 
92
static void     gimp_statusbar_progress_style_set (GtkWidget         *widget,
 
93
                                                   GtkStyle          *prev_style,
 
94
                                                   GimpStatusbar     *statusbar);
 
95
static gboolean gimp_statusbar_progress_expose    (GtkWidget         *widget,
 
96
                                                   GdkEventExpose    *event,
 
97
                                                   GimpStatusbar     *statusbar);
 
98
 
78
99
static void     gimp_statusbar_update             (GimpStatusbar     *statusbar);
79
100
static void     gimp_statusbar_unit_changed       (GimpUnitComboBox  *combo,
80
101
                                                   GimpStatusbar     *statusbar);
84
105
                                                   GimpStatusbar     *statusbar);
85
106
static guint    gimp_statusbar_get_context_id     (GimpStatusbar     *statusbar,
86
107
                                                   const gchar       *context);
87
 
 
88
 
 
89
 
static GtkHBoxClass *parent_class = NULL;
90
 
 
91
 
 
92
 
GType
93
 
gimp_statusbar_get_type (void)
94
 
{
95
 
  static GType statusbar_type = 0;
96
 
 
97
 
  if (! statusbar_type)
98
 
    {
99
 
      static const GTypeInfo statusbar_info =
100
 
      {
101
 
        sizeof (GimpStatusbarClass),
102
 
        (GBaseInitFunc) NULL,
103
 
        (GBaseFinalizeFunc) NULL,
104
 
        (GClassInitFunc) gimp_statusbar_class_init,
105
 
        NULL,           /* class_finalize */
106
 
        NULL,           /* class_data     */
107
 
        sizeof (GimpStatusbar),
108
 
        0,              /* n_preallocs    */
109
 
        (GInstanceInitFunc) gimp_statusbar_init,
110
 
      };
111
 
 
112
 
      static const GInterfaceInfo progress_iface_info =
113
 
      {
114
 
        (GInterfaceInitFunc) gimp_statusbar_progress_iface_init,
115
 
        NULL,           /* iface_finalize */
116
 
        NULL            /* iface_data     */
117
 
      };
118
 
 
119
 
      statusbar_type = g_type_register_static (GTK_TYPE_HBOX,
120
 
                                               "GimpStatusbar",
121
 
                                               &statusbar_info, 0);
122
 
 
123
 
      g_type_add_interface_static (statusbar_type, GIMP_TYPE_PROGRESS,
124
 
                                   &progress_iface_info);
125
 
    }
126
 
 
127
 
  return statusbar_type;
128
 
}
 
108
static gboolean gimp_statusbar_temp_timeout       (GimpStatusbar     *statusbar);
 
109
 
 
110
static void     gimp_statusbar_msg_free           (GimpStatusbarMsg  *msg);
 
111
 
 
112
static gchar *  gimp_statusbar_vprintf            (const gchar       *format,
 
113
                                                   va_list            args);
 
114
 
 
115
 
 
116
G_DEFINE_TYPE_WITH_CODE (GimpStatusbar, gimp_statusbar, GTK_TYPE_HBOX,
 
117
                         G_IMPLEMENT_INTERFACE (GIMP_TYPE_PROGRESS,
 
118
                                                gimp_statusbar_progress_iface_init))
 
119
 
 
120
#define parent_class gimp_statusbar_parent_class
 
121
 
129
122
 
130
123
static void
131
124
gimp_statusbar_class_init (GimpStatusbarClass *klass)
132
125
{
133
 
  GtkObjectClass *object_class = GTK_OBJECT_CLASS (klass);
134
 
  GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
135
 
 
136
 
  parent_class = g_type_class_peek_parent (klass);
137
 
 
138
 
  object_class->destroy = gimp_statusbar_destroy;
139
 
 
140
 
  gtk_widget_class_install_style_property (widget_class,
141
 
                                           g_param_spec_enum ("shadow_type",
142
 
                                           _("Shadow type"),
143
 
                                           _("Style of bevel around the statusbar text"),
144
 
                                           GTK_TYPE_SHADOW_TYPE,
145
 
                                           GTK_SHADOW_IN,
146
 
                                           G_PARAM_READABLE));
 
126
  GObjectClass   *object_class     = G_OBJECT_CLASS (klass);
 
127
  GtkObjectClass *gtk_object_class = GTK_OBJECT_CLASS (klass);
 
128
 
 
129
  object_class->finalize    = gimp_statusbar_finalize;
 
130
 
 
131
  gtk_object_class->destroy = gimp_statusbar_destroy;
 
132
}
 
133
 
 
134
static void
 
135
gimp_statusbar_progress_iface_init (GimpProgressInterface *iface)
 
136
{
 
137
  iface->start     = gimp_statusbar_progress_start;
 
138
  iface->end       = gimp_statusbar_progress_end;
 
139
  iface->is_active = gimp_statusbar_progress_is_active;
 
140
  iface->set_text  = gimp_statusbar_progress_set_text;
 
141
  iface->set_value = gimp_statusbar_progress_set_value;
 
142
  iface->get_value = gimp_statusbar_progress_get_value;
 
143
  iface->pulse     = gimp_statusbar_progress_pulse;
 
144
  iface->message   = gimp_statusbar_progress_message;
147
145
}
148
146
 
149
147
static void
150
148
gimp_statusbar_init (GimpStatusbar *statusbar)
151
149
{
152
150
  GtkBox        *box = GTK_BOX (statusbar);
153
 
  GtkWidget     *hbox;
154
 
  GtkWidget     *frame;
155
151
  GimpUnitStore *store;
156
 
  GtkShadowType  shadow_type;
157
 
  gboolean       has_focus_on_click;
158
 
 
159
 
  box->spacing     = 2;
160
 
  box->homogeneous = FALSE;
161
 
 
162
 
  statusbar->shell                = NULL;
 
152
 
 
153
  statusbar->shell          = NULL;
 
154
  statusbar->messages       = NULL;
 
155
  statusbar->context_ids    = g_hash_table_new_full (g_str_hash, g_str_equal,
 
156
                                                     g_free, NULL);
 
157
  statusbar->seq_context_id = 1;
 
158
 
 
159
  statusbar->temp_context_id =
 
160
    gimp_statusbar_get_context_id (statusbar, "gimp-statusbar-temp");
 
161
 
163
162
  statusbar->cursor_format_str[0] = '\0';
164
163
  statusbar->length_format_str[0] = '\0';
 
164
 
165
165
  statusbar->progress_active      = FALSE;
166
166
 
167
 
  gtk_box_set_spacing (box, 1);
168
 
 
169
 
  gtk_widget_style_get (GTK_WIDGET (statusbar),
170
 
                        "shadow_type", &shadow_type,
171
 
                        NULL);
172
 
 
173
 
  statusbar->cursor_frame = gtk_frame_new (NULL);
174
 
  gtk_frame_set_shadow_type (GTK_FRAME (statusbar->cursor_frame), shadow_type);
 
167
  box->spacing     = 2;
 
168
  box->homogeneous = FALSE;
 
169
 
 
170
  statusbar->cursor_frame = gtk_hbox_new (FALSE, 0);
175
171
  gtk_box_pack_start (box, statusbar->cursor_frame, FALSE, FALSE, 0);
176
172
  gtk_box_reorder_child (box, statusbar->cursor_frame, 0);
177
173
  gtk_widget_show (statusbar->cursor_frame);
178
174
 
179
 
  hbox = gtk_hbox_new (FALSE, 1);
180
 
  gtk_container_add (GTK_CONTAINER (statusbar->cursor_frame), hbox);
181
 
  gtk_widget_show (hbox);
182
 
 
183
175
  statusbar->cursor_label = gtk_label_new ("0, 0");
184
176
  gtk_misc_set_alignment (GTK_MISC (statusbar->cursor_label), 0.5, 0.5);
185
 
  gtk_container_add (GTK_CONTAINER (hbox), statusbar->cursor_label);
 
177
  gtk_container_add (GTK_CONTAINER (statusbar->cursor_frame),
 
178
                     statusbar->cursor_label);
186
179
  gtk_widget_show (statusbar->cursor_label);
187
180
 
188
181
  store = gimp_unit_store_new (2);
189
182
  statusbar->unit_combo = gimp_unit_combo_box_new_with_model (store);
190
183
  g_object_unref (store);
191
184
 
192
 
  has_focus_on_click =
193
 
    g_object_class_find_property (G_OBJECT_GET_CLASS (statusbar->unit_combo),
194
 
                                  "focus-on-click") != NULL;
195
 
 
196
185
  GTK_WIDGET_UNSET_FLAGS (statusbar->unit_combo, GTK_CAN_FOCUS);
197
 
  if (has_focus_on_click)
198
 
    g_object_set (statusbar->unit_combo, "focus-on-click", FALSE, NULL);
199
 
  gtk_container_add (GTK_CONTAINER (hbox), statusbar->unit_combo);
 
186
  g_object_set (statusbar->unit_combo, "focus-on-click", FALSE, NULL);
 
187
  gtk_container_add (GTK_CONTAINER (statusbar->cursor_frame),
 
188
                     statusbar->unit_combo);
200
189
  gtk_widget_show (statusbar->unit_combo);
201
190
 
202
191
  g_signal_connect (statusbar->unit_combo, "changed",
203
192
                    G_CALLBACK (gimp_statusbar_unit_changed),
204
193
                    statusbar);
205
194
 
206
 
  frame = gtk_frame_new (NULL);
207
 
  gtk_frame_set_shadow_type (GTK_FRAME (frame), shadow_type);
208
 
  gtk_box_pack_start (box, frame, FALSE, FALSE, 0);
209
 
  gtk_widget_show (frame);
210
 
 
211
195
  statusbar->scale_combo = gimp_scale_combo_box_new ();
212
196
  GTK_WIDGET_UNSET_FLAGS (statusbar->scale_combo, GTK_CAN_FOCUS);
213
 
  if (has_focus_on_click)
214
 
    g_object_set (statusbar->scale_combo, "focus-on-click", FALSE, NULL);
215
 
  gtk_container_add (GTK_CONTAINER (frame), statusbar->scale_combo);
 
197
  g_object_set (statusbar->scale_combo, "focus-on-click", FALSE, NULL);
 
198
  gtk_box_pack_start (box, statusbar->scale_combo, FALSE, FALSE, 0);
216
199
  gtk_widget_show (statusbar->scale_combo);
217
200
 
218
201
  g_signal_connect (statusbar->scale_combo, "changed",
220
203
                    statusbar);
221
204
 
222
205
  statusbar->progressbar = gtk_progress_bar_new ();
 
206
  gtk_progress_bar_set_ellipsize (GTK_PROGRESS_BAR (statusbar->progressbar),
 
207
                                  PANGO_ELLIPSIZE_END);
 
208
  g_object_set (statusbar->progressbar,
 
209
                "text-xalign", 0.0,
 
210
                "text-yalign", 0.5,
 
211
                NULL);
223
212
  gtk_box_pack_start (box, statusbar->progressbar, TRUE, TRUE, 0);
224
213
  gtk_widget_show (statusbar->progressbar);
225
214
 
226
 
  GTK_PROGRESS_BAR (statusbar->progressbar)->progress.x_align = 0.0;
227
 
  GTK_PROGRESS_BAR (statusbar->progressbar)->progress.y_align = 0.5;
 
215
  g_signal_connect_after (statusbar->progressbar, "style-set",
 
216
                          G_CALLBACK (gimp_statusbar_progress_style_set),
 
217
                          statusbar);
 
218
  g_signal_connect_after (statusbar->progressbar, "expose-event",
 
219
                          G_CALLBACK (gimp_statusbar_progress_expose),
 
220
                          statusbar);
228
221
 
229
222
  statusbar->cancel_button = gtk_button_new_with_label (_("Cancel"));
230
223
  gtk_widget_set_sensitive (statusbar->cancel_button, FALSE);
231
224
  gtk_box_pack_start (box, statusbar->cancel_button, FALSE, FALSE, 0);
232
225
  GTK_WIDGET_UNSET_FLAGS (statusbar->cancel_button, GTK_CAN_FOCUS);
233
 
  gtk_widget_show (statusbar->cancel_button);
234
226
 
235
227
  g_signal_connect (statusbar->cancel_button, "clicked",
236
228
                    G_CALLBACK (gimp_statusbar_progress_canceled),
237
229
                    statusbar);
238
 
 
239
 
  /* Update the statusbar once to work around a canvas size problem:
240
 
   *
241
 
   *  The first update of the statusbar used to queue a resize which
242
 
   *  in term caused the canvas to be resized. That made it shrink by
243
 
   *  one pixel in height resulting in the last row not being displayed.
244
 
   *  Shrink-wrapping the display used to fix this reliably. With the
245
 
   *  next call the resize doesn't seem to happen any longer.
246
 
   */
247
 
 
248
 
  gtk_progress_bar_set_text (GTK_PROGRESS_BAR (statusbar->progressbar),
249
 
                             "GIMP");
250
 
 
251
 
  statusbar->seq_context_id = 1;
252
 
  statusbar->messages       = NULL;
253
 
  statusbar->keys           = NULL;
254
 
}
255
 
 
256
 
static void
257
 
gimp_statusbar_progress_iface_init (GimpProgressInterface *progress_iface)
258
 
{
259
 
  progress_iface->start     = gimp_statusbar_progress_start;
260
 
  progress_iface->end       = gimp_statusbar_progress_end;
261
 
  progress_iface->is_active = gimp_statusbar_progress_is_active;
262
 
  progress_iface->set_text  = gimp_statusbar_progress_set_text;
263
 
  progress_iface->set_value = gimp_statusbar_progress_set_value;
264
 
  progress_iface->get_value = gimp_statusbar_progress_get_value;
265
 
}
266
 
 
267
 
static void
268
 
gimp_statusbar_destroy (GtkObject *object)
 
230
}
 
231
 
 
232
static void
 
233
gimp_statusbar_finalize (GObject *object)
269
234
{
270
235
  GimpStatusbar *statusbar = GIMP_STATUSBAR (object);
271
 
  GSList        *list;
272
 
 
273
 
  for (list = statusbar->messages; list; list = list->next)
274
 
    {
275
 
      GimpStatusbarMsg *msg = list->data;
276
 
 
277
 
      g_free (msg->text);
278
 
      g_free (msg);
279
 
    }
280
 
 
 
236
 
 
237
  g_slist_foreach (statusbar->messages, (GFunc) gimp_statusbar_msg_free, NULL);
281
238
  g_slist_free (statusbar->messages);
282
239
  statusbar->messages = NULL;
283
240
 
284
 
  for (list = statusbar->keys; list; list = list->next)
285
 
    g_free (list->data);
286
 
 
287
 
  g_slist_free (statusbar->keys);
288
 
  statusbar->keys = NULL;
 
241
  g_hash_table_destroy (statusbar->context_ids);
 
242
  statusbar->context_ids = NULL;
 
243
 
 
244
  g_free (statusbar->temp_spaces);
 
245
  statusbar->temp_spaces = NULL;
 
246
 
 
247
  G_OBJECT_CLASS (parent_class)->finalize (object);
 
248
}
 
249
 
 
250
static void
 
251
gimp_statusbar_destroy (GtkObject *object)
 
252
{
 
253
  GimpStatusbar *statusbar = GIMP_STATUSBAR (object);
 
254
 
 
255
  if (statusbar->temp_timeout_id)
 
256
    {
 
257
      g_source_remove (statusbar->temp_timeout_id);
 
258
      statusbar->temp_timeout_id = 0;
 
259
    }
289
260
 
290
261
  GTK_OBJECT_CLASS (parent_class)->destroy (object);
291
262
}
301
272
    {
302
273
      GtkWidget *bar = statusbar->progressbar;
303
274
 
304
 
      gimp_statusbar_push (statusbar, "progress", message);
 
275
      gimp_statusbar_push (statusbar, "progress", "%s", message);
305
276
      gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (bar), 0.0);
306
277
      gtk_widget_set_sensitive (statusbar->cancel_button, cancelable);
307
278
 
 
279
      if (cancelable)
 
280
        gtk_widget_show (statusbar->cancel_button);
 
281
 
308
282
      statusbar->progress_active = TRUE;
309
283
 
310
284
      if (GTK_WIDGET_DRAWABLE (bar))
325
299
    {
326
300
      GtkWidget *bar = statusbar->progressbar;
327
301
 
 
302
      statusbar->progress_active = FALSE;
 
303
 
328
304
      gimp_statusbar_pop (statusbar, "progress");
329
305
      gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (bar), 0.0);
330
306
      gtk_widget_set_sensitive (statusbar->cancel_button, FALSE);
331
 
 
332
 
      statusbar->progress_active = FALSE;
 
307
      gtk_widget_hide (statusbar->cancel_button);
333
308
    }
334
309
}
335
310
 
351
326
    {
352
327
      GtkWidget *bar = statusbar->progressbar;
353
328
 
354
 
      gimp_statusbar_replace (statusbar, "progress", message);
 
329
      gimp_statusbar_replace (statusbar, "progress", "%s", message);
355
330
 
356
331
      if (GTK_WIDGET_DRAWABLE (bar))
357
332
        gdk_window_process_updates (bar->window, TRUE);
391
366
}
392
367
 
393
368
static void
 
369
gimp_statusbar_progress_pulse (GimpProgress *progress)
 
370
{
 
371
  GimpStatusbar *statusbar = GIMP_STATUSBAR (progress);
 
372
 
 
373
  if (statusbar->progress_active)
 
374
    {
 
375
      GtkWidget *bar = statusbar->progressbar;
 
376
 
 
377
      gtk_progress_bar_pulse (GTK_PROGRESS_BAR (bar));
 
378
 
 
379
      if (GTK_WIDGET_DRAWABLE (bar))
 
380
        gdk_window_process_updates (bar->window, TRUE);
 
381
    }
 
382
}
 
383
 
 
384
static gboolean
 
385
gimp_statusbar_progress_message (GimpProgress        *progress,
 
386
                                 Gimp                *gimp,
 
387
                                 GimpMessageSeverity  severity,
 
388
                                 const gchar         *domain,
 
389
                                 const gchar         *message)
 
390
{
 
391
  GimpStatusbar *statusbar = GIMP_STATUSBAR (progress);
 
392
 
 
393
  /*  we can handle only one-liners  */
 
394
  if (strchr (message, '\n'))
 
395
    return FALSE;
 
396
 
 
397
  gimp_statusbar_push_temp (statusbar,
 
398
                            gimp_get_message_stock_id (severity), "%s", message);
 
399
 
 
400
  return TRUE;
 
401
}
 
402
 
 
403
static void
394
404
gimp_statusbar_progress_canceled (GtkWidget     *button,
395
405
                                  GimpStatusbar *statusbar)
396
406
{
401
411
static void
402
412
gimp_statusbar_update (GimpStatusbar *statusbar)
403
413
{
404
 
  gchar *text = NULL;
 
414
  const gchar *text = NULL;
405
415
 
406
416
  if (statusbar->messages)
407
417
    {
408
418
      GimpStatusbarMsg *msg = statusbar->messages->data;
409
419
 
 
420
      /*  only allow progress messages while the progress is active  */
 
421
      if (statusbar->progress_active)
 
422
        {
 
423
          guint context_id = gimp_statusbar_get_context_id (statusbar,
 
424
                                                            "progress");
 
425
 
 
426
          if (context_id != msg->context_id)
 
427
            return;
 
428
        }
 
429
 
410
430
      text = msg->text;
411
431
    }
412
432
 
413
 
  gtk_progress_bar_set_text (GTK_PROGRESS_BAR (statusbar->progressbar),
414
 
                             text ? text : "");
 
433
  if (text && statusbar->temp_timeout_id)
 
434
    {
 
435
      gchar *temp = g_strconcat (statusbar->temp_spaces, text, NULL);
 
436
      gtk_progress_bar_set_text (GTK_PROGRESS_BAR (statusbar->progressbar),
 
437
                                 temp);
 
438
      g_free (temp);
 
439
    }
 
440
  else
 
441
    {
 
442
      gtk_progress_bar_set_text (GTK_PROGRESS_BAR (statusbar->progressbar),
 
443
                                 text ? text : "");
 
444
    }
415
445
}
416
446
 
 
447
 
 
448
/*  public functions  */
 
449
 
417
450
GtkWidget *
418
451
gimp_statusbar_new (GimpDisplayShell *shell)
419
452
{
420
453
  GimpStatusbar *statusbar;
 
454
  GtkAction     *action;
421
455
 
422
456
  g_return_val_if_fail (GIMP_IS_DISPLAY_SHELL (shell), NULL);
423
457
 
425
459
 
426
460
  statusbar->shell = shell;
427
461
 
 
462
  action = gimp_ui_manager_find_action (shell->menubar_manager,
 
463
                                        "view", "view-zoom-other");
 
464
 
 
465
  if (action)
 
466
    {
 
467
      GimpScaleComboBox *combo = GIMP_SCALE_COMBO_BOX (statusbar->scale_combo);
 
468
 
 
469
      gimp_scale_combo_box_add_action (combo, action, _("Other..."));
 
470
    }
 
471
 
428
472
  g_signal_connect_object (shell, "scaled",
429
473
                           G_CALLBACK (gimp_statusbar_shell_scaled),
430
474
                           statusbar, 0);
435
479
void
436
480
gimp_statusbar_push (GimpStatusbar *statusbar,
437
481
                     const gchar   *context,
438
 
                     const gchar   *message)
 
482
                     const gchar   *format,
 
483
                     ...)
 
484
{
 
485
  va_list args;
 
486
 
 
487
  g_return_if_fail (GIMP_IS_STATUSBAR (statusbar));
 
488
  g_return_if_fail (context != NULL);
 
489
  g_return_if_fail (format != NULL);
 
490
 
 
491
  va_start (args, format);
 
492
  gimp_statusbar_push_valist (statusbar, context, format, args);
 
493
  va_end (args);
 
494
}
 
495
 
 
496
void
 
497
gimp_statusbar_push_valist (GimpStatusbar *statusbar,
 
498
                            const gchar   *context,
 
499
                            const gchar   *format,
 
500
                            va_list        args)
439
501
{
440
502
  GimpStatusbarMsg *msg;
441
503
  guint             context_id;
442
504
  GSList           *list;
 
505
  gchar            *message;
443
506
 
444
507
  g_return_if_fail (GIMP_IS_STATUSBAR (statusbar));
445
 
  g_return_if_fail (message != NULL);
 
508
  g_return_if_fail (context != NULL);
 
509
  g_return_if_fail (format != NULL);
 
510
 
 
511
  message = gimp_statusbar_vprintf (format, args);
446
512
 
447
513
  context_id = gimp_statusbar_get_context_id (statusbar, context);
448
514
 
 
515
  if (statusbar->messages)
 
516
    {
 
517
      msg = statusbar->messages->data;
 
518
 
 
519
      if (msg->context_id == context_id && strcmp (msg->text, message) == 0)
 
520
        {
 
521
          g_free (message);
 
522
          return;
 
523
        }
 
524
    }
 
525
 
449
526
  for (list = statusbar->messages; list; list = g_slist_next (list))
450
527
    {
451
528
      msg = list->data;
453
530
      if (msg->context_id == context_id)
454
531
        {
455
532
          statusbar->messages = g_slist_remove (statusbar->messages, msg);
456
 
          g_free (msg->text);
457
 
          g_free (msg);
 
533
          gimp_statusbar_msg_free (msg);
458
534
 
459
535
          break;
460
536
        }
463
539
  msg = g_new0 (GimpStatusbarMsg, 1);
464
540
 
465
541
  msg->context_id = context_id;
466
 
  msg->text       = g_strdup (message);
 
542
  msg->text       = message;
467
543
 
468
 
  statusbar->messages = g_slist_prepend (statusbar->messages, msg);
 
544
  if (statusbar->temp_timeout_id)
 
545
    statusbar->messages = g_slist_insert (statusbar->messages, msg, 1);
 
546
  else
 
547
    statusbar->messages = g_slist_prepend (statusbar->messages, msg);
469
548
 
470
549
  gimp_statusbar_update (statusbar);
471
550
}
476
555
                            const gchar   *title,
477
556
                            gdouble        x,
478
557
                            const gchar   *separator,
479
 
                            gdouble        y)
 
558
                            gdouble        y,
 
559
                            const gchar   *help)
480
560
{
481
561
  GimpDisplayShell *shell;
482
 
  gchar             buf[CURSOR_LEN];
483
562
 
484
563
  g_return_if_fail (GIMP_IS_STATUSBAR (statusbar));
485
564
  g_return_if_fail (title != NULL);
486
565
  g_return_if_fail (separator != NULL);
 
566
  if (help == NULL)
 
567
    {
 
568
      help = "";
 
569
    }
487
570
 
488
571
  shell = statusbar->shell;
489
572
 
490
573
  if (shell->unit == GIMP_UNIT_PIXEL)
491
574
    {
492
 
      g_snprintf (buf, sizeof (buf), statusbar->cursor_format_str,
493
 
                  title,
494
 
                  (gint) RINT (x),
495
 
                  separator,
496
 
                  (gint) RINT (y));
 
575
      gimp_statusbar_push (statusbar, context,
 
576
                           statusbar->cursor_format_str,
 
577
                           title,
 
578
                           (gint) RINT (x),
 
579
                           separator,
 
580
                           (gint) RINT (y),
 
581
                           help);
497
582
    }
498
583
  else /* show real world units */
499
584
    {
500
 
      GimpImage *image       = shell->gdisp->gimage;
 
585
      GimpImage *image       = shell->display->image;
501
586
      gdouble    unit_factor = _gimp_unit_get_factor (image->gimp,
502
587
                                                      shell->unit);
503
588
 
504
 
      g_snprintf (buf, sizeof (buf), statusbar->cursor_format_str,
505
 
                  title,
506
 
                  x * unit_factor / image->xresolution,
507
 
                  separator,
508
 
                  y * unit_factor / image->yresolution);
 
589
      gimp_statusbar_push (statusbar, context,
 
590
                           statusbar->cursor_format_str,
 
591
                           title,
 
592
                           x * unit_factor / image->xresolution,
 
593
                           separator,
 
594
                           y * unit_factor / image->yresolution,
 
595
                           help);
509
596
    }
510
 
 
511
 
  gimp_statusbar_push (statusbar, context, buf);
512
597
}
513
598
 
514
599
void
516
601
                            const gchar         *context,
517
602
                            const gchar         *title,
518
603
                            GimpOrientationType  axis,
519
 
                            gdouble              value)
 
604
                            gdouble              value,
 
605
                            const gchar         *help)
520
606
{
521
607
  GimpDisplayShell *shell;
522
 
  gchar             buf[CURSOR_LEN];
523
608
 
524
609
  g_return_if_fail (GIMP_IS_STATUSBAR (statusbar));
525
610
  g_return_if_fail (title != NULL);
 
611
  if (help == NULL)
 
612
    {
 
613
      help = "";
 
614
    }
526
615
 
527
616
  shell = statusbar->shell;
528
617
 
529
618
  if (shell->unit == GIMP_UNIT_PIXEL)
530
619
    {
531
 
      g_snprintf (buf, sizeof (buf), statusbar->length_format_str,
532
 
                  title,
533
 
                  (gint) RINT (value));
 
620
      gimp_statusbar_push (statusbar, context,
 
621
                           statusbar->length_format_str,
 
622
                           title,
 
623
                           (gint) RINT (value),
 
624
                           help);
534
625
    }
535
626
  else /* show real world units */
536
627
    {
537
 
      GimpImage *image       = shell->gdisp->gimage;
 
628
      GimpImage *image       = shell->display->image;
538
629
      gdouble    resolution;
539
630
      gdouble    unit_factor = _gimp_unit_get_factor (image->gimp,
540
631
                                                      shell->unit);
554
645
          break;
555
646
        }
556
647
 
557
 
      g_snprintf (buf, sizeof (buf), statusbar->length_format_str,
558
 
                  title,
559
 
                  value * unit_factor / resolution);
 
648
      gimp_statusbar_push (statusbar, context,
 
649
                           statusbar->length_format_str,
 
650
                           title,
 
651
                           value * unit_factor / resolution,
 
652
                           help);
560
653
    }
561
 
 
562
 
  gimp_statusbar_push (statusbar, context, buf);
563
654
}
564
655
 
565
656
void
566
657
gimp_statusbar_replace (GimpStatusbar *statusbar,
567
658
                        const gchar   *context,
568
 
                        const gchar   *message)
 
659
                        const gchar   *format,
 
660
                        ...)
 
661
{
 
662
  va_list args;
 
663
 
 
664
  g_return_if_fail (GIMP_IS_STATUSBAR (statusbar));
 
665
  g_return_if_fail (context != NULL);
 
666
  g_return_if_fail (format != NULL);
 
667
 
 
668
  va_start (args, format);
 
669
  gimp_statusbar_replace_valist (statusbar, context, format, args);
 
670
  va_end (args);
 
671
}
 
672
 
 
673
void
 
674
gimp_statusbar_replace_valist (GimpStatusbar *statusbar,
 
675
                               const gchar   *context,
 
676
                               const gchar   *format,
 
677
                               va_list        args)
569
678
{
570
679
  GimpStatusbarMsg *msg;
 
680
  GSList           *list;
571
681
  guint             context_id;
572
 
  GSList           *list;
 
682
  gchar            *message;
573
683
 
574
684
  g_return_if_fail (GIMP_IS_STATUSBAR (statusbar));
575
 
  g_return_if_fail (message != NULL);
 
685
  g_return_if_fail (context != NULL);
 
686
  g_return_if_fail (format != NULL);
576
687
 
577
 
  if (! statusbar->messages)
578
 
    {
579
 
      gimp_statusbar_push (statusbar, context, message);
580
 
      return;
581
 
    }
 
688
  message =  gimp_statusbar_vprintf (format, args);
582
689
 
583
690
  context_id = gimp_statusbar_get_context_id (statusbar, context);
584
691
 
585
 
  msg = statusbar->messages->data;
586
 
 
587
 
  if (msg->context_id == context_id)
588
 
    {
589
 
      gimp_statusbar_pop (statusbar, context);
590
 
      gimp_statusbar_push (statusbar, context, message);
591
 
 
592
 
      return;
593
 
    }
594
 
 
595
692
  for (list = statusbar->messages; list; list = g_slist_next (list))
596
693
    {
597
694
      msg = list->data;
599
696
      if (msg->context_id == context_id)
600
697
        {
601
698
          g_free (msg->text);
602
 
          msg->text = g_strdup (message);
 
699
          msg->text = message;
 
700
 
 
701
          if (list == statusbar->messages)
 
702
            gimp_statusbar_update (statusbar);
603
703
 
604
704
          return;
605
705
        }
608
708
  msg = g_new0 (GimpStatusbarMsg, 1);
609
709
 
610
710
  msg->context_id = context_id;
611
 
  msg->text       = g_strdup (message);
 
711
  msg->text       = message;
612
712
 
613
 
  statusbar->messages = g_slist_prepend (statusbar->messages, msg);
 
713
  if (statusbar->temp_timeout_id)
 
714
    statusbar->messages = g_slist_insert (statusbar->messages, msg, 1);
 
715
  else
 
716
    statusbar->messages = g_slist_prepend (statusbar->messages, msg);
614
717
 
615
718
  gimp_statusbar_update (statusbar);
616
719
}
619
722
gimp_statusbar_pop (GimpStatusbar *statusbar,
620
723
                    const gchar   *context)
621
724
{
 
725
  GSList *list;
622
726
  guint   context_id;
623
 
  GSList *list;
624
727
 
625
728
  g_return_if_fail (GIMP_IS_STATUSBAR (statusbar));
 
729
  g_return_if_fail (context != NULL);
626
730
 
627
731
  context_id = gimp_statusbar_get_context_id (statusbar, context);
628
732
 
633
737
      if (msg->context_id == context_id)
634
738
        {
635
739
          statusbar->messages = g_slist_remove (statusbar->messages, msg);
 
740
          gimp_statusbar_msg_free (msg);
 
741
 
 
742
          break;
 
743
        }
 
744
    }
 
745
 
 
746
  gimp_statusbar_update (statusbar);
 
747
}
 
748
 
 
749
void
 
750
gimp_statusbar_push_temp (GimpStatusbar *statusbar,
 
751
                          const gchar   *stock_id,
 
752
                          const gchar   *format,
 
753
                          ...)
 
754
{
 
755
  va_list args;
 
756
 
 
757
  g_return_if_fail (GIMP_IS_STATUSBAR (statusbar));
 
758
  g_return_if_fail (format != NULL);
 
759
 
 
760
  va_start (args, format);
 
761
  gimp_statusbar_push_temp_valist (statusbar, stock_id, format, args);
 
762
  va_end (args);
 
763
}
 
764
 
 
765
void
 
766
gimp_statusbar_push_temp_valist (GimpStatusbar *statusbar,
 
767
                                 const gchar   *stock_id,
 
768
                                 const gchar   *format,
 
769
                                 va_list        args)
 
770
{
 
771
  GimpStatusbarMsg *msg = NULL;
 
772
  gchar            *message;
 
773
 
 
774
  g_return_if_fail (GIMP_IS_STATUSBAR (statusbar));
 
775
  g_return_if_fail (format != NULL);
 
776
 
 
777
  message = gimp_statusbar_vprintf (format, args);
 
778
 
 
779
  if (statusbar->temp_timeout_id)
 
780
    g_source_remove (statusbar->temp_timeout_id);
 
781
 
 
782
  statusbar->temp_timeout_id =
 
783
    g_timeout_add (MESSAGE_TIMEOUT,
 
784
                   (GSourceFunc) gimp_statusbar_temp_timeout, statusbar);
 
785
 
 
786
  if (statusbar->messages)
 
787
    {
 
788
      msg = statusbar->messages->data;
 
789
 
 
790
      if (msg->context_id == statusbar->temp_context_id)
 
791
        {
 
792
          if (strcmp (msg->text, message) == 0)
 
793
            {
 
794
              g_free (message);
 
795
              return;
 
796
            }
 
797
 
 
798
          g_free (msg->stock_id);
 
799
          msg->stock_id = g_strdup (stock_id);
 
800
 
636
801
          g_free (msg->text);
637
 
          g_free (msg);
 
802
          msg->text = message;
638
803
 
639
 
          break;
 
804
          gimp_statusbar_update (statusbar);
 
805
          return;
640
806
        }
641
807
    }
642
808
 
 
809
  msg = g_new0 (GimpStatusbarMsg, 1);
 
810
 
 
811
  msg->context_id = statusbar->temp_context_id;
 
812
  msg->stock_id   = g_strdup (stock_id);
 
813
  msg->text       = message;
 
814
 
 
815
  statusbar->messages = g_slist_prepend (statusbar->messages, msg);
 
816
 
643
817
  gimp_statusbar_update (statusbar);
644
818
}
645
819
 
646
820
void
647
 
gimp_statusbar_set_cursor (GimpStatusbar *statusbar,
648
 
                           gdouble        x,
649
 
                           gdouble        y)
 
821
gimp_statusbar_pop_temp (GimpStatusbar *statusbar)
 
822
{
 
823
  g_return_if_fail (GIMP_IS_STATUSBAR (statusbar));
 
824
 
 
825
  if (statusbar->temp_timeout_id)
 
826
    {
 
827
      g_source_remove (statusbar->temp_timeout_id);
 
828
      statusbar->temp_timeout_id = 0;
 
829
    }
 
830
 
 
831
  if (statusbar->messages)
 
832
    {
 
833
      GimpStatusbarMsg *msg = statusbar->messages->data;
 
834
 
 
835
      if (msg->context_id == statusbar->temp_context_id)
 
836
        {
 
837
          statusbar->messages = g_slist_remove (statusbar->messages, msg);
 
838
          gimp_statusbar_msg_free (msg);
 
839
 
 
840
          gimp_statusbar_update (statusbar);
 
841
        }
 
842
    }
 
843
}
 
844
 
 
845
void
 
846
gimp_statusbar_update_cursor (GimpStatusbar *statusbar,
 
847
                              gdouble        x,
 
848
                              gdouble        y)
650
849
{
651
850
  GimpDisplayShell *shell;
652
851
  GtkTreeModel     *model;
657
856
 
658
857
  shell = statusbar->shell;
659
858
 
 
859
  if (x <  0 ||
 
860
      y <  0 ||
 
861
      x >= shell->display->image->width ||
 
862
      y >= shell->display->image->height)
 
863
    {
 
864
      gtk_widget_set_sensitive (statusbar->cursor_label, FALSE);
 
865
    }
 
866
  else
 
867
    {
 
868
      gtk_widget_set_sensitive (statusbar->cursor_label, TRUE);
 
869
    }
 
870
 
660
871
  model = gtk_combo_box_get_model (GTK_COMBO_BOX (statusbar->unit_combo));
661
872
  store = GIMP_UNIT_STORE (model);
662
873
 
666
877
    {
667
878
      g_snprintf (buffer, sizeof (buffer),
668
879
                  statusbar->cursor_format_str,
669
 
                  "", (gint) RINT (x), ", ", (gint) RINT (y));
 
880
                  "", (gint) RINT (x), ", ", (gint) RINT (y), "");
670
881
    }
671
882
  else /* show real world units */
672
883
    {
674
885
 
675
886
      g_snprintf (buffer, sizeof (buffer),
676
887
                  statusbar->cursor_format_str,
677
 
                  "", x, ", ", y);
 
888
                  "", x, ", ", y, "");
678
889
    }
679
890
 
680
891
  gtk_label_set_text (GTK_LABEL (statusbar->cursor_label), buffer);
681
 
 
682
 
  if (x <  0 ||
683
 
      y <  0 ||
684
 
      x >= statusbar->shell->gdisp->gimage->width ||
685
 
      y >= statusbar->shell->gdisp->gimage->height)
686
 
    {
687
 
      gtk_widget_set_sensitive (statusbar->cursor_label, FALSE);
688
 
    }
689
 
  else
690
 
    {
691
 
      gtk_widget_set_sensitive (statusbar->cursor_label, TRUE);
692
 
    }
693
892
}
694
893
 
695
894
void
699
898
  gtk_widget_set_sensitive (statusbar->cursor_label, TRUE);
700
899
}
701
900
 
 
901
 
 
902
/*  private functions  */
 
903
 
 
904
static void
 
905
gimp_statusbar_progress_style_set (GtkWidget     *widget,
 
906
                                   GtkStyle      *prev_style,
 
907
                                   GimpStatusbar *statusbar)
 
908
{
 
909
  PangoLayout *layout;
 
910
  GdkPixbuf   *pixbuf;
 
911
  gint         n_spaces = 1;
 
912
  gint         layout_width;
 
913
 
 
914
  layout = gtk_widget_create_pango_layout (widget, " ");
 
915
  pixbuf = gtk_widget_render_icon (widget, GIMP_STOCK_WARNING,
 
916
                                   GTK_ICON_SIZE_MENU, NULL);
 
917
 
 
918
  pango_layout_get_pixel_size (layout, &layout_width, NULL);
 
919
 
 
920
  while (layout_width < gdk_pixbuf_get_width (pixbuf) + 4)
 
921
    {
 
922
      n_spaces++;
 
923
 
 
924
      statusbar->temp_spaces = g_realloc (statusbar->temp_spaces, n_spaces + 1);
 
925
 
 
926
      memset (statusbar->temp_spaces, ' ', n_spaces);
 
927
      statusbar->temp_spaces[n_spaces] = '\0';
 
928
 
 
929
      pango_layout_set_text (layout, statusbar->temp_spaces, -1);
 
930
      pango_layout_get_pixel_size (layout, &layout_width, NULL);
 
931
    }
 
932
 
 
933
  g_object_unref (layout);
 
934
  g_object_unref (pixbuf);
 
935
}
 
936
 
 
937
static gboolean
 
938
gimp_statusbar_progress_expose (GtkWidget      *widget,
 
939
                                GdkEventExpose *event,
 
940
                                GimpStatusbar  *statusbar)
 
941
{
 
942
  GdkPixbuf   *pixbuf;
 
943
  const gchar *stock_id = NULL;
 
944
  gint         text_xalign;
 
945
  gint         text_yalign;
 
946
  gint         x, y;
 
947
 
 
948
  if (statusbar->messages)
 
949
    {
 
950
      GimpStatusbarMsg *msg = statusbar->messages->data;
 
951
 
 
952
      stock_id = msg->stock_id;
 
953
    }
 
954
 
 
955
  if (! stock_id)
 
956
    return FALSE;
 
957
 
 
958
  pixbuf = gtk_widget_render_icon (widget, stock_id,
 
959
                                   GTK_ICON_SIZE_MENU, NULL);
 
960
 
 
961
  g_object_get (widget,
 
962
                "text-xalign", &text_xalign,
 
963
                "text-yalign", &text_yalign,
 
964
                NULL);
 
965
 
 
966
  x = (widget->style->xthickness + 2);
 
967
  y = ((widget->allocation.height - gdk_pixbuf_get_height (pixbuf)) / 2);
 
968
 
 
969
  if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_RTL)
 
970
    x += (widget->allocation.width - 2 * (widget->style->xthickness + 1) -
 
971
          gdk_pixbuf_get_width (pixbuf));
 
972
 
 
973
  gdk_draw_pixbuf (widget->window, widget->style->black_gc,
 
974
                   pixbuf,
 
975
                   0, 0, x, y,
 
976
                   gdk_pixbuf_get_width (pixbuf),
 
977
                   gdk_pixbuf_get_height (pixbuf),
 
978
                   GDK_RGB_DITHER_NORMAL, 0, 0);
 
979
 
 
980
  g_object_unref (pixbuf);
 
981
 
 
982
  return FALSE;
 
983
}
 
984
 
702
985
static void
703
986
gimp_statusbar_shell_scaled (GimpDisplayShell *shell,
704
987
                             GimpStatusbar    *statusbar)
705
988
{
706
989
  static PangoLayout *layout = NULL;
707
990
 
708
 
  GimpImage    *image = shell->gdisp->gimage;
 
991
  GimpImage    *image = shell->display->image;
709
992
  GtkTreeModel *model;
710
993
  const gchar  *text;
711
994
  gint          width;
714
997
  g_signal_handlers_block_by_func (statusbar->scale_combo,
715
998
                                   gimp_statusbar_scale_changed, statusbar);
716
999
  gimp_scale_combo_box_set_scale (GIMP_SCALE_COMBO_BOX (statusbar->scale_combo),
717
 
                                  shell->scale);
 
1000
                                  gimp_zoom_model_get_factor (shell->zoom));
718
1001
  g_signal_handlers_unblock_by_func (statusbar->scale_combo,
719
1002
                                     gimp_statusbar_scale_changed, statusbar);
720
1003
 
733
1016
    {
734
1017
      g_snprintf (statusbar->cursor_format_str,
735
1018
                  sizeof (statusbar->cursor_format_str),
736
 
                  "%%s%%d%%s%%d");
 
1019
                  "%%s%%d%%s%%d%%s");
737
1020
      g_snprintf (statusbar->length_format_str,
738
1021
                  sizeof (statusbar->length_format_str),
739
 
                  "%%s%%d");
 
1022
                  "%%s%%d%%s");
740
1023
    }
741
1024
  else /* show real world units */
742
1025
    {
743
1026
      g_snprintf (statusbar->cursor_format_str,
744
1027
                  sizeof (statusbar->cursor_format_str),
745
 
                  "%%s%%.%df%%s%%.%df",
 
1028
                  "%%s%%.%df%%s%%.%df%%s",
746
1029
                  _gimp_unit_get_digits (image->gimp, shell->unit),
747
1030
                  _gimp_unit_get_digits (image->gimp, shell->unit));
748
1031
      g_snprintf (statusbar->length_format_str,
749
1032
                  sizeof (statusbar->length_format_str),
750
 
                  "%%s%%.%df",
 
1033
                  "%%s%%.%df%%s",
751
1034
                  _gimp_unit_get_digits (image->gimp, shell->unit));
752
1035
    }
753
1036
 
754
 
  gimp_statusbar_set_cursor (statusbar, - image->width, - image->height);
 
1037
  gimp_statusbar_update_cursor (statusbar, -image->width, -image->height);
755
1038
 
756
1039
  text = gtk_label_get_text (GTK_LABEL (statusbar->cursor_label));
757
1040
 
799
1082
gimp_statusbar_get_context_id (GimpStatusbar *statusbar,
800
1083
                               const gchar   *context)
801
1084
{
802
 
  gchar *string;
803
 
  guint *id;
804
 
 
805
 
  g_return_val_if_fail (GIMP_IS_STATUSBAR (statusbar), 0);
806
 
  g_return_val_if_fail (context != NULL, 0);
807
 
 
808
 
  /* we need to preserve namespaces on object datas */
809
 
  string = g_strconcat ("gimp-status-bar-context:", context, NULL);
810
 
 
811
 
  id = g_object_get_data (G_OBJECT (statusbar), string);
812
 
  if (!id)
813
 
    {
814
 
      id = g_new (guint, 1);
815
 
      *id = statusbar->seq_context_id++;
816
 
      g_object_set_data_full (G_OBJECT (statusbar), string, id, g_free);
817
 
      statusbar->keys = g_slist_prepend (statusbar->keys, string);
818
 
    }
819
 
  else
820
 
    {
821
 
      g_free (string);
822
 
    }
823
 
 
824
 
  return *id;
 
1085
  guint id = GPOINTER_TO_UINT (g_hash_table_lookup (statusbar->context_ids,
 
1086
                                                    context));
 
1087
 
 
1088
  if (! id)
 
1089
    {
 
1090
      id = statusbar->seq_context_id++;
 
1091
 
 
1092
      g_hash_table_insert (statusbar->context_ids,
 
1093
                           g_strdup (context), GUINT_TO_POINTER (id));
 
1094
    }
 
1095
 
 
1096
  return id;
 
1097
}
 
1098
 
 
1099
static gboolean
 
1100
gimp_statusbar_temp_timeout (GimpStatusbar *statusbar)
 
1101
{
 
1102
  gimp_statusbar_pop_temp (statusbar);
 
1103
 
 
1104
  statusbar->temp_timeout_id = 0;
 
1105
 
 
1106
  return FALSE;
 
1107
}
 
1108
 
 
1109
static void
 
1110
gimp_statusbar_msg_free (GimpStatusbarMsg *msg)
 
1111
{
 
1112
  g_free (msg->stock_id);
 
1113
  g_free (msg->text);
 
1114
  g_free (msg);
 
1115
}
 
1116
 
 
1117
static gchar *
 
1118
gimp_statusbar_vprintf (const gchar *format,
 
1119
                        va_list      args)
 
1120
{
 
1121
  gchar *message;
 
1122
  gchar *newline;
 
1123
 
 
1124
  message = g_strdup_vprintf (format, args);
 
1125
 
 
1126
  /*  guard us from multi-line strings  */
 
1127
  newline = strchr (message, '\n');
 
1128
  if (newline)
 
1129
    *newline = '\0';
 
1130
 
 
1131
  return message;
825
1132
}