2005-01-07 [colin] 0.9.13cvs28.3
[claws.git] / src / gtk / progressdialog.c
1 /*
2  * Sylpheed -- a GTK+ based, lightweight, and fast e-mail client
3  * Copyright (C) 1999-2001 Hiroyuki Yamamoto
4  *
5  * This program is free software; you can redistribute it and/or modify
6  * it under the terms of the GNU General Public License as published by
7  * the Free Software Foundation; either version 2 of the License, or
8  * (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
18  */
19
20 #ifdef HAVE_CONFIG_H
21 #  include "config.h"
22 #endif
23
24 #include <glib.h>
25 #include <gtk/gtk.h>
26 #include <gtk/gtkwindow.h>
27 #include <gtk/gtkvbox.h>
28 #include <gtk/gtkhbox.h>
29 #include <gtk/gtklabel.h>
30 #include <gtk/gtkprogressbar.h>
31 #include <gtk/gtkscrolledwindow.h>
32 #include <gtk/gtkbutton.h>
33
34 #include "intl.h"
35 #include "progressdialog.h"
36 #include "gtkutils.h"
37 #include "utils.h"
38
39 enum {
40         PROGRESS_IMAGE,
41         PROGRESS_ACCOUNT,
42         PROGRESS_STATE,
43         N_PROGRESS_COLUMNS
44 };
45
46
47 static GtkListStore* progress_dialog_create_data_store(void);
48 static gint progress_dialog_list_view_insert_account(GtkWidget   *list_view,
49                                                      gint         row,
50                                                      const gchar *account,
51                                                      const gchar *status,
52                                                      GdkPixbuf   *image);
53 static GtkWidget *progress_dialog_list_view_create(void);
54 static void progress_dialog_create_list_view_columns(GtkTreeView *list_view);
55
56 ProgressDialog *progress_dialog_create(void)
57 {
58         ProgressDialog *progress;
59         GtkWidget *window;
60         GtkWidget *vbox;
61         GtkWidget *hbox;
62         GtkWidget *label;
63         GtkWidget *cancel_btn;
64         GtkWidget *cancel_area;
65         GtkWidget *progressbar;
66         GtkWidget *scrolledwin;
67         GtkWidget *clist;
68         GtkWidget *list_view;
69         gchar *text[] = {NULL, NULL, NULL};
70
71         text[1] = _("Account");
72         text[2] = _("Status");
73
74         debug_print("Creating progress dialog...\n");
75         progress = g_new0(ProgressDialog, 1);
76
77         window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
78         gtk_widget_set_usize(window, 460, -1);
79         gtk_container_set_border_width(GTK_CONTAINER(window), 8);
80         gtk_window_set_resizable(GTK_WINDOW(window), TRUE);
81         gtk_widget_realize(window);
82
83         vbox = gtk_vbox_new(FALSE, 8);
84         gtk_container_add(GTK_CONTAINER(window), vbox);
85         gtk_widget_show(vbox);
86
87         hbox = gtk_hbox_new(FALSE, 0);
88         gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 8);
89         gtk_widget_show(hbox);
90
91         label = gtk_label_new("");
92         gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, FALSE, 8);
93         gtk_widget_show(label);
94
95         gtkut_button_set_create_stock(&cancel_area, &cancel_btn, 
96                                       GTK_STOCK_CANCEL, NULL, NULL, 
97                                       NULL, NULL);
98         gtk_box_pack_end(GTK_BOX(vbox), cancel_area, FALSE, FALSE, 0);
99         gtk_widget_grab_default(cancel_btn);
100         gtk_widget_show_all(cancel_area);
101
102         progressbar = gtk_progress_bar_new();
103         gtk_box_pack_start(GTK_BOX(vbox), progressbar, FALSE, FALSE, 0);
104         gtk_widget_show(progressbar);
105
106         scrolledwin = gtk_scrolled_window_new(NULL, NULL);
107         gtk_widget_show(scrolledwin);
108         gtk_box_pack_start(GTK_BOX(vbox), scrolledwin, TRUE, TRUE, 0);
109         gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scrolledwin),
110                                        GTK_POLICY_AUTOMATIC,
111                                        GTK_POLICY_AUTOMATIC);
112
113         /* GTK2: we hide the clist, but it is available for migration
114          * purposes. now if there only was a way to catch "set clist 
115          * things"!.. */
116         clist = gtk_clist_new_with_titles(3, text);
117         gtk_widget_hide(clist);
118         /* gtk_container_add(GTK_CONTAINER(scrolledwin), clist); */
119         /* gtk_widget_set_usize(clist, -1, 120); */
120         gtk_clist_set_column_justification(GTK_CLIST(clist), 0,
121                                            GTK_JUSTIFY_CENTER);
122         gtk_clist_set_column_width(GTK_CLIST(clist), 0, 16);
123         gtk_clist_set_column_width(GTK_CLIST(clist), 1, 160);
124
125         list_view = progress_dialog_list_view_create();
126         gtk_widget_show(list_view);
127         gtk_container_add(GTK_CONTAINER(scrolledwin), list_view);
128         gtk_widget_set_usize(list_view, -1, 120);
129
130         progress->window      = window;
131         progress->label       = label;
132         progress->cancel_btn  = cancel_btn;
133         progress->progressbar = progressbar;
134         progress->clist       = clist;
135         progress->list_view   = list_view;
136
137         return progress;
138 }
139
140 void progress_dialog_set_label(ProgressDialog *progress, gchar *str)
141 {
142         gtk_label_set_text(GTK_LABEL(progress->label), str);
143 }
144
145 void progress_dialog_get_fraction(ProgressDialog *progress)
146 {
147         gtk_progress_bar_get_fraction(GTK_PROGRESS_BAR(progress->progressbar));
148 }
149
150 void progress_dialog_set_fraction(ProgressDialog *progress,
151                                   gfloat percentage)
152 {
153         gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(progress->progressbar),
154                                       percentage);
155 }
156
157 void progress_dialog_destroy(ProgressDialog *progress)
158 {
159         if (progress) {
160                 gtk_widget_destroy(progress->window);
161                 g_free(progress);
162         }
163 }
164
165 /*!
166  *\return       gint Row where account was set
167  */
168 gint progress_dialog_list_set_account(ProgressDialog *progress,
169                                       gint            row,
170                                       const gchar    *account_name)
171 {
172         return progress_dialog_list_view_insert_account(progress->list_view,
173                                                         row, account_name, NULL, 
174                                                         NULL);
175 }
176
177 /*!
178  *\return       gint Row where image was set
179  */
180 gint progress_dialog_list_set_image(ProgressDialog *progress,
181                                     gint            row,
182                                     GdkPixbuf      *image)
183 {
184         return progress_dialog_list_view_insert_account(progress->list_view,
185                                                         row, NULL, NULL, 
186                                                         image);
187 }
188
189 /*!
190  *\return       gint Row where status was set
191  */
192 gint progress_dialog_list_set_status(ProgressDialog *progress,
193                                      gint            row,
194                                      const gchar    *status)
195 {
196         return progress_dialog_list_view_insert_account(progress->list_view,
197                                                         row, NULL, status, 
198                                                         NULL);
199 }
200
201 /*!
202  *\return       gint Row where data were set 
203  */
204 gint progress_dialog_list_set(ProgressDialog    *progress,
205                               gint               row,
206                               GdkPixbuf         *image,
207                               const gchar       *account_name,
208                               const gchar       *status)
209 {
210         return progress_dialog_list_view_insert_account(progress->list_view,
211                                                         row,  account_name, 
212                                                         status, image);
213 }
214
215 /* XXX: maybe scroll into view, but leaving that for someone else to
216  * pickup: I don't have that many accounts... */
217 gboolean progress_dialog_list_select_row(ProgressDialog *progress,
218                                          gint            row)
219 {
220         GtkTreeSelection *selection = gtk_tree_view_get_selection
221                                         (GTK_TREE_VIEW(progress->list_view));
222         GtkTreeIter iter;
223         GtkTreeModel *model;
224
225         model = gtk_tree_view_get_model(GTK_TREE_VIEW(progress->list_view));
226
227         if (!gtk_tree_model_iter_nth_child(model, &iter, NULL, row))
228                 return FALSE;
229
230         gtk_tree_selection_select_iter(selection, &iter);               
231
232         return TRUE;
233 }
234
235 static GtkListStore* progress_dialog_create_data_store(void)
236 {
237         return gtk_list_store_new(N_PROGRESS_COLUMNS,
238                                   GDK_TYPE_PIXBUF,
239                                   G_TYPE_STRING,
240                                   G_TYPE_STRING,        
241                                   -1);
242 }
243
244 static gint progress_dialog_list_view_insert_account(GtkWidget   *list_view,
245                                                      gint         row,
246                                                      const gchar *account,
247                                                      const gchar *status,
248                                                      GdkPixbuf   *image)
249 {
250         GtkTreeIter iter;
251         GtkListStore *store = GTK_LIST_STORE(gtk_tree_view_get_model
252                                         (GTK_TREE_VIEW(list_view)));
253         gint result = -1;                                       
254         
255         if (account == NULL && status == NULL && image == NULL)
256                 return -1;
257
258         /* see if row exists, if not append */
259         if (row < 0 || !gtk_tree_model_iter_nth_child(GTK_TREE_MODEL(store), 
260                                                       &iter, NULL, row)) {
261                 result = gtk_tree_model_iter_n_children(GTK_TREE_MODEL(store),
262                                                         NULL);
263                 gtk_list_store_append(store, &iter);
264         } else
265                 result = row;
266
267         /*
268          * XXX: uhm, when does the iter invalidate? sure not while
269          * just setting a row's column i hope?
270          */
271         
272         if (account)
273                 gtk_list_store_set(store, &iter, 
274                                    PROGRESS_ACCOUNT, account,
275                                    -1);
276         if (status)
277                 gtk_list_store_set(store, &iter,
278                                    PROGRESS_STATE, status,
279                                    -1);
280         if (image)
281                 gtk_list_store_set(store, &iter,
282                                    PROGRESS_IMAGE, image,
283                                    -1);
284
285         return result;
286 }
287
288 static GtkWidget *progress_dialog_list_view_create(void)
289 {
290         GtkTreeView *list_view;
291         GtkTreeModel *model;
292
293         model = GTK_TREE_MODEL(progress_dialog_create_data_store());
294         list_view = GTK_TREE_VIEW(gtk_tree_view_new_with_model(model));
295         g_object_unref(model);  
296         
297         gtk_tree_view_set_rules_hint(list_view, TRUE);
298         
299         /* create the columns */
300         progress_dialog_create_list_view_columns(list_view);
301
302         return GTK_WIDGET(list_view);
303 }
304
305 static void progress_dialog_create_list_view_columns(GtkTreeView *list_view)
306 {
307         GtkTreeViewColumn *column;
308         GtkCellRenderer *renderer;
309
310         renderer = gtk_cell_renderer_pixbuf_new();
311         column = gtk_tree_view_column_new_with_attributes
312                         ("", renderer, 
313                          "pixbuf", PROGRESS_IMAGE,
314                          NULL);
315         gtk_tree_view_append_column(GTK_TREE_VIEW(list_view), column);                   
316
317         renderer = gtk_cell_renderer_text_new();
318         column = gtk_tree_view_column_new_with_attributes
319                 (_("Account"),
320                  renderer,
321                  "text", PROGRESS_ACCOUNT,
322                  NULL);
323         gtk_tree_view_append_column(GTK_TREE_VIEW(list_view), column);          
324
325         renderer = gtk_cell_renderer_text_new();
326         column = gtk_tree_view_column_new_with_attributes
327                 (_("Status"),
328                  renderer,
329                  "text", PROGRESS_STATE,
330                  NULL);
331         gtk_tree_view_append_column(GTK_TREE_VIEW(list_view), column);          
332 }
333