Updated Traditional Chinese translation.
[evolution.git] / mail / em-folder-properties.c
blobe4e50b8aebb810092d071534c7722ba9439fa4fa
1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2 /*
3 * Authors: Michael Zucchi <notzed@ximian.com>
5 * Copyright 2003 Ximian, Inc. (www.ximian.com)
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; version 2.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Street #330, Boston, MA 02111-1307, USA.
22 #ifdef HAVE_CONFIG_H
23 #include <config.h>
24 #endif
26 #include <string.h>
28 #include <gtk/gtkbox.h>
29 #include <gtk/gtkcheckbutton.h>
30 #include <gtk/gtkdialog.h>
31 #include <gtk/gtkentry.h>
32 #include <gtk/gtkframe.h>
33 #include <gtk/gtkhbox.h>
34 #include <gtk/gtklabel.h>
35 #include <gtk/gtkmisc.h>
36 #include <gtk/gtkstock.h>
37 #include <gtk/gtktable.h>
38 #include <gtk/gtktogglebutton.h>
39 #include <gtk/gtkvbox.h>
41 #include <camel/camel-folder.h>
42 #include <camel/camel-vee-folder.h>
43 #include <libgnome/gnome-i18n.h>
45 #include "em-folder-properties.h"
46 #include "em-config.h"
48 #include "mail-component.h"
49 #include "mail-ops.h"
50 #include "mail-mt.h"
51 #include "mail-vfolder.h"
53 struct _prop_data {
54 void *object;
55 CamelArgV *argv;
56 GtkWidget **widgets;
58 GSList *properties;
59 char *name;
60 int total;
61 int unread;
62 EMConfig *config;
65 static void
66 emfp_dialog_response (GtkWidget *dialog, int response, struct _prop_data *prop_data)
68 if (response == GTK_RESPONSE_OK)
69 e_config_commit((EConfig *)prop_data->config);
70 else
71 e_config_abort((EConfig *)prop_data->config);
73 gtk_widget_destroy (dialog);
76 static void
77 emfp_commit(EConfig *ec, GSList *items, void *data)
79 struct _prop_data *prop_data = data;
80 CamelArgV *argv = prop_data->argv;
81 int i;
83 for (i = 0; i < argv->argc; i++) {
84 CamelArg *arg = &argv->argv[i];
86 switch (arg->tag & CAMEL_ARG_TYPE) {
87 case CAMEL_ARG_BOO:
88 arg->ca_int = gtk_toggle_button_get_active ((GtkToggleButton *) prop_data->widgets[i]);
89 break;
90 case CAMEL_ARG_STR:
91 g_free (arg->ca_str);
92 arg->ca_str = (char *) gtk_entry_get_text ((GtkEntry *) prop_data->widgets[i]);
93 break;
94 default:
95 g_assert_not_reached ();
96 break;
100 camel_object_setv (prop_data->object, NULL, argv);
103 static void
104 emfp_free(EConfig *ec, GSList *items, void *data)
106 struct _prop_data *prop_data = data;
107 int i;
109 g_slist_free(items);
111 for (i = 0; i < prop_data->argv->argc; i++) {
112 if ((prop_data->argv->argv[i].tag & CAMEL_ARG_TYPE) == CAMEL_ARG_STR)
113 g_free (prop_data->argv->argv[i].ca_str);
116 camel_object_free (prop_data->object, CAMEL_FOLDER_PROPERTIES, prop_data->properties);
117 camel_object_free (prop_data->object, CAMEL_FOLDER_NAME, prop_data->name);
119 camel_object_unref (prop_data->object);
120 g_free (prop_data->argv);
122 g_free (prop_data);
125 static GtkWidget *
126 emfp_get_folder_item(EConfig *ec, EConfigItem *item, struct _GtkWidget *parent, struct _GtkWidget *old, void *data)
128 char countstr[16];
129 GtkWidget *w, *table, *label;
130 struct _prop_data *prop_data = data;
131 int row = 0, i;
132 GSList *l;
134 if (old)
135 return old;
137 table = gtk_table_new (g_slist_length (prop_data->properties) + 2, 2, FALSE);
138 gtk_table_set_row_spacings ((GtkTable *) table, 6);
139 gtk_table_set_col_spacings ((GtkTable *) table, 12);
140 gtk_widget_show (table);
141 gtk_box_pack_start ((GtkBox *) parent, table, TRUE, TRUE, 0);
143 /* TODO: can this be done in a loop? */
144 label = gtk_label_new (ngettext ("Total message:", "Total messages:", prop_data->total));
145 gtk_widget_show (label);
146 gtk_misc_set_alignment ((GtkMisc *) label, 0.0, 0.5);
147 gtk_table_attach ((GtkTable *) table, label, 0, 1, row, row+1, GTK_FILL, 0, 0, 0);
149 sprintf(countstr, "%d", prop_data->total);
150 label = gtk_label_new (countstr);
151 gtk_widget_show (label);
152 gtk_misc_set_alignment ((GtkMisc *) label, 1.0, 0.5);
153 gtk_table_attach ((GtkTable *) table, label, 1, 2, row, row+1, GTK_FILL | GTK_EXPAND, 0, 0, 0);
154 row++;
156 label = gtk_label_new (ngettext ("Unread message:", "Unread messages:", prop_data->unread));
157 gtk_widget_show (label);
158 gtk_misc_set_alignment ((GtkMisc *) label, 0.0, 0.5);
159 gtk_table_attach ((GtkTable *) table, label, 0, 1, row, row+1, GTK_FILL, 0, 0, 0);
161 sprintf(countstr, "%d", prop_data->unread);
162 label = gtk_label_new (countstr);
163 gtk_widget_show (label);
164 gtk_misc_set_alignment ((GtkMisc *) label, 1.0, 0.5);
165 gtk_table_attach ((GtkTable *) table, label, 1, 2, row, row+1, GTK_FILL | GTK_EXPAND, 0, 0, 0);
166 row++;
168 /* setup the ui with the values retrieved */
169 l = prop_data->properties;
170 i = 0;
171 while (l) {
172 CamelProperty *prop = l->data;
174 switch (prop->tag & CAMEL_ARG_TYPE) {
175 case CAMEL_ARG_BOO:
176 w = gtk_check_button_new_with_label (prop->description);
177 gtk_toggle_button_set_active ((GtkToggleButton *) w, prop_data->argv->argv[i].ca_int != 0);
178 gtk_widget_show (w);
179 gtk_table_attach ((GtkTable *) table, w, 0, 2, row, row + 1, GTK_FILL | GTK_EXPAND, 0, 0, 0);
180 prop_data->widgets[i] = w;
181 break;
182 case CAMEL_ARG_STR:
183 label = gtk_label_new (prop->description);
184 gtk_misc_set_alignment ((GtkMisc *) label, 0.0, 0.5);
185 gtk_widget_show (label);
186 gtk_table_attach ((GtkTable *) table, label, 0, 1, row, row + 1, GTK_FILL, 0, 0, 0);
188 w = gtk_entry_new ();
189 gtk_widget_show (w);
190 if (prop_data->argv->argv[i].ca_str) {
191 gtk_entry_set_text ((GtkEntry *) w, prop_data->argv->argv[i].ca_str);
192 camel_object_free (prop_data->object, prop_data->argv->argv[i].tag, prop_data->argv->argv[i].ca_str);
193 prop_data->argv->argv[i].ca_str = NULL;
195 gtk_table_attach ((GtkTable *) table, w, 1, 2, row, row + 1, GTK_FILL | GTK_EXPAND, 0, 0, 0);
196 prop_data->widgets[i] = w;
197 break;
198 default:
199 g_assert_not_reached ();
200 break;
203 row++;
204 l = l->next;
205 i++;
208 return table;
211 #define EMFP_FOLDER_SECTION (2)
213 static EMConfigItem emfp_items[] = {
214 { E_CONFIG_BOOK, "", NULL },
215 { E_CONFIG_PAGE, "00.general", N_("General") },
216 { E_CONFIG_SECTION, "00.general/00.folder", NULL /* set by code */ },
217 { E_CONFIG_ITEM, "00.general/00.folder/00.info", NULL, emfp_get_folder_item },
220 static void
221 emfp_dialog_got_folder (char *uri, CamelFolder *folder, void *data)
223 GtkWidget *dialog, *w;
224 struct _prop_data *prop_data;
225 GSList *l;
226 gint32 count, i;
227 EMConfig *ec;
228 EMConfigTargetFolder *target;
229 CamelArgGetV *arggetv;
230 CamelArgV *argv;
232 if (folder == NULL)
233 return;
235 prop_data = g_malloc0 (sizeof (*prop_data));
236 prop_data->object = folder;
237 camel_object_ref (folder);
239 camel_object_get (folder, NULL, CAMEL_FOLDER_PROPERTIES, &prop_data->properties, CAMEL_FOLDER_NAME, &prop_data->name,
240 CAMEL_FOLDER_TOTAL, &prop_data->total, CAMEL_FOLDER_UNREAD, &prop_data->unread, NULL);
242 if (folder->parent_store == mail_component_peek_local_store(NULL)
243 && (!strcmp(prop_data->name, "Drafts")
244 || !strcmp(prop_data->name, "Inbox")
245 || !strcmp(prop_data->name, "Outbox")
246 || !strcmp(prop_data->name, "Sent")))
247 emfp_items[EMFP_FOLDER_SECTION].label = _(prop_data->name);
248 else
249 emfp_items[EMFP_FOLDER_SECTION].label = prop_data->name;
251 count = g_slist_length (prop_data->properties);
253 prop_data->widgets = g_malloc0 (sizeof (prop_data->widgets[0]) * count);
255 /* build an arggetv/argv to retrieve/store the results */
256 argv = g_malloc0 (sizeof (*argv) + (count - CAMEL_ARGV_MAX) * sizeof (argv->argv[0]));
257 argv->argc = count;
258 arggetv = g_malloc0 (sizeof (*arggetv) + (count - CAMEL_ARGV_MAX) * sizeof (arggetv->argv[0]));
259 arggetv->argc = count;
261 i = 0;
262 l = prop_data->properties;
263 while (l) {
264 CamelProperty *prop = l->data;
266 argv->argv[i].tag = prop->tag;
267 arggetv->argv[i].tag = prop->tag;
268 arggetv->argv[i].ca_ptr = &argv->argv[i].ca_ptr;
270 l = l->next;
271 i++;
274 camel_object_getv (prop_data->object, NULL, arggetv);
275 g_free (arggetv);
276 prop_data->argv = argv;
278 dialog = gtk_dialog_new_with_buttons (_("Folder Properties"), NULL,
279 GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_NO_SEPARATOR,
280 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
281 GTK_STOCK_OK, GTK_RESPONSE_OK,
282 NULL);
283 gtk_window_set_default_size ((GtkWindow *) dialog, 192, 160);
284 gtk_widget_ensure_style (dialog);
285 gtk_container_set_border_width ((GtkContainer *) ((GtkDialog *) dialog)->vbox, 12);
287 /** @HookPoint-EMConfig: Folder Properties Window
288 * @Id: org.gnome.evolution.mail.folderConfig
289 * @Type: E_CONFIG_BOOK
290 * @Class: org.gnome.evolution.mail.config:1.0
291 * @Target: EMConfigTargetFolder
293 * The folder properties window.
295 ec = em_config_new(E_CONFIG_BOOK, "org.gnome.evolution.mail.folderConfig");
296 prop_data->config = ec;
297 l = NULL;
298 for (i=0;i<sizeof(emfp_items)/sizeof(emfp_items[0]);i++)
299 l = g_slist_prepend(l, &emfp_items[i]);
300 e_config_add_items((EConfig *)ec, l, emfp_commit, NULL, emfp_free, prop_data);
302 target = em_config_target_new_folder(ec, folder, uri);
303 e_config_set_target((EConfig *)ec, (EConfigTarget *)target);
304 w = e_config_create_widget((EConfig *)ec);
306 gtk_box_pack_start ((GtkBox *) ((GtkDialog *) dialog)->vbox, w, TRUE, TRUE, 0);
308 /* we do 'apply on ok' ... since instant apply may apply some very long running tasks */
310 g_signal_connect (dialog, "response", G_CALLBACK (emfp_dialog_response), prop_data);
311 gtk_widget_show (dialog);
315 * em_folder_properties_show:
316 * @parent: parent window for dialogue (currently unused)
317 * @folder:
318 * @uri:
320 * Show folder properties for @folder and @uri. If @folder is passed
321 * as NULL, then the folder @uri will be loaded first.
323 void
324 em_folder_properties_show(GtkWindow *parent, CamelFolder *folder, const char *uri)
326 /* HACK: its the old behaviour, not very 'neat' but it works */
327 if (!strncmp(uri, "vfolder:", 8)) {
328 CamelURL *url = camel_url_new(uri, NULL);
330 /* MORE HACK: UNMATCHED is a special folder which you can't modify, so check for it here */
331 if (url == NULL
332 || url->fragment == NULL
333 || strcmp(url->fragment, CAMEL_UNMATCHED_NAME) != 0) {
334 if (url)
335 camel_url_free(url);
336 vfolder_edit_rule(uri);
337 return;
339 if (url)
340 camel_url_free(url);
343 if (folder == NULL)
344 mail_get_folder(uri, 0, emfp_dialog_got_folder, NULL, mail_thread_new);
345 else
346 emfp_dialog_got_folder((char *)uri, folder, NULL);