Deleting old icons
[gtkdiskfree:master.git] / src / interface.c
1 /*Written with Emacs.*/
2 /*
3   GtkDiskFree shows free space on your mounted partitions.  Copyright
4   (C) 2001-2002 Dj-Death (Landwerlin Lionel)
5   
6   This program is free software; you can redistribute it and/or modify
7   it under the terms of the GNU General Public License as published by
8   the Free Software Foundation; either version 2 of the License, or
9   (at your option) any later version.
10   
11   This program is distributed in the hope that it will be useful, but
12   WITHOUT ANY WARRANTY; without even the implied warranty of
13   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14   General Public License for more details.
15   
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 Place, Suite 330, Boston, MA 02111-1307
19   USA */
20
21 #include "main.h"
22 #include "configure.h"
23 #include "diskfree.h"
24 #include "menus.h"
25 #include "interface.h"
26 #include "pixmap.h"
27
28 #include "icons/atr_window.xpm"
29
30 /* Signals */
31
32 gint capacity_resize_timeout = 0;
33
34 void
35 gui_capacity_column_resize_end (gpointer data)
36 {
37         capacity_resize_timeout = 0;
38         
39         return;
40 }
41
42 gboolean
43 gui_capacity_column_resize_start (GtkTreeViewColumn *cl, gpointer data)
44 {
45         if (!options->capacity_style[2])
46                 return FALSE;
47         
48         if (capacity_resize_timeout)
49                 g_source_remove(capacity_resize_timeout);
50         capacity_resize_timeout = g_timeout_add_full(G_PRIORITY_DEFAULT,
51                                                        125,
52                                                        (GSourceFunc)gui_list_capacitys_redraw,
53                                                        NULL,
54                                                        (GDestroyNotify)gui_capacity_column_resize_end);
55         
56         return FALSE;
57 }
58
59 gint
60 gui_list_column_get_position (GtkTreeViewColumn *column)
61 {
62         gint i = 0;
63         GList *columns_list = NULL;
64         
65         columns_list = gtk_tree_view_get_columns(GTK_TREE_VIEW(list_treeview));
66         columns_list = g_list_first(columns_list);
67         
68         while (GTK_TREE_VIEW_COLUMN(columns_list->data) != column && i <= CAPACITY_COLUMN) {
69                 columns_list = columns_list->next;
70                 i++;
71         }
72         
73         return i;
74 }
75
76 gint
77 gui_list_column_sort (GtkTreeModel *model, GtkTreeIter *a,
78                       GtkTreeIter *b, gpointer data)
79 {
80         gint ret = 1;
81         gchar *str[2];
82         
83         
84         gtk_tree_model_get(model, a, options->sort[0], &(str[0]), -1);
85         gtk_tree_model_get(model, b, options->sort[0], &(str[1]), -1);
86         
87         if (strcmp(str[0], str[1]) > 0)
88                 ret = -1;
89         
90         g_free(str[0]);
91         g_free(str[1]);
92         
93         return ret;
94 }
95
96 void
97 gui_list_column_clicked (GtkTreeViewColumn *column, gpointer user_data)
98 {
99         options->sort[0] = gui_list_column_get_position(column);
100         options->sort[1] = gtk_tree_view_column_get_sort_order(column);
101         
102         return;
103 }
104
105 void
106 gui_list_columns_disp_update (void)
107 {
108         gint i = 0;
109         GList *columns_list = NULL;
110         
111         columns_list = gtk_tree_view_get_columns(GTK_TREE_VIEW(list_treeview));
112         columns_list = g_list_first(columns_list);
113         
114         while (columns_list != NULL && i < N_COLUMNS) {
115                 if (i > CAPACITY_COLUMN)
116                         gtk_tree_view_column_set_visible(GTK_TREE_VIEW_COLUMN(columns_list->data),
117                                                          FALSE);
118                 else {
119                         if (options->show_columns[i] || options->show_columns_all)
120                                 gtk_tree_view_column_set_visible(GTK_TREE_VIEW_COLUMN(columns_list->data),
121                                                                  TRUE);
122                         else
123                                 gtk_tree_view_column_set_visible(GTK_TREE_VIEW_COLUMN(columns_list->data),
124                                                                  FALSE);
125                         if (options->clist_style[0])
126                                 gtk_tree_view_column_set_sizing(GTK_TREE_VIEW_COLUMN(columns_list->data),
127                                                                 GTK_TREE_VIEW_COLUMN_AUTOSIZE);
128                         else
129                                 gtk_tree_view_column_set_sizing(GTK_TREE_VIEW_COLUMN(columns_list->data),
130                                                                 GTK_TREE_VIEW_COLUMN_FIXED);
131                         if (options->clist_style[1])
132                                 gtk_tree_view_column_set_resizable(GTK_TREE_VIEW_COLUMN(columns_list->data),
133                                                                    TRUE);
134                         else
135                                 gtk_tree_view_column_set_resizable(GTK_TREE_VIEW_COLUMN(columns_list->data),
136                                                                    FALSE);
137                 }
138                 
139                 columns_list = columns_list->next;
140                 i++;
141         }
142         
143         if (options->clist_style[2])
144                 gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(list_treeview), TRUE);
145         else
146                 gtk_tree_view_set_headers_visible(GTK_TREE_VIEW(list_treeview), FALSE);
147         
148         if (options->clist_style[3])
149                 gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(list_treeview), TRUE);
150         else
151                 gtk_tree_view_set_rules_hint(GTK_TREE_VIEW(list_treeview), FALSE);
152         
153         return;
154 }
155
156 void
157 gui_list_columns_init_sortway (void)
158 {
159         GtkTreeViewColumn *column;
160         
161         column = gtk_tree_view_get_column(GTK_TREE_VIEW(list_treeview), options->sort[0]);
162         gtk_tree_view_column_set_sort_indicator(column, TRUE);
163         if (options->sort[1] == GTK_SORT_ASCENDING) {
164                 gtk_tree_view_column_set_sort_order(column, GTK_SORT_ASCENDING);
165                 gtk_tree_view_column_clicked(column);
166         } else
167                 gtk_tree_view_column_set_sort_order(column, GTK_SORT_DESCENDING);
168         gtk_tree_view_column_clicked(column);
169         
170         return;
171 }
172
173 void
174 gui_statusbar_timeout_update (GtkWidget *widget, order_t action)
175 {
176         /* timeout is used by GTK+ to remember which function and when
177            to call it, GTK+ use only > 0 values, here we use -1 value
178            to know if there is a timeout. */
179         static gint timeout = -1;
180         static gfloat last_timeout = 0;
181         
182         switch (action) {
183         case UPDATE:
184                 if (timeout < 0) {
185                         gui_list_main_update(GTK_TREE_VIEW(list_treeview));
186                         break;
187                 }
188         case REFRESH:
189                 if (timeout > 0)
190                         g_source_remove(timeout);
191                 gui_list_main_update(GTK_TREE_VIEW(list_treeview));
192                 timeout = g_timeout_add((gint) (1000 * options->update_interval),
193                                           (GSourceFunc)gui_list_main_update,
194                                           (gpointer)list_treeview);
195                 last_timeout = options->update_interval;
196                 gtk_statusbar_pop(GTK_STATUSBAR(status_bar_timeout), timeout_status);
197                 break;
198         case STOP:
199                 g_source_remove(timeout);
200                 gtk_statusbar_pop(GTK_STATUSBAR(status_bar_timeout), timeout_status);
201                 gtk_statusbar_push(GTK_STATUSBAR(status_bar_timeout), timeout_status,
202                                    _(" Stopped..."));
203                 timeout = -1;
204                 break;
205         default:
206                 break;
207         }
208         
209         return;
210 }
211
212 gboolean
213 gui_statusbar_update_block (void)
214 {
215         gtk_statusbar_pop(GTK_STATUSBAR(status_bar_block), block_size_status);
216         
217         switch (options->blocks[0]) {
218         case GIGABYTE:
219                 gtk_statusbar_push(GTK_STATUSBAR(status_bar_block),
220                                    block_size_status, _(" Gigabytes"));    
221                 break;
222         case MEGABYTE:
223                 gtk_statusbar_push(GTK_STATUSBAR(status_bar_block),
224                                    block_size_status, _(" Megabytes"));
225                 break;
226         case KILOBYTE:
227                 gtk_statusbar_push(GTK_STATUSBAR(status_bar_block),
228                                    block_size_status, _(" Kilobytes"));
229                 break;
230         default:
231                 options->blocks[0] = AUTOSIZE;
232         case AUTOSIZE:
233                 gtk_statusbar_push(GTK_STATUSBAR(status_bar_block),
234                                    block_size_status, _(" Human readable"));
235                 break;
236         }
237         
238         return TRUE;
239 }
240
241 void
242 gui_main_window_set_posize (void)
243 {
244         if (gdk_screen_width() >= options->window_position[0] &&
245             gdk_screen_height() >= options->window_position[1] &&
246             (options->window_position[0] != -1 && options->window_position[1] != -1)) {
247                 gtk_window_move(GTK_WINDOW(mwindow),
248                                 options->window_position[0],
249                                 options->window_position[1]);
250                 gtk_window_resize(GTK_WINDOW(mwindow),
251                                   options->window_size[0],
252                                   options->window_size[1]);
253         }
254         
255         return;
256 }
257
258 void
259 gui_main_window_disp_update (void)
260 {
261         if (options->gui_style[0])
262                 gtk_widget_show(menu_handle_box);
263         else 
264                 gtk_widget_hide(menu_handle_box);
265         
266         if (options->gui_style[1])
267                 gtk_widget_show(tool_handle_box);
268         else
269                 gtk_widget_hide(tool_handle_box);
270         
271         if (options->gui_style[2])
272                 gtk_widget_show(status_hbox);
273         else
274                 gtk_widget_hide(status_hbox);
275         
276         return;
277 }
278
279 void
280 gui_main_window_resize (void)
281 {
282         if (!gtk_widget_get_visible(mwindow))
283                 return;
284         
285         if (options->gui_style[3]) {
286                 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(list_scroll),
287                                                GTK_POLICY_NEVER,
288                                                GTK_POLICY_NEVER);
289                 gtk_window_set_decorated(GTK_WINDOW(mwindow), TRUE);
290                 gtk_window_set_resizable(GTK_WINDOW(mwindow), FALSE);
291         } else {
292                 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(list_scroll),
293                                                GTK_POLICY_AUTOMATIC,
294                                                GTK_POLICY_AUTOMATIC);
295                 gtk_window_set_resizable(GTK_WINDOW(mwindow), TRUE);
296         }
297         
298         return;
299 }
300
301 gboolean
302 gui_main_window_configure (GtkWidget *win, GdkEventConfigure *ev,
303                            gpointer data)
304 {
305         gint w = gdk_screen_width(), h = gdk_screen_height(), ret = FALSE;
306         
307         options->window_position[0] = ev->x;
308         options->window_position[1] = ev->y;
309         
310         if (ev->width <= w)
311                 options->window_size[0] = ev->width;
312         else {
313                 options->window_size[0] = w;
314                 ret = TRUE;
315         }
316         if (ev->height <= h)
317                 options->window_size[1] = ev->height;
318         else {
319                 options->window_size[1] = h;
320                 ret = TRUE;
321         }
322         
323         if (ret)
324                 gtk_window_resize(GTK_WINDOW(mwindow),
325                                   options->window_size[0],
326                                   options->window_size[1]);
327         
328         return FALSE;
329 }
330
331 void
332 gui_list_columns_create (GtkTreeView *list)
333 {
334         gint i;
335         gchar *titles[CAPACITY_COLUMN + 1] = {_("Filesystem"), _("Size"), _("Used space"),
336                                               _("Free space"), _("Used %"), _("Free %"),
337                                               _("Filesystem type"), _("Mount option's"),
338                                               _("Mount dir"), _("Capacity")};
339         GtkCellRenderer *cell_renderer;
340         GtkTreeViewColumn *column;
341         
342         /* We want to display text in our list, so cell will be
343            text. */
344         for (i = 0 ; i < CAPACITY_COLUMN ; i++) {
345                 cell_renderer = gtk_cell_renderer_text_new();
346                 column = gtk_tree_view_column_new_with_attributes(titles[i], cell_renderer,
347                                                                   "text", i, NULL);
348                 g_signal_connect(G_OBJECT(column), "clicked",
349                                  G_CALLBACK(gui_list_column_clicked), NULL);
350                 switch (i) {
351                 case SIZE_COLUMN:
352                         gtk_tree_view_column_set_sort_column_id(column, SIZEK_COLUMN);
353                         break;
354                 case USED_SPACE_COLUMN:
355                         gtk_tree_view_column_set_sort_column_id(column, USEDK_SPACE_COLUMN);
356                         break;
357                 case FREE_SPACE_COLUMN:
358                         gtk_tree_view_column_set_sort_column_id(column, FREEK_SPACE_COLUMN);
359                         break;
360                 case USED_PERCENT_COLUMN:
361                         gtk_tree_view_column_set_sort_column_id(column, USEDP_PERCENT_COLUMN);
362                         break;
363                 case FREE_PERCENT_COLUMN:
364                         gtk_tree_view_column_set_sort_column_id(column, FREEP_PERCENT_COLUMN);
365                         break;
366                 default:
367                         gtk_tree_sortable_set_sort_func(GTK_TREE_SORTABLE(list_treemodel), i,
368                                                         (GtkTreeIterCompareFunc)gui_list_column_sort,
369                                                         NULL, NULL);
370                         gtk_tree_view_column_set_sort_column_id(column, i);
371                         break;
372                 }
373                 gtk_tree_view_append_column(list, column);
374         }
375         
376         /* Except last column which is a 'pixmap' or 'pixbuf'
377            column. */
378         cell_renderer = gtk_cell_renderer_pixbuf_new();
379         g_object_set(G_OBJECT(cell_renderer), "xalign", 0.0, NULL);
380         column = gtk_tree_view_column_new_with_attributes(titles[i], cell_renderer,
381                                                           "pixbuf", i, NULL);
382         gtk_tree_view_column_set_sort_column_id(column, USEDP_PERCENT_COLUMN);
383         gtk_tree_view_append_column(list, column);
384         g_signal_connect(G_OBJECT(column), "clicked",
385                          G_CALLBACK(gui_list_column_clicked), NULL);
386         g_signal_connect(G_OBJECT(column), "notify::width",
387                          G_CALLBACK(gui_capacity_column_resize_start), NULL);
388         
389         return;
390 }
391
392 /* This function define the treeview wigdet we will use later in this
393    apps */
394 GtkTreeModel *
395 gui_list_model_create (void)
396 {
397         GtkListStore *store;
398         GType list_types[N_COLUMNS] = {G_TYPE_STRING, // File
399                                        G_TYPE_STRING, // Size
400                                        G_TYPE_STRING, // Used space
401                                        G_TYPE_STRING, // Free space
402                                        G_TYPE_STRING, // Used percent
403                                        G_TYPE_STRING, // Free percent
404                                        G_TYPE_STRING, // FS type
405                                        G_TYPE_STRING, // Mount opts
406                                        G_TYPE_STRING, // Mount point
407                                        GDK_TYPE_PIXBUF, // Capacity
408                                        
409                                        G_TYPE_ULONG,   // Size in Kb (used to sort)
410                                        G_TYPE_ULONG,   // Used space in Kb (used to sort)
411                                        G_TYPE_ULONG,   // Free space in Kb (used to sort)
412                                        G_TYPE_INT,    // Used percent
413                                        G_TYPE_INT,    // Free percent
414                                        G_TYPE_INT     // Status
415         };
416         
417         store = gtk_list_store_newv(N_COLUMNS, list_types);
418         
419         return GTK_TREE_MODEL(store);
420 }
421
422 /* This function create & show the main window, we display the list
423    into it. */
424 void
425 gui_main_window_create (void)
426 {
427         GtkWidget *main_box, *menu_box;
428         GdkPixbuf *icon;
429         
430         GtkTreeSelection *selection;
431         
432         GtkWidget *status_table, *status_bar;
433         
434         /*--MainWindow--*/
435         mwindow = gtk_window_new(GTK_WINDOW_TOPLEVEL);
436         gtk_window_set_title(GTK_WINDOW(mwindow), "gtkdiskfree");
437         g_signal_connect(G_OBJECT(mwindow), "destroy",
438                          G_CALLBACK(gtk_main_quit), NULL);
439         gtk_container_set_border_width(GTK_CONTAINER(mwindow), 0);
440         gtk_widget_realize(mwindow);
441
442         icon = gdk_pixbuf_new_from_xpm_data(atr_window_xpm);
443
444         gtk_window_set_icon_name(GTK_WINDOW(mwindow), "GtkDiskFree");
445         gtk_window_set_icon(GTK_WINDOW(mwindow), icon);
446         gtk_window_set_default_icon(icon);
447
448         main_box = gtk_vbox_new(FALSE, 0);
449         gtk_container_add(GTK_CONTAINER(mwindow), main_box);
450         gtk_widget_show(main_box);
451         
452         /*--MenuBar & ToolBar--*/
453         menu_box = gtk_vbox_new(FALSE, 0);
454         gtk_box_pack_start(GTK_BOX(main_box), menu_box, FALSE, FALSE, 0);
455         gtk_widget_show(menu_box);
456         
457         gui_main_menu_create(menu_box);
458         gui_toolbar_create(menu_box);
459         
460         /*--List--*/
461         list_box = gtk_vbox_new(FALSE, 0);
462         gtk_box_pack_start(GTK_BOX(main_box), list_box, TRUE, TRUE, 0);
463         gtk_container_set_border_width(GTK_CONTAINER(list_box), 0);
464         gtk_widget_show(list_box);
465         
466         list_scroll = gtk_scrolled_window_new(NULL, NULL);
467         gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(list_scroll),
468                                        GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
469         gtk_box_pack_start(GTK_BOX(list_box), list_scroll, TRUE, TRUE, 0);
470         gtk_widget_show(list_scroll);
471         
472         /* We get the model from the function we did before. */
473         list_treemodel = gui_list_model_create();
474         
475         /* We create the widget from the model. */
476         list_treeview = gtk_tree_view_new_with_model(list_treemodel);
477         g_object_unref(G_OBJECT(list_treemodel));
478         
479         /* GtkTreeView config */
480         selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(list_treeview));
481         gtk_tree_selection_set_mode(selection, GTK_SELECTION_SINGLE);
482         gtk_tree_view_set_reorderable(GTK_TREE_VIEW(list_treeview), FALSE);
483         gtk_container_add(GTK_CONTAINER(list_scroll), list_treeview);
484         
485         /* We need to create & defined cells (title and others). */
486         gui_list_columns_create(GTK_TREE_VIEW(list_treeview));
487         
488         /* Signals */
489         g_signal_connect(G_OBJECT(list_treeview), "button-press-event",
490                          G_CALLBACK(gui_popup_menu_signal), NULL);
491         gtk_widget_show_all(list_treeview);
492         
493         /*--StatusBar--*/
494         
495         status_hbox = gtk_hbox_new(FALSE, 0);
496         gtk_box_pack_start(GTK_BOX(main_box), status_hbox, FALSE, FALSE, 0);
497         gtk_widget_show(status_hbox);
498         
499         status_table = gtk_table_new(1, 5, TRUE);
500         gtk_box_pack_start(GTK_BOX(status_hbox), status_table, TRUE, TRUE, 0);
501         gtk_widget_show(status_table);
502         
503         status_bar = gtk_statusbar_new();
504         #ifndef HAVE_GTK3
505         gtk_statusbar_set_has_resize_grip(GTK_STATUSBAR(status_bar), FALSE);
506         #else
507         gtk_window_set_has_resize_grip(GTK_WINDOW(mwindow), FALSE);
508         #endif
509         gtk_table_attach(GTK_TABLE(status_table), status_bar, 0, 3, 0, 1,
510                          GTK_FILL | GTK_EXPAND, GTK_FILL, 0, 0);
511         gtk_widget_show(status_bar);
512           
513         status_bar_timeout = gtk_statusbar_new();
514         #ifndef HAVE_GTK3
515         gtk_statusbar_set_has_resize_grip(GTK_STATUSBAR(status_bar_timeout), FALSE);
516         #endif
517         gtk_table_attach(GTK_TABLE(status_table), status_bar_timeout, 3, 4, 0, 1,
518                          GTK_FILL | GTK_EXPAND, GTK_FILL, 0, 0);
519         gtk_widget_show(status_bar_timeout);
520         timeout_status = gtk_statusbar_get_context_id(GTK_STATUSBAR(status_bar_timeout),
521                                                       "Program status");
522         status_bar_block = gtk_statusbar_new();
523         #ifndef HAVE_GTK3
524         gtk_statusbar_set_has_resize_grip(GTK_STATUSBAR(status_bar_block), FALSE);
525         #endif
526         gtk_table_attach(GTK_TABLE(status_table), status_bar_block, 4, 5, 0, 1,
527                          GTK_FILL | GTK_EXPAND, GTK_FILL, 0, 0);
528         gtk_widget_show(status_bar_block);
529         block_size_status = gtk_statusbar_get_context_id(GTK_STATUSBAR(status_bar_block),
530                                                          "Blocks size status");
531         gtk_widget_show(status_hbox);
532         gui_statusbar_update_block();
533         
534         /*-------*/
535         gtk_widget_show(mwindow);
536         
537         gui_main_window_disp_update();
538         gui_list_columns_disp_update();
539         gui_list_columns_init_sortway();
540         
541         gui_main_window_set_posize();
542         gui_main_window_resize();
543         
544         g_signal_connect(G_OBJECT(mwindow), "configure-event",
545                          G_CALLBACK(gui_main_window_configure), NULL);
546
547         gtk_widget_show(mwindow);
548         
549         return;
550 }