Move the placeholder list store into MilkListStore
[milk] / src / milk-main-window.c
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License as
4  * published by the Free Software Foundation; either version 2 of the
5  * License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
10  * General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public
13  * License along with this program; if not, write to the
14  * Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
15  * Boston, MA  02110-1301  USA
16  *
17  * Authors: Travis Reitter <treitter@gmail.com>
18  */
19
20 #include <config.h>
21
22 #include <glib.h>
23 #include <glib/gi18n.h>
24 #include <gtk/gtk.h>
25 #include <hildon/hildon.h>
26
27 #include "milk-main-window.h"
28 #include "milk-list-store.h"
29
30 G_DEFINE_TYPE (MilkMainWindow, milk_main_window, HILDON_TYPE_WINDOW)
31
32 #define MILK_MAIN_WINDOW_PRIVATE(o) \
33                 (G_TYPE_INSTANCE_GET_PRIVATE ((o), MILK_TYPE_MAIN_WINDOW, MilkMainWindowPrivate))
34
35 struct _MilkMainWindowPrivate
36 {
37         GtkWidget *main_vbox;
38
39         GtkWidget *new_task_entry;
40         GtkWidget *task_view;
41 };
42
43 enum {
44         TASK_VIEW_COLUMN_TITLE,
45         N_VIEW_COLUMNS
46 };
47
48 static void
49 milk_main_window_get_property (GObject    *object,
50                                guint       property_id,
51                                GValue     *value,
52                                GParamSpec *pspec)
53 {
54         switch (property_id)
55         {
56                 default:
57                         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id,
58                                         pspec);
59         }
60 }
61
62 static void
63 milk_main_window_set_property (GObject      *object,
64                                guint         property_id,
65                                const GValue *value,
66                                GParamSpec   *pspec)
67 {
68         switch (property_id)
69         {
70                 default:
71                         G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id,
72                                         pspec);
73         }
74 }
75
76 static void
77 milk_main_window_dispose (GObject *object)
78 {
79         G_OBJECT_CLASS (milk_main_window_parent_class)->dispose (object);
80 }
81
82 static void
83 complete_clicked_cb (GtkButton      *button,
84                      MilkMainWindow *window)
85 {
86         g_debug ("FIXME: implement 'complete' action");
87 }
88
89 static void
90 delete_clicked_cb (GtkButton      *button,
91                    MilkMainWindow *window)
92 {
93         g_debug ("FIXME: implement 'delete' action");
94 }
95
96 static void
97 priority_plus_clicked_cb (GtkButton      *button,
98                           MilkMainWindow *window)
99 {
100         g_debug ("FIXME: implement 'priority plus' action");
101 }
102
103 static void
104 priority_minus_clicked_cb (GtkButton      *button,
105                            MilkMainWindow *window)
106 {
107         g_debug ("FIXME: implement 'priority minus' action");
108 }
109
110 static void
111 edit_clicked_cb (GtkButton      *button,
112                  MilkMainWindow *window)
113 {
114         g_debug ("FIXME: implement 'edit' action");
115 }
116
117 static MenuItem menu_items_always_shown[] = {
118         {"New Task",   "menu-item-new-task",       new_task_clicked_cb},
119 };
120
121 static MenuItem menu_items_selection_required[] = {
122         {"Edit",       "menu-item-edit",           edit_clicked_cb},
123         {"Priority +", "menu-item-priority_plus",  priority_plus_clicked_cb},
124         {"Priority -", "menu-item-priority_minus", priority_minus_clicked_cb},
125         {"Complete",   "menu-item-complete",       complete_clicked_cb},
126         {"Delete",     "menu-item-delete",         delete_clicked_cb},
127 };
128
129 static void
130 task_view_selection_changed_cb (HildonTouchSelector *view,
131                                 gint                 column,
132                                 MilkMainWindow      *window)
133 {
134         MilkMainWindowPrivate *priv;
135         GList *rows;
136         gboolean show = FALSE;
137         gint i;
138
139         priv = MILK_MAIN_WINDOW_PRIVATE (window);
140
141         rows = hildon_touch_selector_get_selected_rows (view, column);
142         show = (g_list_length (rows) > 0);
143
144         for (i = 0; i < G_N_ELEMENTS (menu_items_selection_required); i++) {
145                 GtkWidget *w;
146
147                 w = g_object_get_data (
148                                 G_OBJECT (priv->app_menu),
149                                 menu_items_selection_required[i].id);
150
151                 if (show)
152                         gtk_widget_show (w);
153                 else
154                         gtk_widget_hide (w);
155         }
156 }
157
158 static GtkWidget*
159 create_menu (gpointer user_data)
160 {
161         HildonAppMenu *menu;
162         MenuItem *menu_array;
163         gint i, length;
164         GtkWidget *w;
165
166         menu = HILDON_APP_MENU (hildon_app_menu_new ());
167
168         menu_array = menu_items_always_shown;
169         length = G_N_ELEMENTS (menu_items_always_shown);
170         for (i = 0; i < length; i++) {
171                 w = hildon_button_new_with_text (
172                                 HILDON_SIZE_FINGER_HEIGHT | HILDON_SIZE_AUTO_WIDTH,
173                                 HILDON_BUTTON_ARRANGEMENT_VERTICAL,
174                                 _(menu_array[i].display_name), "");
175                 g_signal_connect (w, "clicked",
176                                 G_CALLBACK (menu_array[i].callback), user_data);
177                 g_object_set_data (G_OBJECT (menu), menu_array[i].id, w);
178                 hildon_app_menu_append (menu, GTK_BUTTON (w));
179                 gtk_widget_show (w);
180         }
181
182         menu_array = menu_items_selection_required;
183         length = G_N_ELEMENTS (menu_items_selection_required);
184         for (i = 0; i < length; i++) {
185                 w = hildon_button_new_with_text (
186                                 HILDON_SIZE_FINGER_HEIGHT | HILDON_SIZE_AUTO_WIDTH,
187                                 HILDON_BUTTON_ARRANGEMENT_VERTICAL,
188                                 menu_array[i].display_name, "");
189                 g_signal_connect (w, "clicked",
190                                 G_CALLBACK (menu_array[i].callback), user_data);
191                 g_object_set_data (G_OBJECT (menu), menu_array[i].id, w);
192                 hildon_app_menu_append (menu, GTK_BUTTON (w));
193                 gtk_widget_hide (w);
194         }
195
196         gtk_widget_show (GTK_WIDGET (menu));
197
198         return GTK_WIDGET (menu);
199 }
200
201 static MenuItem menu_items_always_shown[] = {
202         {"New Task",   "menu-item-new-task",       new_task_clicked_cb},
203 };
204
205 static MenuItem menu_items_selection_required[] = {
206         {"Edit",       "menu-item-edit",           edit_clicked_cb},
207         {"Priority +", "menu-item-priority_plus",  priority_plus_clicked_cb},
208         {"Priority -", "menu-item-priority_minus", priority_minus_clicked_cb},
209         {"Complete",   "menu-item-complete",       complete_clicked_cb},
210         {"Delete",     "menu-item-delete",         delete_clicked_cb},
211 };
212
213 static void
214 task_view_selection_changed_cb (HildonTouchSelector *view,
215                                 gint                 column,
216                                 MilkMainWindow      *window)
217 {
218         MilkMainWindowPrivate *priv;
219         GList *rows;
220         gboolean show = FALSE;
221         gint i;
222
223         priv = MILK_MAIN_WINDOW_PRIVATE (window);
224
225         rows = hildon_touch_selector_get_selected_rows (view, column);
226         show = (g_list_length (rows) > 0);
227
228         for (i = 0; i < G_N_ELEMENTS (menu_items_selection_required); i++) {
229                 GtkWidget *w;
230
231                 w = g_object_get_data (
232                                 G_OBJECT (priv->app_menu),
233                                 menu_items_selection_required[i].id);
234
235                 if (show)
236                         gtk_widget_show (w);
237                 else
238                         gtk_widget_hide (w);
239         }
240 }
241
242 static GtkWidget*
243 create_menu (gpointer user_data)
244 {
245         HildonAppMenu *menu;
246         MenuItem *menu_array;
247         gint i, length;
248         GtkWidget *w;
249
250         menu = HILDON_APP_MENU (hildon_app_menu_new ());
251
252         menu_array = menu_items_always_shown;
253         length = G_N_ELEMENTS (menu_items_always_shown);
254         for (i = 0; i < length; i++) {
255                 w = hildon_button_new_with_text (
256                                 HILDON_SIZE_FINGER_HEIGHT | HILDON_SIZE_AUTO_WIDTH,
257                                 HILDON_BUTTON_ARRANGEMENT_VERTICAL,
258                                 _(menu_array[i].display_name), "");
259                 g_signal_connect (w, "clicked",
260                                 G_CALLBACK (menu_array[i].callback), user_data);
261                 g_object_set_data (G_OBJECT (menu), menu_array[i].id, w);
262                 hildon_app_menu_append (menu, GTK_BUTTON (w));
263                 gtk_widget_show (w);
264         }
265
266         menu_array = menu_items_selection_required;
267         length = G_N_ELEMENTS (menu_items_selection_required);
268         for (i = 0; i < length; i++) {
269                 w = hildon_button_new_with_text (
270                                 HILDON_SIZE_FINGER_HEIGHT | HILDON_SIZE_AUTO_WIDTH,
271                                 HILDON_BUTTON_ARRANGEMENT_VERTICAL,
272                                 menu_array[i].display_name, "");
273                 g_signal_connect (w, "clicked",
274                                 G_CALLBACK (menu_array[i].callback), user_data);
275                 g_object_set_data (G_OBJECT (menu), menu_array[i].id, w);
276                 hildon_app_menu_append (menu, GTK_BUTTON (w));
277                 gtk_widget_hide (w);
278         }
279
280         gtk_widget_show (GTK_WIDGET (menu));
281
282         return GTK_WIDGET (menu);
283 }
284
285 static void
286 contact_column_render_func (GtkCellLayout   *cell_layout,
287                             GtkCellRenderer *renderer,
288                             GtkTreeModel    *model,
289                             GtkTreeIter     *iter,
290                             gpointer         user_data)
291 {
292         MilkTask *task;
293         char *title;
294
295         gtk_tree_model_get (
296                         model, iter, MILK_TASK_MODEL_COLUMN_TASK, &task, -1);
297
298         g_object_get (task, "title", &title, NULL);
299         g_object_set (renderer, "text", title, NULL);
300
301         g_free (title);
302         g_object_unref (task);
303 }
304
305 static HildonAppMenu*
306 create_menu (gpointer user_data)
307 {
308         HildonAppMenu *menu;
309         GtkWidget *w;
310
311         menu = HILDON_APP_MENU (hildon_app_menu_new ());
312
313         w = hildon_button_new_with_text (
314                         HILDON_SIZE_FINGER_HEIGHT | HILDON_SIZE_AUTO_WIDTH,
315                         HILDON_BUTTON_ARRANGEMENT_VERTICAL,
316                         _("Complete"), "");
317         g_signal_connect (w, "clicked", G_CALLBACK (complete_clicked_cb),
318                         user_data);
319         hildon_app_menu_append (menu, GTK_BUTTON (w));
320
321         w = hildon_button_new_with_text (
322                         HILDON_SIZE_FINGER_HEIGHT | HILDON_SIZE_AUTO_WIDTH,
323                         HILDON_BUTTON_ARRANGEMENT_VERTICAL,
324                         _("Edit"), "");
325         g_signal_connect (w, "clicked", G_CALLBACK (edit_clicked_cb),
326                         user_data);
327         hildon_app_menu_append (menu, GTK_BUTTON (w));
328
329         w = hildon_button_new_with_text (
330                         HILDON_SIZE_FINGER_HEIGHT | HILDON_SIZE_AUTO_WIDTH,
331                         HILDON_BUTTON_ARRANGEMENT_VERTICAL,
332                         _("Priority +"), "");
333         g_signal_connect (w, "clicked", G_CALLBACK (priority_plus_clicked_cb),
334                         user_data);
335         hildon_app_menu_append (menu, GTK_BUTTON (w));
336
337         w = hildon_button_new_with_text (
338                         HILDON_SIZE_FINGER_HEIGHT | HILDON_SIZE_AUTO_WIDTH,
339                         HILDON_BUTTON_ARRANGEMENT_VERTICAL,
340                         _("Priority -"), "");
341         g_signal_connect (w, "clicked", G_CALLBACK (priority_minus_clicked_cb),
342                         user_data);
343         hildon_app_menu_append (menu, GTK_BUTTON (w));
344
345         w = hildon_button_new_with_text (
346                         HILDON_SIZE_FINGER_HEIGHT | HILDON_SIZE_AUTO_WIDTH,
347                         HILDON_BUTTON_ARRANGEMENT_VERTICAL,
348                         _("Delete"), "");
349         g_signal_connect (w, "clicked", G_CALLBACK (delete_clicked_cb),
350                         user_data);
351         hildon_app_menu_append (menu, GTK_BUTTON (w));
352
353         gtk_widget_show_all (GTK_WIDGET (menu));
354
355         return menu;
356 }
357
358 static void
359 milk_main_window_constructed (GObject* object)
360 {
361         MilkMainWindow *self = MILK_MAIN_WINDOW (object);
362         MilkMainWindowPrivate *priv = MILK_MAIN_WINDOW_PRIVATE (object);
363         GtkWidget *w;
364         GtkTreeModel *model;
365         GtkCellRenderer *renderer;
366         HildonTouchSelectorColumn *col;
367
368         w = gtk_vbox_new (FALSE, HILDON_MARGIN_DEFAULT);
369         gtk_container_add (GTK_CONTAINER (self), w);
370         priv->main_vbox = w;
371
372         /*
373          * New Task entry
374          */
375         w = hildon_entry_new (HILDON_SIZE_FINGER_HEIGHT);
376         gtk_box_pack_start (GTK_BOX (priv->main_vbox), w, FALSE, FALSE, 0);
377
378         /* FIXME: change this to hildon_gtk_entry_set_placeholder_text() is
379          * fixed, since this is deprecated */
380         hildon_entry_set_placeholder (HILDON_ENTRY (w),
381                         _("Enter a new task..."));
382         priv->new_task_entry = w;
383
384         /*
385          * Task List
386          */
387         model = GTK_TREE_MODEL (milk_list_store_new ());
388         w = hildon_touch_selector_new ();
389
390         renderer = gtk_cell_renderer_text_new ();
391         g_object_set (renderer,
392                         "ellipsize", PANGO_ELLIPSIZE_END,
393                         NULL);
394         col = hildon_touch_selector_append_column (HILDON_TOUCH_SELECTOR (w),
395                         model, renderer,
396                         "text", MILK_LIST_STORE_COLUMN_TITLE,
397                         NULL);
398         g_object_unref (model);
399
400         hildon_touch_selector_column_set_text_column (
401                         col, MILK_LIST_STORE_COLUMN_TITLE);
402         hildon_touch_selector_set_column_selection_mode (
403                         HILDON_TOUCH_SELECTOR (w),
404                         HILDON_TOUCH_SELECTOR_SELECTION_MODE_MULTIPLE);
405         hildon_touch_selector_set_hildon_ui_mode (
406                         HILDON_TOUCH_SELECTOR (w), HILDON_UI_MODE_EDIT);
407         hildon_touch_selector_unselect_all (
408                         HILDON_TOUCH_SELECTOR (w), TASK_VIEW_COLUMN_TITLE);
409
410         gtk_box_pack_start (GTK_BOX (priv->main_vbox), w, TRUE, TRUE, 0);
411         g_object_set (w, "can-focus", TRUE, NULL);
412         gtk_widget_grab_focus (w);
413         priv->task_view = w;
414
415         hildon_window_set_app_menu (HILDON_WINDOW (self), create_menu (self));
416 }
417
418 static void
419 milk_main_window_class_init (MilkMainWindowClass *klass)
420 {
421         GObjectClass *object_class = G_OBJECT_CLASS (klass);
422
423         g_type_class_add_private (klass, sizeof (MilkMainWindowPrivate));
424
425         object_class->get_property = milk_main_window_get_property;
426         object_class->set_property = milk_main_window_set_property;
427         object_class->constructed = milk_main_window_constructed;
428         object_class->dispose = milk_main_window_dispose;
429 }
430
431 static void
432 milk_main_window_init (MilkMainWindow *self)
433 {
434         self->priv = MILK_MAIN_WINDOW_PRIVATE (self);
435 }
436
437 GtkWidget*
438 milk_main_window_new ()
439 {
440         return g_object_new (MILK_TYPE_MAIN_WINDOW,
441                              NULL);
442 }