added gtk_dialog_help_disable(), modified gtk_dialog_help_enable() (fixes #19468)
[hildon] / hildon-widgets / hildon-file-details-dialog.c
1 /*
2  * This file is part of hildon-libs
3  *
4  * Copyright (C) 2005 Nokia Corporation.
5  *
6  * Contact: Luc Pionchon <luc.pionchon@nokia.com>
7  *
8  * This library is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU Lesser General Public License
10  * as published by the Free Software Foundation; either version 2.1 of
11  * the License, or (at your option) any later version.
12  *
13  * This library is distributed in the hope that it will be useful, but
14  * WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16  * Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with this library; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
21  * 02110-1301 USA
22  *
23  */
24
25 /* @file hildon-file-details-dialog.c 
26  * 
27  * This file contains API for Hildon File Details dialog.
28  * 
29  */
30
31 #include <gtk/gtkcheckbutton.h>
32 #include <gtk/gtklabel.h>
33 #include <gtk/gtknotebook.h>
34 #include <gtk/gtkhbox.h>
35 #include <gtk/gtkvbox.h>
36 #include <gtk/gtkimage.h>
37 #include <gtk/gtkscrolledwindow.h>
38 #include <time.h>
39 #include <libintl.h>
40 #include <libgnomevfs/gnome-vfs.h>
41
42 #include <hildon-widgets/hildon-caption.h>
43 #include <hildon-widgets/hildon-file-system-model.h>
44 #include <hildon-widgets/gtk-infoprint.h>
45 #include <hildon-widgets/hildon-defines.h>
46 #include "hildon-file-details-dialog.h"
47
48 #ifdef HAVE_CONFIG_H
49 #include <config.h>
50 #endif
51
52 #define _(String) dgettext(PACKAGE, String)
53
54 enum
55 {
56   PROP_SHOW_TABS = 1,
57   PROP_ADDITIONAL_TAB,
58   PROP_ADDITIONAL_TAB_LABEL,
59   PROP_MODEL
60 };
61
62 struct _HildonFileDetailsDialogPrivate {
63     GtkNotebook *notebook;
64
65     GtkWidget *file_location, *file_name;
66     GtkWidget *file_type, *file_size;
67     GtkWidget *file_date, *file_time;
68     GtkWidget *file_readonly, *file_device;
69     GtkWidget *file_location_image, *file_device_image;
70     GtkWidget *ok_button;
71
72     GtkTreeRowReference *active_file;
73     gboolean checkbox_original_state;
74     gulong toggle_handler;
75
76     /* Properties */
77     HildonFileSystemModel *model;
78     GtkWidget *tab_label;
79 };
80
81 static void
82 hildon_file_details_dialog_class_init(HildonFileDetailsDialogClass *
83                                       klass);
84 static void hildon_file_details_dialog_init(HildonFileDetailsDialog *
85                                             filedetailsdialog);
86 static void hildon_file_details_dialog_finalize(GObject * object);
87
88 static void
89 hildon_file_details_dialog_set_property( GObject *object, guint param_id,
90                                                            const GValue *value,
91                                          GParamSpec *pspec );
92 static void
93 hildon_file_details_dialog_get_property( GObject *object, guint param_id,
94                                                            GValue *value, GParamSpec *pspec );
95 static void 
96 hildon_file_details_dialog_response(GtkDialog *dialog, gint response_id);
97
98 static GtkDialogClass *file_details_dialog_parent_class = NULL;
99
100 GType hildon_file_details_dialog_get_type(void)
101 {
102     static GType file_details_dialog_type = 0;
103
104     if (!file_details_dialog_type) {
105         static const GTypeInfo file_details_dialog_info = {
106             sizeof(HildonFileDetailsDialogClass),
107             NULL,       /* base_init */
108             NULL,       /* base_finalize */
109             (GClassInitFunc) hildon_file_details_dialog_class_init,
110             NULL,       /* class_finalize */
111             NULL,       /* class_data */
112             sizeof(HildonFileDetailsDialog),
113             0,  /* n_preallocs */
114             (GInstanceInitFunc) hildon_file_details_dialog_init,
115         };
116
117         file_details_dialog_type =
118             g_type_register_static(GTK_TYPE_DIALOG,
119                                    "HildonFileDetailsDialog",
120                                    &file_details_dialog_info,
121                                    0);
122     }
123
124     return file_details_dialog_type;
125 }
126
127 static gboolean write_access(const gchar *uri)
128 {
129   GnomeVFSFileInfo *info;
130   gboolean result = FALSE;
131
132   info = gnome_vfs_file_info_new ();
133   if (gnome_vfs_get_file_info(uri, info, 
134     GNOME_VFS_FILE_INFO_GET_ACCESS_RIGHTS) == GNOME_VFS_OK)
135     result = ((info->permissions & GNOME_VFS_PERM_ACCESS_WRITABLE) 
136               == GNOME_VFS_PERM_ACCESS_WRITABLE);
137
138   gnome_vfs_file_info_unref(info);
139   return result;
140 }
141
142 static void change_state(HildonFileDetailsDialog *self, gboolean readonly)
143 {
144   GtkTreeIter iter;
145
146   g_return_if_fail(HILDON_IS_FILE_DETAILS_DIALOG(self));
147
148   if (hildon_file_details_dialog_get_file_iter(self, &iter))
149   {  
150     gchar *uri;
151     GnomeVFSFileInfo *info;
152     GnomeVFSResult result;
153
154     gtk_tree_model_get(GTK_TREE_MODEL(self->priv->model), &iter, 
155       HILDON_FILE_SYSTEM_MODEL_COLUMN_URI, &uri, -1);    
156
157     info = gnome_vfs_file_info_new();
158     result = gnome_vfs_get_file_info(uri, info, 
159       GNOME_VFS_FILE_INFO_DEFAULT);
160
161     if (result == GNOME_VFS_OK)
162     {
163       if (readonly)
164         info->permissions &= ~(S_IWUSR | S_IWGRP | S_IWOTH);
165       else      
166         info->permissions |= (S_IWUSR | S_IWGRP);
167       
168       result = gnome_vfs_set_file_info(uri, info, 
169           GNOME_VFS_SET_FILE_INFO_PERMISSIONS);
170     }
171
172     /* No errors are defined in the specs, but the previous operations can still fail */
173     if (result != GNOME_VFS_OK)
174       gtk_infoprint(GTK_WINDOW(self), gnome_vfs_result_to_string(result));
175     
176     gnome_vfs_file_info_unref(info);
177     g_free(uri);
178   }
179   else
180     g_assert_not_reached();
181 }
182
183 /* Cancel changes if read-only is changed */
184 static void 
185 hildon_file_details_dialog_response(GtkDialog *dialog, gint response_id)
186 {
187     if (response_id == GTK_RESPONSE_CANCEL)
188     {
189       HildonFileDetailsDialog *self;
190       gboolean state;
191
192       self = HILDON_FILE_DETAILS_DIALOG(dialog);  
193       state = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(self->priv->file_readonly));
194
195       if (state != self->priv->checkbox_original_state)
196         change_state(self, self->priv->checkbox_original_state);
197     }
198 }
199
200 static void
201 hildon_file_details_dialog_read_only_toggled(GtkWidget *widget, gpointer data)
202 {
203   change_state(HILDON_FILE_DETAILS_DIALOG(data), 
204     gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)));
205 }
206
207 static void 
208 hildon_file_details_dialog_map(GtkWidget *widget)
209 {
210   HildonFileDetailsDialogPrivate *priv;
211
212   priv = HILDON_FILE_DETAILS_DIALOG(widget)->priv;
213
214   GTK_WIDGET_CLASS(file_details_dialog_parent_class)->map(widget);
215
216   if (gtk_notebook_get_show_tabs(priv->notebook))
217   {
218     gtk_notebook_set_current_page(priv->notebook, 0);
219     gtk_widget_grab_focus(GTK_WIDGET(priv->notebook));
220   }
221   else
222     gtk_widget_grab_focus(priv->ok_button);
223 }
224
225 static void
226 hildon_file_details_dialog_class_init(HildonFileDetailsDialogClass * klass)
227 {
228     GObjectClass *gobject_class;
229
230     file_details_dialog_parent_class = g_type_class_peek_parent(klass);
231     gobject_class = G_OBJECT_CLASS(klass);
232     gobject_class->finalize = hildon_file_details_dialog_finalize;
233     gobject_class->get_property = hildon_file_details_dialog_get_property;
234     gobject_class->set_property = hildon_file_details_dialog_set_property;
235     GTK_WIDGET_CLASS(klass)->map = hildon_file_details_dialog_map;
236     GTK_DIALOG_CLASS(klass)->response = hildon_file_details_dialog_response;
237
238     g_type_class_add_private(klass, sizeof(HildonFileDetailsDialogPrivate));
239
240   /**
241    * HildonFileDetailsDialog:additional_tab:
242    *
243    * This is a place for an additional tab.
244    */
245   g_object_class_install_property( gobject_class, PROP_ADDITIONAL_TAB,
246                                    g_param_spec_object("additional-tab",
247                                    "Additional tab",
248                                    "Tab to show additinal information",
249                                                        GTK_TYPE_WIDGET, G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
250   /**
251    * HildonFileDetailsDialog:show_tabs:
252    *
253    * Do we want to show the tab labels.
254    */
255   g_object_class_install_property( gobject_class, PROP_SHOW_TABS,
256                                    g_param_spec_boolean("show-tabs",
257                                    "Show tab labels",
258                                    "Do we want to show the tab label.",
259                                    FALSE, G_PARAM_READWRITE | G_PARAM_CONSTRUCT));
260   /**
261    * HildonFileDetailsDialog:additional_tab_label:
262    *
263    * 
264    */
265   g_object_class_install_property( gobject_class, PROP_ADDITIONAL_TAB_LABEL,
266                                    g_param_spec_string("additional-tab-label",
267                                    "Additional tab label",
268                                    "Label to the additional tab",
269                                    NULL, G_PARAM_READWRITE));
270
271   g_object_class_install_property( gobject_class, PROP_MODEL,
272                  g_param_spec_object("model", "Model", 
273                  "HildonFileSystemModel to use when fetching information",
274                  HILDON_TYPE_FILE_SYSTEM_MODEL, G_PARAM_READWRITE));
275 }
276
277 /* This handler is needed to correctly position the scrollbar down. 
278    It doesn't happen automatically... */
279 static gboolean 
280 handle_focus(GtkWidget *widget, GtkDirectionType *dir, gpointer data)
281 {
282   if (!GTK_WIDGET_HAS_FOCUS(widget))
283   {
284     GtkAdjustment *adj;
285     adj = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(data));
286     gtk_adjustment_set_value(adj, adj->upper - adj->page_size);
287   }
288
289   return FALSE;
290 }
291
292 static void
293 hildon_file_details_dialog_init(HildonFileDetailsDialog *self)
294 {
295     GtkWidget *caption_location, *caption_name, *caption_type;
296     GtkWidget *caption_date, *caption_size, *caption_time;
297     GtkWidget *caption_read, *caption_device;
298     GtkWidget *hbox_location, *hbox_device;
299     GtkWidget *vbox;
300     GtkWidget *scroll;
301     GtkSizeGroup *group;
302     GdkGeometry geometry;
303
304     HildonFileDetailsDialogPrivate *priv;
305
306     self->priv = priv =
307       G_TYPE_INSTANCE_GET_PRIVATE(self, \
308           HILDON_TYPE_FILE_DETAILS_DIALOG, HildonFileDetailsDialogPrivate);
309
310     priv->notebook = GTK_NOTEBOOK(gtk_notebook_new());
311     scroll = gtk_scrolled_window_new(NULL, NULL);
312     vbox = gtk_vbox_new(FALSE, 0);
313     group = gtk_size_group_new(GTK_SIZE_GROUP_BOTH);
314     
315     priv->tab_label = gtk_label_new(_("sfil_ti_notebook_file"));
316     g_object_ref(priv->tab_label);
317     gtk_object_sink(GTK_OBJECT(priv->tab_label));
318     gtk_widget_show(priv->tab_label);
319
320     priv->file_device = g_object_new(GTK_TYPE_LABEL, "xalign", 0.0f, NULL);
321     priv->file_location = g_object_new(GTK_TYPE_LABEL, "xalign", 0.0f, NULL);
322     priv->file_name = g_object_new(GTK_TYPE_LABEL, "xalign", 0.0f, NULL);
323     priv->file_type = g_object_new(GTK_TYPE_LABEL, "xalign", 0.0f, NULL);
324     priv->file_size = g_object_new(GTK_TYPE_LABEL, "xalign", 0.0f, NULL);
325     priv->file_date = g_object_new(GTK_TYPE_LABEL,"xalign", 0.0f, NULL);
326     priv->file_time = g_object_new(GTK_TYPE_LABEL, "xalign", 0.0f, NULL);
327     priv->file_readonly = gtk_check_button_new();
328
329     hbox_location = gtk_hbox_new(FALSE, HILDON_MARGIN_DEFAULT);
330     hbox_device = gtk_hbox_new(FALSE, HILDON_MARGIN_DEFAULT);
331
332     priv->file_location_image = gtk_image_new();
333     priv->file_device_image = gtk_image_new();
334
335     gtk_box_pack_start(GTK_BOX(hbox_location), priv->file_location_image, FALSE, TRUE, 0);
336     gtk_box_pack_start(GTK_BOX(hbox_location), priv->file_location, TRUE, TRUE, 0);
337     gtk_box_pack_start(GTK_BOX(hbox_device), priv->file_device_image, FALSE, TRUE, 0);
338     gtk_box_pack_start(GTK_BOX(hbox_device), priv->file_device, TRUE, TRUE, 0);
339
340     /* Tab one */
341     caption_name = hildon_caption_new(group, _("ckdg_fi_properties_name_prompt"), 
342       priv->file_name, NULL, HILDON_CAPTION_OPTIONAL);
343     caption_type = hildon_caption_new(group, _("ckdg_fi_properties_type_prompt"), 
344       priv->file_type, NULL, HILDON_CAPTION_OPTIONAL);
345     caption_location = hildon_caption_new(group, _("sfil_fi_properties_location_prompt"), 
346       hbox_location, NULL, HILDON_CAPTION_OPTIONAL);
347     caption_device = hildon_caption_new(group, _("sfil_fi_properties_device_prompt"), 
348       hbox_device, NULL, HILDON_CAPTION_OPTIONAL);
349     caption_date = hildon_caption_new(group, _("ckdg_fi_properties_date_prompt"), 
350       priv->file_date, NULL, HILDON_CAPTION_OPTIONAL);
351     caption_time = hildon_caption_new(group, _("ckdg_fi_properties_time_prompt"), 
352       priv->file_time, NULL, HILDON_CAPTION_OPTIONAL);
353     caption_size = hildon_caption_new(group, _("ckdg_fi_properties_size_prompt"), 
354       priv->file_size, NULL, HILDON_CAPTION_OPTIONAL);
355     caption_read = hildon_caption_new(group, _("ckdg_fi_properties_read_only"), 
356       priv->file_readonly, NULL, HILDON_CAPTION_OPTIONAL);
357
358     hildon_caption_set_separator(HILDON_CAPTION(caption_name), "");
359     hildon_caption_set_separator(HILDON_CAPTION(caption_type), "");
360     hildon_caption_set_separator(HILDON_CAPTION(caption_location), "");
361     hildon_caption_set_separator(HILDON_CAPTION(caption_device), "");
362     hildon_caption_set_separator(HILDON_CAPTION(caption_date), "");
363     hildon_caption_set_separator(HILDON_CAPTION(caption_time), "");
364     hildon_caption_set_separator(HILDON_CAPTION(caption_size), "");
365     hildon_caption_set_separator(HILDON_CAPTION(caption_read), "");
366
367     g_object_unref(group);
368
369     gtk_box_pack_start(GTK_BOX(vbox), caption_name, FALSE, TRUE, 0);
370     gtk_box_pack_start(GTK_BOX(vbox), caption_type, FALSE, TRUE, 0);
371     gtk_box_pack_start(GTK_BOX(vbox), caption_location, FALSE, TRUE, 0);
372     gtk_box_pack_start(GTK_BOX(vbox), caption_device, FALSE, TRUE, 0);
373     gtk_box_pack_start(GTK_BOX(vbox), caption_date, FALSE, TRUE, 0);
374     gtk_box_pack_start(GTK_BOX(vbox), caption_time, FALSE, TRUE, 0);
375     gtk_box_pack_start(GTK_BOX(vbox), caption_size, FALSE, TRUE, 0);
376     gtk_box_pack_start(GTK_BOX(vbox), caption_read, FALSE, TRUE, 0);
377
378     gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(scroll), vbox);
379     gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll), 
380         GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
381     gtk_container_set_border_width(GTK_CONTAINER(scroll), 
382         HILDON_MARGIN_DEFAULT);
383     /* Both scrolled window and viewport have separate shadows... */
384     gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW(scroll),
385         GTK_SHADOW_NONE);
386     gtk_viewport_set_shadow_type(
387         GTK_VIEWPORT(gtk_bin_get_child(GTK_BIN(scroll))),
388         GTK_SHADOW_NONE);
389
390     /* Populate dialog */
391     gtk_notebook_append_page(priv->notebook, scroll,
392                              gtk_label_new(_("sfil_ti_notebook_common")));
393
394     gtk_box_pack_start(GTK_BOX(GTK_DIALOG(self)->vbox),
395                        GTK_WIDGET(priv->notebook), TRUE, TRUE, 0);
396
397     /* From widget specs, generic dialog size */
398     geometry.min_width = 133;
399     geometry.max_width = 602;
400     /* Scrolled windows do not ask space for whole contents in size_request.
401        So, we must force the dialog to have larger than minimum size */
402     geometry.min_height = 240 + (2 * HILDON_MARGIN_DEFAULT);
403     geometry.max_height = 240 + (2 * HILDON_MARGIN_DEFAULT);
404
405     gtk_window_set_geometry_hints(GTK_WINDOW(self),
406                                   GTK_WIDGET(priv->notebook), &geometry,
407                                   GDK_HINT_MIN_SIZE | GDK_HINT_MAX_SIZE);
408
409     gtk_widget_show_all(GTK_WIDGET(priv->notebook));
410     priv->ok_button = gtk_dialog_add_button(GTK_DIALOG(self),
411                           _("sfil_bd_filetype_details_dialog_ok"),
412                           GTK_RESPONSE_OK);
413     gtk_dialog_add_button(GTK_DIALOG(self),
414                           _("sfil_bd_filetype_details_dialog_cancel"),
415                           GTK_RESPONSE_CANCEL);
416     gtk_dialog_set_default_response(GTK_DIALOG(self),
417                           GTK_RESPONSE_OK);
418
419     priv->toggle_handler = g_signal_connect(priv->file_readonly, "toggled", 
420       G_CALLBACK(hildon_file_details_dialog_read_only_toggled), 
421       self);
422     g_signal_connect(priv->file_readonly, "focus",
423       G_CALLBACK(handle_focus), scroll);
424 }
425
426 static void
427 hildon_file_details_dialog_set_property( GObject *object, guint param_id,
428                                                            const GValue *value,
429                                          GParamSpec *pspec )
430 {
431   HildonFileDetailsDialogPrivate *priv;
432   GtkNotebook *notebook;
433   GtkLabel *label;
434
435   priv = HILDON_FILE_DETAILS_DIALOG(object)->priv;
436   notebook = priv->notebook;
437   label = GTK_LABEL(priv->tab_label);
438
439   switch( param_id ) 
440   {
441     case PROP_SHOW_TABS:
442     {
443       gtk_notebook_set_show_tabs(notebook, g_value_get_boolean(value));
444       gtk_notebook_set_show_border(notebook, g_value_get_boolean(value));
445       break;
446     }
447     case PROP_ADDITIONAL_TAB:
448     {
449       GtkWidget *widget = g_value_get_object(value);
450       GtkWidget *sw = gtk_scrolled_window_new(NULL, NULL);
451       
452       if (gtk_notebook_get_n_pages(notebook) == 2)
453         gtk_notebook_remove_page(notebook, 1);
454
455       if (widget == NULL)
456       {
457         widget = g_object_new(GTK_TYPE_LABEL, 
458             "label", _("sfil_ia_filetype_no_details"), "yalign", 0.0f, NULL);
459         gtk_widget_show(widget);
460       }
461
462       gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(sw),
463                                      GTK_POLICY_NEVER, GTK_POLICY_AUTOMATIC);
464       gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(sw), widget);
465       gtk_viewport_set_shadow_type(GTK_VIEWPORT(GTK_BIN(sw)->child),
466                                    GTK_SHADOW_NONE);
467       gtk_widget_show_all(sw);
468       gtk_notebook_append_page(notebook, sw, priv->tab_label);
469       gtk_notebook_set_current_page(notebook, 0);
470       break;
471     }
472     case PROP_ADDITIONAL_TAB_LABEL:
473       gtk_label_set_text(label, g_value_get_string(value));
474       break;
475     case PROP_MODEL:
476     {
477       HildonFileSystemModel *new_model = g_value_get_object(value);
478       if (new_model != priv->model)
479       {
480         if (G_IS_OBJECT(priv->model))
481           g_object_unref(priv->model);
482         priv->model = new_model;
483         if (new_model)
484           g_object_ref(new_model);
485       }  
486       break;
487     }
488     default:
489       G_OBJECT_WARN_INVALID_PROPERTY_ID(object, param_id, pspec);
490       break;
491   }
492 }
493
494 static void
495 hildon_file_details_dialog_get_property( GObject *object, guint param_id,
496                                                            GValue *value, GParamSpec *pspec )
497 {
498   HildonFileDetailsDialogPrivate *priv;
499
500   priv = HILDON_FILE_DETAILS_DIALOG(object)->priv;
501
502   switch (param_id) 
503   {
504     case PROP_SHOW_TABS:
505       g_value_set_boolean(value, gtk_notebook_get_show_tabs(priv->notebook));
506       break;
507     case PROP_ADDITIONAL_TAB:
508       g_assert(gtk_notebook_get_n_pages(priv->notebook) == 2);        
509       g_value_set_object(value, gtk_notebook_get_nth_page(priv->notebook, 1));
510       break;
511     case PROP_ADDITIONAL_TAB_LABEL:
512       g_value_set_string(value, gtk_label_get_text(GTK_LABEL(priv->tab_label)));
513       break;
514     case PROP_MODEL:
515       g_value_set_object(value, priv->model);
516       break;
517     default:
518       G_OBJECT_WARN_INVALID_PROPERTY_ID(object, param_id, pspec);
519       break;
520   }
521 }
522
523 static void hildon_file_details_dialog_finalize(GObject * object)
524 {
525   HildonFileDetailsDialogPrivate *priv;
526
527   g_return_if_fail(HILDON_IS_FILE_DETAILS_DIALOG(object));
528
529   priv = HILDON_FILE_DETAILS_DIALOG(object)->priv;
530   if (G_IS_OBJECT(priv->model))
531     g_object_unref(priv->model);
532   if (G_IS_OBJECT(priv->tab_label))
533     g_object_unref(priv->tab_label);
534   if (priv->active_file)
535     gtk_tree_row_reference_free(priv->active_file);
536     
537   G_OBJECT_CLASS(file_details_dialog_parent_class)->finalize(object);
538 }
539
540 /*******************/
541 /* Public functions */
542 /*******************/
543
544 /**
545  * hildon_file_details_dialog_new:
546  * @parent: the parent window.
547  * @filename: the filename.
548  *
549  * Creates a new #hildon_file_details_dialog AND new underlying 
550  * HildonFileSystemModel. Be carefull with #filename
551  * parameter: You don't get any notification if something fails.
552  * THIS FUNCTION IS DEPRICATED AND PROVIDED ONLY FOR
553  * BACKWARDS COMPABILITY.
554  *
555  * Returns: a new #HildonFileDetailsDialog.
556  */
557 #ifndef HILDON_DISABLE_DEPRECATED
558 GtkWidget *hildon_file_details_dialog_new(GtkWindow * parent,
559                                           const gchar * filename)
560 {
561   HildonFileDetailsDialog *dialog;
562   HildonFileSystemModel *model;
563   GtkTreeIter iter;
564
565   model = g_object_new(HILDON_TYPE_FILE_SYSTEM_MODEL, NULL);
566
567   dialog =
568         g_object_new(HILDON_TYPE_FILE_DETAILS_DIALOG, 
569           "has-separator", FALSE, "title", _("sfil_ti_file_details"), 
570           "model", model, NULL);
571
572   if (filename && filename[0] && 
573     hildon_file_system_model_load_local_path(dialog->priv->model, filename, &iter))
574       hildon_file_details_dialog_set_file_iter(dialog, &iter);
575
576   if (parent)
577     gtk_window_set_transient_for(GTK_WINDOW(dialog), parent);
578
579   return GTK_WIDGET(dialog);
580 }
581 #endif
582 /**
583  * hildon_file_details_dialog_new_with_model:
584  * @parent: the parent window.
585  * @model: a #HildonFileSystemModel object used to fetch data.
586  *
587  * This is the preferred way to create #HildonFileDetailsDialog.
588  * You can use a shared model structure to save loading times
589  * (because you probably already have one at your disposal).
590  *
591  * Returns: a new #HildonFileDetailsDialog.
592  */
593 GtkWidget *hildon_file_details_dialog_new_with_model(GtkWindow *parent,
594   HildonFileSystemModel *model)
595 {
596   GtkWidget *dialog;
597
598   dialog = g_object_new(HILDON_TYPE_FILE_DETAILS_DIALOG,
599     "has-separator", FALSE, "title", _("sfil_ti_file_details"), 
600     "model", model, NULL);
601
602   if (parent)
603     gtk_window_set_transient_for(GTK_WINDOW(dialog), parent);
604
605   return dialog;
606 }
607
608 /**
609  * hildon_file_details_dialog_set_file_iter:
610  * @self: a #HildonFileDetailsDialog.
611  * @iter: a #GtkTreeIter pointing to desired file.
612  *
613  * Sets the dialog to display information about a file defined by
614  * given iterator.
615  */
616 void hildon_file_details_dialog_set_file_iter(HildonFileDetailsDialog *self, GtkTreeIter *iter)
617 {
618   GtkTreeModel *model;
619   GtkTreePath *path;
620   GtkTreeIter temp_iter, parent_iter;
621   gchar *name, *mime, *uri;
622   const gchar *fmt;
623   gint64 time_stamp, size;
624   gchar buffer[256];
625   struct tm *time_struct;
626   time_t time_val;
627   gint type;
628   gboolean location_readonly = TRUE;
629
630   g_return_if_fail(HILDON_IS_FILE_DETAILS_DIALOG(self));
631
632   model = GTK_TREE_MODEL(self->priv->model);
633
634   /* Save iterator to priv struct as row reference */
635   gtk_tree_row_reference_free(self->priv->active_file);
636   path = gtk_tree_model_get_path(model, iter);
637   self->priv->active_file = gtk_tree_row_reference_new(model, path);
638   gtk_tree_path_free(path);
639
640   /* Setup the view */
641   gtk_tree_model_get(model, iter,
642     HILDON_FILE_SYSTEM_MODEL_COLUMN_DISPLAY_NAME, &name,
643     HILDON_FILE_SYSTEM_MODEL_COLUMN_MIME_TYPE, &mime,
644     HILDON_FILE_SYSTEM_MODEL_COLUMN_URI, &uri,
645     HILDON_FILE_SYSTEM_MODEL_COLUMN_FILE_SIZE, &size,
646     HILDON_FILE_SYSTEM_MODEL_COLUMN_FILE_TIME, &time_stamp,
647     -1);
648
649   g_object_set(self->priv->file_name, "label", name, NULL);
650   g_object_set(self->priv->file_type, "label", _(mime), NULL);
651
652   if (size < 1024)
653     g_snprintf(buffer, sizeof(buffer),
654                _("ckdg_va_properties_size_bytes"), (gint) size);
655   else
656     g_snprintf(buffer, sizeof(buffer),
657                _("ckdg_va_properties_size_kb"), (gint) size / 1024);
658
659   g_object_set(self->priv->file_size, "label", buffer, NULL);
660
661   /* Too bad. We cannot use GDate function, because it doesn't handle
662       time, just dates */
663   time_val = (time_t) time_stamp;
664   time_struct = localtime(&time_val);
665
666   /* There are no more logical names for these. We are allowed
667       to hardcode */
668   strftime(buffer, sizeof(buffer), "%X", time_struct);
669   g_object_set(self->priv->file_time, "label", buffer, NULL);
670   
671   /* If format is passed directly to strftime, gcc complains about
672       that some locales use only 2 digit year numbers. Using
673       a temporary disable this warning (from strftime man page) */
674   fmt = "%x";
675   strftime(buffer, sizeof(buffer), fmt, time_struct);
676   g_object_set(self->priv->file_date, "label", buffer, NULL);
677
678   /* Parent information */
679   if (gtk_tree_model_iter_parent(model, &parent_iter, iter))
680   {
681     gchar *location_name, *parent_path;
682     GdkPixbuf *location_icon;
683
684     gtk_tree_model_get(model, &parent_iter,
685       HILDON_FILE_SYSTEM_MODEL_COLUMN_DISPLAY_NAME, &location_name,
686       HILDON_FILE_SYSTEM_MODEL_COLUMN_URI, &parent_path,
687       HILDON_FILE_SYSTEM_MODEL_COLUMN_ICON, &location_icon, -1);      
688
689     if (parent_path)
690       location_readonly = !write_access(parent_path);
691
692     gtk_label_set_text(GTK_LABEL(self->priv->file_location), location_name);
693     gtk_image_set_from_pixbuf(GTK_IMAGE(self->priv->file_location_image), 
694       location_icon);
695
696     if (G_IS_OBJECT(location_icon))
697       g_object_unref(location_icon);
698     g_free(location_name);
699
700     /* Go upwards in model until we find a device node */
701     while (TRUE)
702     {
703       gtk_tree_model_get(model, &parent_iter,
704         HILDON_FILE_SYSTEM_MODEL_COLUMN_TYPE, &type, -1);
705
706       if (type >= HILDON_FILE_SYSTEM_MODEL_MMC)
707         break;
708
709       if (gtk_tree_model_iter_parent(model, &temp_iter, &parent_iter))
710         parent_iter = temp_iter;
711       else 
712         break;
713     }   
714
715     gtk_tree_model_get(model, &parent_iter,
716       HILDON_FILE_SYSTEM_MODEL_COLUMN_DISPLAY_NAME, &location_name, 
717       HILDON_FILE_SYSTEM_MODEL_COLUMN_ICON, &location_icon, 
718       -1);
719
720     gtk_label_set_text(GTK_LABEL(self->priv->file_device), location_name);
721     gtk_image_set_from_pixbuf(GTK_IMAGE(self->priv->file_device_image), 
722       location_icon);
723
724     if (G_IS_OBJECT(location_icon))
725       g_object_unref(location_icon);
726     g_free(location_name);
727     g_free(parent_path);
728   }
729   else 
730   {   /* We really should not come here */
731       gtk_label_set_text(GTK_LABEL(self->priv->file_location), "");
732       gtk_image_set_from_pixbuf(GTK_IMAGE(self->priv->file_location_image), NULL);
733       gtk_label_set_text(GTK_LABEL(self->priv->file_device), "");
734       gtk_image_set_from_pixbuf(GTK_IMAGE(self->priv->file_device_image), NULL);
735   }
736
737   /* We do not want initial setting to cause any action */
738   g_signal_handler_block(self->priv->file_readonly, self->priv->toggle_handler);
739
740   gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(self->priv->file_readonly), 
741     location_readonly || !write_access(uri));
742   gtk_widget_set_sensitive(self->priv->file_readonly, !location_readonly);
743
744   self->priv->checkbox_original_state = gtk_toggle_button_get_active(
745         GTK_TOGGLE_BUTTON(self->priv->file_readonly));
746
747   g_signal_handler_unblock(self->priv->file_readonly, self->priv->toggle_handler);
748
749   g_free(uri);
750   g_free(name);
751   g_free(mime);
752 }
753
754 /**
755  * hildon_file_details_dialog_get_file_iter:
756  * @self: a #HildonFileDetailsDialog.
757  * @iter: a #GtkTreeIter to be filled.
758  *
759  * Gets an iterator pointing to displayed file.
760  *
761  * Returns: %TRUE, if dialog is displaying some information.
762  */
763 gboolean 
764 hildon_file_details_dialog_get_file_iter(HildonFileDetailsDialog *self, GtkTreeIter *iter)
765 {
766   GtkTreePath *path;
767   gboolean result;
768
769   g_return_val_if_fail(HILDON_IS_FILE_DETAILS_DIALOG(self), FALSE);
770
771   if (!self->priv->active_file)
772     return FALSE;
773   path = gtk_tree_row_reference_get_path(self->priv->active_file);
774   if (!path)
775     return FALSE;
776   
777   result = gtk_tree_model_get_iter(GTK_TREE_MODEL(self->priv->model), iter, path);
778   gtk_tree_path_free(path);  
779
780   return result;
781 }