1 /*
2 *
3 * This program is free software; you can redistribute it and/or modify it
4 * under the terms of the GNU Lesser General Public License as published by
5 * the Free Software Foundation.
6 *
7 * This program is distributed in the hope that it will be useful, but
8 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
9 * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
10 * for more details.
11 *
12 * You should have received a copy of the GNU Lesser General Public License
13 * along with this program; if not, see <http://www.gnu.org/licenses/>.
14 *
15 *
16 * Authors:
17 * Jeffrey Stedfast <fejj@ximian.com>
18 *
19 * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
20 *
21 */
22
23 #include "evolution-config.h"
24
25 #include "e-mail-tag-editor.h"
26
27 #include <time.h>
28 #include <glib/gi18n-lib.h>
29
30 #include "e-util/e-util.h"
31
32 #define E_MAIL_TAG_EDITOR_GET_PRIVATE(obj) \
33 (G_TYPE_INSTANCE_GET_PRIVATE \
34 ((obj), E_TYPE_MAIL_TAG_EDITOR, EMailTagEditorPrivate))
35
36 #define DEFAULT_FLAG 2 /* "Follow-Up" */
37
38 struct _EMailTagEditorPrivate {
39 GtkTreeView *message_list;
40 GtkComboBox *combo_entry;
41 EDateEdit *target_date;
42
43 gboolean completed;
44 time_t completed_date;
45 };
46
47 enum {
48 PROP_0,
49 PROP_COMPLETED
50 };
51
52 enum {
53 COLUMN_FROM,
54 COLUMN_SUBJECT
55 };
56
G_DEFINE_TYPE(EMailTagEditor,e_mail_tag_editor,GTK_TYPE_DIALOG)57 G_DEFINE_TYPE (EMailTagEditor, e_mail_tag_editor, GTK_TYPE_DIALOG)
58
59 static void
60 mail_tag_editor_set_property (GObject *object,
61 guint property_id,
62 const GValue *value,
63 GParamSpec *pspec)
64 {
65 switch (property_id) {
66 case PROP_COMPLETED:
67 e_mail_tag_editor_set_completed (
68 E_MAIL_TAG_EDITOR (object),
69 g_value_get_boolean (value));
70 return;
71 }
72
73 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
74 }
75
76 static void
mail_tag_editor_get_property(GObject * object,guint property_id,GValue * value,GParamSpec * pspec)77 mail_tag_editor_get_property (GObject *object,
78 guint property_id,
79 GValue *value,
80 GParamSpec *pspec)
81 {
82 switch (property_id) {
83 case PROP_COMPLETED:
84 g_value_set_boolean (
85 value,
86 e_mail_tag_editor_get_completed (
87 E_MAIL_TAG_EDITOR (object)));
88 return;
89 }
90
91 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
92 }
93
94 static void
mail_tag_editor_realize(GtkWidget * widget)95 mail_tag_editor_realize (GtkWidget *widget)
96 {
97 GtkWidget *action_area;
98 GtkWidget *content_area;
99
100 /* Chain up to parent's realize() method. */
101 GTK_WIDGET_CLASS (e_mail_tag_editor_parent_class)->realize (widget);
102
103 /* XXX Override GTK's brain-dead border width defaults. */
104
105 action_area = gtk_dialog_get_action_area (GTK_DIALOG (widget));
106 content_area = gtk_dialog_get_content_area (GTK_DIALOG (widget));
107
108 gtk_container_set_border_width (GTK_CONTAINER (content_area), 0);
109 gtk_container_set_border_width (GTK_CONTAINER (action_area), 12);
110 }
111
112 static void
e_mail_tag_editor_class_init(EMailTagEditorClass * class)113 e_mail_tag_editor_class_init (EMailTagEditorClass *class)
114 {
115 GObjectClass *object_class;
116 GtkWidgetClass *widget_class;
117
118 g_type_class_add_private (class, sizeof (EMailTagEditorPrivate));
119
120 object_class = G_OBJECT_CLASS (class);
121 object_class->set_property = mail_tag_editor_set_property;
122 object_class->get_property = mail_tag_editor_get_property;
123
124 widget_class = GTK_WIDGET_CLASS (class);
125 widget_class->realize = mail_tag_editor_realize;
126
127 g_object_class_install_property (
128 object_class,
129 PROP_COMPLETED,
130 g_param_spec_boolean (
131 "completed",
132 "Completed",
133 NULL,
134 FALSE,
135 G_PARAM_READWRITE));
136 }
137
138 static void
e_mail_tag_editor_init(EMailTagEditor * editor)139 e_mail_tag_editor_init (EMailTagEditor *editor)
140 {
141 GtkBuilder *builder;
142 GtkDialog *dialog;
143 GtkWidget *widget;
144 GtkWidget *content_area;
145 GtkWindow *window;
146 GtkCellRenderer *renderer;
147 GtkListStore *store;
148
149 editor->priv = E_MAIL_TAG_EDITOR_GET_PRIVATE (editor);
150
151 dialog = GTK_DIALOG (editor);
152 window = GTK_WINDOW (editor);
153
154 gtk_window_set_default_size (window, 400, 500);
155 gtk_window_set_title (window, _("Flag to Follow Up"));
156 gtk_window_set_icon_name (window, "stock_mail-flag-for-followup");
157
158 gtk_dialog_add_buttons (
159 dialog,
160 _("_Cancel"), GTK_RESPONSE_CANCEL,
161 _("Cl_ear"), GTK_RESPONSE_REJECT,
162 _("_OK"), GTK_RESPONSE_OK,
163 NULL);
164
165 gtk_dialog_set_default_response (dialog, GTK_RESPONSE_OK);
166
167 content_area = gtk_dialog_get_content_area (dialog);
168
169 /* Make sure our custom widget classes are registered with
170 * GType before we load the GtkBuilder definition file. */
171 g_type_ensure (E_TYPE_DATE_EDIT);
172
173 /* Load the rest of the UI from the builder file. */
174
175 builder = gtk_builder_new ();
176 e_load_ui_builder_definition (builder, "mail-dialogs.ui");
177
178 widget = e_builder_get_widget (builder, "toplevel");
179 gtk_box_pack_start (GTK_BOX (content_area), widget, TRUE, TRUE, 6);
180
181 widget = e_builder_get_widget (builder, "pixmap");
182 e_binding_bind_property (
183 window, "icon-name",
184 widget, "icon-name",
185 G_BINDING_SYNC_CREATE);
186
187 widget = e_builder_get_widget (builder, "message_list");
188 editor->priv->message_list = GTK_TREE_VIEW (widget);
189
190 store = gtk_list_store_new (2, G_TYPE_STRING, G_TYPE_STRING);
191 gtk_tree_view_set_model (
192 GTK_TREE_VIEW (widget), GTK_TREE_MODEL (store));
193
194 renderer = gtk_cell_renderer_text_new ();
195 gtk_tree_view_insert_column_with_attributes (
196 GTK_TREE_VIEW (widget), -1, _("From"),
197 renderer, "text", 0, NULL);
198
199 renderer = gtk_cell_renderer_text_new ();
200 gtk_tree_view_insert_column_with_attributes (
201 GTK_TREE_VIEW (widget), -1, _("Subject"),
202 renderer, "text", 1, NULL);
203
204 widget = e_builder_get_widget (builder, "combo");
205 editor->priv->combo_entry = GTK_COMBO_BOX (widget);
206 gtk_combo_box_set_active (GTK_COMBO_BOX (widget), DEFAULT_FLAG);
207
208 widget = e_builder_get_widget (builder, "target_date");
209 editor->priv->target_date = E_DATE_EDIT (widget);
210
211 widget = e_builder_get_widget (builder, "completed");
212 e_binding_bind_property (
213 editor, "completed",
214 widget, "active",
215 G_BINDING_BIDIRECTIONAL |
216 G_BINDING_SYNC_CREATE);
217
218 g_object_unref (builder);
219 }
220
221 GtkWidget *
e_mail_tag_editor_new(void)222 e_mail_tag_editor_new (void)
223 {
224 return g_object_new (E_TYPE_MAIL_TAG_EDITOR, NULL);
225 }
226
227 gboolean
e_mail_tag_editor_get_completed(EMailTagEditor * editor)228 e_mail_tag_editor_get_completed (EMailTagEditor *editor)
229 {
230 g_return_val_if_fail (E_IS_MAIL_TAG_EDITOR (editor), FALSE);
231
232 return editor->priv->completed;
233 }
234
235 void
e_mail_tag_editor_set_completed(EMailTagEditor * editor,gboolean completed)236 e_mail_tag_editor_set_completed (EMailTagEditor *editor,
237 gboolean completed)
238 {
239 g_return_if_fail (E_IS_MAIL_TAG_EDITOR (editor));
240
241 if (editor->priv->completed == completed)
242 return;
243
244 editor->priv->completed = completed;
245 editor->priv->completed_date = completed ? time (NULL) : 0;
246
247 g_object_notify (G_OBJECT (editor), "completed");
248 }
249
250 CamelNameValueArray *
e_mail_tag_editor_get_tag_list(EMailTagEditor * editor)251 e_mail_tag_editor_get_tag_list (EMailTagEditor *editor)
252 {
253 CamelNameValueArray *tag_list;
254 time_t date;
255 gchar *text = NULL;
256 GtkWidget *entry;
257
258 g_return_val_if_fail (E_IS_MAIL_TAG_EDITOR (editor), NULL);
259
260 tag_list = camel_name_value_array_new ();
261
262 entry = gtk_bin_get_child (GTK_BIN (editor->priv->combo_entry));
263 if (entry)
264 text = g_strdup (gtk_entry_get_text (GTK_ENTRY (entry)));
265 camel_name_value_array_set_named (tag_list, CAMEL_COMPARE_CASE_SENSITIVE, "follow-up", text);
266 g_free (text);
267
268 date = e_date_edit_get_time (editor->priv->target_date);
269 if (date != (time_t) -1) {
270 text = camel_header_format_date (date, 0);
271 camel_name_value_array_set_named (tag_list, CAMEL_COMPARE_CASE_SENSITIVE, "due-by", text);
272 g_free (text);
273 } else
274 camel_name_value_array_set_named (tag_list, CAMEL_COMPARE_CASE_SENSITIVE, "due-by", "");
275
276 if (e_mail_tag_editor_get_completed (editor)) {
277 text = camel_header_format_date (editor->priv->completed_date, 0);
278 camel_name_value_array_set_named (tag_list, CAMEL_COMPARE_CASE_SENSITIVE, "completed-on", text);
279 g_free (text);
280 } else
281 camel_name_value_array_set_named (tag_list, CAMEL_COMPARE_CASE_SENSITIVE, "completed-on", "");
282
283 return tag_list;
284 }
285
286 void
e_mail_tag_editor_set_tag_list(EMailTagEditor * editor,const CamelNameValueArray * tag_list)287 e_mail_tag_editor_set_tag_list (EMailTagEditor *editor,
288 const CamelNameValueArray *tag_list)
289 {
290 GtkWidget *child;
291 const gchar *text;
292 time_t date;
293
294 g_return_if_fail (E_IS_MAIL_TAG_EDITOR (editor));
295 g_return_if_fail (tag_list != NULL);
296
297 /* Extract the GtkEntry from the GtkComboBoxEntry. */
298 child = gtk_bin_get_child (GTK_BIN (editor->priv->combo_entry));
299
300 /* XXX This is kind of cheating. Since we only store the
301 * translated tag there's no sure-fire way to determine
302 * the corresponding combo box index (e.g. the tag may
303 * have been set while running in a different locale). */
304 text = camel_name_value_array_get_named (tag_list, CAMEL_COMPARE_CASE_SENSITIVE, "follow-up");
305 if (text != NULL)
306 gtk_entry_set_text (GTK_ENTRY (child), text);
307
308 text = camel_name_value_array_get_named (tag_list, CAMEL_COMPARE_CASE_SENSITIVE, "due-by");
309 if (text != NULL && *text != '\0') {
310 date = camel_header_decode_date (text, NULL);
311 e_date_edit_set_time (editor->priv->target_date, date);
312 } else
313 e_date_edit_set_time (editor->priv->target_date, (time_t) -1);
314
315 text = camel_name_value_array_get_named (tag_list, CAMEL_COMPARE_CASE_SENSITIVE, "completed-on");
316 if (text != NULL && *text != '\0') {
317 date = camel_header_decode_date (text, NULL);
318 if (date != (time_t) 0) {
319 e_mail_tag_editor_set_completed (editor, TRUE);
320 editor->priv->completed_date = date;
321 }
322 }
323 }
324
325 void
e_mail_tag_editor_add_message(EMailTagEditor * editor,const gchar * from,const gchar * subject)326 e_mail_tag_editor_add_message (EMailTagEditor *editor,
327 const gchar *from,
328 const gchar *subject)
329 {
330 GtkTreeModel *model;
331 GtkTreeIter iter;
332
333 g_return_if_fail (E_MAIL_TAG_EDITOR (editor));
334
335 model = gtk_tree_view_get_model (editor->priv->message_list);
336
337 gtk_list_store_append (GTK_LIST_STORE (model), &iter);
338
339 gtk_list_store_set (
340 GTK_LIST_STORE (model), &iter,
341 COLUMN_FROM, from, COLUMN_SUBJECT, subject, -1);
342 }
343