aboutsummaryrefslogblamecommitdiffstats
path: root/mail/em-folder-properties.c
blob: 8a2875969ec509bf9eee7914bfbc186dd6b6f1eb (plain) (tree)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
















                                                                           
                                                                                 






                    

                   




                               
                        




                                
                        
 


                               
                               
                                      
                                   
                       

                                 
                      
 
                           


                         
                        




                            





                           




                                                                                    











                                                              

                                          
 

                                               
 








                                                                                                               
                                                                  


                              
 
                                                          


           
                                                 


                                            
 

                            



                                                                                     


                                                                                              
 

                                               
 


                           

                                                                                                                   
 
                          



                                            
 

                           
 
                                                                                     

                                                            
                                
                                                                     
 
                                                                                              
                                                                                                     

                                                             
                                                                                          
 
                                                   

                                         

                                                                                                       

              
                                               
                                                                                              
                                                                                                  
                                

                                                                                          
 
                                                  

                                         

                                                                                                       

              
                                                    
                                  


                                              
 


                                                                                
                                                                                                                   
                                            
                                                                                                                     



                                                                  
                                                                             
                                                
                                                                                                            
 

                                             



                                                                                                                                     
                         
                                                                                                                     


                                                  
                                                                  

                              
 

                            
                    
         











                                                                                      
                                              






                                                                   
                                



                                     


                              



                           

                                     
                                                    

                                   
 
          
                                                                                                 

                                                                                         
                                                                                                                             
                                                                                                                                                  
 


                                                                                                        
          







                                                                           
 






                                                                                             
                                                          


                                                     
                                                       
                                                                           







                                                                                     

                                                                        









                                                                                                       
 



                                              
 


                                                                
 


                            
 












                                                                                                       







                                                         
                                                                                   











                                                                                       
                                                                                                
 
                                                                                            





                                                         


           






                                                                                  
















                                                                                                           
                                                                                               


                                                                  
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
/*
 * Authors: Michael Zucchi <notzed@ximian.com>
 *
 * Copyright 2003 Ximian, Inc. (www.ximian.com)
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; version 2.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 *
 */

#ifdef HAVE_CONFIG_H
#include <config.h>
#endif

#include <string.h>

#include <gtk/gtkbox.h>
#include <gtk/gtkcheckbutton.h>
#include <gtk/gtkdialog.h>
#include <gtk/gtkentry.h>
#include <gtk/gtkframe.h>
#include <gtk/gtkhbox.h>
#include <gtk/gtklabel.h>
#include <gtk/gtkmisc.h>
#include <gtk/gtkstock.h>
#include <gtk/gtktable.h>
#include <gtk/gtktogglebutton.h>
#include <gtk/gtkvbox.h>

#include <gconf/gconf-client.h>

#include <camel/camel-store.h>
#include <camel/camel-folder.h>
#include <camel/camel-vtrash-folder.h>
#include <camel/camel-vee-folder.h>
#include <glib/gi18n.h>

#include "em-folder-properties.h"
#include "em-config.h"

#include "mail-component.h"
#include "mail-ops.h"
#include "mail-mt.h"
#include "mail-vfolder.h"
#include "mail-config.h"

struct _prop_data {
    void *object;
    CamelArgV *argv;
    GtkWidget **widgets;

    GSList *properties;
    char *name;
    int total;
    int unread;
    EMConfig *config;
};

static void
emfp_dialog_response (GtkWidget *dialog, int response, struct _prop_data *prop_data)
{
    if (response == GTK_RESPONSE_OK)
        e_config_commit((EConfig *)prop_data->config);
    else
        e_config_abort((EConfig *)prop_data->config);

    gtk_widget_destroy (dialog);
}

static void
emfp_commit(EConfig *ec, GSList *items, void *data)
{
    struct _prop_data *prop_data = data;
    CamelArgV *argv = prop_data->argv;
    int i;

    for (i = 0; i < argv->argc; i++) {
        CamelArg *arg = &argv->argv[i];

        switch (arg->tag & CAMEL_ARG_TYPE) {
        case CAMEL_ARG_BOO:
            arg->ca_int = gtk_toggle_button_get_active ((GtkToggleButton *) prop_data->widgets[i]);
            break;
        case CAMEL_ARG_STR:
            g_free (arg->ca_str);
            arg->ca_str = (char *) gtk_entry_get_text ((GtkEntry *) prop_data->widgets[i]);
            break;
        default:
            g_warning ("This shouldn't be reached\n");
            break;
        }
    }

    camel_object_setv (prop_data->object, NULL, argv);
}

static void
emfp_free(EConfig *ec, GSList *items, void *data)
{
    struct _prop_data *prop_data = data;
    int i;

    g_slist_free(items);

    for (i = 0; i < prop_data->argv->argc; i++) {
        if ((prop_data->argv->argv[i].tag & CAMEL_ARG_TYPE) == CAMEL_ARG_STR)
            g_free (prop_data->argv->argv[i].ca_str);
    }

    camel_object_free (prop_data->object, CAMEL_FOLDER_PROPERTIES, prop_data->properties);
    camel_object_free (prop_data->object, CAMEL_FOLDER_NAME, prop_data->name);

    camel_object_unref (prop_data->object);
    g_free (prop_data->argv);

    g_free (prop_data);
}

static GtkWidget *
emfp_get_folder_item(EConfig *ec, EConfigItem *item, struct _GtkWidget *parent, struct _GtkWidget *old, void *data)
{
    char countstr[16];
    GtkWidget *w, *table, *label;
    struct _prop_data *prop_data = data;
    int row = 0, i;
    GSList *l;

    if (old)
        return old;

    table = gtk_table_new (g_slist_length (prop_data->properties) + 2, 2, FALSE);
    gtk_table_set_row_spacings ((GtkTable *) table, 6);
    gtk_table_set_col_spacings ((GtkTable *) table, 12);
    gtk_widget_show (table);
    gtk_box_pack_start ((GtkBox *) parent, table, TRUE, TRUE, 0);

    /* to be on the safe side, ngettext is used here, see e.g. comment #3 at bug 272567 */
    label = gtk_label_new (ngettext ("Unread messages:", "Unread messages:", prop_data->unread));
    gtk_widget_show (label);
    gtk_misc_set_alignment ((GtkMisc *) label, 0.0, 0.5);
    gtk_table_attach ((GtkTable *) table, label, 0, 1, row, row+1, GTK_FILL, 0, 0, 0);

    sprintf(countstr, "%d", prop_data->unread);
    label = gtk_label_new (countstr);
    gtk_widget_show (label);
    gtk_misc_set_alignment ((GtkMisc *) label, 1.0, 0.5);
    gtk_table_attach ((GtkTable *) table, label, 1, 2, row, row+1, GTK_FILL | GTK_EXPAND, 0, 0, 0);
    row++;

    /* TODO: can this be done in a loop? */
    /* to be on the safe side, ngettext is used here, see e.g. comment #3 at bug 272567 */
    label = gtk_label_new (ngettext ("Total messages:", "Total messages:", prop_data->total));
    gtk_widget_show (label);
    gtk_misc_set_alignment ((GtkMisc *) label, 0.0, 0.5);
    gtk_table_attach ((GtkTable *) table, label, 0, 1, row, row+1, GTK_FILL, 0, 0, 0);

    sprintf(countstr, "%d", prop_data->total);
    label = gtk_label_new (countstr);
    gtk_widget_show (label);
    gtk_misc_set_alignment ((GtkMisc *) label, 1.0, 0.5);
    gtk_table_attach ((GtkTable *) table, label, 1, 2, row, row+1, GTK_FILL | GTK_EXPAND, 0, 0, 0);
    row++;

    /* setup the ui with the values retrieved */
    l = prop_data->properties;
    i = 0;
    while (l) {
        CamelProperty *prop = l->data;

        switch (prop->tag & CAMEL_ARG_TYPE) {
        case CAMEL_ARG_BOO:
            w = gtk_check_button_new_with_label (prop->description);
            gtk_toggle_button_set_active ((GtkToggleButton *) w, prop_data->argv->argv[i].ca_int != 0);
            gtk_widget_show (w);
            gtk_table_attach ((GtkTable *) table, w, 0, 2, row, row + 1, GTK_FILL | GTK_EXPAND, 0, 0, 0);
            prop_data->widgets[i] = w;
            break;
        case CAMEL_ARG_STR:
            label = gtk_label_new (prop->description);
            gtk_misc_set_alignment ((GtkMisc *) label, 0.0, 0.5);
            gtk_widget_show (label);
            gtk_table_attach ((GtkTable *) table, label, 0, 1, row, row + 1, GTK_FILL, 0, 0, 0);

            w = gtk_entry_new ();
            gtk_widget_show (w);
            if (prop_data->argv->argv[i].ca_str) {
                gtk_entry_set_text ((GtkEntry *) w, prop_data->argv->argv[i].ca_str);
                camel_object_free (prop_data->object, prop_data->argv->argv[i].tag, prop_data->argv->argv[i].ca_str);
                prop_data->argv->argv[i].ca_str = NULL;
            }
            gtk_table_attach ((GtkTable *) table, w, 1, 2, row, row + 1, GTK_FILL | GTK_EXPAND, 0, 0, 0);
            prop_data->widgets[i] = w;
            break;
        default:
            g_warning ("This shouldn't be reached\n");
            break;
        }

        row++;
        l = l->next;
        i++;
    }

    return table;
}

#define EMFP_FOLDER_SECTION (2)

static EMConfigItem emfp_items[] = {
    { E_CONFIG_BOOK,  "", NULL },
    { E_CONFIG_PAGE, "00.general", N_("General") },
    { E_CONFIG_SECTION, "00.general/00.folder", NULL /* set by code */ },
    { E_CONFIG_ITEM, "00.general/00.folder/00.info", NULL, emfp_get_folder_item },
};
static gboolean emfp_items_translated = FALSE;

static void
emfp_dialog_got_folder (char *uri, CamelFolder *folder, void *data)
{
    GtkWidget *dialog, *w;
    struct _prop_data *prop_data;
    GSList *l;
    gint32 count, i,deleted;
    EMConfig *ec;
    EMConfigTargetFolder *target;
    CamelArgGetV *arggetv;
    CamelArgV *argv;
    gboolean hide_deleted;
    GConfClient *gconf;
    CamelStore *store;

    if (folder == NULL)
        return;

    store = folder->parent_store;

    prop_data = g_malloc0 (sizeof (*prop_data));
    prop_data->object = folder;
    camel_object_ref (folder);

    /*
      Get number of VISIBLE and DELETED messages, instead of TOTAL messages.  VISIBLE+DELETED
       gives the correct count that matches the label below the Send & Receive button
    */
    camel_object_get (folder, NULL, CAMEL_FOLDER_PROPERTIES, &prop_data->properties, CAMEL_FOLDER_NAME, &prop_data->name,
              CAMEL_FOLDER_VISIBLE, &prop_data->total, CAMEL_FOLDER_UNREAD, &prop_data->unread, CAMEL_FOLDER_DELETED, &deleted, NULL);

    gconf = mail_config_get_gconf_client ();
    hide_deleted = !gconf_client_get_bool(gconf, "/apps/evolution/mail/display/show_deleted", NULL);

    /*
       Do the calculation only for those accounts that support VTRASHes
     */
    if (store->flags & CAMEL_STORE_VTRASH) {
        if (CAMEL_IS_VTRASH_FOLDER(folder))
            prop_data->total += deleted;
        else if (!hide_deleted && deleted > 0)
            prop_data->total += deleted;
    }

    /*
     * If the ffolder is junk folder, get total number of mails.
     */
    if (store->flags & CAMEL_STORE_VJUNK) {
        camel_object_get (folder, NULL, CAMEL_FOLDER_TOTAL, &prop_data->total, NULL);
    }

    if (store == mail_component_peek_local_store(NULL)
        && (!strcmp(prop_data->name, "Drafts")
        || !strcmp(prop_data->name, "Inbox")
        || !strcmp(prop_data->name, "Outbox")
        || !strcmp(prop_data->name, "Sent"))) {
        emfp_items[EMFP_FOLDER_SECTION].label = _(prop_data->name);
        if (!emfp_items_translated) {
            for (i=0;i<sizeof(emfp_items)/sizeof(emfp_items[0]);i++) {
                if (emfp_items[i].label)
                    emfp_items[i].label = _(emfp_items[i].label);
            }
            emfp_items_translated = TRUE;
        }
    }
    else
        emfp_items[EMFP_FOLDER_SECTION].label = prop_data->name;

    count = g_slist_length (prop_data->properties);

    prop_data->widgets = g_malloc0 (sizeof (prop_data->widgets[0]) * count);

    /* build an arggetv/argv to retrieve/store the results */
    argv = g_malloc0 (sizeof (*argv) + (count - CAMEL_ARGV_MAX) * sizeof (argv->argv[0]));
    argv->argc = count;
    arggetv = g_malloc0 (sizeof (*arggetv) + (count - CAMEL_ARGV_MAX) * sizeof (arggetv->argv[0]));
    arggetv->argc = count;

    i = 0;
    l = prop_data->properties;
    while (l) {
        CamelProperty *prop = l->data;

        argv->argv[i].tag = prop->tag;
        arggetv->argv[i].tag = prop->tag;
        arggetv->argv[i].ca_ptr = &argv->argv[i].ca_ptr;

        l = l->next;
        i++;
    }

    camel_object_getv (prop_data->object, NULL, arggetv);
    g_free (arggetv);
    prop_data->argv = argv;

    dialog = gtk_dialog_new_with_buttons (_("Folder Properties"), NULL,
                          GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_NO_SEPARATOR,
                          GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
                          GTK_STOCK_OK, GTK_RESPONSE_OK,
                          NULL);
    gtk_window_set_default_size ((GtkWindow *) dialog, 192, 160);
    gtk_widget_ensure_style (dialog);
    gtk_container_set_border_width ((GtkContainer *) ((GtkDialog *) dialog)->vbox, 12);

    /** @HookPoint-EMConfig: Folder Properties Window
     * @Id: org.gnome.evolution.mail.folderConfig
     * @Type: E_CONFIG_BOOK
     * @Class: org.gnome.evolution.mail.config:1.0
     * @Target: EMConfigTargetFolder
     *
     * The folder properties window.
     */
    ec = em_config_new(E_CONFIG_BOOK, "org.gnome.evolution.mail.folderConfig");
    prop_data->config = ec;
    l = NULL;
    for (i=0;i<sizeof(emfp_items)/sizeof(emfp_items[0]);i++)
        l = g_slist_prepend(l, &emfp_items[i]);
    e_config_add_items((EConfig *)ec, l, emfp_commit, NULL, emfp_free, prop_data);

    target = em_config_target_new_folder(ec, folder, uri);
    e_config_set_target((EConfig *)ec, (EConfigTarget *)target);
    w = e_config_create_widget((EConfig *)ec);

    gtk_box_pack_start ((GtkBox *) ((GtkDialog *) dialog)->vbox, w, TRUE, TRUE, 0);

    /* we do 'apply on ok' ... since instant apply may apply some very long running tasks */

    g_signal_connect (dialog, "response", G_CALLBACK (emfp_dialog_response), prop_data);
    gtk_widget_show (dialog);
}

/**
 * em_folder_properties_show:
 * @parent: parent window for dialogue (currently unused)
 * @folder:
 * @uri:
 *
 * Show folder properties for @folder and @uri.  If @folder is passed
 * as NULL, then the folder @uri will be loaded first.
 **/
void
em_folder_properties_show(GtkWindow *parent, CamelFolder *folder, const char *uri)
{
    /* HACK: its the old behaviour, not very 'neat' but it works */
    if (!strncmp(uri, "vfolder:", 8)) {
        CamelURL *url = camel_url_new(uri, NULL);

        /* MORE HACK: UNMATCHED is a special folder which you can't modify, so check for it here */
        if (url == NULL
            || url->fragment == NULL
            || strcmp(url->fragment, CAMEL_UNMATCHED_NAME) != 0) {
            if (url)
                camel_url_free(url);
            vfolder_edit_rule(uri);
            return;
        }
        if (url)
            camel_url_free(url);
    }

    if (folder == NULL)
        mail_get_folder(uri, 0, emfp_dialog_got_folder, NULL, mail_msg_unordered_push);
    else
        emfp_dialog_got_folder((char *)uri, folder, NULL);
}