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