Fix FSF address (Tobias Mueller, #470445)
[platform/upstream/evolution-data-server.git] / servers / exchange / storage / exchange-folder-size.c
1 /* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
2
3 /* Copyright (C) 2002-2004 Novell, Inc.
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of version 2 of the GNU Lesser General Public
7  * License as published by the Free Software Foundation.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this program; if not, write to the
16  * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17  * Boston, MA 02110-1301, USA.
18  */
19
20 /* ExchangeFolderSize: Display the folder tree with the folder sizes */
21
22 #ifdef HAVE_CONFIG_H
23 #include <config.h>
24 #endif
25
26 #include <string.h>
27
28 #include <glade/glade-xml.h>
29 #include <gtk/gtkbox.h>
30 #include <gtk/gtkcellrenderertext.h>
31 #include <gtk/gtkliststore.h>
32 #include <gtk/gtkmessagedialog.h>
33 #include <gtk/gtktreeselection.h>
34 #include <gtk/gtktreeview.h>
35
36 #include "exchange-hierarchy-webdav.h"
37 #include "e-folder-exchange.h"
38 #include "exchange-folder-size.h"
39
40 #define PARENT_TYPE G_TYPE_OBJECT
41 static GObjectClass *parent_class = NULL;
42
43 typedef struct {
44         char *folder_name;
45         gdouble folder_size;
46 } folder_info;
47
48
49 struct _ExchangeFolderSizePrivate {
50         
51         GHashTable *table;
52         GtkListStore *model;
53         GHashTable *row_refs;
54 };
55
56 enum {
57         COLUMN_NAME,
58         COLUMN_SIZE,
59         NUM_COLUMNS
60 };
61
62 static gboolean
63 free_fsize_table (gpointer key, gpointer value, gpointer data)
64 {
65         folder_info *f_info = (folder_info *) value;
66
67         g_free (key);
68         g_free (f_info->folder_name);
69         g_free (f_info);
70         return TRUE;
71 }
72
73 static gboolean
74 free_row_refs (gpointer key, gpointer value, gpointer user_data)
75 {
76         g_free (key);
77         gtk_tree_row_reference_free (value);
78         return TRUE;
79 }
80
81 static void
82 finalize (GObject *object)
83 {
84         ExchangeFolderSize *fsize = EXCHANGE_FOLDER_SIZE (object);
85
86         g_hash_table_foreach_remove (fsize->priv->table, free_fsize_table, NULL);
87         g_hash_table_destroy (fsize->priv->table);
88         g_hash_table_foreach_remove (fsize->priv->row_refs, free_row_refs, NULL);
89         g_hash_table_destroy (fsize->priv->row_refs);
90         if (fsize->priv->model)
91                 g_object_unref (fsize->priv->model);
92         g_free (fsize->priv);
93
94         G_OBJECT_CLASS (parent_class)->finalize (object);
95 }
96
97 static void
98 dispose (GObject *object)
99 {
100         G_OBJECT_CLASS (parent_class)->dispose (object);
101 }
102
103 static void
104 exchange_folder_size_class_init (ExchangeFolderSizeClass *class)
105 {
106         GObjectClass *object_class;
107         parent_class = g_type_class_ref (PARENT_TYPE);
108
109         object_class = G_OBJECT_CLASS (class);
110
111         /* override virtual methods */
112         object_class->dispose = dispose;
113         object_class->finalize = finalize;
114
115 }
116
117 static void
118 exchange_folder_size_init (ExchangeFolderSize *fsize)
119 {
120         fsize->priv = g_new0 (ExchangeFolderSizePrivate, 1);
121         fsize->priv->table = g_hash_table_new (g_str_hash, g_str_equal);
122         fsize->priv->model = gtk_list_store_new (NUM_COLUMNS, G_TYPE_STRING, G_TYPE_DOUBLE);
123         fsize->priv->row_refs = g_hash_table_new (g_str_hash, g_str_equal);
124 }
125
126 G_DEFINE_TYPE (ExchangeFolderSize, exchange_folder_size, G_TYPE_OBJECT)
127
128 /**
129  * exchange_folder_size_new:
130  *
131  * Return value: a foldersize object with the table initialized
132  **/
133 ExchangeFolderSize *
134 exchange_folder_size_new (void)
135 {
136         ExchangeFolderSize *fsize;
137
138         fsize = g_object_new (EXCHANGE_TYPE_FOLDER_SIZE, NULL);
139
140         return fsize;
141 }
142
143 void
144 exchange_folder_size_update (ExchangeFolderSize *fsize, 
145                                 const char *folder_name,
146                                 gdouble folder_size)
147 {
148         folder_info *f_info, *cached_info;
149         ExchangeFolderSizePrivate *priv;
150         GHashTable *folder_size_table;
151         GtkTreeRowReference *row;
152         GtkTreeIter iter;
153         GtkTreePath *path;
154
155         g_return_if_fail (EXCHANGE_IS_FOLDER_SIZE (fsize));
156
157         priv = fsize->priv;
158         folder_size_table = priv->table;
159
160         cached_info = g_hash_table_lookup (folder_size_table, folder_name);
161         if (cached_info) {
162                 if (cached_info->folder_size == folder_size) {
163                         return;
164                 } else {
165                         cached_info->folder_size = folder_size;
166                         row = g_hash_table_lookup (priv->row_refs, folder_name);
167                         path = gtk_tree_row_reference_get_path (row);
168                         if (gtk_tree_model_get_iter (GTK_TREE_MODEL (fsize->priv->model), &iter, path)) {
169                                 gtk_list_store_set (fsize->priv->model, &iter,
170                                                       COLUMN_NAME, cached_info->folder_name,
171                                                       COLUMN_SIZE, cached_info->folder_size,
172                                                       -1);
173                         }
174                         gtk_tree_path_free (path);
175                         return;
176                 }
177         } else {
178                 f_info = g_new0(folder_info, 1);
179                 f_info->folder_name = g_strdup (folder_name);
180                 f_info->folder_size = folder_size;
181                 g_hash_table_insert (folder_size_table, f_info->folder_name, f_info); 
182
183                 gtk_list_store_append (fsize->priv->model, &iter);
184                 gtk_list_store_set (fsize->priv->model, &iter,
185                                       COLUMN_NAME, f_info->folder_name,
186                                       COLUMN_SIZE, f_info->folder_size,
187                                       -1);
188                 
189                 path = gtk_tree_model_get_path (GTK_TREE_MODEL (fsize->priv->model), &iter);
190                 row = gtk_tree_row_reference_new (GTK_TREE_MODEL (fsize->priv->model), path);
191                 gtk_tree_path_free (path);
192
193                 g_hash_table_insert (fsize->priv->row_refs, g_strdup (folder_name), row);
194         }
195 }
196
197 void
198 exchange_folder_size_remove (ExchangeFolderSize *fsize, 
199                                 const char *folder_name)
200 {
201         ExchangeFolderSizePrivate *priv;
202         GHashTable *folder_size_table;
203         folder_info *cached_info;
204         GtkTreeRowReference *row;
205         GtkTreeIter iter;
206         GtkTreePath *path;
207
208         g_return_if_fail (EXCHANGE_IS_FOLDER_SIZE (fsize));
209         g_return_if_fail (folder_name != NULL);
210
211         priv = fsize->priv;
212         folder_size_table = priv->table;
213
214         cached_info = g_hash_table_lookup (folder_size_table, folder_name);
215         if (cached_info)  {
216                 row = g_hash_table_lookup (priv->row_refs, folder_name);
217                 path = gtk_tree_row_reference_get_path (row);
218                 g_hash_table_remove (folder_size_table, folder_name);
219                 if (gtk_tree_model_get_iter (GTK_TREE_MODEL (fsize->priv->model), &iter, path)) {
220                         gtk_list_store_remove (fsize->priv->model, &iter);
221                 }
222                 g_hash_table_remove (priv->row_refs, row);
223                 gtk_tree_path_free (path);
224         }
225 }
226
227 gdouble
228 exchange_folder_size_get (ExchangeFolderSize *fsize,
229                           const char *folder_name)
230 {
231         ExchangeFolderSizePrivate *priv;
232         GHashTable *folder_size_table;
233         folder_info *cached_info;
234
235         g_return_val_if_fail (EXCHANGE_IS_FOLDER_SIZE (fsize), -1);
236         
237         priv = fsize->priv;
238         folder_size_table = priv->table;
239
240         cached_info = g_hash_table_lookup (folder_size_table, folder_name);
241         if (cached_info)  {
242                 return cached_info->folder_size;
243         }
244         return -1;
245 }
246
247 GtkListStore *
248 exchange_folder_size_get_model (ExchangeFolderSize *fsize)
249 {
250         ExchangeFolderSizePrivate *priv;
251
252         priv = fsize->priv;
253
254         if (!g_hash_table_size (priv->table))
255                 return NULL;
256
257         return priv->model;
258 }