2008-05-05 Paolo Borelli <pborelli@katamail.com>
[nautilus.git] / src / nautilus-sidebar-title.c
blob7d01aded3f4d6cebda0307c6bb6e8ae491b5e9a6
1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
3 /*
4 * Nautilus
6 * Copyright (C) 2000, 2001 Eazel, Inc.
8 * Nautilus is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 * Author: Andy Hertzfeld <andy@eazel.com>
25 /* This is the sidebar title widget, which is the title part of the sidebar. */
27 #include <config.h>
28 #include <math.h>
29 #include "nautilus-sidebar-title.h"
31 #include "nautilus-window.h"
33 #include <eel/eel-background.h>
34 #include <eel/eel-gdk-extensions.h>
35 #include <eel/eel-gdk-pixbuf-extensions.h>
36 #include <eel/eel-glib-extensions.h>
37 #include <eel/eel-gtk-extensions.h>
38 #include <eel/eel-gtk-macros.h>
39 #include <eel/eel-pango-extensions.h>
40 #include <eel/eel-string.h>
41 #include <gtk/gtkhbox.h>
42 #include <gtk/gtkimage.h>
43 #include <gtk/gtklabel.h>
44 #include <gtk/gtksignal.h>
45 #include <gtk/gtkwidget.h>
46 #include <glib/gi18n.h>
47 #include <libnautilus-private/nautilus-file-attributes.h>
48 #include <libnautilus-private/nautilus-global-preferences.h>
49 #include <libnautilus-private/nautilus-metadata.h>
50 #include <libnautilus-private/nautilus-sidebar.h>
51 #include <string.h>
52 #include <stdlib.h>
54 /* maximum allowable size to be displayed as the title */
55 #define MAX_TITLE_SIZE 256
56 #define MINIMUM_INFO_WIDTH 32
57 #define SIDEBAR_INFO_MARGIN 4
58 #define SHADOW_OFFSET 1
60 #define MORE_INFO_FONT_SIZE 12
61 #define MIN_TITLE_FONT_SIZE 12
62 #define TITLE_PADDING 4
64 static void nautilus_sidebar_title_class_init (NautilusSidebarTitleClass *klass);
65 static void nautilus_sidebar_title_destroy (GtkObject *object);
66 static void nautilus_sidebar_title_init (NautilusSidebarTitle *pixmap);
67 static void nautilus_sidebar_title_size_allocate (GtkWidget *widget,
68 GtkAllocation *allocation);
69 static void update_icon (NautilusSidebarTitle *sidebar_title);
70 static GtkWidget * sidebar_title_create_title_label (void);
71 static GtkWidget * sidebar_title_create_more_info_label (void);
72 static void update_all (NautilusSidebarTitle *sidebar_title);
73 static void update_more_info (NautilusSidebarTitle *sidebar_title);
74 static void update_title_font (NautilusSidebarTitle *sidebar_title);
75 static void style_set (GtkWidget *widget,
76 GtkStyle *previous_style);
77 static guint get_best_icon_size (NautilusSidebarTitle *sidebar_title);
79 struct NautilusSidebarTitleDetails {
80 NautilusFile *file;
81 guint file_changed_connection;
82 gboolean monitoring_count;
84 char *title_text;
85 GtkWidget *icon;
86 GtkWidget *title_label;
87 GtkWidget *more_info_label;
88 GtkWidget *emblem_box;
90 guint best_icon_size;
92 gboolean determined_icon;
95 EEL_CLASS_BOILERPLATE (NautilusSidebarTitle, nautilus_sidebar_title, gtk_vbox_get_type ())
97 static void
98 nautilus_sidebar_title_class_init (NautilusSidebarTitleClass *class)
100 GtkObjectClass *object_class;
101 GtkWidgetClass *widget_class;
103 object_class = (GtkObjectClass*) class;
104 widget_class = (GtkWidgetClass*) class;
106 object_class->destroy = nautilus_sidebar_title_destroy;
107 widget_class->size_allocate = nautilus_sidebar_title_size_allocate;
108 widget_class->style_set = style_set;
112 static void
113 style_set (GtkWidget *widget,
114 GtkStyle *previous_style)
116 NautilusSidebarTitle *sidebar_title;
117 PangoFontDescription *font_desc;
118 GtkStyle *style;
120 g_return_if_fail (NAUTILUS_IS_SIDEBAR_TITLE (widget));
122 sidebar_title = NAUTILUS_SIDEBAR_TITLE (widget);
124 /* Update the dynamically-sized title font */
125 update_title_font (sidebar_title);
127 /* Update the fixed-size "more info" font */
128 style = gtk_widget_get_style (widget);
129 font_desc = pango_font_description_copy (style->font_desc);
130 if (pango_font_description_get_size (font_desc) < MORE_INFO_FONT_SIZE * PANGO_SCALE) {
131 pango_font_description_set_size (font_desc, MORE_INFO_FONT_SIZE * PANGO_SCALE);
134 gtk_widget_modify_font (sidebar_title->details->more_info_label,
135 font_desc);
136 pango_font_description_free (font_desc);
139 static void
140 nautilus_sidebar_title_init (NautilusSidebarTitle *sidebar_title)
142 sidebar_title->details = g_new0 (NautilusSidebarTitleDetails, 1);
144 /* Create the icon */
145 sidebar_title->details->icon = gtk_image_new ();
146 gtk_box_pack_start (GTK_BOX (sidebar_title), sidebar_title->details->icon, 0, 0, 0);
147 gtk_widget_show (sidebar_title->details->icon);
149 /* Create the title label */
150 sidebar_title->details->title_label = sidebar_title_create_title_label ();
151 gtk_box_pack_start (GTK_BOX (sidebar_title), sidebar_title->details->title_label, 0, 0, 0);
152 gtk_widget_show (sidebar_title->details->title_label);
154 /* Create the more info label */
155 sidebar_title->details->more_info_label = sidebar_title_create_more_info_label ();
156 gtk_box_pack_start (GTK_BOX (sidebar_title), sidebar_title->details->more_info_label, 0, 0, 0);
157 gtk_widget_show (sidebar_title->details->more_info_label);
159 sidebar_title->details->emblem_box = gtk_hbox_new (FALSE, 0);
160 gtk_widget_show (sidebar_title->details->emblem_box);
161 gtk_box_pack_start (GTK_BOX (sidebar_title), sidebar_title->details->emblem_box, 0, 0, 0);
163 sidebar_title->details->best_icon_size = get_best_icon_size (sidebar_title);
164 /* Keep track of changes in graphics trade offs */
165 update_all (sidebar_title);
167 /* initialize the label colors & fonts */
168 style_set (GTK_WIDGET (sidebar_title), NULL);
170 eel_preferences_add_callback_while_alive (
171 NAUTILUS_PREFERENCES_SHOW_DIRECTORY_ITEM_COUNTS,
172 (EelPreferencesCallback) update_more_info,
173 sidebar_title, G_OBJECT (sidebar_title));
176 /* destroy by throwing away private storage */
177 static void
178 release_file (NautilusSidebarTitle *sidebar_title)
180 if (sidebar_title->details->file_changed_connection != 0) {
181 g_signal_handler_disconnect (sidebar_title->details->file,
182 sidebar_title->details->file_changed_connection);
183 sidebar_title->details->file_changed_connection = 0;
186 if (sidebar_title->details->file != NULL) {
187 nautilus_file_monitor_remove (sidebar_title->details->file, sidebar_title);
188 nautilus_file_unref (sidebar_title->details->file);
189 sidebar_title->details->file = NULL;
193 static void
194 nautilus_sidebar_title_destroy (GtkObject *object)
196 NautilusSidebarTitle *sidebar_title;
198 sidebar_title = NAUTILUS_SIDEBAR_TITLE (object);
200 if (sidebar_title->details) {
201 release_file (sidebar_title);
203 g_free (sidebar_title->details->title_text);
204 g_free (sidebar_title->details);
205 sidebar_title->details = NULL;
208 EEL_CALL_PARENT (GTK_OBJECT_CLASS, destroy, (object));
211 /* return a new index title object */
212 GtkWidget *
213 nautilus_sidebar_title_new (void)
215 return gtk_widget_new (nautilus_sidebar_title_get_type (), NULL);
218 void
219 nautilus_sidebar_title_select_text_color (NautilusSidebarTitle *sidebar_title,
220 EelBackground *background,
221 gboolean is_default)
223 char *sidebar_title_color;
224 char *sidebar_info_title_color;
225 char *sidebar_title_shadow_color;
227 g_return_if_fail (background != NULL);
229 /* if the background is set to the default, the theme can explicitly
230 * define the title colors. Check if the background has been customized
231 * and if the theme specified any colors
233 sidebar_title_color = NULL;
234 sidebar_info_title_color = NULL;
235 sidebar_title_shadow_color = NULL;
237 /* FIXME bugzilla.gnome.org 42496: for now, both the title and info
238 * colors are the same - and hard coded */
239 if (eel_background_is_dark (background)) {
240 sidebar_title_color = g_strdup ("#FFFFFF");
241 sidebar_info_title_color = g_strdup ("#FFFFFF");
242 sidebar_title_shadow_color = g_strdup ("#000000");
243 } else {
244 sidebar_title_color = g_strdup ("#000000");
245 sidebar_info_title_color = g_strdup ("#000000");
246 sidebar_title_shadow_color = g_strdup ("#FFFFFF");
249 eel_gtk_widget_set_foreground_color (sidebar_title->details->title_label,
250 sidebar_title_color);
251 eel_gtk_widget_set_foreground_color (sidebar_title->details->more_info_label,
252 sidebar_info_title_color);
254 eel_gtk_label_set_drop_shadow_color (GTK_LABEL (sidebar_title->details->title_label),
255 eel_parse_rgb_with_white_default (sidebar_title_shadow_color));
256 eel_gtk_label_set_drop_shadow_color (GTK_LABEL (sidebar_title->details->more_info_label),
257 eel_parse_rgb_with_white_default (sidebar_title_shadow_color));
259 eel_gtk_label_set_drop_shadow_offset (GTK_LABEL (sidebar_title->details->title_label),
260 SHADOW_OFFSET);
261 eel_gtk_label_set_drop_shadow_offset (GTK_LABEL (sidebar_title->details->more_info_label),
262 SHADOW_OFFSET);
264 g_free (sidebar_title_color);
265 g_free (sidebar_info_title_color);
266 g_free (sidebar_title_shadow_color);
269 static char*
270 get_property_from_component (NautilusSidebarTitle *sidebar_title, const char *property)
272 /* There used to be a way to get icon and summary_text from main view,
273 * but its not used right now, so this sas stubbed out for now
275 return NULL;
278 static guint
279 get_best_icon_size (NautilusSidebarTitle *sidebar_title)
281 gint width;
283 width = GTK_WIDGET (sidebar_title)->allocation.width - TITLE_PADDING;
285 if (width < 0) {
286 /* use smallest available icon size */
287 return nautilus_icon_get_smaller_icon_size (0);
288 } else {
289 return nautilus_icon_get_smaller_icon_size ((guint) width);
293 /* set up the icon image */
294 static void
295 update_icon (NautilusSidebarTitle *sidebar_title)
297 GdkPixbuf *pixbuf;
298 NautilusIconInfo *info;
299 char *icon_name;
300 gboolean leave_pixbuf_unchanged;
302 leave_pixbuf_unchanged = FALSE;
304 /* see if the current content view is specifying an icon */
305 icon_name = get_property_from_component (sidebar_title, "icon_name");
307 pixbuf = NULL;
308 if (icon_name != NULL && icon_name[0] != '\0') {
309 info = nautilus_icon_info_lookup_from_name (icon_name, NAUTILUS_ICON_SIZE_LARGE);
310 pixbuf = nautilus_icon_info_get_pixbuf_at_size (info, NAUTILUS_ICON_SIZE_LARGE);
311 g_object_unref (info);
312 } else if (sidebar_title->details->file != NULL &&
313 nautilus_file_check_if_ready (sidebar_title->details->file,
314 NAUTILUS_FILE_ATTRIBUTES_FOR_ICON)) {
315 pixbuf = nautilus_file_get_icon_pixbuf (sidebar_title->details->file,
316 sidebar_title->details->best_icon_size,
317 FALSE,
318 NAUTILUS_FILE_ICON_FLAGS_FOR_DRAG_ACCEPT);
319 } else if (sidebar_title->details->determined_icon) {
320 /* We used to know the icon for this file, but now the file says it isn't
321 * ready. This means that some file info has been invalidated, which
322 * doesn't necessarily mean that the previously-determined icon is
323 * wrong (in fact, in practice it usually doesn't mean that). Keep showing
324 * the one we last determined for now.
326 leave_pixbuf_unchanged = TRUE;
329 g_free (icon_name);
331 if (pixbuf != NULL) {
332 sidebar_title->details->determined_icon = TRUE;
335 if (!leave_pixbuf_unchanged) {
336 gtk_image_set_from_pixbuf (GTK_IMAGE (sidebar_title->details->icon), pixbuf);
340 static void
341 update_title_font (NautilusSidebarTitle *sidebar_title)
343 int available_width;
344 PangoFontDescription *title_font;
345 int largest_fitting_font_size;
346 int max_style_font_size;
347 GtkStyle *style;
349 /* Make sure theres work to do */
350 if (eel_strlen (sidebar_title->details->title_text) < 1) {
351 return;
354 available_width = GTK_WIDGET (sidebar_title)->allocation.width - TITLE_PADDING;
356 /* No work to do */
357 if (available_width <= 0) {
358 return;
361 style = gtk_widget_get_style (GTK_WIDGET (sidebar_title));
362 title_font = pango_font_description_copy (style->font_desc);
364 max_style_font_size = pango_font_description_get_size (title_font) * 1.8 / PANGO_SCALE;
365 if (max_style_font_size < MIN_TITLE_FONT_SIZE + 1) {
366 max_style_font_size = MIN_TITLE_FONT_SIZE + 1;
369 largest_fitting_font_size = eel_pango_font_description_get_largest_fitting_font_size (
370 title_font,
371 gtk_widget_get_pango_context (sidebar_title->details->title_label),
372 sidebar_title->details->title_text,
373 available_width,
374 MIN_TITLE_FONT_SIZE,
375 max_style_font_size);
376 pango_font_description_set_size (title_font, largest_fitting_font_size * PANGO_SCALE);
378 pango_font_description_set_weight (title_font, PANGO_WEIGHT_BOLD);
380 gtk_widget_modify_font (sidebar_title->details->title_label,
381 title_font);
382 pango_font_description_free (title_font);
385 static void
386 update_title (NautilusSidebarTitle *sidebar_title)
388 GtkLabel *label;
389 const char *text;
391 label = GTK_LABEL (sidebar_title->details->title_label);
392 text = sidebar_title->details->title_text;
394 if (eel_strcmp (text, gtk_label_get_text (label)) == 0) {
395 return;
397 gtk_label_set_text (label, text);
398 update_title_font (sidebar_title);
401 static void
402 append_and_eat (GString *string, const char *separator, char *new_string)
404 if (new_string == NULL) {
405 return;
407 if (separator != NULL) {
408 g_string_append (string, separator);
410 g_string_append (string, new_string);
411 g_free (new_string);
414 static int
415 measure_width_callback (const char *string, gpointer callback_data)
417 PangoLayout *layout;
418 int width;
420 layout = PANGO_LAYOUT (callback_data);
421 pango_layout_set_text (layout, string, -1);
422 pango_layout_get_pixel_size (layout, &width, NULL);
423 return width;
426 static void
427 update_more_info (NautilusSidebarTitle *sidebar_title)
429 NautilusFile *file;
430 GString *info_string;
431 char *type_string, *component_info;
432 char *date_modified_str;
433 int sidebar_width;
434 PangoLayout *layout;
436 file = sidebar_title->details->file;
438 /* allow components to specify the info if they wish to */
439 component_info = get_property_from_component (sidebar_title, "summary_info");
440 if (component_info != NULL && strlen (component_info) > 0) {
441 info_string = g_string_new (component_info);
442 g_free (component_info);
443 } else {
444 info_string = g_string_new (NULL);
446 type_string = NULL;
447 if (file != NULL && nautilus_file_should_show_type (file)) {
448 type_string = nautilus_file_get_string_attribute (file, "type");
451 if (type_string != NULL) {
452 append_and_eat (info_string, NULL, type_string);
453 append_and_eat (info_string, ", ",
454 nautilus_file_get_string_attribute (file, "size"));
455 } else {
456 append_and_eat (info_string, NULL,
457 nautilus_file_get_string_attribute (file, "size"));
460 sidebar_width = GTK_WIDGET (sidebar_title)->allocation.width - 2 * SIDEBAR_INFO_MARGIN;
461 if (sidebar_width > MINIMUM_INFO_WIDTH) {
462 layout = pango_layout_copy (gtk_label_get_layout (GTK_LABEL (sidebar_title->details->more_info_label)));
463 pango_layout_set_width (layout, -1);
464 date_modified_str = nautilus_file_fit_modified_date_as_string
465 (file, sidebar_width, measure_width_callback, NULL, layout);
466 g_object_unref (layout);
467 append_and_eat (info_string, "\n", date_modified_str);
470 gtk_label_set_text (GTK_LABEL (sidebar_title->details->more_info_label),
471 info_string->str);
473 g_string_free (info_string, TRUE);
476 /* add a pixbuf to the emblem box */
477 static void
478 add_emblem (NautilusSidebarTitle *sidebar_title, GdkPixbuf *pixbuf)
480 GtkWidget *image_widget;
482 image_widget = gtk_image_new_from_pixbuf (pixbuf);
483 gtk_widget_show (image_widget);
484 gtk_container_add (GTK_CONTAINER (sidebar_title->details->emblem_box), image_widget);
487 static void
488 update_emblems (NautilusSidebarTitle *sidebar_title)
490 GList *pixbufs, *p;
491 GdkPixbuf *pixbuf;
493 /* exit if we don't have the file yet */
494 if (sidebar_title->details->file == NULL) {
495 return;
498 /* First, deallocate any existing ones */
499 gtk_container_foreach (GTK_CONTAINER (sidebar_title->details->emblem_box),
500 (GtkCallback) gtk_widget_destroy,
501 NULL);
503 /* fetch the emblem icons from metadata */
504 pixbufs = nautilus_file_get_emblem_pixbufs (sidebar_title->details->file,
505 nautilus_icon_get_emblem_size_for_icon_size (NAUTILUS_ICON_SIZE_STANDARD),
506 FALSE,
507 NULL);
509 /* loop through the list of emblems, installing them in the box */
510 for (p = pixbufs; p != NULL; p = p->next) {
511 pixbuf = p->data;
512 add_emblem (sidebar_title, pixbuf);
513 g_object_unref (pixbuf);
515 g_list_free (pixbufs);
518 /* return the filename text */
519 char *
520 nautilus_sidebar_title_get_text (NautilusSidebarTitle *sidebar_title)
522 return g_strdup (sidebar_title->details->title_text);
525 /* set up the filename text */
526 void
527 nautilus_sidebar_title_set_text (NautilusSidebarTitle *sidebar_title,
528 const char* new_text)
530 g_free (sidebar_title->details->title_text);
532 /* truncate the title to a reasonable size */
533 if (new_text && strlen (new_text) > MAX_TITLE_SIZE) {
534 sidebar_title->details->title_text = g_strndup (new_text, MAX_TITLE_SIZE);
535 } else {
536 sidebar_title->details->title_text = g_strdup (new_text);
538 /* Recompute the displayed text. */
539 update_title (sidebar_title);
542 static gboolean
543 item_count_ready (NautilusSidebarTitle *sidebar_title)
545 return sidebar_title->details->file != NULL
546 && nautilus_file_get_directory_item_count
547 (sidebar_title->details->file, NULL, NULL) != 0;
550 static void
551 monitor_add (NautilusSidebarTitle *sidebar_title)
553 NautilusFileAttributes attributes;
555 /* Monitor the things needed to get the right icon. Don't
556 * monitor a directory's item count at first even though the
557 * "size" attribute is based on that, because the main view
558 * will get it for us in most cases, and in other cases it's
559 * OK to not show the size -- if we did monitor it, we'd be in
560 * a race with the main view and could cause it to have to
561 * load twice. Once we have a size, though, we want to monitor
562 * the size to guarantee it stays up to date.
565 sidebar_title->details->monitoring_count = item_count_ready (sidebar_title);
567 attributes = NAUTILUS_FILE_ATTRIBUTES_FOR_ICON | NAUTILUS_FILE_ATTRIBUTE_METADATA;
568 if (sidebar_title->details->monitoring_count) {
569 attributes |= NAUTILUS_FILE_ATTRIBUTE_DIRECTORY_ITEM_COUNT;
572 nautilus_file_monitor_add (sidebar_title->details->file, sidebar_title, attributes);
575 static void
576 update_all (NautilusSidebarTitle *sidebar_title)
578 update_icon (sidebar_title);
580 update_title (sidebar_title);
581 update_more_info (sidebar_title);
583 update_emblems (sidebar_title);
585 /* Redo monitor once the count is ready. */
586 if (!sidebar_title->details->monitoring_count && item_count_ready (sidebar_title)) {
587 nautilus_file_monitor_remove (sidebar_title->details->file, sidebar_title);
588 monitor_add (sidebar_title);
592 void
593 nautilus_sidebar_title_set_file (NautilusSidebarTitle *sidebar_title,
594 NautilusFile *file,
595 const char *initial_text)
597 if (file != sidebar_title->details->file) {
598 release_file (sidebar_title);
599 sidebar_title->details->file = file;
600 sidebar_title->details->determined_icon = FALSE;
601 nautilus_file_ref (sidebar_title->details->file);
603 /* attach file */
604 if (file != NULL) {
605 sidebar_title->details->file_changed_connection =
606 g_signal_connect_object
607 (sidebar_title->details->file, "changed",
608 G_CALLBACK (update_all), sidebar_title, G_CONNECT_SWAPPED);
609 monitor_add (sidebar_title);
613 g_free (sidebar_title->details->title_text);
614 sidebar_title->details->title_text = g_strdup (initial_text);
616 update_all (sidebar_title);
619 static void
620 nautilus_sidebar_title_size_allocate (GtkWidget *widget,
621 GtkAllocation *allocation)
623 NautilusSidebarTitle *sidebar_title;
624 guint16 old_width;
625 guint best_icon_size;
627 sidebar_title = NAUTILUS_SIDEBAR_TITLE (widget);
629 old_width = widget->allocation.width;
631 EEL_CALL_PARENT (GTK_WIDGET_CLASS, size_allocate, (widget, allocation));
633 if (old_width != widget->allocation.width) {
634 best_icon_size = get_best_icon_size (sidebar_title);
635 if (best_icon_size != sidebar_title->details->best_icon_size) {
636 sidebar_title->details->best_icon_size = best_icon_size;
637 update_icon (sidebar_title);
640 /* update the title font and info format as the size changes. */
641 update_title_font (sidebar_title);
642 update_more_info (sidebar_title);
646 gboolean
647 nautilus_sidebar_title_hit_test_icon (NautilusSidebarTitle *sidebar_title, int x, int y)
649 g_return_val_if_fail (NAUTILUS_IS_SIDEBAR_TITLE (sidebar_title), FALSE);
651 return eel_point_in_widget (sidebar_title->details->icon, x, y);
654 static GtkWidget *
655 sidebar_title_create_title_label (void)
657 GtkWidget *title_label;
659 title_label = gtk_label_new ("");
660 eel_gtk_label_make_bold (GTK_LABEL (title_label));
661 gtk_label_set_line_wrap (GTK_LABEL (title_label), TRUE);
662 gtk_label_set_justify (GTK_LABEL (title_label), GTK_JUSTIFY_CENTER);
663 gtk_label_set_selectable (GTK_LABEL (title_label), TRUE);
664 gtk_label_set_ellipsize (GTK_LABEL (title_label), PANGO_ELLIPSIZE_END);
666 return title_label;
669 static GtkWidget *
670 sidebar_title_create_more_info_label (void)
672 GtkWidget *more_info_label;
674 more_info_label = gtk_label_new ("");
675 eel_gtk_label_set_scale (GTK_LABEL (more_info_label), PANGO_SCALE_SMALL);
676 gtk_label_set_justify (GTK_LABEL (more_info_label), GTK_JUSTIFY_CENTER);
677 gtk_label_set_selectable (GTK_LABEL (more_info_label), TRUE);
678 gtk_label_set_ellipsize (GTK_LABEL (more_info_label), PANGO_ELLIPSIZE_END);
680 return more_info_label;