r3768: Updated years.
[rox-filer.git] / ROX-Filer / src / abox.c
blobfef811ad314cbef03ad744520cf1cc690b029281
1 /*
2 * $Id$
4 * ROX-Filer, filer for the ROX desktop project
5 * Copyright (C) 2005, the ROX-Filer team.
7 * This program is free software; you can redistribute it and/or modify it
8 * under the terms of the GNU General Public License as published by the Free
9 * Software Foundation; either version 2 of the License, or (at your option)
10 * any later version.
12 * This program is distributed in the hope that it will be useful, but WITHOUT
13 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15 * more details.
17 * You should have received a copy of the GNU General Public License along with
18 * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
19 * Place, Suite 330, Boston, MA 02111-1307 USA
22 /* abox.c - the dialog box widget used for filer operations.
24 * The actual code for specific operations is in action.c.
27 #include "config.h"
29 #include <string.h>
31 #include "global.h"
33 #include "main.h"
34 #include "abox.h"
35 #include "gui_support.h"
36 #include "filer.h"
37 #include "display.h"
38 #include "support.h"
39 #include "diritem.h"
40 #include "pixmaps.h"
42 #define RESPONSE_QUIET 1
44 /* Static prototypes */
45 static void abox_class_init(GObjectClass *gclass, gpointer data);
46 static void abox_init(GTypeInstance *object, gpointer gclass);
47 static gboolean abox_delete(GtkWidget *dialog, GdkEventAny *event);
48 static void response(GtkDialog *dialog, gint response_id);
49 static void abox_finalise(GObject *object);
50 static void shade(ABox *abox);
52 GType abox_get_type(void)
54 static GType type = 0;
56 if (!type)
58 static const GTypeInfo info =
60 sizeof (ABoxClass),
61 NULL, /* base_init */
62 NULL, /* base_finalise */
63 (GClassInitFunc) abox_class_init,
64 NULL, /* class_finalise */
65 NULL, /* class_data */
66 sizeof(ABox),
67 0, /* n_preallocs */
68 (GInstanceInitFunc) abox_init
71 type = g_type_register_static(GTK_TYPE_DIALOG,
72 "ABox", &info, 0);
75 return type;
78 GtkWidget* abox_new(const gchar *title, gboolean quiet)
80 GtkWidget *widget;
81 ABox *abox;
83 widget = GTK_WIDGET(gtk_widget_new(abox_get_type(), NULL));
84 abox = (ABox *) widget;
86 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(abox->quiet), quiet);
88 gtk_window_set_title(GTK_WINDOW(widget), title);
89 gtk_dialog_set_has_separator(GTK_DIALOG(widget), FALSE);
91 return widget;
94 static void abox_class_init(GObjectClass *gclass, gpointer data)
96 GtkWidgetClass *widget = (GtkWidgetClass *) gclass;
97 GtkDialogClass *dialog = (GtkDialogClass *) gclass;
98 ABoxClass *abox = (ABoxClass *) gclass;
100 widget->delete_event = abox_delete;
101 dialog->response = response;
102 abox->flag_toggled = NULL;
103 abox->abort_operation = NULL;
105 g_signal_new("flag_toggled", G_TYPE_FROM_CLASS(gclass),
106 G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET(ABoxClass, flag_toggled),
107 NULL, NULL, g_cclosure_marshal_VOID__INT,
108 G_TYPE_NONE, 1, G_TYPE_INT);
110 g_signal_new("abort_operation", G_TYPE_FROM_CLASS(gclass),
111 G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET(ABoxClass, abort_operation),
112 NULL, NULL, g_cclosure_marshal_VOID__VOID,
113 G_TYPE_NONE, 0);
115 gclass->finalize = abox_finalise;
118 static void abox_init(GTypeInstance *object, gpointer gclass)
120 GtkWidget *frame, *text, *scrollbar, *button;
121 ABox *abox = ABOX(object);
122 GtkDialog *dialog = GTK_DIALOG(object);
123 int i;
125 gtk_window_set_position(GTK_WINDOW(dialog), GTK_WIN_POS_MOUSE);
127 abox->dir_label = gtk_label_new(_("<dir>"));
128 gtk_widget_set_size_request(abox->dir_label, 8, -1);
129 abox->results = NULL;
130 abox->entry = NULL;
131 abox->next_dir = NULL;
132 abox->next_timer = 0;
133 abox->question = FALSE;
134 gtk_misc_set_alignment(GTK_MISC(abox->dir_label), 0.5, 0.5);
135 gtk_box_pack_start(GTK_BOX(dialog->vbox),
136 abox->dir_label, FALSE, TRUE, 0);
138 abox->log_hbox = gtk_hbox_new(FALSE, 0);
139 gtk_box_pack_start(GTK_BOX(dialog->vbox),
140 abox->log_hbox, TRUE, TRUE, 4);
142 frame = gtk_frame_new(NULL);
143 gtk_box_pack_start_defaults(GTK_BOX(abox->log_hbox), frame);
145 text = gtk_text_view_new();
146 gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_IN);
147 gtk_container_add(GTK_CONTAINER(frame), text);
149 gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(text), GTK_WRAP_WORD);
150 abox->log = text;
152 scrollbar = gtk_vscrollbar_new(NULL);
153 gtk_widget_set_scroll_adjustments(text, NULL,
154 gtk_range_get_adjustment(GTK_RANGE(scrollbar)));
155 gtk_text_buffer_create_tag(
156 gtk_text_view_get_buffer(GTK_TEXT_VIEW(abox->log)),
157 "error", "foreground", "red",
158 NULL);
159 gtk_text_buffer_create_tag(
160 gtk_text_view_get_buffer(GTK_TEXT_VIEW(abox->log)),
161 "question", "weight", "bold",
162 NULL);
163 gtk_text_view_set_editable(GTK_TEXT_VIEW(text), FALSE);
164 gtk_text_view_set_cursor_visible(GTK_TEXT_VIEW(text), FALSE);
165 gtk_widget_set_size_request(text, 400, 100);
167 gtk_box_pack_start(GTK_BOX(abox->log_hbox), scrollbar, FALSE, TRUE, 0);
169 gtk_dialog_add_buttons(dialog,
170 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
171 GTK_STOCK_NO, GTK_RESPONSE_NO,
172 GTK_STOCK_YES, GTK_RESPONSE_YES,
173 NULL);
175 abox->cmp_area = gtk_table_new(2, 6, FALSE);
176 gtk_box_pack_start(GTK_BOX(dialog->vbox),
177 abox->cmp_area, FALSE, FALSE, 2);
178 gtk_table_set_row_spacings(GTK_TABLE(abox->cmp_area), 2);
179 gtk_table_set_col_spacings(GTK_TABLE(abox->cmp_area), 2);
181 for (i = 0; i < 2; i++)
184 abox->cmp_icon[i] = gtk_image_new();
185 gtk_table_attach(GTK_TABLE(abox->cmp_area),
186 abox->cmp_icon[i],
187 1, 2, i, i + 1,
188 GTK_SHRINK, GTK_SHRINK, 4, 1);
189 abox->cmp_name[i] = gtk_label_new("");
190 gtk_misc_set_alignment(GTK_MISC(abox->cmp_name[i]), 0., 0.5);
191 gtk_table_attach(GTK_TABLE(abox->cmp_area),
192 abox->cmp_name[i],
193 2, 3, i, i + 1,
194 GTK_EXPAND | GTK_FILL, GTK_SHRINK, 4, 1);
195 abox->cmp_size[i] = gtk_label_new("");
196 gtk_table_attach(GTK_TABLE(abox->cmp_area),
197 abox->cmp_size[i],
198 3, 4, i, i + 1,
199 GTK_SHRINK, GTK_SHRINK, 4, 1);
200 abox->cmp_date[i] = gtk_label_new("");
201 gtk_table_attach(GTK_TABLE(abox->cmp_area),
202 abox->cmp_date[i],
203 4, 5, i, i + 1,
204 GTK_SHRINK, GTK_SHRINK, 4, 1);
206 abox->cmp_arrow=gtk_arrow_new(GTK_ARROW_DOWN, GTK_SHADOW_IN);
207 gtk_widget_set_size_request(abox->cmp_arrow, 32, 64);
208 gtk_table_attach(GTK_TABLE(abox->cmp_area),
209 abox->cmp_arrow,
210 0, 1, 0, 2,
211 GTK_SHRINK, GTK_EXPAND | GTK_FILL, 1, 2);
213 abox->progress=NULL;
215 abox->flag_box = gtk_hbox_new(FALSE, 16);
216 gtk_box_pack_end(GTK_BOX(dialog->vbox),
217 abox->flag_box, FALSE, TRUE, 2);
219 button = button_new_mixed(GTK_STOCK_GOTO_LAST, _("_Quiet"));
220 GTK_WIDGET_SET_FLAGS(button, GTK_CAN_DEFAULT);
221 gtk_dialog_add_action_widget(dialog, button, RESPONSE_QUIET);
222 gtk_dialog_set_default_response(dialog, RESPONSE_QUIET);
224 gtk_widget_show_all(dialog->vbox);
225 gtk_widget_hide(abox->cmp_area);
227 abox->quiet = abox_add_flag(abox,
228 _("Quiet"), _("Don't confirm every operation"),
229 'Q', FALSE);
231 shade(abox);
234 static void flag_toggled(GtkToggleButton *toggle, ABox *abox)
236 gint code;
238 code = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(toggle),
239 "abox-response"));
240 if (code == 'Q')
241 shade(abox);
243 g_signal_emit_by_name(abox, "flag_toggled", code);
247 GtkWidget *abox_add_flag(ABox *abox, const gchar *label, const gchar *tip,
248 gint response, gboolean default_value)
250 GtkWidget *check;
252 check = gtk_check_button_new_with_label(label);
253 gtk_tooltips_set_tip(tooltips, check, tip, NULL);
254 g_object_set_data(G_OBJECT(check), "abox-response",
255 GINT_TO_POINTER(response));
256 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check), default_value);
257 g_signal_connect(check, "toggled", G_CALLBACK(flag_toggled), abox);
258 gtk_box_pack_end(GTK_BOX(abox->flag_box), check, FALSE, TRUE, 0);
259 gtk_widget_show(check);
261 return check;
264 static void response(GtkDialog *dialog, gint response_id)
266 ABox *abox = ABOX(dialog);
268 if (response_id == GTK_RESPONSE_CANCEL)
269 g_signal_emit_by_name(abox, "abort_operation");
270 else if (response_id == RESPONSE_QUIET)
272 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(abox->quiet),
273 TRUE);
274 gtk_dialog_response(dialog, GTK_RESPONSE_YES);
276 else if (response_id == GTK_RESPONSE_YES ||
277 response_id == GTK_RESPONSE_NO)
279 abox->question = FALSE;
280 shade(abox);
284 /* Display the question. Unshade the Yes, No and entry box (if any).
285 * Will send a response signal when the user makes a choice.
287 void abox_ask(ABox *abox, const gchar *question)
289 g_return_if_fail(abox != NULL);
290 g_return_if_fail(question != NULL);
291 g_return_if_fail(IS_ABOX(abox));
293 abox_log(abox, question, "question");
295 abox->question = TRUE;
296 shade(abox);
299 void abox_cancel_ask(ABox *abox)
301 g_return_if_fail(abox != NULL);
302 g_return_if_fail(IS_ABOX(abox));
304 abox->question = FALSE;
305 shade(abox);
308 void abox_log(ABox *abox, const gchar *message, const gchar *style)
310 GtkTextIter end;
311 GtkTextBuffer *text_buffer;
312 GtkTextView *log = GTK_TEXT_VIEW(abox->log);
313 gchar *u8 = NULL;
315 if (!g_utf8_validate(message, -1, NULL))
316 u8 = to_utf8(message);
318 text_buffer = gtk_text_view_get_buffer(log);
320 gtk_text_buffer_get_end_iter(text_buffer, &end);
321 gtk_text_buffer_insert_with_tags_by_name(text_buffer,
322 &end, u8 ? u8 : message, -1, style, NULL);
323 gtk_text_view_scroll_to_mark(
324 log,
325 gtk_text_buffer_get_mark(text_buffer, "insert"),
326 0.0, FALSE, 0, 0);
328 g_free(u8);
331 static void abox_finalise(GObject *object)
333 GObjectClass *parent_class;
334 ABox *abox = ABOX(object);
336 if (abox->next_dir)
338 null_g_free(&abox->next_dir);
339 g_source_remove(abox->next_timer);
342 parent_class = gtk_type_class(GTK_TYPE_DIALOG);
344 if (G_OBJECT_CLASS(parent_class)->finalize)
345 (*G_OBJECT_CLASS(parent_class)->finalize)(object);
348 static gboolean show_next_dir(gpointer data)
350 ABox *abox = (ABox *) data;
352 g_return_val_if_fail(IS_ABOX(abox), FALSE);
354 gtk_label_set_text(GTK_LABEL(abox->dir_label), abox->next_dir);
355 null_g_free(&abox->next_dir);
357 return FALSE;
360 /* Display this message in the current-object area.
361 * The display won't update too fast, even if you call this very often.
363 void abox_set_current_object(ABox *abox, const gchar *message)
365 g_return_if_fail(abox != NULL);
366 g_return_if_fail(message != NULL);
367 g_return_if_fail(IS_ABOX(abox));
369 /* If a string is already set then replace it, but assume the
370 * timer is already running...
373 if (abox->next_dir)
374 g_free(abox->next_dir);
375 else
377 gtk_label_set_text(GTK_LABEL(abox->dir_label), message);
378 abox->next_timer = g_timeout_add(500, show_next_dir, abox);
381 abox->next_dir = g_strdup(message);
384 static void lost_preview(GtkWidget *window, ABox *abox)
386 abox->preview = NULL;
389 static void select_row_callback(GtkTreeView *treeview,
390 GtkTreePath *path,
391 GtkTreeViewColumn *col,
392 ABox *abox)
394 GtkTreeModel *model;
395 GtkTreeIter iter;
396 char *leaf, *dir;
398 model = gtk_tree_view_get_model(GTK_TREE_VIEW(abox->results));
399 gtk_tree_model_get_iter(model, &iter, path);
400 gtk_tree_model_get(model, &iter, 0, &leaf, 1, &dir, -1);
402 if (abox->preview)
404 if (strcmp(abox->preview->real_path, dir) == 0)
405 display_set_autoselect(abox->preview, leaf);
406 else
407 filer_change_to(abox->preview, dir, leaf);
408 goto out;
411 abox->preview = filer_opendir(dir, NULL, NULL);
412 if (abox->preview)
414 display_set_autoselect(abox->preview, leaf);
415 g_signal_connect_object(abox->preview->window, "destroy",
416 G_CALLBACK(lost_preview), abox, 0);
419 out:
420 g_free(dir);
421 g_free(leaf);
424 /* Add a list-of-results area. You must use this before adding files
425 * with abox_add_filename().
427 void abox_add_results(ABox *abox)
429 GtkTreeViewColumn *column;
430 GtkWidget *scroller, *frame;
431 GtkListStore *model;
432 GtkCellRenderer *cell_renderer;
434 g_return_if_fail(abox != NULL);
435 g_return_if_fail(IS_ABOX(abox));
436 g_return_if_fail(abox->results == NULL);
438 scroller = gtk_scrolled_window_new(NULL, NULL);
439 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroller),
440 GTK_POLICY_NEVER, GTK_POLICY_ALWAYS);
442 frame = gtk_frame_new(NULL);
443 gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_IN);
444 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(abox)->vbox),
445 frame, TRUE, TRUE, 4);
447 gtk_container_add(GTK_CONTAINER(frame), scroller);
449 model = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_STRING);
450 abox->results = gtk_tree_view_new_with_model(GTK_TREE_MODEL(model));
451 g_object_unref(G_OBJECT(model));
453 cell_renderer = gtk_cell_renderer_text_new();
454 column = gtk_tree_view_column_new_with_attributes(
455 _("Name"), cell_renderer, "text", 0, NULL);
456 gtk_tree_view_column_set_resizable(column, TRUE);
457 gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_GROW_ONLY);
458 gtk_tree_view_append_column(GTK_TREE_VIEW(abox->results), column);
459 gtk_tree_view_insert_column_with_attributes(
460 GTK_TREE_VIEW(abox->results),
461 1, (gchar *) _("Directory"), cell_renderer,
462 "text", 1, NULL);
464 gtk_container_add(GTK_CONTAINER(scroller), abox->results);
466 gtk_widget_set_size_request(abox->results, 100, 100);
467 gtk_box_set_child_packing(GTK_BOX(GTK_DIALOG(abox)->vbox),
468 abox->log_hbox, FALSE, TRUE, 4, GTK_PACK_START);
470 g_signal_connect(abox->results, "row-activated",
471 G_CALLBACK(select_row_callback), abox);
473 gtk_widget_show_all(frame);
476 void abox_add_filename(ABox *abox, const gchar *path)
478 GtkTreeModel *model;
479 GtkTreeIter iter;
480 gchar *dir;
482 model = gtk_tree_view_get_model(GTK_TREE_VIEW(abox->results));
484 gtk_list_store_append(GTK_LIST_STORE(model), &iter);
486 dir = g_path_get_dirname(path);
487 gtk_list_store_set(GTK_LIST_STORE(model), &iter,
488 0, g_basename(path),
489 1, dir, -1);
490 g_free(dir);
493 /* Clear search results area */
494 void abox_clear_results(ABox *abox)
496 GtkTreeModel *model;
498 g_return_if_fail(abox != NULL);
499 g_return_if_fail(IS_ABOX(abox));
501 model = gtk_tree_view_get_model(GTK_TREE_VIEW(abox->results));
503 gtk_list_store_clear(GTK_LIST_STORE(model));
506 void abox_add_combo(ABox *abox, const gchar *tlabel, GList *presets,
507 const gchar *text, GtkWidget *help_button)
509 GtkWidget *hbox, *label, *combo;
511 g_return_if_fail(abox != NULL);
512 g_return_if_fail(IS_ABOX(abox));
513 g_return_if_fail(abox->entry == NULL);
515 hbox = gtk_hbox_new(FALSE, 0);
516 if (tlabel)
518 label = gtk_label_new(tlabel);
519 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, TRUE, 4);
522 combo = gtk_combo_new();
523 gtk_combo_disable_activate(GTK_COMBO(combo));
524 gtk_combo_set_use_arrows_always(GTK_COMBO(combo), TRUE);
525 gtk_combo_set_popdown_strings(GTK_COMBO(combo), presets);
526 abox->entry = GTK_COMBO(combo)->entry;
527 gtk_entry_set_activates_default(GTK_ENTRY(abox->entry), TRUE);
529 gtk_entry_set_text(GTK_ENTRY(abox->entry), text);
530 gtk_box_pack_start(GTK_BOX(hbox), combo, TRUE, TRUE, 4);
532 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(abox)->vbox), hbox,
533 FALSE, TRUE, 0);
534 gtk_box_pack_start(GTK_BOX(hbox), help_button, FALSE, TRUE, 4);
536 gtk_widget_show_all(hbox);
538 shade(abox);
541 void abox_add_entry(ABox *abox, const gchar *text, GtkWidget *help_button)
543 GtkWidget *hbox, *label;
545 g_return_if_fail(abox != NULL);
546 g_return_if_fail(IS_ABOX(abox));
547 g_return_if_fail(abox->entry == NULL);
549 hbox = gtk_hbox_new(FALSE, 0);
550 label = gtk_label_new(_("Expression:"));
551 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, TRUE, 4);
552 abox->entry = gtk_entry_new();
553 gtk_widget_set_name(abox->entry, "fixed-style");
554 gtk_entry_set_text(GTK_ENTRY(abox->entry), text);
555 gtk_box_pack_start(GTK_BOX(hbox), abox->entry, TRUE, TRUE, 4);
556 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(abox)->vbox),
557 hbox, FALSE, TRUE, 4);
558 gtk_box_pack_start(GTK_BOX(hbox), help_button,
559 FALSE, TRUE, 4);
561 gtk_entry_set_activates_default(GTK_ENTRY(abox->entry), TRUE);
563 gtk_widget_show_all(hbox);
565 shade(abox);
568 static void shade(ABox *abox)
570 GtkDialog *dialog = (GtkDialog *) abox;
571 gboolean quiet, on = abox->question;
573 quiet = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(abox->quiet));
575 gtk_dialog_set_response_sensitive(dialog, GTK_RESPONSE_YES, on);
576 gtk_dialog_set_response_sensitive(dialog, GTK_RESPONSE_NO, on);
578 if (on && !quiet)
579 gtk_dialog_set_response_sensitive(dialog, RESPONSE_QUIET, TRUE);
580 else
581 gtk_dialog_set_response_sensitive(dialog,
582 RESPONSE_QUIET, FALSE);
584 /* Unsetting the focus means that set_default will put it in the
585 * right place...
587 gtk_window_set_focus(GTK_WINDOW(abox), NULL);
588 /* Note: Gtk+-2.0.0 will segfault on Return if an insensitive
589 * widget is the default.
591 if (quiet)
592 gtk_dialog_set_default_response(dialog, GTK_RESPONSE_YES);
593 else
594 gtk_dialog_set_default_response(dialog, RESPONSE_QUIET);
596 if (abox->entry)
598 gtk_widget_set_sensitive(abox->entry, on);
599 if (on)
600 gtk_widget_grab_focus(abox->entry);
604 static gboolean abox_delete(GtkWidget *dialog, GdkEventAny *event)
606 g_signal_emit_by_name(dialog, "abort_operation");
607 return TRUE;
610 void abox_show_compare(ABox *abox, gboolean show)
612 if (show)
613 gtk_widget_show(abox->cmp_area);
614 else
615 gtk_widget_hide(abox->cmp_area);
618 void abox_set_file(ABox *abox, int i, const gchar *path)
620 DirItem *item;
621 gchar *base;
623 g_return_if_fail(i >= 0 && i < 2);
624 g_return_if_fail(IS_ABOX(abox));
626 if (!path || !path[0])
628 gtk_widget_hide(abox->cmp_icon[i]);
629 gtk_widget_hide(abox->cmp_name[i]);
630 gtk_widget_hide(abox->cmp_size[i]);
631 gtk_widget_hide(abox->cmp_date[i]);
632 gtk_widget_hide(abox->cmp_arrow);
633 return;
636 base = g_path_get_basename(path);
637 item = diritem_new(base);
638 g_free(base);
639 diritem_restat(path, item, NULL);
641 gtk_image_set_from_pixbuf(GTK_IMAGE(abox->cmp_icon[i]),
642 di_image(item)->pixbuf);
643 gtk_widget_show(abox->cmp_icon[i]);
645 gtk_label_set_text(GTK_LABEL(abox->cmp_name[i]), item->leafname);
646 gtk_widget_show(abox->cmp_name[i]);
647 gtk_widget_show(abox->cmp_arrow);
649 if (item->lstat_errno)
651 gtk_label_set_text(GTK_LABEL(abox->cmp_size[i]), "Error");
652 gtk_label_set_text(GTK_LABEL(abox->cmp_date[i]),
653 g_strerror(item->lstat_errno));
655 else
657 gchar *str;
659 gtk_label_set_text(GTK_LABEL(abox->cmp_size[i]),
660 format_size_aligned(item->size));
662 str = pretty_time(&item->mtime);
663 gtk_label_set_text(GTK_LABEL(abox->cmp_date[i]), str);
664 g_free(str);
667 gtk_widget_show(abox->cmp_size[i]);
668 gtk_widget_show(abox->cmp_date[i]);
670 diritem_free(item);
673 void abox_set_percentage(ABox *abox, int per)
675 if(!abox->progress) {
676 GtkDialog *dialog = GTK_DIALOG(abox);
678 abox->progress=gtk_progress_bar_new ();
679 gtk_box_pack_start(GTK_BOX(dialog->vbox),
680 abox->progress, FALSE, FALSE, 2);
681 gtk_widget_show(abox->progress);
683 gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(abox->progress),
684 per/100.);