r4164: Allow some labels used to display file names to wrap over more than one line,
[rox-filer.git] / ROX-Filer / src / abox.c
blob4beb9e291409dab570e81efe3eb747d815f8b417
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_label_set_line_wrap(GTK_LABEL(abox->cmp_name[i]), TRUE);
191 gtk_misc_set_alignment(GTK_MISC(abox->cmp_name[i]), 0., 0.5);
192 gtk_table_attach(GTK_TABLE(abox->cmp_area),
193 abox->cmp_name[i],
194 2, 3, i, i + 1,
195 GTK_EXPAND | GTK_FILL, GTK_SHRINK, 4, 1);
196 abox->cmp_size[i] = gtk_label_new("");
197 gtk_table_attach(GTK_TABLE(abox->cmp_area),
198 abox->cmp_size[i],
199 3, 4, i, i + 1,
200 GTK_SHRINK, GTK_SHRINK, 4, 1);
201 abox->cmp_date[i] = gtk_label_new("");
202 gtk_table_attach(GTK_TABLE(abox->cmp_area),
203 abox->cmp_date[i],
204 4, 5, i, i + 1,
205 GTK_SHRINK, GTK_SHRINK, 4, 1);
207 abox->cmp_arrow=gtk_arrow_new(GTK_ARROW_DOWN, GTK_SHADOW_IN);
208 gtk_widget_set_size_request(abox->cmp_arrow, 32, 64);
209 gtk_table_attach(GTK_TABLE(abox->cmp_area),
210 abox->cmp_arrow,
211 0, 1, 0, 2,
212 GTK_SHRINK, GTK_EXPAND | GTK_FILL, 1, 2);
214 abox->progress=NULL;
216 abox->flag_box = gtk_hbox_new(FALSE, 16);
217 gtk_box_pack_end(GTK_BOX(dialog->vbox),
218 abox->flag_box, FALSE, TRUE, 2);
220 button = button_new_mixed(GTK_STOCK_GOTO_LAST, _("_Quiet"));
221 GTK_WIDGET_SET_FLAGS(button, GTK_CAN_DEFAULT);
222 gtk_dialog_add_action_widget(dialog, button, RESPONSE_QUIET);
223 gtk_dialog_set_default_response(dialog, RESPONSE_QUIET);
225 gtk_widget_show_all(dialog->vbox);
226 gtk_widget_hide(abox->cmp_area);
228 abox->quiet = abox_add_flag(abox,
229 _("Quiet"), _("Don't confirm every operation"),
230 'Q', FALSE);
232 shade(abox);
235 static void flag_toggled(GtkToggleButton *toggle, ABox *abox)
237 gint code;
239 code = GPOINTER_TO_INT(g_object_get_data(G_OBJECT(toggle),
240 "abox-response"));
241 if (code == 'Q')
242 shade(abox);
244 g_signal_emit_by_name(abox, "flag_toggled", code);
248 GtkWidget *abox_add_flag(ABox *abox, const gchar *label, const gchar *tip,
249 gint response, gboolean default_value)
251 GtkWidget *check;
253 check = gtk_check_button_new_with_label(label);
254 gtk_tooltips_set_tip(tooltips, check, tip, NULL);
255 g_object_set_data(G_OBJECT(check), "abox-response",
256 GINT_TO_POINTER(response));
257 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(check), default_value);
258 g_signal_connect(check, "toggled", G_CALLBACK(flag_toggled), abox);
259 gtk_box_pack_end(GTK_BOX(abox->flag_box), check, FALSE, TRUE, 0);
260 gtk_widget_show(check);
262 return check;
265 static void response(GtkDialog *dialog, gint response_id)
267 ABox *abox = ABOX(dialog);
269 if (response_id == GTK_RESPONSE_CANCEL)
270 g_signal_emit_by_name(abox, "abort_operation");
271 else if (response_id == RESPONSE_QUIET)
273 gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(abox->quiet),
274 TRUE);
275 gtk_dialog_response(dialog, GTK_RESPONSE_YES);
277 else if (response_id == GTK_RESPONSE_YES ||
278 response_id == GTK_RESPONSE_NO)
280 abox->question = FALSE;
281 shade(abox);
285 /* Display the question. Unshade the Yes, No and entry box (if any).
286 * Will send a response signal when the user makes a choice.
288 void abox_ask(ABox *abox, const gchar *question)
290 g_return_if_fail(abox != NULL);
291 g_return_if_fail(question != NULL);
292 g_return_if_fail(IS_ABOX(abox));
294 abox_log(abox, question, "question");
296 abox->question = TRUE;
297 shade(abox);
300 void abox_cancel_ask(ABox *abox)
302 g_return_if_fail(abox != NULL);
303 g_return_if_fail(IS_ABOX(abox));
305 abox->question = FALSE;
306 shade(abox);
309 void abox_log(ABox *abox, const gchar *message, const gchar *style)
311 GtkTextIter end;
312 GtkTextBuffer *text_buffer;
313 GtkTextView *log = GTK_TEXT_VIEW(abox->log);
314 gchar *u8 = NULL;
316 if (!g_utf8_validate(message, -1, NULL))
317 u8 = to_utf8(message);
319 text_buffer = gtk_text_view_get_buffer(log);
321 gtk_text_buffer_get_end_iter(text_buffer, &end);
322 gtk_text_buffer_insert_with_tags_by_name(text_buffer,
323 &end, u8 ? u8 : message, -1, style, NULL);
324 gtk_text_view_scroll_to_mark(
325 log,
326 gtk_text_buffer_get_mark(text_buffer, "insert"),
327 0.0, FALSE, 0, 0);
329 g_free(u8);
332 static void abox_finalise(GObject *object)
334 GObjectClass *parent_class;
335 ABox *abox = ABOX(object);
337 if (abox->next_dir)
339 null_g_free(&abox->next_dir);
340 g_source_remove(abox->next_timer);
343 parent_class = gtk_type_class(GTK_TYPE_DIALOG);
345 if (G_OBJECT_CLASS(parent_class)->finalize)
346 (*G_OBJECT_CLASS(parent_class)->finalize)(object);
349 static gboolean show_next_dir(gpointer data)
351 ABox *abox = (ABox *) data;
353 g_return_val_if_fail(IS_ABOX(abox), FALSE);
355 gtk_label_set_text(GTK_LABEL(abox->dir_label), abox->next_dir);
356 null_g_free(&abox->next_dir);
358 return FALSE;
361 /* Display this message in the current-object area.
362 * The display won't update too fast, even if you call this very often.
364 void abox_set_current_object(ABox *abox, const gchar *message)
366 g_return_if_fail(abox != NULL);
367 g_return_if_fail(message != NULL);
368 g_return_if_fail(IS_ABOX(abox));
370 /* If a string is already set then replace it, but assume the
371 * timer is already running...
374 if (abox->next_dir)
375 g_free(abox->next_dir);
376 else
378 gtk_label_set_text(GTK_LABEL(abox->dir_label), message);
379 abox->next_timer = g_timeout_add(500, show_next_dir, abox);
382 abox->next_dir = g_strdup(message);
385 static void lost_preview(GtkWidget *window, ABox *abox)
387 abox->preview = NULL;
390 static void select_row_callback(GtkTreeView *treeview,
391 GtkTreePath *path,
392 GtkTreeViewColumn *col,
393 ABox *abox)
395 GtkTreeModel *model;
396 GtkTreeIter iter;
397 char *leaf, *dir;
399 model = gtk_tree_view_get_model(GTK_TREE_VIEW(abox->results));
400 gtk_tree_model_get_iter(model, &iter, path);
401 gtk_tree_model_get(model, &iter, 0, &leaf, 1, &dir, -1);
403 if (abox->preview)
405 if (strcmp(abox->preview->real_path, dir) == 0)
406 display_set_autoselect(abox->preview, leaf);
407 else
408 filer_change_to(abox->preview, dir, leaf);
409 goto out;
412 abox->preview = filer_opendir(dir, NULL, NULL);
413 if (abox->preview)
415 display_set_autoselect(abox->preview, leaf);
416 g_signal_connect_object(abox->preview->window, "destroy",
417 G_CALLBACK(lost_preview), abox, 0);
420 out:
421 g_free(dir);
422 g_free(leaf);
425 /* Add a list-of-results area. You must use this before adding files
426 * with abox_add_filename().
428 void abox_add_results(ABox *abox)
430 GtkTreeViewColumn *column;
431 GtkWidget *scroller, *frame;
432 GtkListStore *model;
433 GtkCellRenderer *cell_renderer;
435 g_return_if_fail(abox != NULL);
436 g_return_if_fail(IS_ABOX(abox));
437 g_return_if_fail(abox->results == NULL);
439 scroller = gtk_scrolled_window_new(NULL, NULL);
440 gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroller),
441 GTK_POLICY_NEVER, GTK_POLICY_ALWAYS);
443 frame = gtk_frame_new(NULL);
444 gtk_frame_set_shadow_type(GTK_FRAME(frame), GTK_SHADOW_IN);
445 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(abox)->vbox),
446 frame, TRUE, TRUE, 4);
448 gtk_container_add(GTK_CONTAINER(frame), scroller);
450 model = gtk_list_store_new(2, G_TYPE_STRING, G_TYPE_STRING);
451 abox->results = gtk_tree_view_new_with_model(GTK_TREE_MODEL(model));
452 g_object_unref(G_OBJECT(model));
454 cell_renderer = gtk_cell_renderer_text_new();
455 column = gtk_tree_view_column_new_with_attributes(
456 _("Name"), cell_renderer, "text", 0, NULL);
457 gtk_tree_view_column_set_resizable(column, TRUE);
458 gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_GROW_ONLY);
459 gtk_tree_view_append_column(GTK_TREE_VIEW(abox->results), column);
460 gtk_tree_view_insert_column_with_attributes(
461 GTK_TREE_VIEW(abox->results),
462 1, (gchar *) _("Directory"), cell_renderer,
463 "text", 1, NULL);
465 gtk_container_add(GTK_CONTAINER(scroller), abox->results);
467 gtk_widget_set_size_request(abox->results, 100, 100);
468 gtk_box_set_child_packing(GTK_BOX(GTK_DIALOG(abox)->vbox),
469 abox->log_hbox, FALSE, TRUE, 4, GTK_PACK_START);
471 g_signal_connect(abox->results, "row-activated",
472 G_CALLBACK(select_row_callback), abox);
474 gtk_widget_show_all(frame);
477 void abox_add_filename(ABox *abox, const gchar *path)
479 GtkTreeModel *model;
480 GtkTreeIter iter;
481 gchar *dir;
483 model = gtk_tree_view_get_model(GTK_TREE_VIEW(abox->results));
485 gtk_list_store_append(GTK_LIST_STORE(model), &iter);
487 dir = g_path_get_dirname(path);
488 gtk_list_store_set(GTK_LIST_STORE(model), &iter,
489 0, g_basename(path),
490 1, dir, -1);
491 g_free(dir);
494 /* Clear search results area */
495 void abox_clear_results(ABox *abox)
497 GtkTreeModel *model;
499 g_return_if_fail(abox != NULL);
500 g_return_if_fail(IS_ABOX(abox));
502 model = gtk_tree_view_get_model(GTK_TREE_VIEW(abox->results));
504 gtk_list_store_clear(GTK_LIST_STORE(model));
507 void abox_add_combo(ABox *abox, const gchar *tlabel, GList *presets,
508 const gchar *text, GtkWidget *help_button)
510 GtkWidget *hbox, *label, *combo;
512 g_return_if_fail(abox != NULL);
513 g_return_if_fail(IS_ABOX(abox));
514 g_return_if_fail(abox->entry == NULL);
516 hbox = gtk_hbox_new(FALSE, 0);
517 if (tlabel)
519 label = gtk_label_new(tlabel);
520 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, TRUE, 4);
523 combo = gtk_combo_new();
524 gtk_combo_disable_activate(GTK_COMBO(combo));
525 gtk_combo_set_use_arrows_always(GTK_COMBO(combo), TRUE);
526 gtk_combo_set_popdown_strings(GTK_COMBO(combo), presets);
527 abox->entry = GTK_COMBO(combo)->entry;
528 gtk_entry_set_activates_default(GTK_ENTRY(abox->entry), TRUE);
530 gtk_entry_set_text(GTK_ENTRY(abox->entry), text);
531 gtk_box_pack_start(GTK_BOX(hbox), combo, TRUE, TRUE, 4);
533 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(abox)->vbox), hbox,
534 FALSE, TRUE, 0);
535 gtk_box_pack_start(GTK_BOX(hbox), help_button, FALSE, TRUE, 4);
537 gtk_widget_show_all(hbox);
539 shade(abox);
542 void abox_add_entry(ABox *abox, const gchar *text, GtkWidget *help_button)
544 GtkWidget *hbox, *label;
546 g_return_if_fail(abox != NULL);
547 g_return_if_fail(IS_ABOX(abox));
548 g_return_if_fail(abox->entry == NULL);
550 hbox = gtk_hbox_new(FALSE, 0);
551 label = gtk_label_new(_("Expression:"));
552 gtk_box_pack_start(GTK_BOX(hbox), label, FALSE, TRUE, 4);
553 abox->entry = gtk_entry_new();
554 gtk_widget_set_name(abox->entry, "fixed-style");
555 gtk_entry_set_text(GTK_ENTRY(abox->entry), text);
556 gtk_box_pack_start(GTK_BOX(hbox), abox->entry, TRUE, TRUE, 4);
557 gtk_box_pack_start(GTK_BOX(GTK_DIALOG(abox)->vbox),
558 hbox, FALSE, TRUE, 4);
559 gtk_box_pack_start(GTK_BOX(hbox), help_button,
560 FALSE, TRUE, 4);
562 gtk_entry_set_activates_default(GTK_ENTRY(abox->entry), TRUE);
564 gtk_widget_show_all(hbox);
566 shade(abox);
569 static void shade(ABox *abox)
571 GtkDialog *dialog = (GtkDialog *) abox;
572 gboolean quiet, on = abox->question;
574 quiet = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(abox->quiet));
576 gtk_dialog_set_response_sensitive(dialog, GTK_RESPONSE_YES, on);
577 gtk_dialog_set_response_sensitive(dialog, GTK_RESPONSE_NO, on);
579 if (on && !quiet)
580 gtk_dialog_set_response_sensitive(dialog, RESPONSE_QUIET, TRUE);
581 else
582 gtk_dialog_set_response_sensitive(dialog,
583 RESPONSE_QUIET, FALSE);
585 /* Unsetting the focus means that set_default will put it in the
586 * right place...
588 gtk_window_set_focus(GTK_WINDOW(abox), NULL);
589 /* Note: Gtk+-2.0.0 will segfault on Return if an insensitive
590 * widget is the default.
592 if (quiet)
593 gtk_dialog_set_default_response(dialog, GTK_RESPONSE_YES);
594 else
595 gtk_dialog_set_default_response(dialog, RESPONSE_QUIET);
597 if (abox->entry)
599 gtk_widget_set_sensitive(abox->entry, on);
600 if (on)
601 gtk_widget_grab_focus(abox->entry);
605 static gboolean abox_delete(GtkWidget *dialog, GdkEventAny *event)
607 g_signal_emit_by_name(dialog, "abort_operation");
608 return TRUE;
611 void abox_show_compare(ABox *abox, gboolean show)
613 if (show)
614 gtk_widget_show(abox->cmp_area);
615 else
616 gtk_widget_hide(abox->cmp_area);
619 void abox_set_file(ABox *abox, int i, const gchar *path)
621 DirItem *item;
622 gchar *base;
624 g_return_if_fail(i >= 0 && i < 2);
625 g_return_if_fail(IS_ABOX(abox));
627 if (!path || !path[0])
629 gtk_widget_hide(abox->cmp_icon[i]);
630 gtk_widget_hide(abox->cmp_name[i]);
631 gtk_widget_hide(abox->cmp_size[i]);
632 gtk_widget_hide(abox->cmp_date[i]);
633 gtk_widget_hide(abox->cmp_arrow);
634 return;
637 base = g_path_get_basename(path);
638 item = diritem_new(base);
639 g_free(base);
640 diritem_restat(path, item, NULL);
642 gtk_image_set_from_pixbuf(GTK_IMAGE(abox->cmp_icon[i]),
643 di_image(item)->pixbuf);
644 gtk_widget_show(abox->cmp_icon[i]);
646 gtk_label_set_text(GTK_LABEL(abox->cmp_name[i]), item->leafname);
647 gtk_widget_show(abox->cmp_name[i]);
648 gtk_widget_show(abox->cmp_arrow);
650 if (item->lstat_errno)
652 gtk_label_set_text(GTK_LABEL(abox->cmp_size[i]), "Error");
653 gtk_label_set_text(GTK_LABEL(abox->cmp_date[i]),
654 g_strerror(item->lstat_errno));
656 else
658 gchar *str;
660 gtk_label_set_text(GTK_LABEL(abox->cmp_size[i]),
661 format_size_aligned(item->size));
663 str = pretty_time(&item->mtime);
664 gtk_label_set_text(GTK_LABEL(abox->cmp_date[i]), str);
665 g_free(str);
668 gtk_widget_show(abox->cmp_size[i]);
669 gtk_widget_show(abox->cmp_date[i]);
671 diritem_free(item);
674 void abox_set_percentage(ABox *abox, int per)
676 if(!abox->progress) {
677 GtkDialog *dialog = GTK_DIALOG(abox);
679 abox->progress=gtk_progress_bar_new ();
680 gtk_box_pack_start(GTK_BOX(dialog->vbox),
681 abox->progress, FALSE, FALSE, 2);
682 gtk_widget_show(abox->progress);
684 if(per<0 || per>100) {
685 gtk_widget_hide(abox->progress);
686 return;
688 gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(abox->progress),
689 per/100.);