1 | /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */ |
---|
2 | |
---|
3 | /* |
---|
4 | * Nautilus |
---|
5 | * |
---|
6 | * Copyright (C) 2000, 2001 Eazel, Inc. |
---|
7 | * |
---|
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. |
---|
12 | * |
---|
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. |
---|
17 | * |
---|
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 |
---|
21 | * |
---|
22 | * Author: Andy Hertzfeld <andy@eazel.com> |
---|
23 | */ |
---|
24 | |
---|
25 | /* This is the sidebar title widget, which is the title part of the sidebar. */ |
---|
26 | |
---|
27 | #include <config.h> |
---|
28 | #include "nautilus-sidebar-title.h" |
---|
29 | |
---|
30 | #include "nautilus-window.h" |
---|
31 | |
---|
32 | #include <bonobo/bonobo-exception.h> |
---|
33 | #include <bonobo/bonobo-property-bag-client.h> |
---|
34 | #include <eel/eel-background.h> |
---|
35 | #include <eel/eel-gdk-extensions.h> |
---|
36 | #include <eel/eel-gdk-pixbuf-extensions.h> |
---|
37 | #include <eel/eel-glib-extensions.h> |
---|
38 | #include <eel/eel-gtk-extensions.h> |
---|
39 | #include <eel/eel-gtk-macros.h> |
---|
40 | #include <eel/eel-pango-extensions.h> |
---|
41 | #include <eel/eel-string.h> |
---|
42 | #include <gtk/gtkhbox.h> |
---|
43 | #include <gtk/gtkimage.h> |
---|
44 | #include <gtk/gtklabel.h> |
---|
45 | #include <gtk/gtksignal.h> |
---|
46 | #include <gtk/gtkwidget.h> |
---|
47 | #include <libgnome/gnome-i18n.h> |
---|
48 | #include <libgnomevfs/gnome-vfs-types.h> |
---|
49 | #include <libgnomevfs/gnome-vfs-uri.h> |
---|
50 | #include <libnautilus-private/nautilus-file-attributes.h> |
---|
51 | #include <libnautilus-private/nautilus-global-preferences.h> |
---|
52 | #include <libnautilus-private/nautilus-icon-factory.h> |
---|
53 | #include <libnautilus-private/nautilus-metadata.h> |
---|
54 | #include <libnautilus-private/nautilus-search-uri.h> |
---|
55 | #include <libnautilus-private/nautilus-theme.h> |
---|
56 | #include <math.h> |
---|
57 | #include <string.h> |
---|
58 | #include <stdlib.h> |
---|
59 | |
---|
60 | /* maximum allowable size to be displayed as the title */ |
---|
61 | #define MAX_TITLE_SIZE 256 |
---|
62 | #define MINIMUM_INFO_WIDTH 32 |
---|
63 | #define SIDEBAR_INFO_MARGIN 4 |
---|
64 | |
---|
65 | #define MORE_INFO_FONT_SIZE 12 |
---|
66 | #define MIN_TITLE_FONT_SIZE 12 |
---|
67 | #define MAX_TITLE_FONT_SIZE 18 |
---|
68 | #define TITLE_PADDING 4 |
---|
69 | |
---|
70 | static void nautilus_sidebar_title_class_init (NautilusSidebarTitleClass *klass); |
---|
71 | static void nautilus_sidebar_title_destroy (GtkObject *object); |
---|
72 | static void nautilus_sidebar_title_init (NautilusSidebarTitle *pixmap); |
---|
73 | static void nautilus_sidebar_title_size_allocate (GtkWidget *widget, |
---|
74 | GtkAllocation *allocation); |
---|
75 | static void nautilus_sidebar_title_theme_changed (gpointer user_data); |
---|
76 | static void update_icon (NautilusSidebarTitle *sidebar_title); |
---|
77 | static GtkWidget * sidebar_title_create_title_label (void); |
---|
78 | static GtkWidget * sidebar_title_create_more_info_label (void); |
---|
79 | static void update_all (NautilusSidebarTitle *sidebar_title); |
---|
80 | static void update_title_font (NautilusSidebarTitle *sidebar_title); |
---|
81 | static void style_set (GtkWidget *widget, |
---|
82 | GtkStyle *previous_style); |
---|
83 | |
---|
84 | struct NautilusSidebarTitleDetails { |
---|
85 | NautilusFile *file; |
---|
86 | guint file_changed_connection; |
---|
87 | gboolean monitoring_count; |
---|
88 | |
---|
89 | char *title_text; |
---|
90 | GtkWidget *icon; |
---|
91 | GtkWidget *title_label; |
---|
92 | GtkWidget *more_info_label; |
---|
93 | GtkWidget *emblem_box; |
---|
94 | GtkWidget *notes; |
---|
95 | |
---|
96 | int shadow_offset; |
---|
97 | gboolean determined_icon; |
---|
98 | }; |
---|
99 | |
---|
100 | EEL_CLASS_BOILERPLATE (NautilusSidebarTitle, nautilus_sidebar_title, gtk_vbox_get_type ()) |
---|
101 | |
---|
102 | static void |
---|
103 | nautilus_sidebar_title_class_init (NautilusSidebarTitleClass *class) |
---|
104 | { |
---|
105 | GtkObjectClass *object_class; |
---|
106 | GtkWidgetClass *widget_class; |
---|
107 | |
---|
108 | object_class = (GtkObjectClass*) class; |
---|
109 | widget_class = (GtkWidgetClass*) class; |
---|
110 | |
---|
111 | object_class->destroy = nautilus_sidebar_title_destroy; |
---|
112 | widget_class->size_allocate = nautilus_sidebar_title_size_allocate; |
---|
113 | widget_class->style_set = style_set; |
---|
114 | |
---|
115 | } |
---|
116 | |
---|
117 | static void |
---|
118 | style_set (GtkWidget *widget, |
---|
119 | GtkStyle *previous_style) |
---|
120 | { |
---|
121 | NautilusSidebarTitle *sidebar_title; |
---|
122 | PangoFontDescription *font_desc; |
---|
123 | GtkStyle *style; |
---|
124 | |
---|
125 | g_return_if_fail (NAUTILUS_IS_SIDEBAR_TITLE (widget)); |
---|
126 | |
---|
127 | sidebar_title = NAUTILUS_SIDEBAR_TITLE (widget); |
---|
128 | |
---|
129 | /* Update the dynamically-sized title font */ |
---|
130 | update_title_font (sidebar_title); |
---|
131 | |
---|
132 | /* Update the fixed-size "more info" font */ |
---|
133 | style = gtk_widget_get_style (widget); |
---|
134 | font_desc = pango_font_description_copy (style->font_desc); |
---|
135 | pango_font_description_set_size (font_desc, MORE_INFO_FONT_SIZE * PANGO_SCALE); |
---|
136 | |
---|
137 | gtk_widget_modify_font (sidebar_title->details->more_info_label, |
---|
138 | font_desc); |
---|
139 | pango_font_description_free (font_desc); |
---|
140 | } |
---|
141 | |
---|
142 | static void |
---|
143 | nautilus_sidebar_title_init (NautilusSidebarTitle *sidebar_title) |
---|
144 | { |
---|
145 | sidebar_title->details = g_new0 (NautilusSidebarTitleDetails, 1); |
---|
146 | |
---|
147 | /* Register to find out about icon theme changes */ |
---|
148 | g_signal_connect_object (nautilus_icon_factory_get (), "icons_changed", |
---|
149 | G_CALLBACK (update_icon), sidebar_title, G_CONNECT_SWAPPED); |
---|
150 | |
---|
151 | /* Create the icon */ |
---|
152 | sidebar_title->details->icon = gtk_image_new (); |
---|
153 | gtk_box_pack_start (GTK_BOX (sidebar_title), sidebar_title->details->icon, 0, 0, 0); |
---|
154 | gtk_widget_show (sidebar_title->details->icon); |
---|
155 | |
---|
156 | /* Create the title label */ |
---|
157 | sidebar_title->details->title_label = sidebar_title_create_title_label (); |
---|
158 | gtk_box_pack_start (GTK_BOX (sidebar_title), sidebar_title->details->title_label, 0, 0, 0); |
---|
159 | gtk_widget_show (sidebar_title->details->title_label); |
---|
160 | |
---|
161 | /* Create the more info label */ |
---|
162 | sidebar_title->details->more_info_label = sidebar_title_create_more_info_label (); |
---|
163 | gtk_box_pack_start (GTK_BOX (sidebar_title), sidebar_title->details->more_info_label, 0, 0, 0); |
---|
164 | gtk_widget_show (sidebar_title->details->more_info_label); |
---|
165 | |
---|
166 | sidebar_title->details->emblem_box = gtk_hbox_new (FALSE, 0); |
---|
167 | gtk_widget_show (sidebar_title->details->emblem_box); |
---|
168 | gtk_box_pack_start (GTK_BOX (sidebar_title), sidebar_title->details->emblem_box, 0, 0, 0); |
---|
169 | |
---|
170 | sidebar_title->details->notes = GTK_WIDGET (gtk_label_new (NULL)); |
---|
171 | gtk_label_set_line_wrap (GTK_LABEL (sidebar_title->details->notes), TRUE); |
---|
172 | gtk_widget_show (sidebar_title->details->notes); |
---|
173 | gtk_box_pack_start (GTK_BOX (sidebar_title), sidebar_title->details->notes, 0, 0, 0); |
---|
174 | |
---|
175 | /* Keep track of changes in graphics trade offs */ |
---|
176 | update_all (sidebar_title); |
---|
177 | |
---|
178 | eel_preferences_add_callback_while_alive (NAUTILUS_PREFERENCES_THEME, |
---|
179 | nautilus_sidebar_title_theme_changed, |
---|
180 | sidebar_title, |
---|
181 | G_OBJECT (sidebar_title)); |
---|
182 | |
---|
183 | /* initialize the label colors & fonts */ |
---|
184 | nautilus_sidebar_title_theme_changed (sidebar_title); |
---|
185 | style_set (GTK_WIDGET (sidebar_title), NULL); |
---|
186 | } |
---|
187 | |
---|
188 | /* destroy by throwing away private storage */ |
---|
189 | static void |
---|
190 | release_file (NautilusSidebarTitle *sidebar_title) |
---|
191 | { |
---|
192 | if (sidebar_title->details->file_changed_connection != 0) { |
---|
193 | g_signal_handler_disconnect (sidebar_title->details->file, |
---|
194 | sidebar_title->details->file_changed_connection); |
---|
195 | sidebar_title->details->file_changed_connection = 0; |
---|
196 | } |
---|
197 | |
---|
198 | if (sidebar_title->details->file != NULL) { |
---|
199 | nautilus_file_monitor_remove (sidebar_title->details->file, sidebar_title); |
---|
200 | nautilus_file_unref (sidebar_title->details->file); |
---|
201 | sidebar_title->details->file = NULL; |
---|
202 | } |
---|
203 | } |
---|
204 | |
---|
205 | static void |
---|
206 | nautilus_sidebar_title_destroy (GtkObject *object) |
---|
207 | { |
---|
208 | NautilusSidebarTitle *sidebar_title; |
---|
209 | |
---|
210 | sidebar_title = NAUTILUS_SIDEBAR_TITLE (object); |
---|
211 | |
---|
212 | if (sidebar_title->details) { |
---|
213 | release_file (sidebar_title); |
---|
214 | |
---|
215 | g_free (sidebar_title->details->title_text); |
---|
216 | g_free (sidebar_title->details); |
---|
217 | sidebar_title->details = NULL; |
---|
218 | } |
---|
219 | |
---|
220 | EEL_CALL_PARENT (GTK_OBJECT_CLASS, destroy, (object)); |
---|
221 | } |
---|
222 | |
---|
223 | /* return a new index title object */ |
---|
224 | GtkWidget * |
---|
225 | nautilus_sidebar_title_new (void) |
---|
226 | { |
---|
227 | return gtk_widget_new (nautilus_sidebar_title_get_type (), NULL); |
---|
228 | } |
---|
229 | |
---|
230 | void |
---|
231 | nautilus_sidebar_title_select_text_color (NautilusSidebarTitle *sidebar_title, |
---|
232 | EelBackground *background, |
---|
233 | gboolean is_default) |
---|
234 | { |
---|
235 | char *sidebar_title_color; |
---|
236 | char *sidebar_info_title_color; |
---|
237 | char *sidebar_title_shadow_color; |
---|
238 | |
---|
239 | g_return_if_fail (background != NULL); |
---|
240 | |
---|
241 | /* if the background is set to the default, the theme can explicitly |
---|
242 | * define the title colors. Check if the background has been customized |
---|
243 | * and if the theme specified any colors |
---|
244 | */ |
---|
245 | sidebar_title_color = NULL; |
---|
246 | sidebar_info_title_color = NULL; |
---|
247 | sidebar_title_shadow_color = NULL; |
---|
248 | |
---|
249 | if (is_default) { |
---|
250 | sidebar_title_color = nautilus_theme_get_theme_data ("sidebar", "title_color"); |
---|
251 | sidebar_info_title_color = nautilus_theme_get_theme_data ("sidebar", "title_info_color"); |
---|
252 | sidebar_title_shadow_color = nautilus_theme_get_theme_data ("sidebar", "title_shadow_color"); |
---|
253 | } |
---|
254 | |
---|
255 | if (sidebar_title_color == NULL) { |
---|
256 | /* FIXME bugzilla.gnome.org 42496: for now, both the title and info |
---|
257 | * colors are the same - and hard coded */ |
---|
258 | if (eel_background_is_dark (background)) { |
---|
259 | sidebar_title_color = g_strdup ("#FFFFFF"); |
---|
260 | sidebar_info_title_color = g_strdup ("#FFFFFF"); |
---|
261 | sidebar_title_shadow_color = g_strdup ("#000000"); |
---|
262 | |
---|
263 | } else { |
---|
264 | sidebar_title_color = g_strdup ("#000000"); |
---|
265 | sidebar_info_title_color = g_strdup ("#000000"); |
---|
266 | sidebar_title_shadow_color = g_strdup ("#FFFFFF"); |
---|
267 | } |
---|
268 | } else { |
---|
269 | if (sidebar_info_title_color == NULL) { |
---|
270 | sidebar_info_title_color = g_strdup (sidebar_title_color); |
---|
271 | } |
---|
272 | if (sidebar_title_shadow_color == NULL) { |
---|
273 | sidebar_title_shadow_color = g_strdup ("#FFFFFF"); |
---|
274 | } |
---|
275 | } |
---|
276 | |
---|
277 | eel_gtk_widget_set_foreground_color (sidebar_title->details->title_label, |
---|
278 | sidebar_title_color); |
---|
279 | eel_gtk_widget_set_foreground_color (sidebar_title->details->more_info_label, |
---|
280 | sidebar_info_title_color); |
---|
281 | |
---|
282 | eel_gtk_label_set_drop_shadow_color (GTK_LABEL (sidebar_title->details->title_label), |
---|
283 | eel_parse_rgb_with_white_default (sidebar_title_shadow_color)); |
---|
284 | eel_gtk_label_set_drop_shadow_color (GTK_LABEL (sidebar_title->details->more_info_label), |
---|
285 | eel_parse_rgb_with_white_default (sidebar_title_shadow_color)); |
---|
286 | |
---|
287 | eel_gtk_label_set_drop_shadow_offset (GTK_LABEL (sidebar_title->details->title_label), |
---|
288 | sidebar_title->details->shadow_offset); |
---|
289 | eel_gtk_label_set_drop_shadow_offset (GTK_LABEL (sidebar_title->details->more_info_label), |
---|
290 | sidebar_title->details->shadow_offset); |
---|
291 | |
---|
292 | g_free (sidebar_title_color); |
---|
293 | g_free (sidebar_info_title_color); |
---|
294 | g_free (sidebar_title_shadow_color); |
---|
295 | } |
---|
296 | |
---|
297 | /* handle theme changes by setting up the color of the labels */ |
---|
298 | static void |
---|
299 | nautilus_sidebar_title_theme_changed (gpointer user_data) |
---|
300 | { |
---|
301 | char *shadow_offset_str; |
---|
302 | NautilusSidebarTitle *sidebar_title; |
---|
303 | |
---|
304 | sidebar_title = NAUTILUS_SIDEBAR_TITLE (user_data); |
---|
305 | |
---|
306 | shadow_offset_str = nautilus_theme_get_theme_data ("sidebar", "shadow_offset"); |
---|
307 | if (shadow_offset_str) { |
---|
308 | sidebar_title->details->shadow_offset = atoi (shadow_offset_str); |
---|
309 | g_free (shadow_offset_str); |
---|
310 | } else { |
---|
311 | sidebar_title->details->shadow_offset = 1; |
---|
312 | } |
---|
313 | } |
---|
314 | |
---|
315 | /* get a property from the current content view's property bag if we can */ |
---|
316 | static char* |
---|
317 | get_property_from_component (NautilusSidebarTitle *sidebar_title, const char *property) |
---|
318 | { |
---|
319 | GtkWidget *window; |
---|
320 | Bonobo_Control control; |
---|
321 | CORBA_Environment ev; |
---|
322 | Bonobo_PropertyBag property_bag; |
---|
323 | char* icon_name; |
---|
324 | |
---|
325 | window = gtk_widget_get_ancestor (GTK_WIDGET (sidebar_title), NAUTILUS_TYPE_WINDOW); |
---|
326 | |
---|
327 | if (window == NULL || NAUTILUS_WINDOW (window)->content_view == NULL) { |
---|
328 | return NULL; |
---|
329 | } |
---|
330 | |
---|
331 | |
---|
332 | control = nautilus_view_frame_get_control (NAUTILUS_VIEW_FRAME (NAUTILUS_WINDOW (window)->content_view)); |
---|
333 | if (control == NULL) { |
---|
334 | return NULL; |
---|
335 | } |
---|
336 | |
---|
337 | CORBA_exception_init (&ev); |
---|
338 | property_bag = Bonobo_Control_getProperties (control, &ev); |
---|
339 | if (BONOBO_EX (&ev)) { |
---|
340 | property_bag = CORBA_OBJECT_NIL; |
---|
341 | } |
---|
342 | CORBA_exception_free (&ev); |
---|
343 | |
---|
344 | if (property_bag == CORBA_OBJECT_NIL) { |
---|
345 | return NULL; |
---|
346 | } |
---|
347 | |
---|
348 | icon_name = bonobo_property_bag_client_get_value_string |
---|
349 | (property_bag, property, NULL); |
---|
350 | bonobo_object_release_unref (property_bag, NULL); |
---|
351 | |
---|
352 | return icon_name; |
---|
353 | } |
---|
354 | |
---|
355 | /* set up the icon image */ |
---|
356 | static void |
---|
357 | update_icon (NautilusSidebarTitle *sidebar_title) |
---|
358 | { |
---|
359 | GdkPixbuf *pixbuf; |
---|
360 | char *icon_name; |
---|
361 | gboolean leave_pixbuf_unchanged; |
---|
362 | |
---|
363 | leave_pixbuf_unchanged = FALSE; |
---|
364 | |
---|
365 | /* see if the current content view is specifying an icon */ |
---|
366 | icon_name = get_property_from_component (sidebar_title, "icon_name"); |
---|
367 | |
---|
368 | pixbuf = NULL; |
---|
369 | if (icon_name != NULL && icon_name[0] != '\0') { |
---|
370 | pixbuf = nautilus_icon_factory_get_pixbuf_from_name (icon_name, NULL, NAUTILUS_ICON_SIZE_LARGE, NULL); |
---|
371 | } else if (nautilus_icon_factory_is_icon_ready_for_file (sidebar_title->details->file)) { |
---|
372 | pixbuf = nautilus_icon_factory_get_pixbuf_for_file (sidebar_title->details->file, |
---|
373 | "accept", |
---|
374 | NAUTILUS_ICON_SIZE_LARGE); |
---|
375 | } else if (sidebar_title->details->determined_icon) { |
---|
376 | /* We used to know the icon for this file, but now the file says it isn't |
---|
377 | * ready. This means that some file info has been invalidated, which |
---|
378 | * doesn't necessarily mean that the previously-determined icon is |
---|
379 | * wrong (in fact, in practice it usually doesn't mean that). Keep showing |
---|
380 | * the one we last determined for now. |
---|
381 | */ |
---|
382 | leave_pixbuf_unchanged = TRUE; |
---|
383 | } |
---|
384 | |
---|
385 | g_free (icon_name); |
---|
386 | |
---|
387 | if (pixbuf != NULL) { |
---|
388 | sidebar_title->details->determined_icon = TRUE; |
---|
389 | } |
---|
390 | |
---|
391 | if (!leave_pixbuf_unchanged) { |
---|
392 | gtk_image_set_from_pixbuf (GTK_IMAGE (sidebar_title->details->icon), pixbuf); |
---|
393 | } |
---|
394 | } |
---|
395 | |
---|
396 | static void |
---|
397 | update_title_font (NautilusSidebarTitle *sidebar_title) |
---|
398 | { |
---|
399 | int available_width; |
---|
400 | PangoFontDescription *title_font; |
---|
401 | int largest_fitting_font_size; |
---|
402 | GtkStyle *style; |
---|
403 | |
---|
404 | /* Make sure theres work to do */ |
---|
405 | if (eel_strlen (sidebar_title->details->title_text) < 1) { |
---|
406 | return; |
---|
407 | } |
---|
408 | |
---|
409 | available_width = GTK_WIDGET (sidebar_title)->allocation.width - TITLE_PADDING; |
---|
410 | |
---|
411 | /* No work to do */ |
---|
412 | if (available_width <= 0) { |
---|
413 | return; |
---|
414 | } |
---|
415 | |
---|
416 | style = gtk_widget_get_style (GTK_WIDGET (sidebar_title)); |
---|
417 | title_font = pango_font_description_copy (style->font_desc); |
---|
418 | largest_fitting_font_size = eel_pango_font_description_get_largest_fitting_font_size ( |
---|
419 | title_font, |
---|
420 | gtk_widget_get_pango_context (sidebar_title->details->title_label), |
---|
421 | sidebar_title->details->title_text, |
---|
422 | available_width, |
---|
423 | MIN_TITLE_FONT_SIZE, |
---|
424 | MAX_TITLE_FONT_SIZE); |
---|
425 | pango_font_description_set_size (title_font, largest_fitting_font_size * PANGO_SCALE); |
---|
426 | pango_font_description_set_weight (title_font, PANGO_WEIGHT_BOLD); |
---|
427 | |
---|
428 | gtk_widget_modify_font (sidebar_title->details->title_label, |
---|
429 | title_font); |
---|
430 | pango_font_description_free (title_font); |
---|
431 | } |
---|
432 | |
---|
433 | static void |
---|
434 | update_title (NautilusSidebarTitle *sidebar_title) |
---|
435 | { |
---|
436 | GtkLabel *label; |
---|
437 | const char *text; |
---|
438 | |
---|
439 | label = GTK_LABEL (sidebar_title->details->title_label); |
---|
440 | text = sidebar_title->details->title_text; |
---|
441 | |
---|
442 | if (eel_strcmp (text, gtk_label_get_text (label)) == 0) { |
---|
443 | return; |
---|
444 | } |
---|
445 | gtk_label_set_text (label, text); |
---|
446 | update_title_font (sidebar_title); |
---|
447 | } |
---|
448 | |
---|
449 | static void |
---|
450 | append_and_eat (GString *string, const char *separator, char *new_string) |
---|
451 | { |
---|
452 | if (new_string == NULL) { |
---|
453 | return; |
---|
454 | } |
---|
455 | if (separator != NULL) { |
---|
456 | g_string_append (string, separator); |
---|
457 | } |
---|
458 | g_string_append (string, new_string); |
---|
459 | g_free (new_string); |
---|
460 | } |
---|
461 | |
---|
462 | static gboolean |
---|
463 | file_is_search_location (NautilusFile *file) |
---|
464 | { |
---|
465 | char *uri; |
---|
466 | gboolean is_search_uri; |
---|
467 | |
---|
468 | uri = nautilus_file_get_uri (file); |
---|
469 | is_search_uri = nautilus_is_search_uri (uri); |
---|
470 | g_free (uri); |
---|
471 | |
---|
472 | return is_search_uri; |
---|
473 | } |
---|
474 | |
---|
475 | static int |
---|
476 | measure_width_callback (const char *string, gpointer callback_data) |
---|
477 | { |
---|
478 | PangoLayout *layout; |
---|
479 | int width; |
---|
480 | |
---|
481 | layout = PANGO_LAYOUT (callback_data); |
---|
482 | pango_layout_set_text (layout, string, -1); |
---|
483 | pango_layout_get_pixel_size (layout, &width, NULL); |
---|
484 | return width; |
---|
485 | } |
---|
486 | |
---|
487 | static void |
---|
488 | update_more_info (NautilusSidebarTitle *sidebar_title) |
---|
489 | { |
---|
490 | NautilusFile *file; |
---|
491 | GString *info_string; |
---|
492 | char *type_string, *component_info; |
---|
493 | char *search_string, *search_uri; |
---|
494 | char *date_modified_str; |
---|
495 | int sidebar_width; |
---|
496 | PangoLayout *layout; |
---|
497 | |
---|
498 | file = sidebar_title->details->file; |
---|
499 | |
---|
500 | /* allow components to specify the info if they wish to */ |
---|
501 | component_info = get_property_from_component (sidebar_title, "summary_info"); |
---|
502 | if (component_info != NULL && strlen (component_info) > 0) { |
---|
503 | info_string = g_string_new (component_info); |
---|
504 | g_free (component_info); |
---|
505 | } else { |
---|
506 | /* Adding this special case for search results to |
---|
507 | correspond to the fix for bug 2341. */ |
---|
508 | if (file != NULL && file_is_search_location (file)) { |
---|
509 | search_uri = nautilus_file_get_uri (file); |
---|
510 | search_string = nautilus_search_uri_to_human (search_uri); |
---|
511 | g_free (search_uri); |
---|
512 | info_string = g_string_new (search_string); |
---|
513 | g_free (search_string); |
---|
514 | append_and_eat (info_string, "\n ", |
---|
515 | nautilus_file_get_string_attribute (file, "size")); |
---|
516 | } else { |
---|
517 | info_string = g_string_new (NULL); |
---|
518 | type_string = nautilus_file_get_string_attribute (file, "type"); |
---|
519 | if (type_string != NULL) { |
---|
520 | append_and_eat (info_string, NULL, type_string); |
---|
521 | append_and_eat (info_string, ", ", |
---|
522 | nautilus_file_get_string_attribute (file, "size")); |
---|
523 | } else { |
---|
524 | append_and_eat (info_string, NULL, |
---|
525 | nautilus_file_get_string_attribute (file, "size")); |
---|
526 | } |
---|
527 | |
---|
528 | sidebar_width = GTK_WIDGET (sidebar_title)->allocation.width - 2 * SIDEBAR_INFO_MARGIN; |
---|
529 | if (sidebar_width > MINIMUM_INFO_WIDTH) { |
---|
530 | layout = pango_layout_copy (gtk_label_get_layout (GTK_LABEL (sidebar_title->details->more_info_label))); |
---|
531 | pango_layout_set_width (layout, -1); |
---|
532 | date_modified_str = nautilus_file_fit_modified_date_as_string |
---|
533 | (file, sidebar_width, measure_width_callback, NULL, layout); |
---|
534 | g_object_unref (layout); |
---|
535 | append_and_eat (info_string, "\n", date_modified_str); |
---|
536 | } |
---|
537 | } |
---|
538 | } |
---|
539 | gtk_label_set_text (GTK_LABEL (sidebar_title->details->more_info_label), |
---|
540 | info_string->str); |
---|
541 | |
---|
542 | g_string_free (info_string, TRUE); |
---|
543 | } |
---|
544 | |
---|
545 | /* add a pixbuf to the emblem box */ |
---|
546 | static void |
---|
547 | add_emblem (NautilusSidebarTitle *sidebar_title, GdkPixbuf *pixbuf) |
---|
548 | { |
---|
549 | GtkWidget *image_widget; |
---|
550 | |
---|
551 | image_widget = gtk_image_new_from_pixbuf (pixbuf); |
---|
552 | gtk_widget_show (image_widget); |
---|
553 | gtk_container_add (GTK_CONTAINER (sidebar_title->details->emblem_box), image_widget); |
---|
554 | } |
---|
555 | |
---|
556 | static void |
---|
557 | update_emblems (NautilusSidebarTitle *sidebar_title) |
---|
558 | { |
---|
559 | GList *icons, *p; |
---|
560 | GdkPixbuf *pixbuf; |
---|
561 | |
---|
562 | /* exit if we don't have the file yet */ |
---|
563 | if (sidebar_title->details->file == NULL) { |
---|
564 | return; |
---|
565 | } |
---|
566 | |
---|
567 | /* First, deallocate any existing ones */ |
---|
568 | gtk_container_foreach (GTK_CONTAINER (sidebar_title->details->emblem_box), |
---|
569 | (GtkCallback) gtk_widget_destroy, |
---|
570 | NULL); |
---|
571 | |
---|
572 | /* fetch the emblem icons from metadata */ |
---|
573 | icons = nautilus_icon_factory_get_emblem_icons_for_file (sidebar_title->details->file, NULL); |
---|
574 | |
---|
575 | /* loop through the list of emblems, installing them in the box */ |
---|
576 | for (p = icons; p != NULL; p = p->next) { |
---|
577 | pixbuf = nautilus_icon_factory_get_pixbuf_for_icon |
---|
578 | (p->data, NULL, NULL, |
---|
579 | NAUTILUS_ICON_SIZE_STANDARD, |
---|
580 | NULL, FALSE, NULL); |
---|
581 | if (pixbuf != NULL) { |
---|
582 | add_emblem (sidebar_title, pixbuf); |
---|
583 | g_object_unref (pixbuf); |
---|
584 | } |
---|
585 | } |
---|
586 | |
---|
587 | eel_g_list_free_deep (icons); |
---|
588 | } |
---|
589 | |
---|
590 | static void |
---|
591 | update_notes (NautilusSidebarTitle *sidebar_title) |
---|
592 | { |
---|
593 | char *text; |
---|
594 | |
---|
595 | text = nautilus_file_get_metadata (sidebar_title->details->file, |
---|
596 | NAUTILUS_METADATA_KEY_NOTES, |
---|
597 | NULL); |
---|
598 | gtk_label_set_text (GTK_LABEL (sidebar_title->details->notes), text); |
---|
599 | g_free (text); |
---|
600 | } |
---|
601 | |
---|
602 | /* return the filename text */ |
---|
603 | char * |
---|
604 | nautilus_sidebar_title_get_text (NautilusSidebarTitle *sidebar_title) |
---|
605 | { |
---|
606 | return g_strdup (sidebar_title->details->title_text); |
---|
607 | } |
---|
608 | |
---|
609 | /* set up the filename text */ |
---|
610 | void |
---|
611 | nautilus_sidebar_title_set_text (NautilusSidebarTitle *sidebar_title, |
---|
612 | const char* new_text) |
---|
613 | { |
---|
614 | g_free (sidebar_title->details->title_text); |
---|
615 | |
---|
616 | /* truncate the title to a reasonable size */ |
---|
617 | if (new_text && strlen (new_text) > MAX_TITLE_SIZE) { |
---|
618 | sidebar_title->details->title_text = g_strndup (new_text, MAX_TITLE_SIZE); |
---|
619 | } else { |
---|
620 | sidebar_title->details->title_text = g_strdup (new_text); |
---|
621 | } |
---|
622 | /* Recompute the displayed text. */ |
---|
623 | update_title (sidebar_title); |
---|
624 | } |
---|
625 | |
---|
626 | static gboolean |
---|
627 | item_count_ready (NautilusSidebarTitle *sidebar_title) |
---|
628 | { |
---|
629 | return sidebar_title->details->file != NULL |
---|
630 | && nautilus_file_get_directory_item_count |
---|
631 | (sidebar_title->details->file, NULL, NULL) != 0; |
---|
632 | } |
---|
633 | |
---|
634 | static void |
---|
635 | monitor_add (NautilusSidebarTitle *sidebar_title) |
---|
636 | { |
---|
637 | GList *attributes; |
---|
638 | |
---|
639 | /* Monitor the things needed to get the right icon. Don't |
---|
640 | * monitor a directory's item count at first even though the |
---|
641 | * "size" attribute is based on that, because the main view |
---|
642 | * will get it for us in most cases, and in other cases it's |
---|
643 | * OK to not show the size -- if we did monitor it, we'd be in |
---|
644 | * a race with the main view and could cause it to have to |
---|
645 | * load twice. Once we have a size, though, we want to monitor |
---|
646 | * the size to guarantee it stays up to date. |
---|
647 | */ |
---|
648 | |
---|
649 | sidebar_title->details->monitoring_count = item_count_ready (sidebar_title); |
---|
650 | |
---|
651 | attributes = nautilus_icon_factory_get_required_file_attributes (); |
---|
652 | attributes = g_list_prepend (attributes, |
---|
653 | NAUTILUS_FILE_ATTRIBUTE_METADATA); |
---|
654 | if (sidebar_title->details->monitoring_count) { |
---|
655 | attributes = g_list_prepend (attributes, |
---|
656 | NAUTILUS_FILE_ATTRIBUTE_DIRECTORY_ITEM_COUNT); |
---|
657 | } |
---|
658 | |
---|
659 | nautilus_file_monitor_add (sidebar_title->details->file, sidebar_title, attributes); |
---|
660 | |
---|
661 | g_list_free (attributes); |
---|
662 | } |
---|
663 | |
---|
664 | static void |
---|
665 | update_all (NautilusSidebarTitle *sidebar_title) |
---|
666 | { |
---|
667 | update_icon (sidebar_title); |
---|
668 | |
---|
669 | update_title (sidebar_title); |
---|
670 | update_more_info (sidebar_title); |
---|
671 | |
---|
672 | update_emblems (sidebar_title); |
---|
673 | update_notes (sidebar_title); |
---|
674 | |
---|
675 | /* Redo monitor once the count is ready. */ |
---|
676 | if (!sidebar_title->details->monitoring_count && item_count_ready (sidebar_title)) { |
---|
677 | nautilus_file_monitor_remove (sidebar_title->details->file, sidebar_title); |
---|
678 | monitor_add (sidebar_title); |
---|
679 | } |
---|
680 | } |
---|
681 | |
---|
682 | void |
---|
683 | nautilus_sidebar_title_set_file (NautilusSidebarTitle *sidebar_title, |
---|
684 | NautilusFile *file, |
---|
685 | const char *initial_text) |
---|
686 | { |
---|
687 | if (file != sidebar_title->details->file) { |
---|
688 | release_file (sidebar_title); |
---|
689 | sidebar_title->details->file = file; |
---|
690 | sidebar_title->details->determined_icon = FALSE; |
---|
691 | nautilus_file_ref (sidebar_title->details->file); |
---|
692 | |
---|
693 | /* attach file */ |
---|
694 | if (file != NULL) { |
---|
695 | sidebar_title->details->file_changed_connection = |
---|
696 | g_signal_connect_object |
---|
697 | (sidebar_title->details->file, "changed", |
---|
698 | G_CALLBACK (update_all), sidebar_title, G_CONNECT_SWAPPED); |
---|
699 | monitor_add (sidebar_title); |
---|
700 | } |
---|
701 | } |
---|
702 | |
---|
703 | g_free (sidebar_title->details->title_text); |
---|
704 | sidebar_title->details->title_text = g_strdup (initial_text); |
---|
705 | |
---|
706 | update_all (sidebar_title); |
---|
707 | } |
---|
708 | |
---|
709 | static void |
---|
710 | nautilus_sidebar_title_size_allocate (GtkWidget *widget, |
---|
711 | GtkAllocation *allocation) |
---|
712 | { |
---|
713 | guint16 old_width; |
---|
714 | |
---|
715 | old_width = widget->allocation.width; |
---|
716 | |
---|
717 | EEL_CALL_PARENT (GTK_WIDGET_CLASS, size_allocate, (widget, allocation)); |
---|
718 | |
---|
719 | if (old_width != widget->allocation.width) { |
---|
720 | /* update the title font and info format as the size changes. */ |
---|
721 | update_title_font (NAUTILUS_SIDEBAR_TITLE (widget)); |
---|
722 | update_more_info (NAUTILUS_SIDEBAR_TITLE (widget)); |
---|
723 | } |
---|
724 | } |
---|
725 | |
---|
726 | gboolean |
---|
727 | nautilus_sidebar_title_hit_test_icon (NautilusSidebarTitle *sidebar_title, int x, int y) |
---|
728 | { |
---|
729 | g_return_val_if_fail (NAUTILUS_IS_SIDEBAR_TITLE (sidebar_title), FALSE); |
---|
730 | |
---|
731 | return eel_point_in_widget (sidebar_title->details->icon, x, y); |
---|
732 | } |
---|
733 | |
---|
734 | static GtkWidget * |
---|
735 | sidebar_title_create_title_label (void) |
---|
736 | { |
---|
737 | GtkWidget *title_label; |
---|
738 | |
---|
739 | title_label = gtk_label_new (""); |
---|
740 | eel_gtk_label_make_bold (GTK_LABEL (title_label)); |
---|
741 | gtk_label_set_line_wrap (GTK_LABEL (title_label), TRUE); |
---|
742 | gtk_label_set_justify (GTK_LABEL (title_label), GTK_JUSTIFY_CENTER); |
---|
743 | |
---|
744 | return title_label; |
---|
745 | } |
---|
746 | |
---|
747 | static GtkWidget * |
---|
748 | sidebar_title_create_more_info_label (void) |
---|
749 | { |
---|
750 | GtkWidget *more_info_label; |
---|
751 | |
---|
752 | more_info_label = gtk_label_new (""); |
---|
753 | eel_gtk_label_set_scale (GTK_LABEL (more_info_label), PANGO_SCALE_SMALL); |
---|
754 | gtk_label_set_justify (GTK_LABEL (more_info_label), GTK_JUSTIFY_CENTER); |
---|
755 | |
---|
756 | return more_info_label; |
---|
757 | } |
---|