1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
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.
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"
51 #include "mail-vfolder.h"
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
);
71 e_config_abort((EConfig
*)prop_data
->config
);
73 gtk_widget_destroy (dialog
);
77 emfp_commit(EConfig
*ec
, GSList
*items
, void *data
)
79 struct _prop_data
*prop_data
= data
;
80 CamelArgV
*argv
= prop_data
->argv
;
83 for (i
= 0; i
< argv
->argc
; i
++) {
84 CamelArg
*arg
= &argv
->argv
[i
];
86 switch (arg
->tag
& CAMEL_ARG_TYPE
) {
88 arg
->ca_int
= gtk_toggle_button_get_active ((GtkToggleButton
*) prop_data
->widgets
[i
]);
92 arg
->ca_str
= (char *) gtk_entry_get_text ((GtkEntry
*) prop_data
->widgets
[i
]);
95 g_assert_not_reached ();
100 camel_object_setv (prop_data
->object
, NULL
, argv
);
104 emfp_free(EConfig
*ec
, GSList
*items
, void *data
)
106 struct _prop_data
*prop_data
= data
;
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
);
126 emfp_get_folder_item(EConfig
*ec
, EConfigItem
*item
, struct _GtkWidget
*parent
, struct _GtkWidget
*old
, void *data
)
129 GtkWidget
*w
, *table
, *label
;
130 struct _prop_data
*prop_data
= data
;
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);
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);
168 /* setup the ui with the values retrieved */
169 l
= prop_data
->properties
;
172 CamelProperty
*prop
= l
->data
;
174 switch (prop
->tag
& CAMEL_ARG_TYPE
) {
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);
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
;
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 ();
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
;
199 g_assert_not_reached ();
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
},
221 emfp_dialog_got_folder (char *uri
, CamelFolder
*folder
, void *data
)
223 GtkWidget
*dialog
, *w
;
224 struct _prop_data
*prop_data
;
228 EMConfigTargetFolder
*target
;
229 CamelArgGetV
*arggetv
;
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
);
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]));
258 arggetv
= g_malloc0 (sizeof (*arggetv
) + (count
- CAMEL_ARGV_MAX
) * sizeof (arggetv
->argv
[0]));
259 arggetv
->argc
= count
;
262 l
= prop_data
->properties
;
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
;
274 camel_object_getv (prop_data
->object
, NULL
, 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
,
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
;
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)
320 * Show folder properties for @folder and @uri. If @folder is passed
321 * as NULL, then the folder @uri will be loaded first.
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 */
332 || url
->fragment
== NULL
333 || strcmp(url
->fragment
, CAMEL_UNMATCHED_NAME
) != 0) {
336 vfolder_edit_rule(uri
);
344 mail_get_folder(uri
, 0, emfp_dialog_got_folder
, NULL
, mail_thread_new
);
346 emfp_dialog_got_folder((char *)uri
, folder
, NULL
);