aboutsummaryrefslogblamecommitdiffstats
path: root/mail/em-folder-properties.c
blob: 8679fd1dc11eccd4f4a4c3d841ae74030bfacd7d (plain) (tree)
1
2
3
4
5
6
7
8
  



                                                                


                                                                  



                                                                    
                                                                             
  




                                                        






                    

                   
                    
                       
 

                               
                                 
                      
 
                           
                         




                         
                        

                    
                         
                                    


           
                                                                                     
 
                                        
                                                               
            
                                                              




                                    
                                                     

                                            
 
                             
 
                                                     
                                           
 

                                                        


                           
           
                                                                                                     
 
                   






















                                                                                          
                  
                                                                                                       
 


                                  
                                            

                               
 

                           
 
                                            

                                                            
                                
                                                                     
 
                                                                                              
                                                                                                                                                       
 
                                               
                                                                                              
                                                                                                                                                   
 




                                                               

                                     




                                                              

                                                                     
                                                      

                                                                               
                            
                                                                           
 
                                                                                                        





                                                                                              
 













                                                                                 
                                                        

                                                             


                                                                 









                                                                        
                 
         
 

                            





                                    



                                                                                                
  
                                              

           


                                                          
                                            

                              
                                

                                     
                         

                                     

                                   
                                
                                 
                              
                            
                          
                         
 
                           

                       
                                         
                                                                  
 
                                                
                                                              
 
                                                    
                                                  
                                                                 
 


                                                                          



                                                          
 



                                                                 
 
          

                                                                           
                                                       
                                                    



                                                      
 


                                                                    









                                                                                
                                             
                                                                         




                                                                                     
                                           
                                                                   
            
                                                                       
 


                                                                         
                                                        
                                                                     
 
                                         


                                                                          
 







                                                         
                                                                                   

                               
                                                       

                                                                                
 


                                                                      
 
                                                                      
 
                                                                                                
 
                                                                                            
                                 


           
                                                                       
 

                                      
                                                   


                                                          




                                                         


           



                                                                     


                                                  
 
                                     
                              

                              


                                                        
                                                                    


                                                       
 
                                                                       

                                                          



                                                                                                           
                                                                           
                                
                                                     
                                                         

                               

                                             


                           


                                                                
            
                                                                          
 
/*
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2 of the License, or (at your option) version 3.
 *
 * 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with the program; if not, see <http://www.gnu.org/licenses/>
 *
 *
 * Authors:
 *      Michael Zucchi <notzed@ximian.com>
 *
 * Copyright (C) 1999-2008 Novell, Inc. (www.novell.com)
 *
 */

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

#include <string.h>

#include <gtk/gtk.h>
#include <glib/gi18n.h>

#include <gconf/gconf-client.h>

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

#include "e-mail-backend.h"
#include "e-mail-local.h"
#include "mail-ops.h"
#include "mail-mt.h"
#include "mail-vfolder.h"

struct _prop_data {
    gpointer object;
    gint total;
    gint unread;
    EMConfig *config;
    CamelFolderQuotaInfo *quota;
};

static void
emfp_dialog_response (GtkWidget *dialog, gint 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_free (EConfig *ec, GSList *items, gpointer data)
{
    struct _prop_data *prop_data = data;

    g_slist_free (items);

    camel_object_state_write (prop_data->object);
    g_object_unref (prop_data->object);

    camel_folder_quota_info_free (prop_data->quota);

    g_free (prop_data);
}

static gint
add_numbered_row (GtkTable *table, gint row, const gchar *description, const gchar *format, gint num)
{
    gchar *str;
    GtkWidget *label;

    g_return_val_if_fail (table != NULL, row);
    g_return_val_if_fail (description != NULL, row);
    g_return_val_if_fail (format != NULL, row);

    label = gtk_label_new (description);
    gtk_widget_show (label);
    gtk_misc_set_alignment (GTK_MISC (label), 0.0, 0.5);
    gtk_table_attach (table, label, 0, 1, row, row+1, GTK_FILL, 0, 0, 0);

    str = g_strdup_printf (format, num);

    label = gtk_label_new (str);
    gtk_widget_show (label);
    gtk_misc_set_alignment (GTK_MISC (label), 1.0, 0.5);
    gtk_table_attach (table, label, 1, 2, row, row+1, GTK_FILL | GTK_EXPAND, 0, 0, 0);

    g_free (str);

    return row + 1;
}

static GtkWidget *
emfp_get_folder_item (EConfig *ec, EConfigItem *item, GtkWidget *parent, GtkWidget *old, gpointer data)
{
    GObjectClass *class;
    GParamSpec **properties;
    GtkWidget *widget, *table;
    struct _prop_data *prop_data = data;
    guint ii, n_properties;
    gint row = 0;

    if (old)
        return old;

    table = gtk_table_new (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 */
    row = add_numbered_row (GTK_TABLE (table), row, ngettext ("Unread messages:", "Unread messages:", prop_data->unread), "%d", prop_data->unread);

    /* 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 */
    row = add_numbered_row (GTK_TABLE (table), row, ngettext ("Total messages:", "Total messages:", prop_data->total), "%d", prop_data->total);

    if (prop_data->quota) {
        CamelFolderQuotaInfo *info;
        CamelFolderQuotaInfo *quota = prop_data->quota;

        for (info = quota; info; info = info->next) {
            gchar *descr;
            gint procs;

            /* should not happen, but anyway... */
            if (!info->total)
                continue;

            /* Show quota name only when available and we
             * have more than one quota info. */
            if (info->name && quota->next)
                descr = g_strdup_printf (
                    _("Quota usage (%s):"), _(info->name));
            else
                descr = g_strdup_printf (_("Quota usage"));

            procs = (gint) ((((double) info->used) / ((double) info->total)) * 100.0 + 0.5);

            row = add_numbered_row (GTK_TABLE (table), row, descr, "%d%%", procs);

            g_free (descr);
        }
    }

    class = G_OBJECT_GET_CLASS (prop_data->object);
    properties = g_object_class_list_properties (class, &n_properties);

    for (ii = 0; ii < n_properties; ii++) {
        const gchar *blurb;

        if ((properties[ii]->flags & CAMEL_PARAM_PERSISTENT) == 0)
            continue;

        blurb = g_param_spec_get_blurb (properties[ii]);

        switch (properties[ii]->value_type) {
            case G_TYPE_BOOLEAN:
                widget = gtk_check_button_new_with_label (blurb);
                g_object_bind_property (
                    prop_data->object,
                    properties[ii]->name,
                    widget, "active",
                    G_BINDING_BIDIRECTIONAL |
                    G_BINDING_SYNC_CREATE);
                gtk_widget_show (widget);
                gtk_table_attach (
                    GTK_TABLE (table), widget,
                    0, 2, row, row + 1,
                    GTK_FILL | GTK_EXPAND, 0, 0, 0);
                row++;
                break;
            default:
                g_warn_if_reached ();
                break;
        }
    }

    g_free (properties);

    return table;
}

#define EMFP_FOLDER_SECTION (2)

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

static void
emfp_dialog_got_folder_quota (CamelFolder *folder,
                              const gchar *folder_uri,
                              CamelFolderQuotaInfo *quota,
                              gpointer data)
{
    GtkWidget *dialog, *w;
    GtkWidget *content_area;
    struct _prop_data *prop_data;
    GSList *l;
    gint32 i,deleted;
    EMConfig *ec;
    EMConfigTargetFolder *target;
    EShellWindow *shell_window;
    EShellView *shell_view;
    CamelStore *local_store;
    CamelStore *parent_store;
    gboolean hide_deleted;
    GConfClient *client;
    const gchar *name;
    const gchar *key;

    if (folder == NULL)
        return;

    shell_view = E_SHELL_VIEW (data);
    shell_window = e_shell_view_get_shell_window (shell_view);

    local_store = e_mail_local_get_store ();
    parent_store = camel_folder_get_parent_store (folder);

    prop_data = g_malloc0 (sizeof (*prop_data));
    prop_data->object = g_object_ref (folder);
    prop_data->quota = camel_folder_quota_info_clone (quota);

    /* 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. */
    name = camel_folder_get_name (folder);
    prop_data->total = folder->summary->visible_count;
    prop_data->unread = folder->summary->unread_count;
    deleted = folder->summary->deleted_count;

    client = gconf_client_get_default ();
    key = "/apps/evolution/mail/display/show_deleted";
    hide_deleted = !gconf_client_get_bool(client, key, NULL);
    g_object_unref (client);

    /*
       Do the calculation only for those accounts that support VTRASHes
     */
    if (parent_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 (parent_store->flags & CAMEL_STORE_VJUNK)
        prop_data->total = camel_folder_summary_count (folder->summary);

    if (parent_store == local_store
        && (!strcmp (name, "Drafts")
        || !strcmp (name, "Templates")
        || !strcmp (name, "Inbox")
        || !strcmp (name, "Outbox")
        || !strcmp (name, "Sent"))) {
        emfp_items[EMFP_FOLDER_SECTION].label = gettext (name);
        if (!emfp_items_translated) {
            for (i = 0; i < G_N_ELEMENTS (emfp_items); i++) {
                if (emfp_items[i].label)
                    emfp_items[i].label = _(emfp_items[i].label);
            }
            emfp_items_translated = TRUE;
        }
    } else if (!strcmp (name, "INBOX"))
        emfp_items[EMFP_FOLDER_SECTION].label = _("Inbox");
    else
        emfp_items[EMFP_FOLDER_SECTION].label = (gchar *) name;

    dialog = gtk_dialog_new_with_buttons (
        _("Folder Properties"), GTK_WINDOW (shell_window),
        GTK_DIALOG_DESTROY_WITH_PARENT | GTK_DIALOG_NO_SEPARATOR,
        GTK_STOCK_CLOSE, GTK_RESPONSE_OK, NULL);
    gtk_window_set_default_size ((GtkWindow *) dialog, 192, 160);

    gtk_widget_ensure_style (dialog);

    content_area = gtk_dialog_get_content_area (GTK_DIALOG (dialog));
    gtk_container_set_border_width (GTK_CONTAINER (content_area), 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 < G_N_ELEMENTS (emfp_items); i++)
        l = g_slist_prepend (l, &emfp_items[i]);
    e_config_add_items ((EConfig *)ec, l, NULL, NULL, emfp_free, prop_data);

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

    gtk_box_pack_start (GTK_BOX (content_area), 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);
}

static void
emfp_dialog_got_folder (gchar *uri, CamelFolder *folder, gpointer data)
{
    EShellView *shell_view = data;

    /* this should be called in a thread too */
    mail_get_folder_quota (
        folder, uri, emfp_dialog_got_folder_quota,
        shell_view, mail_msg_unordered_push);
}

/**
 * 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 (EShellView *shell_view,
                           CamelFolder *folder,
                           const gchar *uri)
{
    EShellBackend *shell_backend;
    EMailBackend *backend;
    EMailSession *session;

    g_return_if_fail (E_IS_SHELL_VIEW (shell_view));
    g_return_if_fail (uri != NULL);

    shell_backend = e_shell_view_get_shell_backend (shell_view);

    backend = E_MAIL_BACKEND (shell_backend);
    session = e_mail_backend_get_session (backend);

    /* 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 (backend, uri);
            return;
        }
        if (url != NULL)
            camel_url_free (url);
    }

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