Don't use "cp -u" in build script; doesn't work on FreeBSD
[rox-filer.git] / ROX-Filer / src / abox.c
blobee59c45dc3ee35207ef591b30bb0fdac546f6ee5
1 /*
2 * ROX-Filer, filer for the ROX desktop project
3 * Copyright (C) 2006, Thomas Leonard and others (see changelog for details).
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License as published by the Free
7 * Software Foundation; either version 2 of the License, or (at your option)
8 * any later version.
10 * This program is distributed in the hope that it will be useful, but WITHOUT
11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
13 * more details.
15 * You should have received a copy of the GNU General Public License along with
16 * this program; if not, write to the Free Software Foundation, Inc., 59 Temple
17 * Place, Suite 330, Boston, MA 02111-1307 USA
20 /* abox.c - the dialog box widget used for filer operations.
22 * The actual code for specific operations is in action.c.
25 #include "config.h"
27 #include <string.h>
29 #include "global.h"
31 #include "main.h"
32 #include "abox.h"
33 #include "gui_support.h"
34 #include "filer.h"
35 #include "display.h"
36 #include "support.h"
37 #include "diritem.h"
38 #include "pixmaps.h"
40 #define RESPONSE_QUIET 1
42 /* Static prototypes */
43 static void abox_class_init(GObjectClass *gclass, gpointer data);
44 static void abox_init(GTypeInstance *object, gpointer gclass);
45 static gboolean abox_delete(GtkWidget *dialog, GdkEventAny *event);
46 static void response(GtkDialog *dialog, gint response_id);
47 static void abox_finalise(GObject *object);
48 static void shade(ABox *abox);
50 GType abox_get_type(void)
52 static GType type = 0;
54 if (!type)
56 static const GTypeInfo info =
58 sizeof (ABoxClass),
59 NULL, /* base_init */
60 NULL, /* base_finalise */
61 (GClassInitFunc) abox_class_init,
62 NULL, /* class_finalise */
63 NULL, /* class_data */
64 sizeof(ABox),
65 0, /* n_preallocs */
66 (GInstanceInitFunc) abox_init
69 type = g_type_register_static(GTK_TYPE_DIALOG,
70 "ABox", &info, 0);
73 return type;
76 GtkWidget* abox_new(const gchar *title, gboolean quiet)
78 GtkWidget *widget;
79 ABox *abox;
81 widget = GTK_WIDGET(gtk_widget_new(abox_get_type(), NULL));
82 abox = (ABox *) widget;
84 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(abox->quiet), quiet);
86 gtk_window_set_title(GTK_WINDOW(widget), title);
87 gtk_dialog_set_has_separator(GTK_DIALOG(widget), FALSE);
89 return widget;
92 static void abox_class_init(GObjectClass *gclass, gpointer data)
94 GtkWidgetClass *widget = (GtkWidgetClass *) gclass;
95 GtkDialogClass *dialog = (GtkDialogClass *) gclass;
96 ABoxClass *abox = (ABoxClass *) gclass;
98 widget->delete_event = abox_delete;
99 dialog->response = response;
100 abox->flag_toggled = NULL;
101 abox->abort_operation = NULL;
103 g_signal_new("flag_toggled", G_TYPE_FROM_CLASS(gclass),
104 G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET(ABoxClass, flag_toggled),
105 NULL, NULL, g_cclosure_marshal_VOID__INT,
106 G_TYPE_NONE, 1, G_TYPE_INT);
108 g_signal_new("abort_operation", G_TYPE_FROM_CLASS(gclass),
109 G_SIGNAL_RUN_LAST, G_STRUCT_OFFSET(ABoxClass, abort_operation),
110 NULL, NULL, g_cclosure_marshal_VOID__VOID,
111 G_TYPE_NONE, 0);
113 gclass->finalize = abox_finalise;
116 static void abox_init(GTypeInstance *object, gpointer gclass)
118 GtkWidget *frame, *text, *scrollbar, *button;
119 ABox *abox = ABOX(object);
120 GtkDialog *dialog = GTK_DIALOG(object);
121 int i;
123 gtk_window_set_position(GTK_WINDOW(dialog), GTK_WIN_POS_MOUSE);
125 abox->dir_label = gtk_label_new(_("<dir>"));
126 gtk_widget_set_size_request(abox->dir_label, 8, -1);
127 abox->results = NULL;
128 abox->entry = NULL;
129 abox->next_dir = NULL;
130 abox->next_timer = 0;
131 abox->question = FALSE;
132 gtk_misc_set_alignment(GTK_MISC(abox->dir_label), 0.5, 0.5);
133 gtk_box_pack_start(GTK_BOX(dialog->vbox),
134 abox->dir_label, FALSE, TRUE, 0);
136 abox->log_hbox = gtk_hbox_new(FALSE, 0);
137 gtk_box_pack_start(GTK_BOX(dialog->vbox),
138 abox->log_hbox, TRUE, TRUE, 4);
140 frame = gtk_frame_new(NULL);
141 gtk_box_pack_start_defaults(GTK_BOX(abox->log_hbox), frame);
143 text = gtk_text_view_new();
144 gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_IN);
145 gtk_container_add(GTK_CONTAINER(frame), text);
147 gtk_text_view_set_wrap_mode(GTK_TEXT_VIEW(text), GTK_WRAP_WORD);
148 abox->log = text;
150 scrollbar = gtk_vscrollbar_new(NULL);
151 gtk_widget_set_scroll_adjustments(text, NULL,
152 gtk_range_get_adjustment(GTK_RANGE(scrollbar)));
153 gtk_text_buffer_create_tag(
154 gtk_text_view_get_buffer(GTK_TEXT_VIEW(abox->log)),
155 "error", "foreground", "red",
156 NULL);
157 gtk_text_buffer_create_tag(
158 gtk_text_view_get_buffer(GTK_TEXT_VIEW(abox->log)),
159 "question", "weight", "bold",
160 NULL);
161 gtk_text_view_set_editable(GTK_TEXT_VIEW(text), FALSE);
162 gtk_text_view_set_cursor_visible(GTK_TEXT_VIEW(text), FALSE);
163 gtk_widget_set_size_request(text, 400, 100);
165 gtk_box_pack_start(GTK_BOX(abox->log_hbox), scrollbar, FALSE, TRUE, 0);
167 gtk_dialog_add_buttons(dialog,
168 GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
169 GTK_STOCK_NO, GTK_RESPONSE_NO,
170 GTK_STOCK_YES, GTK_RESPONSE_YES,
171 NULL);
173 abox->cmp_area = gtk_table_new(2, 6, FALSE);
174 gtk_box_pack_start(GTK_BOX(dialog->vbox),
175 abox->cmp_area, FALSE, FALSE, 2);
176 gtk_table_set_row_spacings(GTK_TABLE(abox->cmp_area), 2);
177 gtk_table_set_col_spacings(GTK_TABLE(abox->cmp_area), 2);
179 for (i = 0; i < 2; i++)
182 abox->cmp_icon[i] = gtk_image_new();
183 gtk_table_attach(GTK_TABLE(abox->cmp_area),
184 abox->cmp_icon[i],
185 1, 2, i, i + 1,
186 GTK_SHRINK, GTK_SHRINK, 4, 1);
187 abox->cmp_name[i] = gtk_label_new("");
188 gtk_label_set_line_wrap(GTK_LABEL(abox->cmp_name[i]), TRUE);
189 gtk_misc_set_alignment(GTK_MISC(abox->cmp_name[i]), 0., 0.5);
190 gtk_table_attach(GTK_TABLE(abox->cmp_area),
191 abox->cmp_name[i],
192 2, 3, i, i + 1,
193 GTK_EXPAND | GTK_FILL, GTK_SHRINK, 4, 1);
194 abox->cmp_size[i] = gtk_label_new("");
195 gtk_table_attach(GTK_TABLE(abox->cmp_area),
196 abox->cmp_size[i],
197 3, 4, i, i + 1,
198 GTK_SHRINK, GTK_SHRINK, 4, 1);
199 abox->cmp_date[i] = gtk_label_new("");
200 gtk_table_attach(GTK_TABLE(abox->cmp_area),
201 abox->cmp_date[i],
202 4, 5, i, i + 1,
203 GTK_SHRINK, GTK_SHRINK, 4, 1);
205 abox->cmp_arrow=gtk_arrow_new(GTK_ARROW_DOWN, GTK_SHADOW_IN);
206 gtk_widget_set_size_request(abox->cmp_arrow, 32, 64);
207 gtk_table_attach(GTK_TABLE(abox->cmp_area),
208 abox->cmp_arrow,
209 0, 1, 0, 2,
210 GTK_SHRINK, GTK_EXPAND | GTK_FILL, 1, 2);
212 abox->progress=NULL;
214 abox->flag_box = gtk_hbox_new(FALSE, 16);
215 gtk_box_pack_end(GTK_BOX(dialog->vbox),
216 abox->flag_box, FALSE, TRUE, 2);
218 button = button_new_mixed(GTK_STOCK_GOTO_LAST, _("_Quiet"));
219 GTK_WIDGET_SET_FLAGS(button, GTK_CAN_DEFAULT);
220 gtk_dialog_add_action_widget(dialog, button, RESPONSE_QUIET);
221 gtk_dialog_set_default_response(dialog, RESPONSE_QUIET);
223 gtk_widget_show_all(dialog->vbox);
224 gtk_widget_hide(abox->cmp_area);
226 abox->quiet = abox_add_flag(abox,
227 _("Quiet"), _("Don't confirm every operation"),
228 'Q', FALSE);
230 shade(abox);
233 static void flag_toggled(GtkToggleButton *toggle, ABox *abox)
235 gint code;
237 code = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(toggle),
238 "abox-response"));
239 if (code == 'Q')
240 shade(abox);
242 g_signal_emit_by_name(abox, "flag_toggled", code);
246 GtkWidget *abox_add_flag(ABox *abox, const gchar *label, const gchar *tip,
247 gint response, gboolean default_value)
249 GtkWidget *check;
251 check = gtk_check_button_new_with_label(label);
252 gtk_tooltips_set_tip(tooltips, check, tip, NULL);
253 g_object_set_data(G_OBJECT(check), "abox-response",
254 GINT_TO_POINTER(response));
255 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check), default_value);
256 g_signal_connect(check, "toggled", G_CALLBACK(flag_toggled), abox);
257 gtk_box_pack_end(GTK_BOX(abox->flag_box), check, FALSE, TRUE, 0);
258 gtk_widget_show(check);
260 return check;
263 static void response(GtkDialog *dialog, gint response_id)
265 ABox *abox = ABOX(dialog);
267 if (response_id == GTK_RESPONSE_CANCEL)
268 g_signal_emit_by_name(abox, "abort_operation");
269 else if (response_id == RESPONSE_QUIET)
271 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(abox->quiet),
272 TRUE);
273 gtk_dialog_response(dialog, GTK_RESPONSE_YES);
275 else if (response_id == GTK_RESPONSE_YES ||
276 response_id == GTK_RESPONSE_NO)
278 abox->question = FALSE;
279 shade(abox);
283 /* Display the question. Unshade the Yes, No and entry box (if any).
284 * Will send a response signal when the user makes a choice.
286 void abox_ask(ABox *abox, const gchar *question)
288 g_return_if_fail(abox != NULL);
289 g_return_if_fail(question != NULL);
290 g_return_if_fail(IS_ABOX(abox));
292 abox_log(abox, question, "question");
294 abox->question = TRUE;
295 shade(abox);
298 void abox_cancel_ask(ABox *abox)
300 g_return_if_fail(abox != NULL);
301 g_return_if_fail(IS_ABOX(abox));
303 abox->question = FALSE;
304 shade(abox);
307 void abox_log(ABox *abox, const gchar *message, const gchar *style)
309 GtkTextIter end;
310 GtkTextBuffer *text_buffer;
311 GtkTextView *log = GTK_TEXT_VIEW(abox->log);
312 gchar *u8 = NULL;
314 if (!g_utf8_validate(message, -1, NULL))
315 u8 = to_utf8(message);
317 text_buffer = gtk_text_view_get_buffer(log);
319 gtk_text_buffer_get_end_iter(text_buffer, &end);
320 gtk_text_buffer_insert_with_tags_by_name(text_buffer,
321 &end, u8 ? u8 : message, -1, style, NULL);
322 gtk_text_view_scroll_to_mark(
323 log,
324 gtk_text_buffer_get_mark(text_buffer, "insert"),
325 0.0, FALSE, 0, 0);
327 g_free(u8);
330 static void abox_finalise(GObject *object)
332 GObjectClass *parent_class;
333 ABox *abox = ABOX(object);
335 if (abox->next_dir)
337 null_g_free(&abox->next_dir);
338 g_source_remove(abox->next_timer);
341 parent_class = gtk_type_class(GTK_TYPE_DIALOG);
343 if (G_OBJECT_CLASS(parent_class)->finalize)
344 (*G_OBJECT_CLASS(parent_class)->finalize)(object);
347 static gboolean show_next_dir(gpointer data)
349 ABox *abox = (ABox *) data;
351 g_return_val_if_fail(IS_ABOX(abox), FALSE);
353 gtk_label_set_text(GTK_LABEL(abox->dir_label), abox->next_dir);
354 null_g_free(&abox->next_dir);
356 return FALSE;
359 /* Display this message in the current-object area.
360 * The display won't update too fast, even if you call this very often.
362 void abox_set_current_object(ABox *abox, const gchar *message)
364 g_return_if_fail(abox != NULL);
365 g_return_if_fail(message != NULL);
366 g_return_if_fail(IS_ABOX(abox));
368 /* If a string is already set then replace it, but assume the
369 * timer is already running...
372 if (abox->next_dir)
373 g_free(abox->next_dir);
374 else
376 gtk_label_set_text(GTK_LABEL(abox->dir_label), message);
377 abox->next_timer = g_timeout_add(500, show_next_dir, abox);
380 abox->next_dir = g_strdup(message);
383 static void lost_preview(GtkWidget *window, ABox *abox)
385 abox->preview = NULL;
388 static void select_row_callback(GtkTreeView *treeview,
389 GtkTreePath *path,
390 GtkTreeViewColumn *col,
391 ABox *abox)
393 GtkTreeModel *model;
394 GtkTreeIter iter;
395 char *leaf, *dir;
397 model = gtk_tree_view_get_model(GTK_TREE_VIEW(abox->results));
398 gtk_tree_model_get_iter(model, &iter, path);
399 gtk_tree_model_get(model, &iter, 0, &leaf, 1, &dir, -1);
401 if (abox->preview)
403 if (strcmp(abox->preview->real_path, dir) == 0)
404 display_set_autoselect(abox->preview, leaf);
405 else
406 filer_change_to(abox->preview, dir, leaf);
407 goto out;
410 abox->preview = filer_opendir(dir, NULL, NULL);
411 if (abox->preview)
413 display_set_autoselect(abox->preview, leaf);
414 g_signal_connect_object(abox->preview->window, "destroy",
415 G_CALLBACK(lost_preview), abox, 0);
418 out:
419 g_free(dir);
420 g_free(leaf);
423 /* Add a list-of-results area. You must use this before adding files
424 * with abox_add_filename().
426 void abox_add_results(ABox *abox)
428 GtkTreeViewColumn *column;
429 GtkWidget *scroller, *frame;
430 GtkListStore *model;
431 GtkCellRenderer *cell_renderer;
433 g_return_if_fail(abox != NULL);
434 g_return_if_fail(IS_ABOX(abox));
435 g_return_if_fail(abox->results == NULL);
437 scroller = gtk_scrolled_window_new(NULL, NULL);
438 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroller),
439 GTK_POLICY_NEVER, GTK_POLICY_ALWAYS);
441 frame = gtk_frame_new(NULL);
442 gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_IN);
443 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(abox)->vbox),
444 frame, TRUE, TRUE, 4);
446 gtk_container_add(GTK_CONTAINER(frame), scroller);
448 model = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_STRING);
449 abox->results = gtk_tree_view_new_with_model(GTK_TREE_MODEL(model));
450 g_object_unref(G_OBJECT(model));
452 cell_renderer = gtk_cell_renderer_text_new();
453 column = gtk_tree_view_column_new_with_attributes(
454 _("Name"), cell_renderer, "text", 0, NULL);
455 gtk_tree_view_column_set_resizable(column, TRUE);
456 gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_GROW_ONLY);
457 gtk_tree_view_append_column(GTK_TREE_VIEW(abox->results), column);
458 gtk_tree_view_insert_column_with_attributes(
459 GTK_TREE_VIEW(abox->results),
460 1, (gchar *) _("Directory"), cell_renderer,
461 "text", 1, NULL);
463 gtk_container_add(GTK_CONTAINER(scroller), abox->results);
465 gtk_widget_set_size_request(abox->results, 100, 100);
466 gtk_box_set_child_packing(GTK_BOX(GTK_DIALOG(abox)->vbox),
467 abox->log_hbox, FALSE, TRUE, 4, GTK_PACK_START);
469 g_signal_connect(abox->results, "row-activated",
470 G_CALLBACK(select_row_callback), abox);
472 gtk_widget_show_all(frame);
475 void abox_add_filename(ABox *abox, const gchar *path)
477 GtkTreeModel *model;
478 GtkTreeIter iter;
479 gchar *dir;
481 model = gtk_tree_view_get_model(GTK_TREE_VIEW(abox->results));
483 gtk_list_store_append(GTK_LIST_STORE(model), &iter);
485 dir = g_path_get_dirname(path);
486 gtk_list_store_set(GTK_LIST_STORE(model), &iter,
487 0, g_basename(path),
488 1, dir, -1);
489 g_free(dir);
492 /* Clear search results area */
493 void abox_clear_results(ABox *abox)
495 GtkTreeModel *model;
497 g_return_if_fail(abox != NULL);
498 g_return_if_fail(IS_ABOX(abox));
500 model = gtk_tree_view_get_model(GTK_TREE_VIEW(abox->results));
502 gtk_list_store_clear(GTK_LIST_STORE(model));
505 void abox_add_combo(ABox *abox, const gchar *tlabel, GList *presets,
506 const gchar *text, GtkWidget *help_button)
508 GtkWidget *hbox, *label, *combo;
510 g_return_if_fail(abox != NULL);
511 g_return_if_fail(IS_ABOX(abox));
512 g_return_if_fail(abox->entry == NULL);
514 hbox = gtk_hbox_new(FALSE, 0);
515 if (tlabel)
517 label = gtk_label_new(tlabel);
518 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, TRUE, 4);
521 combo = gtk_combo_new();
522 gtk_combo_disable_activate(GTK_COMBO(combo));
523 gtk_combo_set_use_arrows_always(GTK_COMBO(combo), TRUE);
524 gtk_combo_set_popdown_strings(GTK_COMBO(combo), presets);
525 abox->entry = GTK_COMBO(combo)->entry;
526 gtk_entry_set_activates_default(GTK_ENTRY(abox->entry), TRUE);
528 gtk_entry_set_text(GTK_ENTRY(abox->entry), text);
529 gtk_box_pack_start(GTK_BOX(hbox), combo, TRUE, TRUE, 4);
531 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(abox)->vbox), hbox,
532 FALSE, TRUE, 0);
533 gtk_box_pack_start(GTK_BOX(hbox), help_button, FALSE, TRUE, 4);
535 gtk_widget_show_all(hbox);
537 shade(abox);
540 void abox_add_entry(ABox *abox, const gchar *text, GtkWidget *help_button)
542 GtkWidget *hbox, *label;
544 g_return_if_fail(abox != NULL);
545 g_return_if_fail(IS_ABOX(abox));
546 g_return_if_fail(abox->entry == NULL);
548 hbox = gtk_hbox_new(FALSE, 0);
549 label = gtk_label_new(_("Expression:"));
550 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, TRUE, 4);
551 abox->entry = gtk_entry_new();
552 gtk_widget_set_name(abox->entry, "fixed-style");
553 gtk_entry_set_text(GTK_ENTRY(abox->entry), text);
554 gtk_box_pack_start(GTK_BOX(hbox), abox->entry, TRUE, TRUE, 4);
555 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(abox)->vbox),
556 hbox, FALSE, TRUE, 4);
557 gtk_box_pack_start(GTK_BOX(hbox), help_button,
558 FALSE, TRUE, 4);
560 gtk_entry_set_activates_default(GTK_ENTRY(abox->entry), TRUE);
562 gtk_widget_show_all(hbox);
564 shade(abox);
567 static void shade(ABox *abox)
569 GtkDialog *dialog = (GtkDialog *) abox;
570 gboolean quiet, on = abox->question;
572 quiet = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(abox->quiet));
574 gtk_dialog_set_response_sensitive(dialog, GTK_RESPONSE_YES, on);
575 gtk_dialog_set_response_sensitive(dialog, GTK_RESPONSE_NO, on);
577 if (on && !quiet)
578 gtk_dialog_set_response_sensitive(dialog, RESPONSE_QUIET, TRUE);
579 else
580 gtk_dialog_set_response_sensitive(dialog,
581 RESPONSE_QUIET, FALSE);
583 /* Unsetting the focus means that set_default will put it in the
584 * right place...
586 gtk_window_set_focus(GTK_WINDOW(abox), NULL);
587 /* Note: Gtk+-2.0.0 will segfault on Return if an insensitive
588 * widget is the default.
590 if (quiet)
591 gtk_dialog_set_default_response(dialog, GTK_RESPONSE_YES);
592 else
593 gtk_dialog_set_default_response(dialog, RESPONSE_QUIET);
595 if (abox->entry)
597 gtk_widget_set_sensitive(abox->entry, on);
598 if (on)
599 gtk_widget_grab_focus(abox->entry);
603 static gboolean abox_delete(GtkWidget *dialog, GdkEventAny *event)
605 g_signal_emit_by_name(dialog, "abort_operation");
606 return TRUE;
609 void abox_show_compare(ABox *abox, gboolean show)
611 if (show)
612 gtk_widget_show(abox->cmp_area);
613 else
614 gtk_widget_hide(abox->cmp_area);
617 void abox_set_file(ABox *abox, int i, const gchar *path)
619 DirItem *item;
620 gchar *base;
622 g_return_if_fail(i >= 0 && i < 2);
623 g_return_if_fail(IS_ABOX(abox));
625 if (!path || !path[0])
627 gtk_widget_hide(abox->cmp_icon[i]);
628 gtk_widget_hide(abox->cmp_name[i]);
629 gtk_widget_hide(abox->cmp_size[i]);
630 gtk_widget_hide(abox->cmp_date[i]);
631 gtk_widget_hide(abox->cmp_arrow);
632 return;
635 base = g_path_get_basename(path);
636 item = diritem_new(base);
637 g_free(base);
638 diritem_restat(path, item, NULL);
640 gtk_image_set_from_pixbuf(GTK_IMAGE(abox->cmp_icon[i]),
641 di_image(item)->pixbuf);
642 gtk_widget_show(abox->cmp_icon[i]);
644 gtk_label_set_text(GTK_LABEL(abox->cmp_name[i]), item->leafname);
645 gtk_widget_show(abox->cmp_name[i]);
646 gtk_widget_show(abox->cmp_arrow);
648 if (item->lstat_errno)
650 gtk_label_set_text(GTK_LABEL(abox->cmp_size[i]), "Error");
651 gtk_label_set_text(GTK_LABEL(abox->cmp_date[i]),
652 g_strerror(item->lstat_errno));
654 else
656 gchar *str;
658 gtk_label_set_text(GTK_LABEL(abox->cmp_size[i]),
659 format_size_aligned(item->size));
661 str = pretty_time(&item->mtime);
662 gtk_label_set_text(GTK_LABEL(abox->cmp_date[i]), str);
663 g_free(str);
666 gtk_widget_show(abox->cmp_size[i]);
667 gtk_widget_show(abox->cmp_date[i]);
669 diritem_free(item);
672 void abox_set_percentage(ABox *abox, int per)
674 if(!abox->progress) {
675 GtkDialog *dialog = GTK_DIALOG(abox);
677 abox->progress=gtk_progress_bar_new ();
678 gtk_box_pack_start(GTK_BOX(dialog->vbox),
679 abox->progress, FALSE, FALSE, 2);
680 gtk_widget_show(abox->progress);
682 if(per<0 || per>100) {
683 gtk_widget_hide(abox->progress);
684 return;
686 gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(abox->progress),
687 per/100.);