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