1
1
/* Bluefish HTML Editor
2
2
* filebrowser2.c - the filebrowser v2
4
* Copyright (C) 2002-2011 Olivier Sessink
4
* Copyright (C) 2002-2012 Olivier Sessink
5
5
* Copyright (C) 2011 James Hayward
7
7
* This program is free software; you can redistribute it and/or modify
215
fb2config_set_documentroot(GFile *uri)
217
GtkTreeIter *iter = g_hash_table_lookup(FB2CONFIG(main_v->fb2config)->filesystem_itable, uri);
220
DEBUG_MSG("fb2config_set_documentroot, set icon %s\n",BF_STOCK_BROWSER_PREVIEW);
221
gtk_tree_store_set(GTK_TREE_STORE(FB2CONFIG(main_v->fb2config)->filesystem_tstore),
222
iter, ICON_NAME_COLUMN, BF_STOCK_BROWSER_PREVIEW, -1);
232
244
if (drd->bfwin->session->documentroot)
233
245
g_free(drd->bfwin->session->documentroot);
234
246
drd->bfwin->session->documentroot = g_file_get_uri(docroot);
247
fb2config_set_documentroot(docroot);
236
249
if (drd->bfwin->session->webroot)
237
250
g_free(drd->bfwin->session->webroot);
630
643
fb2_enumerate_children_lcb(GObject * source_object, GAsyncResult * res, gpointer user_data)
632
645
Turi_in_refresh *uir = user_data;
633
GError *error = NULL;
634
uir->gfe = g_file_enumerate_children_finish(uir->uri, res, &error);
636
/* delete the directory from the treestore */
637
GtkTreeIter *iter = g_hash_table_lookup(FB2CONFIG(main_v->fb2config)->filesystem_itable, uir->uri);
639
fb2_treestore_delete(FB2CONFIG(main_v->fb2config)->filesystem_tstore, iter);
646
GError *gerror = NULL;
647
uir->gfe = g_file_enumerate_children_finish(uir->uri, res, &gerror);
649
if (gerror->code == 14 /* 14 = permission denied */) {
650
fb2_treestore_delete_children(FB2CONFIG(main_v->fb2config)->filesystem_tstore, uir->parent, FALSE);
652
/* delete the directory from the treestore */
653
fb2_treestore_delete(FB2CONFIG(main_v->fb2config)->filesystem_tstore, uir->parent);
641
g_warning("failed to list directory in filebrowser: %s\n", error->message);
655
g_warning("failed to list directory in filebrowser: %s\n", gerror->message);
656
g_error_free(gerror);
643
657
fb2_uri_in_refresh_cleanup(uir);
661
/*g_print("opened the directory\n");*/
647
662
g_file_enumerator_next_files_async(uir->gfe, 40, G_PRIORITY_LOW, uir->cancel,
648
663
fb2_enumerate_next_files_lcb, uir);
667
682
if (fb2_get_uri_in_refresh(uri) == NULL) {
668
683
Turi_in_refresh *uir;
684
DEBUG_MSG("about to register a low priority callback for fb2_fill_dir_async_low_priority\n");
670
685
fb2_treestore_mark_children_refresh1(FB2CONFIG(main_v->fb2config)->filesystem_tstore, parent);
671
686
uir = g_slice_new0(Turi_in_refresh);
672
687
uir->parent = parent;
962
977
gtk_tree_model_get_path(GTK_TREE_MODEL(FB2CONFIG(main_v->fb2config)->filesystem_tstore), dir);
964
979
refilter_filelist(fb2, fs_path);
965
DEBUG_MSG("fb2_focus_dir, fb2=%p, expand dir tree to this dir..\n", fb2);
966
980
if (!noselect && fb2->filebrowser_viewmode != viewmode_flat) {
967
981
GtkTreePath *sort_path = dir_sort_path_from_treestore_path(fb2, fs_path);
969
983
if (fb2->filebrowser_viewmode == viewmode_tree && gtk_tree_view_row_expanded(GTK_TREE_VIEW(fb2->dir_v), sort_path) && !need_to_scroll_to_dir(fb2, uri)) {
985
/*g_print("fb2_focus_dir, expanded=%d, need to scroll=%d\n",gtk_tree_view_row_expanded(GTK_TREE_VIEW(fb2->dir_v), sort_path), need_to_scroll_to_dir(fb2, uri));*/
972
987
g_signal_handler_block(fb2->dir_v, fb2->expand_signal);
973
988
gtk_tree_view_expand_to_path(GTK_TREE_VIEW(fb2->dir_v), sort_path);
985
1000
/* 'uri' is not persistent, 'dir' is peristent, so only pass 'dir'
986
the "select" or "expand" signal (dual or tree view) will also refresh this directory, so
1001
the "expand" signal (dual or tree view) will also refresh this directory, so
987
1002
we call this only on 'noselect' or in the flat view
989
1004
DEBUG_MSG("fb2_focus_dir, noselect, so directly call refresh\n");
1082
1097
retval = file_visible_in_filter(fb2->curfilter, mime_type, name);
1084
1099
DEBUG_MSG("file %s with mime_type %s: returning %d\n", name, mime_type, retval);
1088
1100
} else { /* directory */
1089
1101
if (fb2->filebrowser_viewmode == viewmode_flat) {
1090
1102
if (fb2->basedir) {
1163
1175
* - files are first sorted without extension, only equal names are sorted by extension
1167
1179
filebrowser_sort_func(GtkTreeModel * model, GtkTreeIter * a, GtkTreeIter * b, gpointer user_data)
1169
1181
gchar *namea, *nameb, *mimea, *mimeb;
1173
1185
gtk_tree_model_get((GtkTreeModel *) model, b, FILENAME_COLUMN, &nameb, TYPE_COLUMN, &mimeb, -1);
1174
1186
isdira = (mimea && MIME_ISDIR(mimea));
1175
1187
isdirb = (mimeb && MIME_ISDIR(mimeb));
1176
/*g_print("isdira=%d, mimea=%s, isdirb=%d, mimeb=%s\n",isdira,mimea,isdirb,mimeb); */
1188
DEBUG_MSG("namea=%s, nameb=%s, isdira=%d, mimea=%s, isdirb=%d, mimeb=%s\n",namea,nameb,isdira,mimea,isdirb,mimeb);
1177
1189
if (isdira == isdirb) { /* both files, or both directories */
1178
1190
if (namea == nameb) {
1179
1191
retval = 0; /* both NULL */
1248
1261
fb2->basedir = uri;
1249
1262
add_uri_to_recent_dirs(fb2, fb2->basedir);
1251
DEBUG_MSG("there is no parent for this path, so we will set the basedir to NULL\n");
1264
DEBUG_MSG("refilter_dirlist, there is no parent for this path, so we will set the basedir to NULL\n");
1252
1265
gtk_tree_path_free(useroot);
1253
1266
useroot = NULL;
1270
/* g_print("refilter_dirlist, creating new filter and sort model\n");*/
1257
1271
fb2->dir_tfilter =
1258
1272
gtk_tree_model_filter_new(GTK_TREE_MODEL(FB2CONFIG(main_v->fb2config)->filesystem_tstore), useroot);
1259
1273
DEBUG_TREEMODELREFS("refilter_dirlist, created new tree model filter at %p for fb2 %p\n",fb2->dir_tfilter, fb2);
2172
2186
/* refresh the directory that is being expanded */
2173
2187
gtk_tree_model_get(fb2->dir_tsort, sort_iter, URI_COLUMN, &uri, -1);
2189
DEBUG_MSG("dir_v_row_expanded_lcb, calling fb2_refresh_dir()\n");
2175
2190
fb2_refresh_dir(uri, NULL);
2309
2324
/* rebuild the current uri */
2310
2325
tmp = g_object_ref(newcurdir);
2312
gchar *name = g_file_get_uri(tmp);
2314
2329
tmp2 = g_file_get_parent(tmp);
2315
2330
DEBUG_MSG("parent for uri %p is at %p\n", tmp, tmp2);
2354
2371
uri = g_file_new_for_uri(tmplist->data);
2355
2372
DEBUG_MSG("new uri at %p for session recent directory %s\n", uri, (gchar *)tmplist->data);
2356
2373
if (uri && g_hash_table_lookup(hasht, uri) == NULL) {
2357
name = g_file_get_uri(uri);
2374
name = g_file_is_native(uri) ? g_file_get_path(uri) : g_file_get_uri(uri);
2358
2375
DEBUG_MSG("dirmenu_set_curdir, appending %s (uri=%p) to model %p\n", name, uri, fb2->dirmenu_m);
2359
2376
gtk_list_store_append(GTK_LIST_STORE(fb2->dirmenu_m), &iter);
2360
2377
gtk_list_store_set(GTK_LIST_STORE(fb2->dirmenu_m), &iter, DIR_NAME_COLUMN, name,
2407
2424
gtk_combo_box_set_active_iter(GTK_COMBO_BOX(fb2->dirmenu_v), &setiter);
2408
2425
g_signal_handler_unblock(fb2->dirmenu_v, fb2->dirmenu_changed_signal);
2409
2426
DEBUG_MSG("dirmenu_set_curdir, activated!\n");
2410
g_idle_add_full(G_PRIORITY_LOW, dirmenu_idle_cleanup_lcb, oldmodel, NULL);
2427
g_idle_add_full(G_PRIORITY_LOW+10, dirmenu_idle_cleanup_lcb, oldmodel, NULL);
2462
2479
DEBUG_MSG("dir_v_selection_changed_lcb, mime_type=%s and uri=", mime_type);
2463
2480
DEBUG_GFILE(uri, TRUE);
2464
2481
if (uri && (mime_type && MIME_ISDIR(mime_type))) {
2465
DEBUG_MSG("uri %p is directory, calling dirmenu_set_curdir\n", uri);
2482
DEBUG_MSG("dir_v_selection_changed_lcb, uri %p is directory, calling dirmenu_set_curdir which will refresh this dir\n", uri);
2466
2483
dirmenu_set_curdir(fb2, uri);
2467
2484
fb2_focus_dir(fb2, uri, TRUE);
2494
2511
DEBUG_MSG("fb2_set_basedir_backend, refilter, basepath=%p\n", basepath);
2495
2512
refilter_dirlist(fb2, basepath);
2496
2513
if (basepath) {
2497
fb2_focus_dir(fb2, fb2->basedir, (fb2->filebrowser_viewmode == viewmode_flat));
2514
fb2_focus_dir(fb2, uri, (fb2->filebrowser_viewmode == viewmode_flat));
2498
2515
gtk_tree_path_free(basepath);
2697
2714
fb2_tooltip_lcb(GtkWidget * widget, gint x, gint y, gboolean keyboard_tip, GtkTooltip * tooltipwidget,
2698
2715
gpointer user_data)
2700
GtkTreeView *tview = user_data;
2717
GtkTreeView *tview = (GtkTreeView *)widget;
2718
Tfilebrowser2 *fb2 = user_data;
2701
2719
GtkTreePath *path;
2702
2720
gboolean retval = FALSE;
2703
2721
if (gtk_tree_view_get_path_at_pos(GTK_TREE_VIEW(tview), x, y, &path, NULL, NULL, NULL)) {
2706
2724
GFile *uri = NULL;
2707
2725
gtk_tree_model_get(gtk_tree_view_get_model(tview), &iter, URI_COLUMN, &uri, -1);
2710
text = g_file_get_uri(uri);
2711
gtk_tooltip_set_text(tooltipwidget, text);
2727
gchar *curi = g_file_get_uri(uri);
2728
gchar *localname=NULL;
2730
if (g_file_is_native(uri)) {
2731
localname = g_file_get_path(uri);
2733
if (fb2->bfwin->session->webroot && fb2->bfwin->session->documentroot && g_str_has_prefix(curi, fb2->bfwin->session->documentroot)) {
2734
text = g_strdup_printf(_("<b>%s</b>\nwhich is the equivalent of\n<b>%s%s</b>"), localname?localname:curi, fb2->bfwin->session->webroot, curi+strlen(fb2->bfwin->session->documentroot));
2736
text = g_strdup_printf("<b>%s</b>",localname?localname:curi);
2738
gtk_tooltip_set_markup(tooltipwidget, text);
2838
2867
if (fb2->filebrowser_viewmode != viewmode_dual) {
2839
2868
gtk_box_pack_start(GTK_BOX(fb2->vbox), fb2->dirscrolwin, TRUE, TRUE, 0);
2870
#if GTK_CHECK_VERSION(3,0,0)
2871
fb2->vpaned = gtk_paned_new(GTK_ORIENTATION_VERTICAL);
2841
2873
fb2->vpaned = gtk_vpaned_new();
2842
2875
gtk_paned_set_position(GTK_PANED(fb2->vpaned), main_v->globses.two_pane_filebrowser_height);
2843
2876
g_signal_connect(G_OBJECT(fb2->vpaned), "notify::position",
2844
2877
G_CALLBACK(fb2_two_pane_notify_position_lcb), NULL);
2892
2925
g_signal_connect(G_OBJECT(fb2->file_v), "drag_data_received",
2893
2926
G_CALLBACK(fb2_file_v_drag_data_received), fb2);
2894
2927
g_object_set(fb2->file_v, "has-tooltip", TRUE, NULL);
2895
g_signal_connect(fb2->file_v, "query-tooltip", G_CALLBACK(fb2_tooltip_lcb), fb2->file_v);
2928
g_signal_connect(fb2->file_v, "query-tooltip", G_CALLBACK(fb2_tooltip_lcb), fb2);
2898
2931
g_signal_connect(G_OBJECT(fb2->dir_v), "row-activated", G_CALLBACK(dir_v_row_activated_lcb), fb2);
2899
2932
g_signal_connect(G_OBJECT(fb2->dir_v), "button_press_event", G_CALLBACK(dir_v_button_press_lcb), fb2);
2900
2933
fb2->expand_signal =
2901
2934
g_signal_connect(G_OBJECT(fb2->dir_v), "row-expanded", G_CALLBACK(dir_v_row_expanded_lcb), fb2->bfwin);
2902
g_signal_connect(fb2->dir_v, "query-tooltip", G_CALLBACK(fb2_tooltip_lcb), fb2->dir_v);
2935
g_signal_connect(fb2->dir_v, "query-tooltip", G_CALLBACK(fb2_tooltip_lcb), fb2);
2903
2936
g_object_set(fb2->dir_v, "has-tooltip", TRUE, NULL);
2904
2937
/*gtk_container_resize_children(GTK_CONTAINER(fb2->vbox)); */
2905
2938
gtk_widget_show_all(fb2->vbox);
2906
2939
DEBUG_MSG("fb2_set_viewmode_widgets, new GUI finished\n");
2911
2943
fb2_update_settings_from_session(Tbfwin * bfwin)
2949
2981
fb2_set_basedir(bfwin, NULL);
2983
if (bfwin->session->webroot && bfwin->session->documentroot) {
2984
GFile *uri = g_file_new_for_uri(bfwin->session->documentroot);
2986
fb2config_set_documentroot(uri);
2987
g_object_unref(uri);
2951
2989
/* TODO: fb2_set_basedir already calls refilter in most cases (not if the
2952
2990
requested basedir was already the active basedir), so
2953
2991
we can optimise this and call refilter only when really needed. */