00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031 #include <gconf/gconf-client.h>
00032 #include <gtk/gtk.h>
00033 #include <gdk/gdkx.h>
00034
00035 #include <libergtk/ergtk.h>
00036 #include <liberutils/display_utils.h>
00037
00038 #include "ctb_log.h"
00039 #include "ctb_actions.h"
00040 #include "fileview.h"
00041 #include "filefind.h"
00042 #include "filetypes.h"
00043 #include "measures.h"
00044 #include "i18n.h"
00045 #include "ipc.h"
00046 #include "menu.h"
00047
00048 #define UNUSED(x) (void)(x)
00049
00050
00051
00052
00053
00054
00055 typedef int (*ctb_item_callback) ( const GString *directory,
00056 const filelist_entry_t *file_info );
00057
00058 typedef struct
00059 {
00060 const char *name;
00061 ctb_item_callback item_callback;
00062 } ctb_action_t;
00063
00064
00065
00066
00067
00068
00069 static const gchar *REGKEY_VIEWTYPE = "/apps/er/sys/ctb/viewtype";
00070 static const gchar *REGVAL_VIEWTYPE_ICON = "iconview";
00071 static const gchar *REGVAL_VIEWTYPE_LIST = "listview";
00072 static const gchar *REGVAL_VIEWTYPE_CONTENT = "listcontent";
00073 static const gchar *REGVAL_VIEWTYPE_AUTO = "auto-select";
00074
00075
00076
00077
00078
00079
00080 static GtkWidget *g_main_window = NULL;
00081 static GtkWidget *g_alphabar = NULL;
00082 static GtkWidget *g_background = NULL;
00083 static ctb_viewtypes_t g_current_view = -1;
00084 static GtkWidget *g_iconview = NULL;
00085 static GtkWidget *g_listview = NULL;
00086 static GtkWidget *g_eventbox = NULL;
00087 #if MACHINE_IS_DR1000S || MACHINE_IS_DR1000SW
00088 static GtkWidget *g_home_label = NULL;
00089 static GtkWidget *g_home_separator = NULL;
00090 static GtkWidget *g_home_eventbox = NULL;
00091 #endif
00092 static GtkWidget *g_title_label = NULL;
00093 static GtkWidget *g_subtitle_label = NULL;
00094 static GtkWidget *g_search_button = NULL;
00095 static GtkWidget *g_search_dialog = NULL;
00096 #if MACHINE_IS_DR1000S || MACHINE_IS_DR1000SW
00097 static GtkWidget *g_shortcut_button = NULL;
00098 #endif
00099
00100 static gboolean g_is_user_selected_view = FALSE;
00101 static ctb_viewmodes_t g_viewmode = BROWSE_MODE;
00102 static GtkTreeViewColumn *g_toggleColumn = NULL;
00103 static int g_handler_id = 0;
00104 static gboolean g_got_display_control = FALSE;
00105 static gboolean g_cursor_in_progress = FALSE;
00106 static gboolean g_operation_in_progress = FALSE;
00107 static int g_cursor_update_type = DM_HINT_FULL;
00108
00109 static int g_width = 0;
00110 static int g_height = 0;
00111
00112 typedef enum
00113 {
00114 INITIAL = 0,
00115 CONFIRM,
00116 } delete_state;
00117 static delete_state g_delete_state = -1;
00118
00119
00120 static const char* letters[FILEMODEL_NUM_ALPHA] = {"#", "A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"};
00121 static GtkWidget *g_labels[FILEMODEL_NUM_ALPHA];
00122 static int g_selected_letter = -1;
00123 static int g_last_clicked_index = -1;
00124
00125
00126
00127
00128
00129 static gchar* get_filename_at_cursor();
00130 static void set_cursor_at_filename(const gchar *cursor_item);
00131 static void set_cursor(gint row, gint column);
00132 static void setViewMode(ctb_viewmodes_t newmode, gboolean updateScreen);
00133 static void scroll_to_letter(gchar letter, gboolean jump_to_dir);
00134 static void alphabar_update();
00135 static void alphabar_select(int new_index);
00136 static void handle_activate_item();
00137
00138
00139
00140
00141
00142 static void listview_set_column_headers()
00143 {
00144
00145 if (g_current_view != CTB_LISTVIEW) return;
00146
00147 static const struct
00148 {
00149 const char *header;
00150 guint index;
00151 } column_headers[] =
00152 {
00153 { N_("Name"), 2 },
00154 { N_("Type"), 4 },
00155 { N_("Size"), 6 },
00156 { N_("Date Modified"), 8 },
00157 { NULL, 0 }
00158 };
00159
00160 int i;
00161 for (i = 0 ; column_headers[i].header ; i++)
00162 {
00163 GtkTreeViewColumn *column = gtk_tree_view_get_column( GTK_TREE_VIEW(g_listview), column_headers[i].index );
00164 if (column)
00165 {
00166 gtk_tree_view_column_set_title(column, _(column_headers[i].header));
00167 }
00168 }
00169 }
00170
00171
00172 static void update_titles()
00173 {
00174 #if MACHINE_IS_DR1000S || MACHINE_IS_DR1000SW
00175 gtk_label_set_text(GTK_LABEL(g_home_label), _("Home"));
00176 if (filemodel_current_is_desktop()) {
00177 gtk_widget_hide(g_home_eventbox);
00178 gtk_widget_hide(g_home_separator);
00179 } else {
00180 gtk_widget_show(g_home_eventbox);
00181 gtk_widget_show(g_home_separator);
00182 }
00183 #endif
00184 gtk_label_set_text(GTK_LABEL(g_title_label), filemodel_get_title());
00185 gtk_label_set_text(GTK_LABEL(g_subtitle_label), filemodel_get_subtitle());
00186 }
00187
00188
00189 static void update_gui()
00190 {
00191 g_last_clicked_index = -1;
00192 if (filemodel_has_searchbutton()) {
00193 gtk_widget_show(g_search_button);
00194 #if MACHINE_IS_DR1000S || MACHINE_IS_DR1000SW
00195 gtk_widget_show(g_shortcut_button);
00196 #endif
00197 } else {
00198 gtk_widget_hide(g_search_button);
00199 #if MACHINE_IS_DR1000S || MACHINE_IS_DR1000SW
00200 gtk_widget_hide(g_shortcut_button);
00201 #endif
00202 }
00203
00204 alphabar_update();
00205 update_titles();
00206 }
00207
00208
00209 void fileview_update_screen_texts()
00210 {
00211 listview_set_column_headers();
00212 fileview_refresh(TRUE);
00213 filemodel_set_delete_text(_("Finish Delete"));
00214 update_titles();
00215 }
00216
00217
00218 void fileview_grab_focus( void )
00219 {
00220 switch (g_current_view)
00221 {
00222 case CTB_ICONVIEW:
00223 gtk_widget_grab_focus(GTK_WIDGET(g_iconview));
00224 break;
00225 case CTB_LISTVIEW:
00226 case CTB_CONTENTVIEW:
00227 gtk_widget_grab_focus(GTK_WIDGET(g_listview));
00228 break;
00229 default:
00230 break;
00231 }
00232 }
00233
00234
00235 static void update_padding()
00236 {
00237 int left = WINDOW_H_PADDING;
00238 int right = WINDOW_H_PADDING;
00239
00240
00241 if (GTK_WIDGET_VISIBLE(g_alphabar)) right -= 20;
00242
00243
00244 switch (g_current_view) {
00245 case CTB_ICONVIEW:
00246 left += 20;
00247 if (!GTK_WIDGET_VISIBLE(g_alphabar)) left += 20;
00248 break;
00249 default:
00250 break;
00251 }
00252
00253 guint delta = (ipc_sys_is_in_portrait_mode()) ? 0 : 5;
00254 gtk_alignment_set_padding( GTK_ALIGNMENT(g_background),
00255 ( WINDOW_TOP_PADDING - delta),
00256 WINDOW_BOTTOM_PADDING,
00257 left, right);
00258 }
00259
00260
00261 void fileview_set_sort_order (const ctb_sort_order_t sort_order)
00262 {
00263 fileview_stop_update_display();
00264 gchar *cursor_item = get_filename_at_cursor();
00265
00266 gboolean order_has_changed = filemodel_set_sortorder( sort_order, cursor_item, TRUE);
00267 if (order_has_changed) {
00268 gtk_label_set_text(GTK_LABEL(g_subtitle_label), filemodel_get_subtitle());
00269 alphabar_update();
00270 }
00271 set_cursor_at_filename(cursor_item);
00272 g_free(cursor_item);
00273 }
00274
00275
00276 static void update_view_for_desktop()
00277 {
00278 if (g_current_view != CTB_CONTENTVIEW && g_current_view != CTB_ICONVIEW)
00279 {
00280 fileview_set_view_type(CTB_CONTENTVIEW, FALSE);
00281 }
00282 }
00283
00284
00285 void fileview_dir_up()
00286 {
00287 g_assert(g_viewmode == BROWSE_MODE);
00288 gchar* cursor_item = NULL;
00289
00290 if (filemodel_get_dir_depth() == 1)
00291 {
00292
00293 update_view_for_desktop();
00294 }
00295
00296 cursor_item = filemodel_chdir_up();
00297 update_gui();
00298
00299 if (cursor_item) {
00300 alphabar_select(filemodel_get_first_alpha_index());
00301 set_cursor_at_filename(cursor_item);
00302 g_free(cursor_item);
00303 } else
00304 ERRORPRINTF("no cursor set!");
00305 }
00306
00307
00308 void fileview_dir_down(const gchar *dir, const char* cursorname)
00309 {
00310 LOGPRINTF("dir=%s cursor=%s", dir, cursorname ? cursorname : "NULL");
00311 g_assert(g_viewmode == BROWSE_MODE);
00312
00313 filemodel_chdir_down(dir, cursorname);
00314
00315 update_gui();
00316 set_cursor(0, 0);
00317 }
00318
00319
00320 void fileview_show_desktop()
00321 {
00322 fileview_stop_update_display();
00323
00324 setViewMode(BROWSE_MODE, FALSE);
00325 update_view_for_desktop();
00326 filemodel_chdir_desktop();
00327
00328 update_gui();
00329 set_cursor(0, 0);
00330 }
00331
00332
00333 ctb_viewtypes_t get_viewtype_from_registry ( void )
00334 {
00335 LOGPRINTF("");
00336
00337
00338 GConfClient *client = gconf_client_get_default();
00339 gchar* val = gconf_client_get_string(client, REGKEY_VIEWTYPE, NULL);
00340 g_object_unref(client);
00341
00342
00343 ctb_viewtypes_t view = CTB_AUTOSELECT;
00344 if (val)
00345 {
00346 if ( strcmp(val, REGVAL_VIEWTYPE_ICON) == 0 )
00347 {
00348 view = CTB_ICONVIEW;
00349 }
00350 else if ( strcmp(val, REGVAL_VIEWTYPE_LIST) == 0 )
00351 {
00352 view = CTB_LISTVIEW;
00353 }
00354 else if ( strcmp(val, REGVAL_VIEWTYPE_CONTENT) == 0 )
00355 {
00356 view = CTB_CONTENTVIEW;
00357 }
00358 g_free(val);
00359 } else {
00360 WARNPRINTF("error fetching GConf key %s", REGKEY_VIEWTYPE);
00361 }
00362
00363
00364 if (view == CTB_AUTOSELECT)
00365 {
00366 const device_caps_t *dev_caps = ipc_sys_get_device_capabilities();
00367 g_assert(dev_caps);
00368 if (dev_caps->has_stylus)
00369 {
00370 view = CTB_ICONVIEW;
00371 }
00372 else
00373 {
00374 view = CTB_LISTVIEW;
00375 }
00376 }
00377
00378 return view;
00379 }
00380
00381
00382 void fileview_media_mounted (const gchar *mountpoint)
00383 {
00384 LOGPRINTF("entry: mountpoint [%s]", mountpoint);
00385 g_assert(mountpoint && *mountpoint);
00386
00387 ctb_viewtypes_t view = get_viewtype_from_registry();
00388 if (view != CTB_AUTOSELECT)
00389 {
00390 fileview_set_view_type(view, FALSE);
00391 g_is_user_selected_view = FALSE;
00392 }
00393
00394 fileview_show_desktop();
00395 }
00396
00397
00398 static void save_viewtype_to_registry ( ctb_viewtypes_t view )
00399 {
00400 GConfClient *client = NULL;
00401 gchar *val_old = NULL;
00402 const gchar *val_new = NULL;
00403 GError *err = NULL;
00404
00405 LOGPRINTF("entry");
00406
00407
00408 switch (view)
00409 {
00410 case CTB_ICONVIEW:
00411 val_new = REGVAL_VIEWTYPE_ICON;
00412 break;
00413 case CTB_LISTVIEW:
00414 val_new = REGVAL_VIEWTYPE_LIST;
00415 break;
00416 case CTB_CONTENTVIEW:
00417 val_new = REGVAL_VIEWTYPE_CONTENT;
00418 break;
00419 default:
00420 val_new = REGVAL_VIEWTYPE_AUTO;
00421 }
00422
00423
00424 client = gconf_client_get_default();
00425 val_old = gconf_client_get_string(client, REGKEY_VIEWTYPE, NULL);
00426 if ( val_old == NULL
00427 || strcmp(val_old, val_new) != 0 )
00428 {
00429 gboolean ok = gconf_client_set_string(client, REGKEY_VIEWTYPE, val_new, &err);
00430 if ( !ok )
00431 {
00432 ERRORPRINTF("cannot write registry key [%s] - error [%s]", REGKEY_VIEWTYPE, err->message);
00433 }
00434 g_clear_error(&err);
00435 }
00436 g_object_unref(client);
00437
00438 g_free(val_old);
00439 }
00440
00441
00442 void fileview_save_view_type()
00443 {
00444 if (g_is_user_selected_view)
00445 {
00446 save_viewtype_to_registry(g_current_view);
00447 g_is_user_selected_view = FALSE;
00448 }
00449 }
00450
00451
00452 void fileview_media_unmounted ()
00453 {
00454 fileview_save_view_type();
00455 if (g_search_dialog) {
00456 gtk_widget_destroy(g_search_dialog);
00457 g_search_dialog = NULL;
00458 }
00459 setViewMode(BROWSE_MODE, FALSE);
00460 filemodel_chdir_desktop();
00461 }
00462
00463
00464 static void get_cursor ( gint *row, gint *column )
00465 {
00466
00467 switch (g_current_view)
00468 {
00469 case CTB_ICONVIEW:
00470 g_assert(g_iconview);
00471 ergtk_icon_view_get_cursor( ERGTK_ICON_VIEW(g_iconview), row, column );
00472 break;
00473 case CTB_LISTVIEW:
00474 case CTB_CONTENTVIEW:
00475 g_assert(g_listview);
00476 ergtk_list_view_get_cursor( ERGTK_LIST_VIEW(g_listview), row);
00477 *column = 0;
00478 break;
00479 default:
00480 g_assert_not_reached();
00481 }
00482 }
00483
00484
00485 void fileview_stop_update_display()
00486 {
00487 LOGPRINTF("got_control=%d", g_got_display_control);
00488 if (!g_got_display_control) {
00489 g_got_display_control = TRUE;
00490 display_gain_control();
00491 }
00492 }
00493
00494
00495 static gboolean update_display(gpointer data)
00496 {
00497 LOGPRINTF("got_control=%d", g_got_display_control);
00498 if (g_got_display_control) {
00499 display_update_return_control((gint) data);
00500 g_got_display_control = FALSE;
00501 STOP_TIMER();
00502 }
00503 return FALSE;
00504 }
00505
00506
00507 static void on_idle_update_display(gint type)
00508 {
00509 if (g_got_display_control) {
00510 g_idle_add(update_display, (gpointer) type);
00511 }
00512 }
00513
00514
00515 static gboolean on_idle_set_cursor( gpointer data )
00516 {
00517 gulong row_col = (gulong)data;
00518 gint row = (row_col >> 8) & 0xFF;
00519 gint column = row_col & 0x00FF;
00520
00521
00522 switch (g_current_view)
00523 {
00524 case CTB_ICONVIEW:
00525 g_assert(g_iconview);
00526 ergtk_icon_view_set_cursor( ERGTK_ICON_VIEW(g_iconview), row, column );
00527 break;
00528 case CTB_LISTVIEW:
00529 case CTB_CONTENTVIEW:
00530 g_assert(g_listview);
00531 ergtk_list_view_set_cursor( ERGTK_LIST_VIEW(g_listview), row);
00532 break;
00533 default:
00534 g_assert_not_reached();
00535 }
00536 g_cursor_in_progress = FALSE;
00537 on_idle_update_display(g_cursor_update_type);
00538 g_cursor_update_type = DM_HINT_FULL;
00539 return FALSE;
00540 }
00541
00542
00543 static void set_cursor(gint row, gint column)
00544 {
00545 if (!g_cursor_in_progress) {
00546 gulong row_col = ((row & 0xFF) << 8) | (column & 0xFF);
00547
00548 g_idle_add(on_idle_set_cursor, (gpointer)row_col);
00549 g_cursor_in_progress = TRUE;
00550 g_operation_in_progress = FALSE;
00551 }
00552 }
00553
00554
00555 static int find_nearest_active(int index) {
00556 const gchar* list = filemodel_get_alpha_list();
00557 if (index >= 1 && list[index-1]) return index-1;
00558 if (index <= FILEMODEL_NUM_ALPHA-1 && list[index+1]) return index+1;
00559 return -1;
00560 }
00561
00562
00563 static gboolean on_letter_click(GtkWidget *widget, GdkEventButton *event, gpointer user_data)
00564 {
00565 UNUSED(widget);
00566 UNUSED(event);
00567 START_TIMER();
00568 const gchar* list = filemodel_get_alpha_list();
00569 int index = (int)user_data;
00570 if (list[index] == 0) {
00571 index = find_nearest_active(index);
00572 }
00573 if (index != -1) {
00574 fileview_stop_update_display();
00575 if (index != g_selected_letter) alphabar_select(index);
00576
00577
00578 gboolean jump_to_dir = TRUE;
00579 if (index == g_last_clicked_index) {
00580 jump_to_dir = FALSE;
00581 g_last_clicked_index = -1;
00582 } else {
00583 g_last_clicked_index = index;
00584 }
00585 scroll_to_letter(letters[index][0], jump_to_dir);
00586 }
00587 return FALSE;
00588 }
00589
00590
00591
00592 static void alphabar_update()
00593 {
00594 if (!filemodel_show_alphabar()) {
00595 gtk_widget_hide(g_alphabar);
00596 update_padding();
00597 return;
00598 } else {
00599 gtk_widget_show(g_alphabar);
00600 update_padding();
00601 }
00602
00603 const char* list = filemodel_get_alpha_list();
00604 int selected = -1;
00605 int i;
00606 for (i=0; i<FILEMODEL_NUM_ALPHA; i++) {
00607 if (list[i] == 0) {
00608 gtk_widget_set_name(g_labels[i], "irex-alphabar-label-inactive");
00609 } else {
00610
00611 if (selected == -1) selected = i;
00612 gtk_widget_set_name(g_labels[i], "irex-alphabar-label-active");
00613 }
00614 }
00615 if (selected != -1) {
00616 alphabar_select(selected);
00617 } else {
00618 alphabar_select(-1);
00619 }
00620 }
00621
00622
00623 static void alphabar_select(int new_index) {
00624 if (!GTK_WIDGET_VISIBLE(g_alphabar)) return;
00625 g_assert(new_index <= FILEMODEL_NUM_ALPHA);
00626
00627
00628 if (g_selected_letter != -1) {
00629 gtk_label_set_text(GTK_LABEL(g_labels[g_selected_letter]), letters[g_selected_letter]);
00630 g_selected_letter = -1;
00631 }
00632 if (new_index == -1) return;
00633
00634
00635 const char* list = filemodel_get_alpha_list();
00636 g_assert(list[new_index] != 0);
00637 g_selected_letter = new_index;
00638 char buffer[4];
00639 snprintf(buffer, sizeof(buffer), "-%s-", letters[g_selected_letter]);
00640 gtk_label_set_text(GTK_LABEL(g_labels[g_selected_letter]), buffer);
00641 }
00642
00643
00644 static GtkWidget *create_alpha_bar()
00645 {
00646 GtkWidget* vbox = gtk_vbox_new(TRUE, 0);
00647 g_alphabar = vbox;
00648 gtk_widget_set_size_request(vbox, 36, -1);
00649
00650 int i;
00651 for (i=0; i<FILEMODEL_NUM_ALPHA; i++) {
00652 GtkWidget* letterbox = gtk_event_box_new();
00653 gtk_box_pack_start(GTK_BOX(vbox), letterbox, TRUE, TRUE, 0);
00654 GtkWidget* label = gtk_label_new(letters[i]);
00655 gtk_misc_set_alignment(GTK_MISC(label), 0.5, 0.5);
00656 gtk_widget_set_name(label, "irex-alphabar-label-inactive");
00657 g_labels[i] = label;
00658 gtk_container_add(GTK_CONTAINER(letterbox), label);
00659 g_signal_connect(GTK_EVENT_BOX(letterbox), "button-press-event",
00660 G_CALLBACK(on_letter_click), (void*)i);
00661 }
00662 return vbox;
00663 }
00664
00665
00666 #if MACHINE_IS_DR1000S || MACHINE_IS_DR1000SW
00667 static gboolean on_shortcut_clicked (GtkWidget* button, GdkEventButton* event, gpointer data)
00668 {
00669 fileview_stop_update_display();
00670 if (!filemodel_current_is_desktop()) {
00671 filemodel_chdir_desktop();
00672 }
00673 filemodel_set_viewmode2(SHORTCUT_VIEW);
00674 char buffer[512];
00675 sprintf(buffer, "%s/%s", ipc_get_media(), DIR_SHORTCUTS);
00676 fileview_dir_down(buffer, SPECIAL_SHORTCUTS);
00677 return FALSE;
00678 }
00679 #endif
00680
00681
00682 static gboolean on_file_search_clicked (GtkWidget* button, GdkEventButton* event, gpointer data)
00683 {
00684 fileview_show_search_dialog();
00685 return FALSE;
00686 }
00687
00688
00689 #if MACHINE_IS_DR1000S || MACHINE_IS_DR1000SW
00690 static gboolean on_home_clicked (GtkWidget* button, GdkEventButton* event, gpointer data)
00691 {
00692 fileview_show_desktop();
00693 return FALSE;
00694 }
00695 #endif
00696
00697
00698 static GtkWidget* create_screen_layout()
00699 {
00700
00701
00702
00703 GtkWidget *background = gtk_alignment_new(0.0, 0.0, 1.0, 1.0);
00704
00705 guint delta = (ipc_sys_is_in_portrait_mode()) ? 0 : 5;
00706 gtk_alignment_set_padding( GTK_ALIGNMENT(background),
00707 (WINDOW_TOP_PADDING - delta),
00708 WINDOW_BOTTOM_PADDING,
00709 WINDOW_H_PADDING,
00710 WINDOW_H_PADDING );
00711 g_background = background;
00712 gtk_widget_show(background);
00713
00714
00715
00716 GtkWidget *widget = gtk_vbox_new(FALSE, 0);
00717 gtk_container_add(GTK_CONTAINER(background), widget);
00718 gtk_widget_show(widget);
00719 GtkBox *vbox = GTK_BOX(widget);
00720
00721
00722
00723 widget = gtk_hbox_new(FALSE, TITLE_SPACING);
00724 gtk_box_pack_start(vbox, widget, FALSE, FALSE, TITLE_V_PADDING);
00725 gtk_widget_set_size_request(widget, -1, TITLE_HEIGHT);
00726 GtkBox *hbox = GTK_BOX(widget);
00727 #if MACHINE_IS_DR1000S || MACHINE_IS_DR1000SW
00728
00729
00730 GtkWidget* home_event_box = gtk_event_box_new();
00731 gtk_box_pack_start(hbox, home_event_box, FALSE, FALSE, 0);
00732 gtk_widget_set_events(home_event_box, GDK_BUTTON_PRESS_MASK);
00733 g_signal_connect(home_event_box, "button-press-event" , G_CALLBACK(on_home_clicked), NULL);
00734 gtk_widget_show(home_event_box);
00735 g_home_eventbox = home_event_box;
00736
00737
00738 GtkWidget* home_label = gtk_label_new(NULL);
00739 gtk_label_set_ellipsize(GTK_LABEL(home_label), PANGO_ELLIPSIZE_NONE);
00740 gtk_widget_set_name(home_label, "irex-ctb-title");
00741 gtk_container_add(GTK_CONTAINER(home_event_box), home_label);
00742 g_home_label = home_label;
00743
00744
00745 GtkWidget* home_separator = gtk_image_new_from_file(DATADIR"/pathbar-separator.png");
00746 gtk_widget_show(home_separator);
00747 gtk_box_pack_start(hbox, home_separator, FALSE, FALSE, 0);
00748 g_home_separator = home_separator;
00749 #endif
00750
00751
00752 GtkWidget* title_label = gtk_label_new(NULL);
00753 gtk_label_set_ellipsize(GTK_LABEL(title_label), PANGO_ELLIPSIZE_NONE);
00754 gtk_widget_set_name(title_label, "irex-ctb-title");
00755 gtk_box_pack_start(hbox, title_label, FALSE, FALSE, 0);
00756 g_title_label = title_label;
00757
00758
00759 GtkWidget* subtitle_label = gtk_label_new(NULL);
00760 gtk_label_set_ellipsize(GTK_LABEL(subtitle_label), PANGO_ELLIPSIZE_END);
00761 gtk_misc_set_alignment(GTK_MISC(subtitle_label), 0.0, 0.5);
00762 gtk_widget_set_name(subtitle_label, "irex-ctb-subtitle");
00763 gtk_box_pack_start(hbox, subtitle_label, TRUE, TRUE, 0);
00764 g_subtitle_label = subtitle_label;
00765
00766 char path[512];
00767 #if MACHINE_IS_DR1000S || MACHINE_IS_DR1000SW
00768
00769 GtkWidget* sc_event_box = gtk_event_box_new();
00770 gtk_box_pack_end(hbox, sc_event_box, FALSE, FALSE, 0);
00771 gtk_widget_show(sc_event_box);
00772 snprintf (path, 512, "%s/%s", DATADIR, "icon-shortcut-button.png");
00773 GtkWidget* sc_image = gtk_image_new_from_file( (gchar*) path );
00774 gtk_container_add(GTK_CONTAINER(sc_event_box), sc_image);
00775 gtk_widget_show(sc_image);
00776 gtk_widget_set_events(sc_event_box, GDK_BUTTON_PRESS_MASK);
00777 g_signal_connect( sc_event_box, "button-press-event" , G_CALLBACK(on_shortcut_clicked), NULL);
00778 g_shortcut_button = sc_event_box;
00779 #endif
00780
00781
00782 GtkWidget* ff_event_box = gtk_event_box_new();
00783 gtk_box_pack_end(hbox, ff_event_box, FALSE, FALSE, 0);
00784 gtk_widget_show(ff_event_box);
00785 snprintf (path, 512, "%s/%s", DATADIR, "icon-search-button.png");
00786 GtkWidget* search_image = gtk_image_new_from_file( (gchar*) path );
00787 gtk_container_add(GTK_CONTAINER(ff_event_box), search_image);
00788 gtk_widget_show(search_image);
00789 gtk_widget_set_events(ff_event_box, GDK_BUTTON_PRESS_MASK);
00790 g_signal_connect( ff_event_box, "button-press-event" , G_CALLBACK(on_file_search_clicked), NULL);
00791 g_search_button = ff_event_box;
00792
00793 gtk_widget_show_all(widget);
00794
00795
00796 GtkWidget* hbox2 = gtk_hbox_new(FALSE, 20);
00797 gtk_box_pack_start(vbox, hbox2, TRUE, TRUE, 0);
00798 gtk_widget_show(hbox2);
00799
00800
00801 widget = gtk_event_box_new();
00802 gtk_widget_show(widget);
00803 gtk_box_pack_start(GTK_BOX(hbox2), widget, TRUE, TRUE, 0);
00804 g_eventbox = widget;
00805
00806
00807 GtkWidget *alphabar = create_alpha_bar();
00808 gtk_box_pack_start(GTK_BOX(hbox2), alphabar, FALSE, FALSE, 0);
00809 gtk_widget_show_all(alphabar);
00810
00811 return background;
00812 }
00813
00814
00815 static void on_iconview_item_activated ( GtkIconView *iconview,
00816 GtkTreePath *path,
00817 gpointer user_data )
00818 {
00819 handle_activate_item();
00820 }
00821
00822
00823 static void fileview_page_previous(int new_row, int new_col) {
00824 fileview_stop_update_display();
00825 filemodel_page_previous();
00826 alphabar_select(filemodel_get_first_alpha_index());
00827 set_cursor(new_row, new_col);
00828 }
00829
00830
00831 static void fileview_page_next(int new_row, int new_col) {
00832 fileview_stop_update_display();
00833 filemodel_page_next();
00834 alphabar_select(filemodel_get_first_alpha_index());
00835 set_cursor(new_row, new_col);
00836 }
00837
00838
00839 static void on_iconview_navigate_cursor ( erGtkIconView *er_iconview,
00840 erGtkIconViewKeyPress keycode,
00841 gpointer user_data )
00842 {
00843
00844 gint old_row;
00845 gint old_col;
00846 gint num_rows;
00847 gint num_cols;
00848 gint num_items;
00849
00850
00851 gboolean prev_page = FALSE;
00852 gboolean next_page = FALSE;
00853 gint new_row = 0;
00854 gint new_col = 0;
00855
00856 LOGPRINTF("entry: keycode [%d]", keycode);
00857
00858
00859 ergtk_icon_view_get_cursor(er_iconview, &old_row, &old_col);
00860 ergtk_icon_view_get_view_size(er_iconview, &num_rows, &num_cols, &num_items);
00861
00862
00863 switch (keycode)
00864 {
00865 case ERGTK_ICON_VIEW_PRESS_SHORT_UP:
00866
00867 prev_page = TRUE;
00868 new_row = num_rows - 1;
00869 new_col = old_col;
00870 break;
00871
00872 case ERGTK_ICON_VIEW_PRESS_SHORT_DOWN:
00873
00874 next_page = TRUE;
00875 new_row = 0;
00876 new_col = old_col;
00877 break;
00878
00879 case ERGTK_ICON_VIEW_PRESS_SHORT_LEFT:
00880
00881 prev_page = TRUE;
00882 new_row = num_rows - 1;
00883 new_col = num_cols - 1;
00884 break;
00885
00886 case ERGTK_ICON_VIEW_PRESS_SHORT_RIGHT:
00887
00888 next_page = TRUE;
00889 new_row = 0;
00890 new_col = 0;
00891 break;
00892
00893 case ERGTK_ICON_VIEW_PRESS_LONG_UP:
00894
00895 prev_page = TRUE;
00896 new_row = old_row;
00897 new_col = old_col;
00898 break;
00899
00900 case ERGTK_ICON_VIEW_PRESS_LONG_DOWN:
00901
00902 next_page = TRUE;
00903 new_row = old_row;
00904 new_col = old_col;
00905 break;
00906
00907 case ERGTK_ICON_VIEW_PRESS_LONG_LEFT:
00908
00909 prev_page = TRUE;
00910 new_row = num_rows - 1;
00911 new_col = 0;
00912 break;
00913
00914 case ERGTK_ICON_VIEW_PRESS_LONG_RIGHT:
00915
00916 next_page = TRUE;
00917 new_row = 0;
00918 new_col = num_cols - 1;
00919 break;
00920
00921 default:
00922 ERRORPRINTF("illegal erGtkIconViewKeyPress [%d]", keycode);
00923 ;
00924 }
00925
00926
00927 if ( prev_page && filemodel_has_prev_page() )
00928 {
00929 fileview_page_previous(new_row, new_col);
00930 }
00931 else if ( next_page && filemodel_has_next_page())
00932 {
00933 fileview_page_next(new_row, new_col);
00934 }
00935 }
00936
00937
00938 static void update_view_size()
00939 {
00940 int num_items = 1;
00941
00942 switch (g_current_view)
00943 {
00944 case CTB_ICONVIEW:
00945 if ( g_iconview && GTK_WIDGET_VISIBLE(g_iconview) )
00946 {
00947 int num_columns = 1;
00948 int num_rows = 1;
00949 erGtkIconView *iconview = ERGTK_ICON_VIEW(g_iconview);
00950 ergtk_icon_view_get_view_size(iconview, &num_columns, &num_rows, NULL);
00951 num_items = num_rows * num_columns;
00952 }
00953 break;
00954 case CTB_LISTVIEW:
00955 case CTB_CONTENTVIEW:
00956 if ( g_listview && GTK_WIDGET_VISIBLE(g_listview) )
00957 {
00958 int num_rows = 1;
00959 erGtkListView *listview = ERGTK_LIST_VIEW(g_listview);
00960 ergtk_list_view_get_view_size(listview, &num_rows, &num_items);
00961 num_items = num_rows;
00962 }
00963 break;
00964 default:
00965 g_assert_not_reached();
00966 }
00967
00968 if (num_items > 0) {
00969 gboolean changed = filemodel_set_viewsize(num_items, !g_operation_in_progress);
00970 if (changed && !g_operation_in_progress) {
00971 alphabar_select(filemodel_get_first_alpha_index());
00972 set_cursor(0,0);
00973 }
00974 }
00975 }
00976
00977
00978 static void on_listview_size_allocate ( GtkWidget *widget,
00979 GtkAllocation *allocation,
00980 gpointer user_data )
00981 {
00982 g_width = allocation->width;
00983 g_height = allocation->height;
00984 if (filemodel_window_is_on_top()) update_view_size();
00985 }
00986
00987
00988 static void on_listview_row_activated ( GtkTreeView *view,
00989 GtkTreePath *path,
00990 GtkTreeViewColumn *column,
00991 gpointer user_data )
00992 {
00993 handle_activate_item();
00994 }
00995
00996
00997 static void on_listview_navigate_cursor ( erGtkListView *er_listview,
00998 erGtkListViewKeyPress keycode,
00999 gpointer user_data )
01000 {
01001
01002 gint old_row;
01003 gint num_rows;
01004 gint num_items;
01005
01006
01007 gboolean prev_page = FALSE;
01008 gboolean next_page = FALSE;
01009 gint new_row = 0;
01010
01011 LOGPRINTF("entry: keycode [%d]", keycode);
01012
01013
01014 ergtk_list_view_get_cursor(er_listview, &old_row);
01015 ergtk_list_view_get_view_size(er_listview, &num_rows, &num_items);
01016
01017
01018 switch (keycode)
01019 {
01020 case ERGTK_LIST_VIEW_PRESS_SHORT_UP:
01021
01022 prev_page = TRUE;
01023 new_row = num_rows - 1;
01024 break;
01025
01026 case ERGTK_LIST_VIEW_PRESS_SHORT_DOWN:
01027
01028 next_page = TRUE;
01029 new_row = 0;
01030 break;
01031
01032 case ERGTK_LIST_VIEW_PRESS_LONG_UP:
01033 if (filemodel_has_prev_page()) {
01034
01035 prev_page = TRUE;
01036 new_row = old_row;
01037 } else {
01038
01039 set_cursor(new_row, 0);
01040 return;
01041 }
01042 break;
01043
01044 case ERGTK_LIST_VIEW_PRESS_LONG_DOWN:
01045 if (filemodel_has_next_page()) {
01046
01047 next_page = TRUE;
01048 new_row = old_row;
01049 } else {
01050
01051 set_cursor(40, 0);
01052 return;
01053 }
01054 break;
01055
01056 default:
01057 ERRORPRINTF("illegal erGtkListViewKeyPress [%d]", keycode);
01058 ;
01059 }
01060
01061
01062 if ( prev_page && filemodel_has_prev_page() )
01063 {
01064 fileview_page_previous(new_row, 0);
01065 }
01066 else if ( next_page && filemodel_has_next_page() )
01067 {
01068 fileview_page_next(new_row, 0);
01069 }
01070 }
01071
01072
01073 static gboolean isFirstItem(GtkTreeModel *model, GtkTreeIter* iter)
01074 {
01075 GtkTreeIter first;
01076 gtk_tree_model_get_iter_first(model, &first);
01077 if (iter->user_data == first.user_data) return TRUE;
01078 return FALSE;
01079 }
01080
01081
01082 static int iter_to_index(GtkTreeModel* model, const GtkTreeIter *iter)
01083 {
01084 int index = 0;
01085 GtkTreeIter iter2;
01086 gtk_tree_model_get_iter_first(model, &iter2);
01087 while (gtk_tree_model_iter_next(model, &iter2)) {
01088 index++;
01089 if (iter->user_data == iter2.user_data) break;
01090 }
01091 return index;
01092 }
01093
01094
01095 static void reset_delete_state()
01096 {
01097 if (g_delete_state != INITIAL) {
01098 g_delete_state = INITIAL;
01099 filemodel_set_delete_text(_("Finish Delete"));
01100 }
01101 }
01102
01103
01104 static void handle_delete_activated(GtkTreeModel* model, GtkTreeIter* iter)
01105 {
01106 START_TIMER();
01107 fileview_stop_update_display();
01108 if (isFirstItem(model, iter)) {
01109
01110 if (g_delete_state == INITIAL) {
01111 int count = filemodel_num_toggled();
01112 if (count > 0) {
01113 g_delete_state = CONFIRM;
01114 char buf[128];
01115
01116 snprintf(buf, 127, ngettext("Finish Delete - delete %d item?", "Finish Delete - delete %d items?", count), count);
01117 filemodel_set_delete_text(buf);
01118 } else {
01119 setViewMode(BROWSE_MODE, TRUE);
01120 return;
01121 }
01122 } else if (g_delete_state == CONFIRM) {
01123 ipc_sys_busy(TRUE);
01124 filemodel_delete_toggled();
01125 alphabar_update();
01126 setViewMode(BROWSE_MODE, TRUE);
01127 ipc_sys_busy(FALSE);
01128 return;
01129 }
01130 } else {
01131 int toggled;
01132 gtk_tree_model_get (model, iter, MODCOL_TOGGLED, &toggled, -1);
01133 if (toggled != -1) {
01134 toggled = 1 - toggled;
01135 filemodel_toggle_entry(iter_to_index(model, iter), toggled, iter);
01136 reset_delete_state();
01137 }
01138 }
01139 on_idle_update_display(DM_HINT_CURSOR);
01140 }
01141
01142
01143 static void on_iconview_item_activated_delete(GtkIconView *iconview,
01144 GtkTreePath *path,
01145 gpointer user_data )
01146 {
01147 GtkTreeModel* model = get_filemodel();
01148 GtkTreeIter iter;
01149 gtk_tree_model_get_iter(model, &iter, path);
01150
01151 handle_delete_activated(model, &iter);
01152 }
01153
01154
01155 static void on_contentview_row_activated_delete( GtkTreeView *view,
01156 GtkTreePath *path,
01157 GtkTreeViewColumn *column,
01158 gpointer user_data )
01159 {
01160 GtkTreeSelection *selection = gtk_tree_view_get_selection(view);
01161 GtkTreeModel *model;
01162 GtkTreeIter iter;
01163 if (!gtk_tree_selection_get_selected(selection, &model, &iter)) {
01164 WARNPRINTF("no row selected");
01165 return;
01166 }
01167 handle_delete_activated(model, &iter);
01168 }
01169
01170
01171 static void toggle_cell_function (GtkTreeViewColumn *col,
01172 GtkCellRenderer *renderer,
01173 GtkTreeModel *model,
01174 GtkTreeIter *iter,
01175 gpointer user_data)
01176 {
01177 int toggled;
01178 gtk_tree_model_get (model, iter, MODCOL_TOGGLED, &toggled, -1);
01179
01180 GdkPixbuf *icon = NULL;
01181 gboolean show = TRUE;
01182
01183 if (toggled == -1) {
01184 show = FALSE;
01185 } else {
01186 filemodel_thumbsize_t size = MODTHUMB_MINI;
01187 switch (g_current_view)
01188 {
01189 case CTB_LISTVIEW:
01190 size = MODTHUMB_MINI;
01191 break;
01192 case CTB_CONTENTVIEW:
01193 size = MODTHUMB_SMALL;
01194 break;
01195 default:
01196 size = MODTHUMB_MEDIUM;
01197 break;
01198 }
01199 icon = get_icon_delete_toggle(toggled, size);
01200 }
01201
01202 g_object_set(G_OBJECT(renderer),
01203 "visible", show,
01204 "pixbuf", icon,
01205 NULL);
01206 }
01207
01208
01209 static void setViewModeIconView(ctb_viewmodes_t newmode)
01210 {
01211 switch (newmode) {
01212 case BROWSE_MODE:
01213 {
01214
01215 if (g_handler_id != 0) g_signal_handler_disconnect(g_iconview, g_handler_id);
01216 g_handler_id = g_signal_connect(G_OBJECT(g_iconview), "item-activated", G_CALLBACK(on_iconview_item_activated), NULL);
01217 break;
01218 }
01219 case DELETE_MODE:
01220 {
01221
01222 if (g_handler_id != 0) g_signal_handler_disconnect(g_iconview, g_handler_id);
01223 g_handler_id = g_signal_connect(G_OBJECT(g_iconview), "item-activated", G_CALLBACK(on_iconview_item_activated_delete), NULL);
01224 break;
01225 }
01226 }
01227 }
01228
01229
01230 static void setViewModeListView(ctb_viewmodes_t newmode, int position, int width)
01231 {
01232 GtkTreeView *view = GTK_TREE_VIEW(g_listview);
01233 switch (newmode) {
01234 case BROWSE_MODE:
01235 {
01236
01237 if (g_toggleColumn) gtk_tree_view_remove_column(view, g_toggleColumn);
01238 g_toggleColumn = NULL;
01239
01240
01241 if (g_handler_id != 0) g_signal_handler_disconnect(g_listview, g_handler_id);
01242 g_handler_id = g_signal_connect(g_listview, "row-activated", G_CALLBACK(on_listview_row_activated), NULL);
01243 break;
01244 }
01245 case DELETE_MODE:
01246 {
01247
01248 GtkCellRenderer *renderer = gtk_cell_renderer_pixbuf_new();
01249 GtkTreeViewColumn *column = gtk_tree_view_column_new();
01250 gtk_tree_view_column_pack_start (column, renderer, TRUE);
01251 gtk_tree_view_column_set_cell_data_func(column, renderer, toggle_cell_function, NULL, NULL);
01252 gtk_tree_view_column_set_sizing(column, GTK_TREE_VIEW_COLUMN_FIXED);
01253 gtk_tree_view_column_set_fixed_width(column, width);
01254 gtk_tree_view_insert_column(view, column, position);
01255 g_toggleColumn = column;
01256
01257
01258 if (g_handler_id != 0) g_signal_handler_disconnect(g_listview, g_handler_id);
01259 g_handler_id = g_signal_connect(g_listview, "row-activated", G_CALLBACK(on_contentview_row_activated_delete), NULL);
01260 break;
01261 }
01262 }
01263 }
01264
01265
01266 static void setViewMode(ctb_viewmodes_t newmode, gboolean updateScreen)
01267 {
01268 if (g_viewmode == newmode) return;
01269
01270 g_viewmode = newmode;
01271 filemodel_set_viewmode(newmode, updateScreen);
01272 reset_delete_state();
01273
01274 if (newmode == DELETE_MODE) {
01275 gtk_widget_hide(g_search_button);
01276 #if MACHINE_IS_DR1000S || MACHINE_IS_DR1000SW
01277 gtk_widget_hide(g_shortcut_button);
01278 #endif
01279 } else {
01280 gtk_widget_show(g_search_button);
01281 #if MACHINE_IS_DR1000S || MACHINE_IS_DR1000SW
01282 gtk_widget_show(g_shortcut_button);
01283 #endif
01284 }
01285
01286 switch (g_current_view)
01287 {
01288 case CTB_ICONVIEW:
01289 setViewModeIconView(newmode);
01290 break;
01291 case CTB_LISTVIEW:
01292 setViewModeListView(newmode, -1, 50);
01293 break;
01294 case CTB_CONTENTVIEW:
01295 setViewModeListView(newmode, 3, 80);
01296 break;
01297 default:
01298 g_assert_not_reached();
01299 }
01300
01301 if (updateScreen) set_cursor(0, 0);
01302 }
01303
01304
01305 void show_error_dialog (const gchar *msg)
01306 {
01307 GtkWidget *dialog = gtk_message_dialog_new(
01308 GTK_WINDOW(g_main_window),
01309 GTK_DIALOG_DESTROY_WITH_PARENT,
01310 GTK_MESSAGE_ERROR,
01311 GTK_BUTTONS_OK,
01312 msg );
01313 gtk_window_set_deletable( GTK_WINDOW(dialog), FALSE );
01314 ipc_menu_block();
01315 gtk_dialog_run( GTK_DIALOG(dialog) );
01316 fileview_stop_update_display();
01317 ipc_menu_unblock();
01318 gtk_widget_destroy( dialog );
01319
01320 on_idle_update_display(DM_HINT_FULL);
01321 }
01322
01323
01324 void fileview_show_search_dialog()
01325 {
01326 ipc_menu_block();
01327 GtkWidget* dialog = filefind_dialog_create(g_main_window);
01328 g_search_dialog = dialog;
01329 gint result = gtk_dialog_run(GTK_DIALOG(dialog));
01330 if (result != GTK_RESPONSE_NONE) fileview_stop_update_display();
01331 switch (result)
01332 {
01333 case GTK_RESPONSE_ACCEPT:
01334 {
01335 if (!filemodel_current_is_desktop()) {
01336 filemodel_chdir_desktop();
01337 }
01338 const gchar* search_string = filefind_get_text();
01339 filemodel_set_search_filter(search_string);
01340 filemodel_set_viewmode2(SEARCH_VIEW);
01341 fileview_dir_down(DIR_LIBRARY, SPECIAL_SEARCH);
01342 }
01343 break;
01344 default:
01345
01346 break;
01347 }
01348 ipc_menu_unblock();
01349 if (g_search_dialog) {
01350 gtk_widget_destroy(dialog);
01351 g_search_dialog = NULL;
01352 }
01353 fileview_grab_focus();
01354 if (result != GTK_RESPONSE_ACCEPT && result != GTK_RESPONSE_NONE) {
01355
01356 on_idle_update_display(DM_HINT_FULL);
01357 }
01358 }
01359
01360
01361 void fileview_refresh(gboolean force_reload)
01362 {
01363 LOGPRINTF("");
01364
01365 if (filemodel_window_is_on_top()) fileview_stop_update_display();
01366
01367
01368 setViewMode(BROWSE_MODE, FALSE);
01369
01370 gchar *cursor_item = get_filename_at_cursor();
01371 if (filemodel_resync(force_reload)) {
01372 alphabar_update();
01373 filemodel_scroll_to_filename(cursor_item);
01374 alphabar_select(filemodel_get_first_alpha_index());
01375 }
01376
01377 set_cursor_at_filename(cursor_item);
01378 g_free(cursor_item);
01379 }
01380
01381
01382 void fileview_set_on_top(gboolean ontop)
01383 {
01384 if (ontop) {
01385 START_TIMER();
01386 } else {
01387 STOP_TIMER();
01388 }
01389 filemodel_set_window_is_on_top(ontop);
01390 }
01391
01392
01393 void fileview_toggle_delete_mode()
01394 {
01395 fileview_stop_update_display();
01396 ctb_viewmodes_t newmode = BROWSE_MODE;
01397 switch (g_viewmode) {
01398 case BROWSE_MODE:
01399 newmode = DELETE_MODE;
01400 break;
01401 case DELETE_MODE:
01402 default:
01403 newmode = BROWSE_MODE;
01404 break;
01405 }
01406 setViewMode(newmode, TRUE);
01407 }
01408
01409
01410 static filelist_entry_t* get_entry_at_cursor()
01411 {
01412 filelist_entry_t *entry = NULL;
01413
01414 switch (g_current_view) {
01415 case CTB_ICONVIEW:
01416 {
01417 GtkIconView *iconview = GTK_ICON_VIEW(g_iconview);
01418 GtkTreePath *path = NULL;
01419 gboolean cursor = gtk_icon_view_get_cursor(iconview, &path, NULL);
01420 if (cursor) {
01421 GtkTreeModel* model = get_filemodel();
01422 GtkTreeIter iter;
01423 gtk_tree_model_get_iter(model, &iter, path);
01424 entry = iter_to_entry(model, &iter);
01425 }
01426 gtk_tree_path_free(path);
01427 break;
01428 }
01429 case CTB_LISTVIEW:
01430 case CTB_CONTENTVIEW:
01431 {
01432 GtkTreeSelection *selection = gtk_tree_view_get_selection(GTK_TREE_VIEW(g_listview));
01433 GtkTreeModel *model;
01434 GtkTreeIter iter;
01435 if (gtk_tree_selection_get_selected(selection, &model, &iter)) {
01436 entry = iter_to_entry(model, &iter);
01437 }
01438 break;
01439 }
01440 default:
01441 break;
01442 }
01443
01444 if (entry) {
01445 if (strcmp(entry->directory_path->str, ".") == 0) {
01446 g_string_assign(entry->directory_path, filemodel_get_current_dir());
01447 }
01448 }
01449 return entry;
01450 }
01451
01452
01453 void fileview_create_shortcut()
01454 {
01455 filelist_entry_t *entry = get_entry_at_cursor();
01456 if (entry) {
01457 create_shortcut_item(entry);
01458 filelist_entry_free(entry);
01459 }
01460 }
01461
01462
01463 static void handle_activate_item()
01464 {
01465 START_TIMER();
01466 filelist_entry_t *entry = get_entry_at_cursor();
01467 if (entry) {
01468 activate_item(entry);
01469 filelist_entry_free(entry);
01470 }
01471 }
01472
01473
01474 void fileview_show_prev_page()
01475 {
01476 START_TIMER();
01477 gint row = 0;
01478 gint column = 0;
01479 get_cursor(&row, &column);
01480 fileview_page_previous(row, column);
01481 }
01482
01483
01484 void fileview_show_next_page()
01485 {
01486 START_TIMER();
01487 gint row = 0;
01488 gint column = 0;
01489 get_cursor(&row, &column);
01490 fileview_page_next(row, column);
01491 }
01492
01493
01494 static gchar* get_filename_at_cursor()
01495 {
01496 gchar *filename = NULL;
01497 filelist_entry_t *entry = get_entry_at_cursor();
01498 if (entry) {
01499 filename = g_strdup(entry->filename->str);
01500 filelist_entry_free(entry);
01501 }
01502 return filename;
01503 }
01504
01505
01506 static void set_cursor_at_index(int index)
01507 {
01508 gint row = 0;
01509 gint col = 0;
01510
01511 if (index > 0)
01512 {
01513 switch (g_current_view)
01514 {
01515 case -1:
01516 WARNPRINTF("viewtype not set");
01517 break;
01518 case CTB_ICONVIEW:
01519 {
01520 g_assert(g_iconview);
01521 erGtkIconView *iconview = ERGTK_ICON_VIEW(g_iconview);
01522 gint n_cols;
01523 ergtk_icon_view_get_view_size(iconview, NULL, &n_cols, NULL);
01524 if (n_cols != 0) {
01525 row = index / n_cols;
01526 col = index % n_cols;
01527 }
01528 break;
01529 }
01530 case CTB_LISTVIEW:
01531 case CTB_CONTENTVIEW:
01532 row = index;
01533 col = 0;
01534 break;
01535 default:
01536 g_assert_not_reached();
01537 }
01538 }
01539 set_cursor(row, col);
01540 }
01541
01542
01543 static void scroll_to_letter(gchar letter, gboolean jump_to_dir)
01544 {
01545 gboolean same_page = FALSE;
01546 int index = filemodel_scroll_to_letter(letter, jump_to_dir, &same_page);
01547 if (same_page) g_cursor_update_type = DM_HINT_CURSOR;
01548 else g_cursor_update_type = DM_HINT_FULL;
01549 set_cursor_at_index(index);
01550 }
01551
01552
01553 static void set_cursor_at_filename(const gchar *cursor_item)
01554 {
01555 int index = filemodel_get_display_index(cursor_item);
01556 set_cursor_at_index(index);
01557 }
01558
01559
01560 static gboolean on_idle_set_cursor_at_filename ( gpointer data )
01561 {
01562 gchar *filename = (gchar*)data;
01563
01564 filemodel_scroll_to_filename(filename);
01565 alphabar_select(filemodel_get_first_alpha_index());
01566 set_cursor_at_filename(filename);
01567
01568 g_free(filename);
01569
01570 return FALSE;
01571 }
01572
01573
01574 static void fileview_set_cursor_at_filename ( const gchar *filename )
01575 {
01576 if (filename && *filename) {
01577 g_idle_add(on_idle_set_cursor_at_filename, g_strdup(filename));
01578 }
01579 }
01580
01581
01582 int fileview_get_xid()
01583 {
01584 return GDK_WINDOW_XID(g_main_window->window);
01585 }
01586
01587
01588 void fileview_move_up(guint delta)
01589 {
01590 if (delta > WINDOW_TOP_PADDING )
01591 {
01592 delta = WINDOW_TOP_PADDING;
01593 }
01594 gtk_alignment_set_padding( GTK_ALIGNMENT(g_background),
01595 (WINDOW_TOP_PADDING - delta),
01596 WINDOW_BOTTOM_PADDING,
01597 WINDOW_H_PADDING,
01598 WINDOW_H_PADDING );
01599 }
01600
01601 void fileview_move_undo()
01602 {
01603 gtk_alignment_set_padding( GTK_ALIGNMENT(g_background),
01604 WINDOW_TOP_PADDING,
01605 WINDOW_BOTTOM_PADDING,
01606 WINDOW_H_PADDING,
01607 WINDOW_H_PADDING );
01608 }
01609
01610
01611 static void on_iconview_size_allocate ( GtkWidget *widget,
01612 GtkAllocation *allocation,
01613 gpointer user_data )
01614 {
01615 g_width = allocation->width;
01616 g_height = allocation->height;
01617 if (filemodel_window_is_on_top()) update_view_size();
01618 }
01619
01620
01621 static GtkWidget* create_iconview()
01622 {
01623 GtkWidget *widget = ergtk_icon_view_new_with_model( get_filemodel() );
01624 #if MACHINE_IS_DR800S || MACHINE_IS_DR800SG || MACHINE_IS_DR800SW
01625 g_object_set(G_OBJECT(widget), "navigate-mode", "simple-navigate-mode", NULL);
01626 #endif
01627 g_signal_connect(G_OBJECT(widget), "size-allocate", G_CALLBACK(on_iconview_size_allocate), NULL);
01628 g_handler_id = g_signal_connect(G_OBJECT(widget), "item-activated", G_CALLBACK(on_iconview_item_activated), NULL);
01629 g_signal_connect(G_OBJECT(widget), "navigate-cursor", G_CALLBACK(on_iconview_navigate_cursor), NULL);
01630 gtk_widget_set_name(widget, "iconview-irex-ctb");
01631 GtkIconView *view = GTK_ICON_VIEW(widget);
01632 ergtk_icon_view_set_focus_mode(ERGTK_ICON_VIEW(widget), TRUE, FALSE);
01633 gtk_icon_view_set_selection_mode(GTK_ICON_VIEW(widget), GTK_SELECTION_SINGLE);
01634 gtk_icon_view_set_spacing(view, 8);
01635
01636
01637 gtk_icon_view_set_text_column(view, MODCOL_TITLE);
01638
01639 gtk_icon_view_set_pixbuf_column(view, MODCOL_THUMBNAIL);
01640
01641 return widget;
01642 }
01643
01644
01645 static GtkWidget* create_listview()
01646 {
01647 GtkWidget *view = ergtk_list_view_new_with_model( get_filemodel() );
01648 g_signal_connect(G_OBJECT(view), "size-allocate", G_CALLBACK(on_listview_size_allocate), NULL);
01649 g_handler_id = g_signal_connect(G_OBJECT(view), "row-activated", G_CALLBACK(on_listview_row_activated), NULL);
01650 g_signal_connect(G_OBJECT(view), "navigate-cursor", G_CALLBACK(on_listview_navigate_cursor), NULL);
01651 gtk_widget_set_name(view, "listview-irex-ctb");
01652
01653 erGtkListView *er_listview = ERGTK_LIST_VIEW(view);
01654 GtkTreeView *treeview = GTK_TREE_VIEW(view);
01655 GtkTreeSelection *selection = gtk_tree_view_get_selection(treeview);
01656 gtk_tree_selection_set_mode(selection, GTK_SELECTION_SINGLE);
01657 ergtk_list_view_set_focus_mode(er_listview, TRUE, FALSE);
01658 gtk_tree_view_set_fixed_height_mode(treeview, TRUE);
01659
01660 ergtk_list_view_set_row_height(er_listview, 34);
01661
01662
01663 GtkCellRenderer *renderer = gtk_cell_renderer_pixbuf_new();
01664 g_object_set( G_OBJECT(renderer),
01665 "xpad", 0,
01666 "ypad", 0,
01667 "xalign", 0.5,
01668 "yalign", 0.5,
01669 NULL );
01670 GtkTreeViewColumn *column = gtk_tree_view_column_new_with_attributes( NULL,
01671 renderer,
01672 "pixbuf", MODCOL_THUMBNAIL,
01673 NULL );
01674 g_object_set( G_OBJECT(column),
01675 "sizing", GTK_TREE_VIEW_COLUMN_FIXED,
01676 "expand", FALSE,
01677 NULL );
01678 gtk_tree_view_column_set_fixed_width(column, 50);
01679 ergtk_list_view_append_column(er_listview, column);
01680
01681
01682 renderer = gtk_cell_renderer_text_new();
01683 g_object_set( G_OBJECT(renderer),
01684 "xpad", 0,
01685 "ypad", 0,
01686 "xalign", 0.0,
01687 "yalign", 0.5,
01688 "ellipsize", PANGO_ELLIPSIZE_END,
01689 "ellipsize-set", TRUE,
01690 NULL );
01691 column = gtk_tree_view_column_new_with_attributes( "",
01692 renderer,
01693 "text", MODCOL_TITLE,
01694 NULL );
01695 g_object_set( G_OBJECT(column),
01696 "sizing", GTK_TREE_VIEW_COLUMN_FIXED,
01697 "expand", TRUE,
01698 NULL );
01699 ergtk_list_view_append_column(er_listview, column);
01700
01701
01702 renderer = gtk_cell_renderer_text_new();
01703 g_object_set( G_OBJECT(renderer),
01704 "xpad", 0,
01705 "ypad", 0,
01706 "xalign", 0.0,
01707 "yalign", 0.5,
01708 NULL );
01709 column = gtk_tree_view_column_new_with_attributes( "",
01710 renderer,
01711 "text", MODCOL_FILETYPE_DISPLAY,
01712 NULL );
01713 g_object_set( G_OBJECT(column),
01714 "sizing", GTK_TREE_VIEW_COLUMN_FIXED,
01715 "expand", FALSE,
01716 NULL );
01717 gtk_tree_view_column_set_fixed_width(column, 120);
01718 ergtk_list_view_append_column(er_listview, column);
01719
01720
01721 renderer = gtk_cell_renderer_text_new();
01722 g_object_set( G_OBJECT(renderer),
01723 "xpad", 0,
01724 "ypad", 0,
01725 "xalign", 1.0,
01726 "yalign", 0.5,
01727 NULL );
01728 column = gtk_tree_view_column_new_with_attributes( "",
01729 renderer,
01730 "text", MODCOL_FILESIZE,
01731 NULL );
01732 g_object_set( G_OBJECT(column),
01733 "sizing", GTK_TREE_VIEW_COLUMN_FIXED,
01734 "alignment", 0.0,
01735 NULL );
01736 gtk_tree_view_column_set_fixed_width(column, 80);
01737 ergtk_list_view_append_column(er_listview, column);
01738
01739
01740 renderer = gtk_cell_renderer_text_new();
01741 g_object_set( G_OBJECT(renderer),
01742 "xpad", 0,
01743 "ypad", 0,
01744 "xalign", 0.5,
01745 "yalign", 0.5,
01746 NULL );
01747 column = gtk_tree_view_column_new_with_attributes( "",
01748 renderer,
01749 "text", MODCOL_FILEDATE,
01750 NULL );
01751 g_object_set( G_OBJECT(column),
01752 "sizing", GTK_TREE_VIEW_COLUMN_FIXED,
01753 NULL );
01754
01755 gtk_tree_view_column_set_fixed_width(column, 250);
01756 ergtk_list_view_append_column(er_listview, column);
01757
01758 return view;
01759 }
01760
01761
01762 static GtkWidget* create_contentview()
01763 {
01764 GtkWidget *view = ergtk_list_view_new_with_model( get_filemodel() );
01765 g_signal_connect(G_OBJECT(view), "size-allocate", G_CALLBACK(on_listview_size_allocate), NULL);
01766 g_handler_id = g_signal_connect(view, "row-activated", G_CALLBACK(on_listview_row_activated), NULL);
01767 g_signal_connect(G_OBJECT(view), "navigate-cursor", G_CALLBACK(on_listview_navigate_cursor), NULL);
01768 gtk_widget_set_name(view, "contentview-irex-ctb");
01769
01770 erGtkListView *er_listview = ERGTK_LIST_VIEW(view);
01771 GtkTreeView *treeview = GTK_TREE_VIEW(view);
01772 gtk_tree_view_set_headers_visible(treeview, FALSE);
01773 GtkTreeSelection *selection = gtk_tree_view_get_selection(treeview);
01774 gtk_tree_selection_set_mode(selection, GTK_SELECTION_SINGLE);
01775 ergtk_list_view_set_focus_mode(er_listview, TRUE, FALSE);
01776 gtk_tree_view_set_fixed_height_mode(treeview, TRUE);
01777
01778
01779 GtkCellRenderer *renderer = gtk_cell_renderer_pixbuf_new();
01780 g_object_set( G_OBJECT(renderer),
01781 "xpad", 10,
01782 "ypad", 0,
01783 "xalign", 0.5,
01784 "yalign", 0.5,
01785 NULL );
01786 GtkTreeViewColumn *column = gtk_tree_view_column_new_with_attributes( NULL,
01787 renderer,
01788 "pixbuf", MODCOL_THUMBNAIL,
01789 NULL );
01790 g_object_set( G_OBJECT(column),
01791 "sizing", GTK_TREE_VIEW_COLUMN_FIXED,
01792 "expand", FALSE,
01793 NULL );
01794 gtk_tree_view_column_set_fixed_width(column, 90);
01795 ergtk_list_view_append_column(er_listview, column);
01796
01797
01798 renderer = ergtk_cell_renderer_text_new(2);
01799 g_object_set( G_OBJECT(renderer),
01800 "xpad", 0,
01801 "ypad", 0,
01802 "xalign", 0.0,
01803 "yalign", 1.0,
01804 "ellipsize", PANGO_ELLIPSIZE_END,
01805 "ellipsize-set", TRUE,
01806 "font-0", "Normal 10",
01807 "font-1", "Normal italic 9",
01808 "height-0", 32,
01809 "height-1", 22,
01810 "foreground-0", "black",
01811 "foreground-1", "#555555",
01812 NULL );
01813 column = gtk_tree_view_column_new_with_attributes( "",
01814 renderer,
01815 "text-0", MODCOL_TITLE,
01816 "text-1", MODCOL_SUBTITLE,
01817 NULL );
01818 g_object_set( G_OBJECT(column),
01819 "sizing", GTK_TREE_VIEW_COLUMN_FIXED,
01820 "expand", TRUE,
01821 NULL );
01822 gtk_tree_view_column_set_fixed_width(column, 300);
01823 ergtk_list_view_append_column(er_listview, column);
01824
01825
01826
01827 renderer = ergtk_cell_renderer_border_new();
01828 g_object_set( G_OBJECT(renderer),
01829 "xpad", 0,
01830 "ypad", 0,
01831 "xalign", 0.0,
01832 "yalign", 0.5,
01833 "border-width", 2,
01834 "border-offset", 3,
01835 "border-color", "dark grey",
01836 NULL );
01837 column = gtk_tree_view_column_new_with_attributes( "",
01838 renderer,
01839 NULL );
01840 g_object_set( G_OBJECT(column),
01841 "sizing", GTK_TREE_VIEW_COLUMN_FIXED,
01842 "expand", FALSE,
01843 NULL );
01844 gtk_tree_view_column_set_fixed_width(column, 10);
01845 gtk_tree_view_append_column(treeview, column);
01846
01847 return view;
01848 }
01849
01850
01851 void fileview_set_view_type (const ctb_viewtypes_t view, gboolean do_cursor)
01852 {
01853 if (g_viewmode == DELETE_MODE) {
01854 WARNPRINTF("cannot switch viewtype in delete mode");
01855 return;
01856 }
01857
01858 LOGPRINTF("old=%d -> new=%d", g_current_view, view);
01859 g_is_user_selected_view = TRUE;
01860 if ( view == g_current_view ) return;
01861 fileview_stop_update_display();
01862
01863 gchar *cursor_item = NULL;
01864 if (do_cursor) cursor_item = get_filename_at_cursor();
01865
01866
01867 switch (g_current_view) {
01868 case CTB_ICONVIEW:
01869 if (g_iconview) {
01870 gtk_widget_destroy(g_iconview);
01871 g_iconview = NULL;
01872 }
01873 break;
01874 case CTB_LISTVIEW:
01875 case CTB_CONTENTVIEW:
01876 if (g_listview) {
01877 gtk_widget_destroy(g_listview);
01878 g_listview = NULL;
01879 }
01880 break;
01881 default:
01882 break;
01883 }
01884
01885 g_current_view = view;
01886
01887
01888 GtkWidget *widget = NULL;
01889 switch (view)
01890 {
01891 case CTB_ICONVIEW:
01892 filemodel_set_thumbsize(MODTHUMB_MEDIUM, do_cursor);
01893 widget = create_iconview();
01894 g_iconview = widget;
01895 g_signal_connect(widget, "destroy", G_CALLBACK(gtk_widget_destroyed), &widget);
01896 gtk_widget_show(widget);
01897 gtk_container_add(GTK_CONTAINER(g_eventbox), widget);
01898 if (g_width != 0) gtk_widget_set_size_request(widget, g_width, g_height);
01899 break;
01900 case CTB_LISTVIEW:
01901 filemodel_set_thumbsize(MODTHUMB_MINI, do_cursor);
01902 widget = create_listview();
01903 g_listview = widget;
01904 g_signal_connect(widget, "destroy", G_CALLBACK(gtk_widget_destroyed), &widget);
01905 gtk_widget_show(widget);
01906 gtk_container_add(GTK_CONTAINER(g_eventbox), widget);
01907 listview_set_column_headers();
01908 break;
01909 case CTB_CONTENTVIEW:
01910 filemodel_set_thumbsize(MODTHUMB_SMALL, do_cursor);
01911 widget = create_contentview();
01912 g_listview = widget;
01913 g_signal_connect(widget, "destroy", G_CALLBACK(gtk_widget_destroyed), &widget);
01914 gtk_widget_show(widget);
01915 gtk_container_add(GTK_CONTAINER(g_eventbox), widget);
01916 if (g_width != 0) gtk_widget_set_size_request(widget, g_width, g_height);
01917 break;
01918 default:
01919 break;
01920 }
01921
01922 update_padding();
01923 menu_select_view_type(view);
01924 if (do_cursor) {
01925 g_operation_in_progress = TRUE;
01926 fileview_set_cursor_at_filename(cursor_item);
01927 g_free(cursor_item);
01928 }
01929 }
01930
01931
01932 static void on_destroy (GtkWidget * widget, gpointer data)
01933 {
01934 gtk_main_quit();
01935 }
01936
01937
01938 void fileview_create()
01939 {
01940
01941 GtkWidget *window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
01942 gtk_window_set_title(GTK_WINDOW(window), PACKAGE " " VERSION);
01943 gtk_window_maximize(GTK_WINDOW(window));
01944 gtk_window_set_resizable(GTK_WINDOW(window), FALSE);
01945 gtk_container_set_border_width(GTK_CONTAINER(window), 0);
01946 gtk_window_set_modal(GTK_WINDOW(window), TRUE);
01947 g_signal_connect(G_OBJECT(window), "destroy", G_CALLBACK(on_destroy), NULL);
01948 g_main_window = window;
01949
01950 GtkWidget *widget = create_screen_layout();
01951 gtk_container_add(GTK_CONTAINER(window), widget);
01952
01953 ctb_viewtypes_t view = get_viewtype_from_registry();
01954 fileview_set_view_type(view, FALSE);
01955 g_is_user_selected_view = FALSE;
01956
01957 fileview_show_desktop();
01958 gtk_widget_show(window);
01959 }
01960
01961
01962 void fileview_init()
01963 {
01964 filemodel_init();
01965 reset_delete_state();
01966 }
01967