* hildon-widgets/hildon-add-home-dialog.c: (hildon_add_home_dialog_new): Move code...
[hildon] / hildon-widgets / hildon-add-home-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 #include <glib.h>
26 #include <gtk/gtk.h>
27 #include <gdk/gdkkeysyms.h>
28 #include <errno.h>
29 #include <string.h>
30 #include <sys/types.h>
31 #include <sys/stat.h>
32 #include <unistd.h>
33 #include <stdio.h>
34
35 #ifdef HAVE_CONFIG_H
36 #include <config.h>
37 #endif
38
39 #include <libintl.h>
40
41 #include "hildon-add-home-dialog.h"
42 #include <hildon-widgets/hildon-caption.h>
43
44 #define _(String) dgettext(PACKAGE, String)
45 #define MAX_ERR_MSG 256
46 #define HILDON_ADD_HOME_DIALOG_WIDTH 370
47 #define HILDON_ADD_HOME_DIALOG_HEIGHT 100
48 #define HILDON_MAX_TITLE_LENGTH 256
49 #define HILDON_HOME_MAX_SHORTCUT_LEN 255
50
51 #define HILDON_ADD_HOME_DIALOG_GET_PRIVATE(obj) \
52   (G_TYPE_INSTANCE_GET_PRIVATE ((obj), \
53                                 HILDON_TYPE_ADD_HOME_DIALOG, \
54                                 HildonAddHomeDialogPrivate));
55
56 typedef struct _HildonAddHomeDialogPrivate HildonAddHomeDialogPrivate;
57
58 static GtkDialogClass *parent_class;
59
60 static const gchar *hildon_add_home_dialog_get_old_name(HildonAddHomeDialog * dialog);
61 static void hildon_add_home_dialog_set_old_name(HildonAddHomeDialog * dialog, const gchar* name);
62 static void hildon_add_home_dialog_set_new_name(HildonAddHomeDialog * dialog, const gchar* name);
63 static void hildon_add_home_dialog_create_widgets(HildonAddHomeDialog * dialog, gboolean new_isrename);
64
65 static void
66 hildon_add_home_dialog_get_property(GObject * object,
67                                     guint prop_id,
68                                     GValue * value,
69                                     GParamSpec * pspec);
70 static void
71 hildon_add_home_dialog_set_property(GObject * object,
72                                     guint prop_id,
73                                     const GValue * value,
74                                     GParamSpec * pspec);
75 static void
76 hildon_add_home_dialog_class_init(HildonAddHomeDialogClass * class);
77 static void hildon_add_home_dialog_init(HildonAddHomeDialog * dialog);
78
79 /* private struct */
80
81 struct _HildonAddHomeDialogPrivate {
82     GtkWidget *desc_label;
83     GtkWidget *name_entry; /* Used when isrename */
84     GtkWidget *name_label; /* Used when !isrename */
85     GtkWidget *caption_name_entry; /* Used when isrename */
86     GtkWidget *new_name_entry;
87     GtkWidget *caption_new_name_entry;
88     GtkSizeGroup *size_group;
89     GtkWidget *okButton;
90     GtkWidget *cancelButton;
91     gboolean isrename;
92 };
93
94 enum
95 {
96   PROP_0,
97
98   PROP_NAME,
99   PROP_NEW_NAME,
100 };
101
102 /* Private functions */
103
104 static void
105 hildon_add_home_dialog_class_init(HildonAddHomeDialogClass * klass)
106 {
107     GObjectClass * gobject_class = G_OBJECT_CLASS(klass);
108     parent_class = g_type_class_peek_parent(klass);
109
110     gobject_class->set_property = hildon_add_home_dialog_set_property;
111     gobject_class->get_property = hildon_add_home_dialog_get_property;
112
113     /**
114      * HildonAddHomeDialog:name
115      * 
116      * The name
117      */
118     g_object_class_install_property(gobject_class,
119                                     PROP_NAME,
120                                     g_param_spec_string ("name",
121                                                         ("Name"),
122                                                         ("The name."),
123                                                         NULL,
124                                                         G_PARAM_READWRITE));
125
126     /**
127      * HildonAddHomeDialog:new_name
128      * 
129      * The new name
130      */
131     g_object_class_install_property(gobject_class,
132                                     PROP_NEW_NAME,
133                                     g_param_spec_string ("new_name",
134                                                         ("New Name"),
135                                                         ("The new name."),
136                                                         NULL,
137                                                         G_PARAM_READWRITE));
138
139     g_type_class_add_private(klass, sizeof(HildonAddHomeDialogPrivate));
140 }
141
142 static void hildon_add_home_dialog_init(HildonAddHomeDialog * dialog)
143 {
144     HildonAddHomeDialogPrivate *priv;
145
146     gtk_dialog_set_has_separator(GTK_DIALOG(dialog), FALSE);
147
148     priv = HILDON_ADD_HOME_DIALOG_GET_PRIVATE(dialog);
149     priv->name_entry = NULL;
150     priv->name_label = NULL;
151     priv->caption_name_entry = NULL;
152     priv->new_name_entry = NULL;
153     priv->isrename = FALSE;
154
155     priv->okButton = gtk_dialog_add_button(GTK_DIALOG(dialog),
156                                            "addtoHome_button_ok",
157                                            GTK_RESPONSE_OK);
158     priv->cancelButton = gtk_dialog_add_button(GTK_DIALOG(dialog),
159                                                "addtoHome_button_cancel",
160                                                GTK_RESPONSE_CANCEL);
161
162     gtk_window_resize(GTK_WINDOW(dialog),
163                       HILDON_ADD_HOME_DIALOG_WIDTH,
164                       HILDON_ADD_HOME_DIALOG_HEIGHT);
165
166     gtk_widget_show_all(GTK_DIALOG(dialog)->vbox);
167     gtk_widget_show_all(GTK_DIALOG(dialog)->action_area);
168
169     priv->size_group = gtk_size_group_new(GTK_SIZE_GROUP_HORIZONTAL);
170
171
172     /* add description text (only shown when isrename==true */
173     priv->desc_label = gtk_label_new(_("ckdg_ib_link_exists"));
174     gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox),
175                            priv->desc_label, FALSE, FALSE, 0);
176
177     /* We don't use the hildon_caption_new() C convenience function, because it demands a non-NULL child widget (via gtk_container_add()). */
178     priv->caption_name_entry = GTK_WIDGET( g_object_new( HILDON_TYPE_CAPTION, "size_group", priv->size_group, "label", _("addtoHome_editor_caption"), "status", HILDON_CAPTION_OPTIONAL, NULL) );
179     gtk_widget_show(priv->caption_name_entry);
180     gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), priv->caption_name_entry,
181                        FALSE, FALSE, 0);
182
183
184     gtk_widget_show_all(GTK_DIALOG(dialog)->action_area);
185 }
186
187 /* Public functions */
188
189 GType hildon_add_home_dialog_get_type(void)
190 {
191     static GType dialog_type = 0;
192
193     if (!dialog_type) {
194         static const GTypeInfo dialog_info = {
195             sizeof(HildonAddHomeDialogClass),
196             NULL,       /* base_init */
197             NULL,       /* base_finalize */
198             (GClassInitFunc) hildon_add_home_dialog_class_init,
199             NULL,       /* class_finalize */
200             NULL,       /* class_data */
201             sizeof(HildonAddHomeDialog),
202             0,  /* n_preallocs */
203             (GInstanceInitFunc) hildon_add_home_dialog_init
204         };
205
206         dialog_type = g_type_register_static(GTK_TYPE_DIALOG,
207                                              "HildonAddHomeDialog",
208                                              &dialog_info, 0);
209     }
210     return dialog_type;
211 }
212
213 static void
214 hildon_add_home_dialog_get_property (GObject    *object,
215                               guint       prop_id,
216                               GValue     *value,
217                               GParamSpec *pspec)
218 {
219     HildonAddHomeDialog * dialog = HILDON_ADD_HOME_DIALOG(object);
220     HildonAddHomeDialogPrivate *priv = HILDON_ADD_HOME_DIALOG_GET_PRIVATE(dialog);
221   
222     switch(prop_id)
223     {
224         case PROP_NAME:
225         {
226             const gchar* name = NULL;
227             if(priv->isrename && priv->name_label)
228                 name = gtk_entry_get_text(GTK_ENTRY(priv->name_label));
229             else if(!(priv->isrename) && priv->name_entry)
230                 name = gtk_entry_get_text(GTK_ENTRY(priv->name_entry));
231
232             g_value_set_string (value, name);
233             break;
234         }
235         case PROP_NEW_NAME:
236         {
237             const gchar* new_name = NULL;
238             if(priv->isrename && priv->new_name_entry)
239                 new_name = gtk_entry_get_text(GTK_ENTRY(priv->new_name_entry));
240
241             g_value_set_string (value, new_name);
242             break;
243         }
244         default:
245             G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
246             break;
247     }
248 }
249
250 static void
251 hildon_add_home_dialog_set_window_title (HildonAddHomeDialog * dialog)
252 {
253     HildonAddHomeDialogPrivate *priv;
254
255     g_return_if_fail(HILDON_IS_ADD_HOME_DIALOG(dialog));
256     priv = HILDON_ADD_HOME_DIALOG_GET_PRIVATE(dialog);
257
258     /* Set up the window title */
259     if (priv->isrename)
260         gtk_window_set_title(GTK_WINDOW(dialog), _("ckdg_ti_rename_link"));
261     else
262         gtk_window_set_title(GTK_WINDOW(dialog), _("addtoHome_dialog_title"));
263 }
264
265
266 static void
267 hildon_add_home_dialog_set_property (GObject      *object,
268                               guint         prop_id,
269                               const GValue *value,
270                               GParamSpec   *pspec)
271 {
272     HildonAddHomeDialog * dialog = HILDON_ADD_HOME_DIALOG(object);
273     HildonAddHomeDialogPrivate *priv;
274
275     g_return_if_fail(HILDON_IS_ADD_HOME_DIALOG(dialog));
276     priv = HILDON_ADD_HOME_DIALOG_GET_PRIVATE(dialog);
277
278     switch (prop_id)
279     {
280     case PROP_NAME:
281         hildon_add_home_dialog_set_old_name (dialog, g_value_get_string (value));
282         break;
283     case PROP_NEW_NAME:
284         hildon_add_home_dialog_set_new_name (dialog, g_value_get_string (value));
285         break;
286     default:
287         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
288         break;
289     }
290 }
291
292 /**
293  * hildon_add_home_dialog_new:
294  * @parent: parent window for the dialog
295  * @name: name to show in the entry (or label, if @new_name is not NULL)
296  * @new_name: name to show in the new name entry. If this is not NULL
297  * the widget acts as a RenameShortcutDialog.
298  *
299  * Creates a new Add to Home dialog or Rename Shortcut dialog.
300  *
301  * Returns: the new dialog.
302  */
303 GtkWidget *hildon_add_home_dialog_new(GtkWindow * parent,
304                                       const gchar * name,
305                                       const gchar * new_name)
306 {
307      HildonAddHomeDialog *dialog =
308        HILDON_ADD_HOME_DIALOG(g_object_new
309                               (HILDON_TYPE_ADD_HOME_DIALOG, "name", name, "new_name", new_name, NULL));
310
311     if (parent)
312         gtk_window_set_transient_for(GTK_WINDOW(dialog), parent);
313
314     return GTK_WIDGET(dialog);
315 }
316
317 /**
318  * hildon_add_home_dialog_get_name:
319  * @dialog: the dialog
320  *
321  * Returns: the string the user has entered in the entry
322  */
323 const gchar *hildon_add_home_dialog_get_name(HildonAddHomeDialog * dialog)
324 {
325     HildonAddHomeDialogPrivate *priv;
326
327     g_return_val_if_fail(HILDON_IS_ADD_HOME_DIALOG(dialog), NULL);
328     priv = HILDON_ADD_HOME_DIALOG_GET_PRIVATE(dialog);
329
330     if (priv->isrename && priv->new_name_entry)
331         return gtk_entry_get_text(GTK_ENTRY(priv->new_name_entry));
332     else if(priv->name_entry)
333         return gtk_entry_get_text(GTK_ENTRY(priv->name_entry));
334     else
335         return NULL;
336 }
337
338 static const gchar *hildon_add_home_dialog_get_old_name(HildonAddHomeDialog * dialog)
339 {
340     HildonAddHomeDialogPrivate *priv;
341
342     g_return_val_if_fail(HILDON_IS_ADD_HOME_DIALOG(dialog), NULL);
343     priv = HILDON_ADD_HOME_DIALOG_GET_PRIVATE(dialog);
344
345     if (priv->isrename && priv->name_label)
346         return gtk_label_get_text(GTK_LABEL(priv->name_label));
347     else if(!priv->isrename && priv->name_entry)
348         return gtk_entry_get_text(GTK_ENTRY(priv->name_entry));
349     else
350         return NULL;
351 }
352
353 static void hildon_add_home_dialog_set_old_name(HildonAddHomeDialog * dialog, const gchar* name)
354 {
355     HildonAddHomeDialogPrivate *priv;
356
357     g_return_if_fail(HILDON_IS_ADD_HOME_DIALOG(dialog));
358     priv = HILDON_ADD_HOME_DIALOG_GET_PRIVATE(dialog);
359
360     hildon_add_home_dialog_create_widgets(dialog, priv->isrename);
361
362     /* Set text in the widgets: */
363     if (priv->isrename)
364         gtk_label_set_text(GTK_LABEL(priv->name_label), name);
365     else
366         gtk_entry_set_text(GTK_ENTRY(priv->name_entry), name);
367 }
368
369 static void hildon_add_home_dialog_set_new_name(HildonAddHomeDialog * dialog, const gchar* new_name)
370 {
371     HildonAddHomeDialogPrivate *priv;
372     gchar* name = NULL;
373     gboolean new_isrename = FALSE; 
374
375     g_return_if_fail(HILDON_IS_ADD_HOME_DIALOG(dialog));
376     priv = HILDON_ADD_HOME_DIALOG_GET_PRIVATE(dialog);
377
378     /* We get the old name, in case we need to set it again in a new widget. */
379     name = g_strdup( hildon_add_home_dialog_get_old_name(dialog) );
380     new_isrename = (new_name != NULL);
381
382     hildon_add_home_dialog_create_widgets(dialog, new_isrename);
383
384
385     /* Set text in the widgets: */
386     if(priv->isrename)
387     {
388         gtk_entry_set_text(GTK_ENTRY(priv->new_name_entry), new_name);
389         gtk_label_set_text(GTK_LABEL(priv->name_label), (name) ? name : "");
390     }
391     else
392     {
393         gtk_entry_set_text(GTK_ENTRY(priv->name_entry), (name) ? name : "");
394     }
395
396     if(name)
397       g_free(name);
398 }
399
400 static void hildon_add_home_dialog_create_widgets(HildonAddHomeDialog * dialog, gboolean new_isrename)
401 {
402     HildonAddHomeDialogPrivate *priv;
403
404     g_return_if_fail(HILDON_IS_ADD_HOME_DIALOG(dialog));
405     priv = HILDON_ADD_HOME_DIALOG_GET_PRIVATE(dialog);
406
407     /* Create and destroy widgets, depending on the mode.
408      * Note that we are making a small speed sacrifice (recreating the widgets) 
409      * in exchange for memory (creating all widgets and just hiding the ones we don't use.)
410      */
411
412     if(priv->isrename && !new_isrename)
413     {
414         /* Remove widgets that were used for isrename mode,
415            because we don't need them anymore. */
416         if(priv->new_name_entry)
417         {
418             gtk_widget_destroy(priv->new_name_entry);
419             priv->new_name_entry = NULL;
420         }
421
422         if(priv->caption_new_name_entry)
423         {
424             gtk_widget_destroy(priv->caption_new_name_entry);
425             priv->caption_new_name_entry = NULL;
426         }
427
428         if(priv->name_label) /* A label */
429         {
430            gtk_widget_destroy(priv->name_label);
431            priv->name_label = NULL;
432         }
433
434         if(priv->name_entry) /* A box with label inside */
435         {
436            gtk_widget_destroy(priv->name_entry);
437            priv->name_entry = NULL;
438         }
439     }
440     else if(!priv->isrename && new_isrename)
441     {
442         /* Remove widgets that were used only for !isrename mode,
443            because we don't need them anymore. */
444         if(priv->name_entry) /* An entry. */
445         {
446            gtk_widget_destroy(priv->name_entry);
447            priv->name_entry = NULL;
448         }
449     }
450
451     priv->isrename = new_isrename;
452
453     if(priv->isrename)
454     {
455         /* Create widgets needed for isrename mode: */
456
457         /* Create Entry (in a Caption) for the new name, and pack it into the dialog: */
458         if(!priv->new_name_entry)
459         {
460             priv->new_name_entry = gtk_entry_new();
461             gtk_widget_show(priv->new_name_entry);
462         }
463
464         if(!priv->caption_new_name_entry)
465         {
466             priv->caption_new_name_entry = hildon_caption_new(priv->size_group, _("ckdg_fi_rename_name"),
467                                            priv->new_name_entry, NULL,
468                                            HILDON_CAPTION_OPTIONAL);
469             gtk_widget_show(priv->caption_new_name_entry);
470             gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), GTK_WIDGET(priv->caption_new_name_entry),
471                                FALSE, FALSE, 0);
472         }
473
474         /* add description text */
475         if(priv->desc_label)
476           gtk_widget_show(priv->desc_label);
477
478         /* Create Label (in a Box) for the existing name: */
479         if(!priv->name_entry)
480         {
481             priv->name_label = gtk_label_new(NULL);
482             gtk_widget_show(priv->name_label);
483
484             priv->name_entry = gtk_hbox_new(FALSE, 0);
485             gtk_widget_show(priv->name_entry);
486             gtk_box_pack_start(GTK_BOX(priv->name_entry), priv->name_label, FALSE, FALSE,
487                            0);
488             gtk_container_add(GTK_CONTAINER(priv->caption_name_entry), GTK_WIDGET(priv->name_entry));
489         }
490     }
491     else
492     {
493         if(priv->desc_label)
494           gtk_widget_hide(priv->desc_label);
495
496         /* Create widgets needed for !isrename mode: */
497         if(!priv->name_entry)
498         {
499             priv->name_entry = gtk_entry_new();
500             gtk_widget_show(priv->name_entry);
501             gtk_container_add(GTK_CONTAINER(priv->caption_name_entry), GTK_WIDGET(priv->name_entry));
502         }
503     }
504
505     hildon_add_home_dialog_set_window_title(dialog);
506
507     priv->isrename = new_isrename;
508 }
509
510 void hildon_add_home_dialog_set_name(HildonAddHomeDialog * dialog, const gchar* name)
511 {
512     HildonAddHomeDialogPrivate *priv;
513
514     g_return_if_fail(HILDON_IS_ADD_HOME_DIALOG(dialog));
515     priv = HILDON_ADD_HOME_DIALOG_GET_PRIVATE(dialog);
516
517     hildon_add_home_dialog_create_widgets(dialog, priv->isrename);
518
519     /* Set text in the widgets: */
520     if (priv->isrename)
521         gtk_entry_set_text(GTK_ENTRY(priv->new_name_entry), name);
522     else
523         gtk_label_set_text(GTK_LABEL(priv->name_entry), name);
524 }
525