Add pgettext for some ambiguous strings
[geeqie.git] / src / bar.c
1 /*
2  * Geeqie
3  * (C) 2004 John Ellis
4  * Copyright (C) 2008 - 2009 The Geeqie Team
5  *
6  * Author: Vladimir Nadvornik
7  *
8  * This software is released under the GNU General Public License (GNU GPL).
9  * Please read the included file COPYING for more information.
10  * This software comes with no warranty of any kind, use at your own risk!
11  */
12
13
14 #include "main.h"
15 #include "bar.h"
16
17 #include "filedata.h"
18 #include "history_list.h"
19 #include "metadata.h"
20 #include "misc.h"
21 #include "ui_fileops.h"
22 #include "ui_misc.h"
23 #include "ui_utildlg.h"
24
25 #include "ui_menu.h"
26 #include "bar_comment.h"
27 #include "bar_keywords.h"
28 #include "bar_exif.h"
29 #include "bar_histogram.h"
30 #include "histogram.h"
31 #include "rcfile.h"
32
33 typedef struct _KnownPanes KnownPanes;
34 struct _KnownPanes
35 {
36         PaneType type;
37         gchar *id;
38         gchar *title;
39         const gchar *config;
40 };
41
42 static const gchar default_config_histogram[] = 
43 "<gq>"
44 "    <layout id = '_current_'>"
45 "        <bar>"
46 "            <pane_histogram id = 'histogram' expanded = 'true' histogram_channel = '4' histogram_mode = '0' />"
47 "        </bar>"
48 "    </layout>"
49 "</gq>";
50
51 static const gchar default_config_title[] = 
52 "<gq>"
53 "    <layout id = '_current_'>"
54 "        <bar>"
55 "            <pane_comment id = 'title' expanded = 'true' key = 'Xmp.dc.title' height = '40' />"
56 "        </bar>"
57 "    </layout>"
58 "</gq>";
59
60 static const gchar default_config_keywords[] = 
61 "<gq>"
62 "    <layout id = '_current_'>"
63 "        <bar>"
64 "            <pane_keywords id = 'keywords' expanded = 'true' key = '" KEYWORD_KEY "' />"
65 "        </bar>"
66 "    </layout>"
67 "</gq>";
68
69 static const gchar default_config_comment[] = 
70 "<gq>"
71 "    <layout id = '_current_'>"
72 "        <bar>"
73 "            <pane_comment id = 'comment' expanded = 'true' key = '" COMMENT_KEY "' height = '150' />"
74 "        </bar>"
75 "    </layout>"
76 "</gq>";
77
78 static const gchar default_config_exif[] = 
79 "<gq>"
80 "    <layout id = '_current_'>"
81 "        <bar>"
82 "            <pane_exif id = 'exif' expanded = 'true' >"
83 "                <entry key = 'formatted.Camera' if_set = 'true' editable = 'false' />"
84 "                <entry key = 'formatted.DateTime' if_set = 'true' editable = 'false' />"
85 "                <entry key = 'formatted.ShutterSpeed' if_set = 'true' editable = 'false' />"
86 "                <entry key = 'formatted.Aperture' if_set = 'true' editable = 'false' />"
87 "                <entry key = 'formatted.ExposureBias' if_set = 'true' editable = 'false' />"
88 "                <entry key = 'formatted.ISOSpeedRating' if_set = 'true' editable = 'false' />"
89 "                <entry key = 'formatted.FocalLength' if_set = 'true' editable = 'false' />"
90 "                <entry key = 'formatted.FocalLength35mmFilm' if_set = 'true' editable = 'false' />"
91 "                <entry key = 'formatted.Flash' if_set = 'true' editable = 'false' />"
92 "                <entry key = 'Exif.Photo.ExposureProgram' if_set = 'true' editable = 'false' />"
93 "                <entry key = 'Exif.Photo.MeteringMode' if_set = 'true' editable = 'false' />"
94 "                <entry key = 'Exif.Photo.LightSource' if_set = 'true' editable = 'false' />"
95 "                <entry key = 'formatted.ColorProfile' if_set = 'true' editable = 'false' />"
96 "                <entry key = 'formatted.SubjectDistance' if_set = 'true' editable = 'false' />"
97 "                <entry key = 'formatted.Resolution' if_set = 'true' editable = 'false' />"
98 "                <entry key = 'Exif.Image.Orientation' if_set = 'true' editable = 'false' />"
99 "            </pane_exif>"
100 "        </bar>"
101 "    </layout>"
102 "</gq>";
103
104 static const gchar default_config_file_info[] = 
105 "<gq>"
106 "    <layout id = '_current_'>"
107 "        <bar>"
108 "            <pane_exif id = 'file_info' expanded = 'true' >"
109 "                <entry key = 'file.mode' if_set = 'false' editable = 'false' />"
110 "                <entry key = 'file.date' if_set = 'false' editable = 'false' />"
111 "                <entry key = 'file.size' if_set = 'false' editable = 'false' />"
112 "            </pane_exif>"
113 "        </bar>"
114 "    </layout>"
115 "</gq>";
116
117 static const gchar default_config_location[] = 
118 "<gq>"
119 "    <layout id = '_current_'>"
120 "        <bar>"
121 "            <pane_exif id = 'location' expanded = 'true' >"
122 "                <entry key = 'formatted.GPSPosition' if_set = 'true' editable = 'false' />"
123 "                <entry key = 'formatted.GPSAltitude' if_set = 'true' editable = 'false' />"
124 "                <entry key = 'Xmp.photoshop.Country' if_set = 'false' editable = 'true' />"
125 "                <entry key = 'Xmp.iptc.CountryCode' if_set = 'false' editable = 'true' />"
126 "                <entry key = 'Xmp.photoshop.State' if_set = 'false' editable = 'true' />"
127 "                <entry key = 'Xmp.photoshop.City' if_set = 'false' editable = 'true' />"
128 "                <entry key = 'Xmp.iptc.Location' if_set = 'false' editable = 'true' />"
129 "            </pane_exif>"
130 "        </bar>"
131 "    </layout>"
132 "</gq>";
133
134 static const gchar default_config_copyright[] = 
135 "<gq>"
136 "    <layout id = '_current_'>"
137 "        <bar>"
138 "            <pane_exif id = 'copyright' expanded = 'true' >"
139 "                <entry key = 'Xmp.dc.creator' if_set = 'true' editable = 'false' />"
140 "                <entry key = 'Xmp.dc.contributor' if_set = 'true' editable = 'false' />"
141 "                <entry key = 'Xmp.dc.rights' if_set = 'false' editable = 'false' />"
142 "            </pane_exif>"
143 "        </bar>"
144 "    </layout>"
145 "</gq>";
146
147 static const KnownPanes known_panes[] = {
148 /* default sidebar */
149         {PANE_HISTOGRAM,        "histogram",    N_("Histogram"),        default_config_histogram},
150         {PANE_COMMENT,          "title",        N_("Title"),            default_config_title},
151         {PANE_KEYWORDS,         "keywords",     N_("Keywords"),         default_config_keywords},
152         {PANE_COMMENT,          "comment",      N_("Comment"),          default_config_comment},
153         {PANE_EXIF,             "exif",         N_("Exif"),             default_config_exif},
154 /* other pre-configured panes */
155         {PANE_EXIF,             "file_info",    N_("File info"),        default_config_file_info},
156         {PANE_EXIF,             "location",     N_("Location"),         default_config_location},
157         {PANE_EXIF,             "copyright",    N_("Copyright"),        default_config_copyright},
158
159         {PANE_UNDEF,            NULL,           NULL,                   NULL}
160 };
161
162 typedef struct _BarData BarData;
163 struct _BarData
164 {
165         GtkWidget *widget;
166         GtkWidget *vbox;
167         FileData *fd;
168         GtkWidget *label_file_name;
169
170         LayoutWindow *lw;
171         gint width;
172 };
173
174 static void bar_expander_move(GtkWidget *widget, gpointer data, gboolean up, gboolean single_step)
175 {
176         GtkWidget *expander = data;
177         GtkWidget *box;
178         gint pos;
179
180         if (!expander) return;
181         box = gtk_widget_get_ancestor(expander, GTK_TYPE_BOX);
182         if (!box) return;
183         
184         gtk_container_child_get(GTK_CONTAINER(box), expander, "position", &pos, NULL);
185         
186         if (single_step)
187                 {
188                 pos = up ? (pos - 1) : (pos + 1);
189                 if (pos < 0) pos = 0;
190                 }
191         else
192                 {
193                 pos = up ? 0 : -1;
194                 }
195         
196         gtk_box_reorder_child(GTK_BOX(box), expander, pos);
197 }
198
199
200 static void bar_expander_move_up_cb(GtkWidget *widget, gpointer data)
201 {
202         bar_expander_move(widget, data, TRUE, TRUE);
203 }
204
205 static void bar_expander_move_down_cb(GtkWidget *widget, gpointer data)
206 {
207         bar_expander_move(widget, data, FALSE, TRUE);
208 }
209
210 static void bar_expander_move_top_cb(GtkWidget *widget, gpointer data)
211 {
212         bar_expander_move(widget, data, TRUE, FALSE);
213 }
214
215 static void bar_expander_move_bottom_cb(GtkWidget *widget, gpointer data)
216 {
217         bar_expander_move(widget, data, FALSE, FALSE);
218 }
219
220 static void bar_expander_delete_cb(GtkWidget *widget, gpointer data)
221 {
222         GtkWidget *expander = data;
223         gtk_widget_destroy(expander);
224 }
225
226 static void bar_expander_add_cb(GtkWidget *widget, gpointer data)
227 {
228         //GtkWidget *bar = data;
229         const KnownPanes *pane = known_panes;
230         const gchar *id = g_object_get_data(G_OBJECT(widget), "pane_add_id");
231         const gchar *config;
232
233         if (!id) return;
234         
235         while (pane->id)
236                 {
237                 if (strcmp(pane->id, id) == 0) break;
238                 pane++;
239                 }
240         if (!pane->id) return;
241         
242         config = bar_pane_get_default_config(id);
243         if (config) load_config_from_buf(config, strlen(config), FALSE);
244
245 }
246
247
248 static void bar_menu_popup(GtkWidget *widget)
249 {
250         GtkWidget *menu;
251         GtkWidget *bar;
252         GtkWidget *expander;
253         const KnownPanes *pane = known_panes;
254         BarData *bd;
255
256         bd = g_object_get_data(G_OBJECT(widget), "bar_data");
257         if (bd) 
258                 {
259                 expander = NULL;
260                 bar = widget; 
261                 }
262         else
263                 {
264                 expander = widget;
265                 bar = widget->parent;
266                 while (bar && !g_object_get_data(G_OBJECT(bar), "bar_data"))
267                         bar = bar->parent;
268                 if (!bar) return;
269                 }
270  
271         menu = popup_menu_short_lived();
272
273         if (expander)
274                 {
275                 menu_item_add_stock(menu, _("Move to _top"), GTK_STOCK_GOTO_TOP, G_CALLBACK(bar_expander_move_top_cb), expander);
276                 menu_item_add_stock(menu, _("Move _up"), GTK_STOCK_GO_UP, G_CALLBACK(bar_expander_move_up_cb), expander);
277                 menu_item_add_stock(menu, _("Move _down"), GTK_STOCK_GO_DOWN, G_CALLBACK(bar_expander_move_down_cb), expander);
278                 menu_item_add_stock(menu, _("Move to _bottom"), GTK_STOCK_GOTO_BOTTOM, G_CALLBACK(bar_expander_move_bottom_cb), expander);
279                 menu_item_add_divider(menu);
280                 menu_item_add_stock(menu, pgettext("virtual","Delete"), GTK_STOCK_DELETE, G_CALLBACK(bar_expander_delete_cb), expander);
281                 menu_item_add_divider(menu);
282                 }
283
284         while (pane->id)
285                 {
286                 GtkWidget *item;
287                 item = menu_item_add_stock(menu, _(pane->title), GTK_STOCK_ADD, G_CALLBACK(bar_expander_add_cb), bar);
288                 g_object_set_data(G_OBJECT(item), "pane_add_id", pane->id);
289                 pane++;
290                 }
291         
292         gtk_menu_popup(GTK_MENU(menu), NULL, NULL, NULL, bar, 0, GDK_CURRENT_TIME);
293 }
294
295
296 static gboolean bar_menu_cb(GtkWidget *widget, GdkEventButton *bevent, gpointer data) 
297
298         if (bevent->button == MOUSE_BUTTON_RIGHT)
299                 {
300                 bar_menu_popup(widget);
301                 return TRUE;
302                 }
303         return FALSE;
304
305
306
307 static void bar_pane_set_fd_cb(GtkWidget *expander, gpointer data)
308 {
309         GtkWidget *widget = gtk_bin_get_child(GTK_BIN(expander));
310         PaneData *pd = g_object_get_data(G_OBJECT(widget), "pane_data");
311         if (!pd) return;
312         if (pd->pane_set_fd) pd->pane_set_fd(widget, data);
313 }
314
315 void bar_set_fd(GtkWidget *bar, FileData *fd)
316 {
317         BarData *bd;
318         bd = g_object_get_data(G_OBJECT(bar), "bar_data");
319         if (!bd) return;
320
321         file_data_unref(bd->fd);
322         bd->fd = file_data_ref(fd);
323
324         gtk_container_foreach(GTK_CONTAINER(bd->vbox), bar_pane_set_fd_cb, fd);
325         
326         gtk_label_set_text(GTK_LABEL(bd->label_file_name), (bd->fd) ? bd->fd->name : "");
327
328 }
329
330 static void bar_pane_notify_selection_cb(GtkWidget *expander, gpointer data)
331 {
332         GtkWidget *widget = gtk_bin_get_child(GTK_BIN(expander));
333         PaneData *pd = g_object_get_data(G_OBJECT(widget), "pane_data");
334         if (!pd) return;
335         if (pd->pane_notify_selection) pd->pane_notify_selection(widget, GPOINTER_TO_INT(data));
336 }
337
338 void bar_notify_selection(GtkWidget *bar, gint count)
339 {
340         BarData *bd;
341         bd = g_object_get_data(G_OBJECT(bar), "bar_data");
342         if (!bd) return;
343
344         gtk_container_foreach(GTK_CONTAINER(bd->vbox), bar_pane_notify_selection_cb, GINT_TO_POINTER(count));
345 }
346
347 gboolean bar_event(GtkWidget *bar, GdkEvent *event)
348 {
349         BarData *bd;
350         GList *list, *work;
351         gboolean ret = FALSE;
352         
353         bd = g_object_get_data(G_OBJECT(bar), "bar_data");
354         if (!bd) return FALSE;
355
356         list = gtk_container_get_children(GTK_CONTAINER(bd->vbox));
357         
358         work = list;
359         while (work)
360                 {
361                 GtkWidget *widget = gtk_bin_get_child(GTK_BIN(work->data));
362                 PaneData *pd = g_object_get_data(G_OBJECT(widget), "pane_data");
363                 if (!pd) continue;
364         
365                 if (pd->pane_event && pd->pane_event(widget, event))
366                         {
367                         ret = TRUE;
368                         break;
369                         }
370                 work = work->next;
371                 }
372         g_list_free(list);
373         return ret;
374 }
375
376 GtkWidget *bar_find_pane_by_id(GtkWidget *bar, PaneType type, const gchar *id)
377 {
378         BarData *bd;
379         GList *list, *work;
380         GtkWidget *ret = NULL;
381         
382         if (!id || !id[0]) return NULL;
383         
384         bd = g_object_get_data(G_OBJECT(bar), "bar_data");
385         if (!bd) return NULL;
386
387         list = gtk_container_get_children(GTK_CONTAINER(bd->vbox));
388         
389         work = list;
390         while (work)
391                 {
392                 GtkWidget *widget = gtk_bin_get_child(GTK_BIN(work->data));
393                 PaneData *pd = g_object_get_data(G_OBJECT(widget), "pane_data");
394                 if (!pd) continue;
395         
396                 if (type == pd->type && strcmp(id, pd->id) == 0)
397                         {
398                         ret = widget;
399                         break;
400                         }
401                 work = work->next;
402                 }
403         g_list_free(list);
404         return ret;
405 }
406
407 void bar_clear(GtkWidget *bar)
408 {
409         BarData *bd;
410         GList *list, *work;
411         
412         bd = g_object_get_data(G_OBJECT(bar), "bar_data");
413         if (!bd) return;
414
415         list = gtk_container_get_children(GTK_CONTAINER(bd->vbox));
416         
417         work = list;
418         while (work)
419                 {
420                 GtkWidget *widget = work->data;
421                 gtk_widget_destroy(widget);
422                 work = work->next;
423                 }
424         g_list_free(list);
425 }
426
427 void bar_write_config(GtkWidget *bar, GString *outstr, gint indent)
428 {
429         BarData *bd;
430         GList *list, *work;
431
432         if (!bar) return;
433         
434         bd = g_object_get_data(G_OBJECT(bar), "bar_data");
435         if (!bd) return;
436
437         WRITE_NL(); WRITE_STRING("<bar ");
438         write_bool_option(outstr, indent, "enabled", GTK_WIDGET_VISIBLE(bar));
439         write_uint_option(outstr, indent, "width", bd->width);
440         WRITE_STRING(">");
441         
442         indent++;
443         WRITE_NL(); WRITE_STRING("<clear/>");
444
445         list = gtk_container_get_children(GTK_CONTAINER(bd->vbox));     
446         work = list;
447         while (work)
448                 {
449                 GtkWidget *expander = work->data;
450                 GtkWidget *widget = gtk_bin_get_child(GTK_BIN(expander));
451                 PaneData *pd = g_object_get_data(G_OBJECT(widget), "pane_data");
452                 if (!pd) continue;
453
454                 pd->expanded = gtk_expander_get_expanded(GTK_EXPANDER(expander));
455
456                 if (pd->pane_write_config)
457                         pd->pane_write_config(widget, outstr, indent);
458
459                 work = work->next;
460                 }
461         g_list_free(list);
462         indent--;
463         WRITE_NL(); WRITE_STRING("</bar>");
464 }
465
466 void bar_update_expander(GtkWidget *pane)
467 {
468         PaneData *pd = g_object_get_data(G_OBJECT(pane), "pane_data");
469         GtkWidget *expander;
470         
471         if (!pd) return;
472
473         expander = pane->parent;
474         
475         gtk_expander_set_expanded(GTK_EXPANDER(expander), pd->expanded);
476 }
477
478 void bar_add(GtkWidget *bar, GtkWidget *pane)
479 {
480         GtkWidget *expander;
481         BarData *bd = g_object_get_data(G_OBJECT(bar), "bar_data");
482         PaneData *pd = g_object_get_data(G_OBJECT(pane), "pane_data");
483         
484         if (!bd) return;
485
486         pd->lw = bd->lw;
487         pd->bar = bar;
488         
489         expander = gtk_expander_new(NULL);
490         if (pd && pd->title)
491                 {
492                 gtk_expander_set_label_widget(GTK_EXPANDER(expander), pd->title);
493                 gtk_widget_show(pd->title);
494                 }
495                 
496         gtk_box_pack_start(GTK_BOX(bd->vbox), expander, FALSE, TRUE, 0);
497         
498         g_signal_connect(expander, "button_press_event", G_CALLBACK(bar_menu_cb), bd); 
499         
500         gtk_container_add(GTK_CONTAINER(expander), pane);
501         
502         gtk_expander_set_expanded(GTK_EXPANDER(expander), pd->expanded);
503
504         gtk_widget_show(expander);
505
506         if (bd->fd && pd && pd->pane_set_fd) pd->pane_set_fd(pane, bd->fd);
507
508 }
509
510 void bar_populate_default(GtkWidget *bar)
511 {
512         const gchar *populate_id[] = {"histogram", "title", "keywords", "comment", "exif", NULL};
513         const gchar **id = populate_id;
514         
515         while (*id)
516                 {
517                 const gchar *config = bar_pane_get_default_config(*id);
518                 if (config) load_config_from_buf(config, strlen(config), FALSE);
519                 id++;
520                 }
521 }
522
523 static void bar_size_allocate(GtkWidget *widget, GtkAllocation *allocation, gpointer data)
524 {
525         BarData *bd = data;
526         
527         bd->width = allocation->width;
528 }
529
530 gint bar_get_width(GtkWidget *bar)
531 {
532         BarData *bd;
533         
534         bd = g_object_get_data(G_OBJECT(bar), "bar_data");
535         if (!bd) return 0;
536
537         return bd->width;
538 }
539
540 void bar_close(GtkWidget *bar)
541 {
542         BarData *bd;
543
544         bd = g_object_get_data(G_OBJECT(bar), "bar_data");
545         if (!bd) return;
546
547         gtk_widget_destroy(bd->widget);
548 }
549
550 static void bar_destroy(GtkWidget *widget, gpointer data)
551 {
552         BarData *bd = data;
553
554         file_data_unref(bd->fd);
555         g_free(bd);
556 }
557
558 GtkWidget *bar_new(LayoutWindow *lw)
559 {
560         BarData *bd;
561         GtkWidget *box;
562         GtkWidget *scrolled;
563
564         bd = g_new0(BarData, 1);
565
566         bd->lw = lw;
567         
568         bd->widget = gtk_vbox_new(FALSE, PREF_PAD_GAP);
569         g_object_set_data(G_OBJECT(bd->widget), "bar_data", bd);
570         g_signal_connect(G_OBJECT(bd->widget), "destroy",
571                          G_CALLBACK(bar_destroy), bd);
572
573         g_signal_connect(G_OBJECT(bd->widget), "size-allocate",
574                          G_CALLBACK(bar_size_allocate), bd);
575
576         g_signal_connect(G_OBJECT(bd->widget), "button_press_event", G_CALLBACK(bar_menu_cb), bd); 
577
578         bd->width = SIDEBAR_DEFAULT_WIDTH;
579         gtk_widget_set_size_request(bd->widget, bd->width, -1);
580
581         box = gtk_hbox_new(FALSE, 0);
582
583         bd->label_file_name = gtk_label_new("");
584         gtk_label_set_ellipsize(GTK_LABEL(bd->label_file_name), PANGO_ELLIPSIZE_END);
585         gtk_label_set_selectable(GTK_LABEL(bd->label_file_name), TRUE);
586         gtk_misc_set_alignment(GTK_MISC(bd->label_file_name), 0.5, 0.5);
587         gtk_box_pack_start(GTK_BOX(box), bd->label_file_name, TRUE, TRUE, 0);
588         gtk_widget_show(bd->label_file_name);
589
590         gtk_box_pack_start(GTK_BOX(bd->widget), box, FALSE, FALSE, 0);
591         gtk_widget_show(box);
592
593         scrolled = gtk_scrolled_window_new(NULL, NULL);
594         gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolled),
595                 GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
596         gtk_box_pack_start(GTK_BOX(bd->widget), scrolled, TRUE, TRUE, 0);
597         gtk_widget_show(scrolled);
598
599
600         bd->vbox = gtk_vbox_new(FALSE, 0);
601         gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(scrolled), bd->vbox);
602         gtk_viewport_set_shadow_type(GTK_VIEWPORT(gtk_bin_get_child(GTK_BIN(scrolled))), GTK_SHADOW_NONE);
603         
604         gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scrolled), GTK_SHADOW_NONE);
605         gtk_widget_show(bd->vbox);
606         return bd->widget;
607 }
608
609
610 GtkWidget *bar_update_from_config(GtkWidget *bar, const gchar **attribute_names, const gchar **attribute_values)
611 {
612         gboolean enabled = TRUE;
613         gint width = SIDEBAR_DEFAULT_WIDTH;
614
615         while (*attribute_names)
616                 {
617                 const gchar *option = *attribute_names++;
618                 const gchar *value = *attribute_values++;
619
620                 if (READ_BOOL_FULL("enabled", enabled)) continue;
621                 if (READ_INT_FULL("width", width)) continue;
622                 
623
624                 log_printf("unknown attribute %s = %s\n", option, value);
625                 }
626         
627         gtk_widget_set_size_request(bar, width, -1);
628         if (enabled) 
629                 {
630                 gtk_widget_show(bar);
631                 }
632         else
633                 {
634                 gtk_widget_hide(bar);
635                 }
636         return bar;
637 }
638
639 GtkWidget *bar_new_from_config(LayoutWindow *lw, const gchar **attribute_names, const gchar **attribute_values)
640 {
641         GtkWidget *bar = bar_new(lw);
642         return bar_update_from_config(bar, attribute_names, attribute_values);
643 }
644
645 GtkWidget *bar_pane_expander_title(const gchar *title)
646 {
647         GtkWidget *widget = gtk_label_new(title);
648
649         pref_label_bold(widget, TRUE, FALSE);
650         //gtk_label_set_ellipsize(GTK_LABEL(widget), PANGO_ELLIPSIZE_END); //FIXME: do not work
651
652         return widget;
653 }
654
655 gboolean bar_pane_translate_title(PaneType type, const gchar *id, gchar **title)
656 {
657         const KnownPanes *pane = known_panes;
658         
659         if (!title) return FALSE;
660         while (pane->id)
661                 {
662                 if (pane->type == type && strcmp(pane->id, id) == 0) break;
663                 pane++;
664                 }
665         if (!pane->id) return FALSE;
666         
667         if (*title && **title && strcmp(pane->title, *title) != 0) return FALSE;
668         
669         g_free(*title);
670         *title = g_strdup(_(pane->title));
671         return TRUE;
672 }
673
674 const gchar *bar_pane_get_default_config(const gchar *id)
675 {
676         const KnownPanes *pane = known_panes;
677         
678         while (pane->id)
679                 {
680                 if (strcmp(pane->id, id) == 0) break;
681                 pane++;
682                 }
683         if (!pane->id) return NULL;
684         return pane->config;
685 }
686         
687 /* vim: set shiftwidth=8 softtabstop=0 cindent cinoptions={1s: */