Make procmsg_msginfo_free() zero out pointers to freed memory.
[claws.git] / src / plugins / vcalendar / common-views.c
1 /*
2  * Claws Mail -- a GTK+ based, lightweight, and fast e-mail client
3  *
4  * Copyright (c) 2007-2008 Juha Kautto (juha at xfce.org)
5  * Copyright (c) 2008 Colin Leroy (colin@colino.net)
6  *
7  * This program is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation; either version 3 of the License, or
10  * (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20  */
21
22 #ifdef HAVE_CONFIG_H
23 #  include "config.h"
24 #include "claws-features.h"
25 #endif
26
27 #include <stddef.h>
28 #include <glib.h>
29 #include <glib/gi18n.h>
30 #include "defs.h"
31
32 #include <string.h>
33 #include <time.h>
34
35 #include <glib.h>
36 #include <glib/gprintf.h>
37 #include <gdk/gdkkeysyms.h>
38 #include <gdk/gdk.h>
39 #include <gtk/gtk.h>
40
41 #include "summaryview.h"
42 #include "vcalendar.h"
43 #include "vcal_folder.h"
44 #include "vcal_prefs.h"
45 #include "vcal_manager.h"
46 #include "vcal_meeting_gtk.h"
47 #include "menu.h"
48
49
50 static void view_new_meeting_cb                 (GtkAction      *action,
51                                                  gpointer        user_data);
52 static void view_edit_meeting_cb                (GtkAction      *action,
53                                                  gpointer        user_data);
54 static void view_cancel_meeting_cb              (GtkAction      *action,
55                                                  gpointer        user_data);
56 static void view_go_today_cb                    (GtkAction      *action,
57                                                  gpointer        user_data);
58
59 static GtkActionEntry view_event_popup_entries[] = 
60 {
61         {"VcalViewEvent",               NULL, "VcalViewEvent" },
62         {"VcalViewEvent/EditMeeting",   NULL, N_("_Edit this meeting..."), NULL, NULL, G_CALLBACK(view_edit_meeting_cb) },
63         {"VcalViewEvent/CancelMeeting", NULL, N_("_Cancel this meeting..."), NULL, NULL, G_CALLBACK(view_cancel_meeting_cb) },
64         {"VcalViewEvent/---",           NULL, "---", NULL, NULL, NULL },
65         {"VcalViewEvent/CreateMeeting", NULL, N_("_Create new meeting..."), NULL, NULL, G_CALLBACK(view_new_meeting_cb) },
66
67         {"VcalViewEvent/GoToday",               NULL, N_("_Go to today"), NULL, NULL, G_CALLBACK(view_go_today_cb) },
68 };
69
70 GtkWidget *build_line(gint start_x, gint start_y
71         , gint width, gint height, GtkWidget *hour_line, GdkColor *line_color)
72 {
73     GdkColormap *pic1_cmap;
74     GdkVisual *pic1_vis;
75     GdkPixmap *pic1;
76     GdkGC *pic1_gc;
77     GtkWidget *new_hour_line;
78     gint depth = 16;
79     gboolean first = FALSE;
80
81     /*
82      * GdkPixbuf *scaled;
83     scaled = gdk_pixbuf_scale_simple (pix, w, h, GDK_INTERP_BILINEAR);
84     */
85      
86     pic1_cmap = gdk_colormap_get_system();
87     pic1_vis = gdk_colormap_get_visual(pic1_cmap);
88     depth = pic1_vis->depth;
89     if (hour_line == NULL) {
90         pic1 = gdk_pixmap_new(NULL, width, height, depth);
91         gdk_drawable_set_colormap(pic1, pic1_cmap);
92         first = TRUE;
93     }
94     else
95         gtk_image_get_pixmap(GTK_IMAGE(hour_line), &pic1, NULL);
96     pic1_gc = gdk_gc_new(pic1);
97     if (first) {
98         gdk_gc_set_foreground(pic1_gc, line_color);
99         gdk_draw_rectangle(pic1, pic1_gc, TRUE, start_x, start_y, width, height);
100     }
101     else {
102         gdk_draw_rectangle(pic1, pic1_gc, TRUE, start_x, start_y, width, height);
103     }
104     
105     new_hour_line = gtk_image_new_from_pixmap(pic1, NULL);
106     g_object_unref(pic1_gc);
107     g_object_unref(pic1);
108     return(new_hour_line);
109 }
110
111 /* move one day forward or backward */
112 void orage_move_day(struct tm *t, int day)
113 {
114     guint monthdays[12] = {31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
115
116     t->tm_year += 1900;
117     if (((t->tm_year%4) == 0) 
118     && (((t->tm_year%100) != 0) || ((t->tm_year%400) == 0)))
119         ++monthdays[1]; /* leap year, february has 29 days */
120
121     t->tm_mday += day; /* may be negative */
122     if (t->tm_mday == 0) { /*  we went to previous month */
123         if (--t->tm_mon == -1) { /* previous year */
124             --t->tm_year;
125             t->tm_mon = 11;
126         }
127         t->tm_mday = monthdays[t->tm_mon];
128     }
129     else if (t->tm_mday > (monthdays[t->tm_mon])) { /* next month */
130         if (++t->tm_mon == 12) {
131             ++t->tm_year;
132             t->tm_mon = 0;
133         }
134         t->tm_mday = 1;
135     }
136     t->tm_year -= 1900;
137     t->tm_wday += day; 
138     if (t->tm_wday < 0)
139         t->tm_wday = 6;
140     t->tm_wday %=7;
141 }
142
143 gint orage_days_between(struct tm *t1, struct tm *t2)
144 {
145     GDate *g_t1, *g_t2;
146     gint dd;
147     g_t1 = g_date_new_dmy(t1->tm_mday, t1->tm_mon, t1->tm_year);
148     g_t2 = g_date_new_dmy(t2->tm_mday, t2->tm_mon, t2->tm_year);
149     dd = g_date_days_between(g_t1, g_t2);
150     g_date_free(g_t1);
151     g_date_free(g_t2);
152     return(dd);
153 }
154
155 gint vcal_view_set_calendar_page(GtkWidget *to_show, GCallback cb, gpointer data)
156 {
157     SummaryView *summaryview = NULL;
158     gint selsig = -1;
159     if (mainwindow_get_mainwindow()) {
160         summaryview = mainwindow_get_mainwindow()->summaryview;
161         gtk_container_add(GTK_CONTAINER(summaryview->mainwidget_book),
162                 to_show);
163         gtk_notebook_set_current_page(GTK_NOTEBOOK(summaryview->mainwidget_book),
164                 gtk_notebook_page_num(GTK_NOTEBOOK(summaryview->mainwidget_book), 
165                 to_show));
166         main_window_set_menu_sensitive(mainwindow_get_mainwindow());
167         toolbar_main_set_sensitive(mainwindow_get_mainwindow());
168         selsig = g_signal_connect(G_OBJECT(summaryview->ctree), "tree_select_row",
169                          G_CALLBACK(cb), data);
170     }
171     return selsig;
172 }
173
174 void vcal_view_set_summary_page(GtkWidget *to_remove, guint selsig)
175 {
176     SummaryView *summaryview = NULL;
177     if (mainwindow_get_mainwindow()) {
178         summaryview = mainwindow_get_mainwindow()->summaryview;
179         if (selsig)
180                 g_signal_handler_disconnect(G_OBJECT(summaryview->ctree), selsig);
181         gtk_container_remove(GTK_CONTAINER(summaryview->mainwidget_book),
182                 to_remove);
183         gtk_notebook_set_current_page(GTK_NOTEBOOK(summaryview->mainwidget_book),
184                 gtk_notebook_page_num(GTK_NOTEBOOK(summaryview->mainwidget_book), 
185                 summaryview->scrolledwin));
186         main_window_set_menu_sensitive(mainwindow_get_mainwindow());
187         toolbar_main_set_sensitive(mainwindow_get_mainwindow());
188     }
189         
190 }
191
192 void vcal_view_select_event (const gchar *uid, FolderItem *item, gboolean edit,
193                             GCallback block_cb, gpointer block_data)
194 {
195         if (edit) {
196                 VCalEvent *event = NULL;
197                 event = vcal_manager_load_event(uid);
198                 if (event) {
199                         vcal_meeting_create(event);
200                         vcal_manager_free_event(event);
201                 }
202         } else {
203                 SummaryView *summaryview = NULL;
204                 if (mainwindow_get_mainwindow()) {
205                    MsgInfo *info = folder_item_get_msginfo_by_msgid(item, uid);
206                    if (info) {
207                            summaryview = mainwindow_get_mainwindow()->summaryview;
208                            g_signal_handlers_block_by_func(G_OBJECT(summaryview->ctree),
209                                                G_CALLBACK(block_cb), block_data);
210                            summary_select_by_msgnum(summaryview, info->msgnum);
211                            summary_display_msg_selected(summaryview, FALSE);
212                            procmsg_msginfo_free(&info);
213                            g_signal_handlers_unblock_by_func(G_OBJECT(summaryview->ctree),
214                                                G_CALLBACK(block_cb), block_data);
215                    }
216                 }
217         }
218 }
219
220 void vcal_view_create_popup_menus(gpointer data, 
221                                 GtkWidget **view_menu,
222                                 GtkWidget **event_menu, GtkActionGroup **event_group,
223                                 GtkUIManager **ui_manager)
224 {
225         *ui_manager = gtk_ui_manager_new();
226         *event_group = cm_menu_create_action_group_full(*ui_manager,"VcalViewEvent", view_event_popup_entries,
227                         G_N_ELEMENTS(view_event_popup_entries), (gpointer)data);
228
229         MENUITEM_ADDUI_MANAGER(*ui_manager, "/", "Menus", "Menus", GTK_UI_MANAGER_MENUBAR)
230         MENUITEM_ADDUI_MANAGER(*ui_manager, "/Menus", "VcalView", "VcalViewEvent", GTK_UI_MANAGER_MENU)
231         MENUITEM_ADDUI_MANAGER(*ui_manager, "/Menus/VcalView", "CreateMeeting", "VcalViewEvent/CreateMeeting", GTK_UI_MANAGER_MENUITEM)
232         MENUITEM_ADDUI_MANAGER(*ui_manager, "/Menus/VcalView", "Separator1", "VcalViewEvent/---", GTK_UI_MANAGER_SEPARATOR)
233         MENUITEM_ADDUI_MANAGER(*ui_manager, "/Menus/VcalView", "GoToday", "VcalViewEvent/GoToday", GTK_UI_MANAGER_MENUITEM)
234
235         MENUITEM_ADDUI_MANAGER(*ui_manager, "/Menus", "VcalViewEvent", "VcalViewEvent", GTK_UI_MANAGER_MENU)
236         MENUITEM_ADDUI_MANAGER(*ui_manager, "/Menus/VcalViewEvent", "EditMeeting", "VcalViewEvent/EditMeeting", GTK_UI_MANAGER_MENUITEM)
237         MENUITEM_ADDUI_MANAGER(*ui_manager, "/Menus/VcalViewEvent", "CancelMeeting", "VcalViewEvent/CancelMeeting", GTK_UI_MANAGER_MENUITEM)
238         MENUITEM_ADDUI_MANAGER(*ui_manager, "/Menus/VcalViewEvent", "Separator1", "VcalViewEvent/---", GTK_UI_MANAGER_SEPARATOR)
239         MENUITEM_ADDUI_MANAGER(*ui_manager, "/Menus/VcalViewEvent", "CreateMeeting", "VcalViewEvent/CreateMeeting", GTK_UI_MANAGER_MENUITEM)
240         MENUITEM_ADDUI_MANAGER(*ui_manager, "/Menus/VcalViewEvent", "Separator2", "VcalViewEvent/---", GTK_UI_MANAGER_SEPARATOR)
241         MENUITEM_ADDUI_MANAGER(*ui_manager, "/Menus/VcalViewEvent", "GoToday", "VcalViewEvent/GoToday", GTK_UI_MANAGER_MENUITEM)
242
243         *view_menu = gtk_menu_item_get_submenu(GTK_MENU_ITEM(
244                                 gtk_ui_manager_get_widget(*ui_manager, "/Menus/VcalView")) );
245         *event_menu= gtk_menu_item_get_submenu(GTK_MENU_ITEM(
246                                 gtk_ui_manager_get_widget(*ui_manager, "/Menus/VcalViewEvent")) );
247 }
248
249 static void view_new_meeting_cb                 (GtkAction      *action,
250                                                  gpointer        user_data)
251 {
252         gpointer data_i = g_object_get_data(G_OBJECT(user_data), "menu_data_i");
253         gpointer data_s = g_object_get_data(G_OBJECT(user_data), "menu_data_s");
254         gpointer win = g_object_get_data(G_OBJECT(user_data), "menu_win");
255         void (*cb)(gpointer win, gpointer data_i, gpointer data_s) = 
256                 g_object_get_data(G_OBJECT(user_data), "new_meeting_cb");
257         if (cb)
258                 cb(win, data_i, data_s);
259 }
260 static void view_edit_meeting_cb                (GtkAction      *action,
261                                                  gpointer        user_data)
262 {
263         gpointer data_i = g_object_get_data(G_OBJECT(user_data), "menu_data_i");
264         gpointer data_s = g_object_get_data(G_OBJECT(user_data), "menu_data_s");
265         gpointer win = g_object_get_data(G_OBJECT(user_data), "menu_win");
266         void (*cb)(gpointer win, gpointer data_i, gpointer data_s) = 
267                 g_object_get_data(G_OBJECT(user_data), "edit_meeting_cb");
268         if (cb)
269                 cb(win, data_i, data_s);
270 }
271 static void view_cancel_meeting_cb              (GtkAction      *action,
272                                                  gpointer        user_data)
273 {
274         gpointer data_i = g_object_get_data(G_OBJECT(user_data), "menu_data_i");
275         gpointer data_s = g_object_get_data(G_OBJECT(user_data), "menu_data_s");
276         gpointer win = g_object_get_data(G_OBJECT(user_data), "menu_win");
277         void (*cb)(gpointer win, gpointer data_i, gpointer data_s) = 
278                 g_object_get_data(G_OBJECT(user_data), "cancel_meeting_cb");
279         if (cb)
280                 cb(win, data_i, data_s);
281 }
282 static void view_go_today_cb                    (GtkAction      *action,
283                                                  gpointer        user_data)
284 {
285         gpointer data_i = g_object_get_data(G_OBJECT(user_data), "menu_data_i");
286         gpointer data_s = g_object_get_data(G_OBJECT(user_data), "menu_data_s");
287         gpointer win = g_object_get_data(G_OBJECT(user_data), "menu_win");
288         void (*cb)(gpointer win, gpointer data_i, gpointer data_s) = 
289                 g_object_get_data(G_OBJECT(user_data), "go_today_cb");
290         if (cb)
291                 cb(win, data_i, data_s);
292 }