static void on_sel_changed(FmFolderView* fv, FmFileInfoList* files, FmMainWin* win) { /* popup previous message if there is any */ gtk_statusbar_pop(GTK_STATUSBAR(win->statusbar), win->statusbar_ctx2); if(files) { char* msg; /* FIXME: display total size of all selected files. */ if(fm_list_get_length(files) == 1) /* only one file is selected */ { FmFileInfo* fi = fm_list_peek_head(files); const char* size_str = fm_file_info_get_disp_size(fi); if(size_str) { msg = g_strdup_printf("\"%s\" (%s) %s", fm_file_info_get_disp_name(fi), size_str ? size_str : "", fm_file_info_get_desc(fi)); } else { msg = g_strdup_printf("\"%s\" %s", fm_file_info_get_disp_name(fi), fm_file_info_get_desc(fi)); } } else msg = g_strdup_printf("%d items selected", fm_list_get_length(files)); gtk_statusbar_push(GTK_STATUSBAR(win->statusbar), win->statusbar_ctx2, msg); g_free(msg); } }
static void on_file_info_job_finished(FmFileInfoJob* job, gpointer user_data) { FmPlacesModel* model = FM_PLACES_MODEL(user_data); GList* l; GtkTreeIter it; FmPlaceItem* item; FmFileInfo* fi; /* g_debug("file info job finished"); */ model->jobs = g_slist_remove(model->jobs, job); if(!gtk_tree_model_get_iter_first(GTK_TREE_MODEL(model), &it)) return; if(fm_list_is_empty(job->file_infos)) return; /* optimize for one file case */ if(fm_list_get_length(job->file_infos) == 1) { fi = FM_FILE_INFO(fm_list_peek_head(job->file_infos)); do { item = NULL; gtk_tree_model_get(GTK_TREE_MODEL(model), &it, FM_PLACES_MODEL_COL_INFO, &item, -1); if( item && item->fi && item->fi->path && fm_path_equal(item->fi->path, fi->path) ) { fm_file_info_unref(item->fi); item->fi = fm_file_info_ref(fi); break; } }while(gtk_tree_model_iter_next(GTK_TREE_MODEL(model), &it)); } else { do { item = NULL; gtk_tree_model_get(GTK_TREE_MODEL(model), &it, FM_PLACES_MODEL_COL_INFO, &item, -1); if( item && item->fi && item->fi->path ) { for(l = fm_list_peek_head_link(job->file_infos); l; l = l->next ) { fi = FM_FILE_INFO(l->data); if(fm_path_equal(item->fi->path, fi->path)) { fm_file_info_unref(item->fi); item->fi = fm_file_info_ref(fi); /* remove the file from list to speed up further loading. * This won't cause problem since nobody else if using the list. */ fm_list_delete_link(job->file_infos, l); break; } } } }while(gtk_tree_model_iter_next(GTK_TREE_MODEL(model), &it)); } }
void on_rename(GtkAction* act, FmMainWin* win) { FmPathList* files = fm_folder_view_get_selected_file_paths(FM_FOLDER_VIEW(win->folder_view)); if( !fm_list_is_empty(files) ) { fm_rename_file(fm_list_peek_head(files)); /* FIXME: is it ok to only rename the first selected file here. */ } fm_list_unref(files); }
inline static gboolean cache_src_file_infos(FmDndDest* dd, GtkWidget *dest_widget, gint x, gint y, GdkDragContext *drag_context) { GdkAtom target; target = gtk_drag_dest_find_target( dest_widget, drag_context, NULL ); if( target != GDK_NONE ) { GdkDragAction action; gboolean ret; /* treat X direct save as a special case. */ if( target == gdk_atom_intern_static_string("XdndDirectSave0") ) { /* FIXME: need a better way to handle this. */ action = drag_context->suggested_action; g_signal_emit(dd, signals[QUERY_INFO], 0, x, y, &action, &ret); gdk_drag_status(drag_context, action, time); return TRUE; } /* g_debug("try to cache src_files"); */ dd->mainloop = g_main_loop_new(NULL, TRUE); gtk_drag_get_data(dest_widget, drag_context, target, time); /* run the main loop to block here waiting for * 'drag-data-received' signal being handled first. */ /* it's possible that g_main_loop_quit is called before we really run the loop. */ if(g_main_loop_is_running(dd->mainloop)) g_main_loop_run(dd->mainloop); g_main_loop_unref(dd->mainloop); dd->mainloop = NULL; /* g_debug("src_files cached: %p", dd->src_files); */ /* dd->src_files should be set now */ if( dd->src_files && fm_list_is_file_info_list(dd->src_files) ) { /* cache file system id of source files */ if( fm_file_info_list_is_same_fs(dd->src_files) ) { FmFileInfo* fi = (FmFileInfo*)fm_list_peek_head(dd->src_files); if(fm_path_is_native(fi->path)) dd->src_dev = fi->dev; else dd->src_fs_id = fi->fs_id; } } } return FALSE; }
/* NOTE: Sticking to natural behavior of returning a list with the unchanged input_string, incase nothing can be substituted, however, this is expensive. A better way would be to return NULL incase of no changes, and let the caller handle the NULL case, which implies that there is no change in the input_string */ GPtrArray* substitute_parameters(gchar *input_string, FmFileInfoList *file_info_list) { //printf("Input string is %s\n", input_string); GPtrArray *out_string_array = g_ptr_array_new(); if(strchr(input_string, '%') == NULL){ //printf("Found nothing to expand. Returning input_string.\n"); g_ptr_array_add(out_string_array, g_string_new(input_string)); return out_string_array; } gsize i, j; gsize len_file_list = fm_list_get_length(file_info_list); GString *out_string = g_string_new(NULL); gsize first_pos = strcspn(input_string, "%"); gchar *pos = input_string + first_pos; g_string_append_len(out_string, input_string, first_pos); GString *g_string_i = NULL; gchar *base_name = NULL, *base_dir = NULL, *file_name = NULL, *host_name = NULL, *user_name = NULL, *port = NULL, *scheme = NULL, *uri = NULL, *file_name_wo_ext = NULL, *ext_pos = NULL; gboolean array_is_init = FALSE; FmFileInfo *file_info_i = NULL, *file_info_j = NULL; char temp[256]; gboolean curr_dir_flag; while((pos = strchr(pos, '%')) != NULL){ switch(pos[1]){ case 'b': /* Works */ if(array_is_init == FALSE){ for(i=0; i<len_file_list; ++i){ g_string_i = g_string_new(out_string->str); file_info_i = fm_list_peek_nth(file_info_list, i); base_name = (gchar *)fm_file_info_get_disp_name(file_info_i); g_string_append(g_string_i, base_name); g_string_append_c(g_string_i, ' '); g_ptr_array_add(out_string_array, g_string_new(g_string_i->str)); g_string_free(g_string_i, TRUE); } break; } file_info_i = fm_list_peek_head(file_info_list); base_name = (gchar *)fm_file_info_get_disp_name(file_info_i); for(i=0; i<out_string_array->len; ++i){ g_string_i = (GString *)g_ptr_array_index(out_string_array, i); g_string_append(g_string_i, base_name); g_string_append_c(g_string_i, ' '); } break; case 'B': /* Works */ if(array_is_init == FALSE) g_ptr_array_add(out_string_array, g_string_new(out_string->str)); for(i=0; i<out_string_array->len; ++i){ g_string_i = (GString *)g_ptr_array_index(out_string_array, i); for(j=0; j<len_file_list; ++j){ file_info_j= fm_list_peek_nth(file_info_list, j); base_name = (gchar *)fm_file_info_get_disp_name(file_info_j); g_string_append(g_string_i, base_name); g_string_append_c(g_string_i, ' '); } } break; case 'c': /* Works */ memset(temp, 256, 0); if(array_is_init == FALSE) g_ptr_array_add(out_string_array, g_string_new(out_string->str)); for(i=0; i<out_string_array->len; ++i){ g_string_i = (GString *)g_ptr_array_index(out_string_array, i); sprintf(temp, "%u", len_file_list); g_string_append(g_string_i, temp); g_string_append_c(g_string_i, ' '); } break; case 'd': /* Works */ curr_dir_flag = FALSE; if(array_is_init == FALSE){ for(i=0; i<len_file_list; ++i){ g_string_i = g_string_new(out_string->str); file_info_i = fm_list_peek_nth(file_info_list, i); if(fm_file_info_is_dir(file_info_i) == TRUE){ base_dir = fm_path_to_str(fm_file_info_get_path(file_info_i)); } else { if(curr_dir_flag == FALSE){ base_dir = g_get_current_dir(); curr_dir_flag = TRUE; } else { continue; } } g_string_append(g_string_i, base_dir); g_string_append_c(g_string_i, ' '); g_ptr_array_add(out_string_array, g_string_new(g_string_i->str)); g_free(base_dir); g_string_free(g_string_i, TRUE); } break; } file_info_i = fm_list_peek_head(file_info_list); if(fm_file_info_is_dir(file_info_i) == TRUE){ base_dir = fm_path_to_str(fm_file_info_get_path(file_info_i)); } else { if(curr_dir_flag == FALSE){ base_dir = g_get_current_dir(); curr_dir_flag = TRUE; } else { continue; } } for(i=0; i<out_string_array->len; ++i){ g_string_i = (GString *)g_ptr_array_index(out_string_array, i); g_string_append(g_string_i, base_dir); g_string_append_c(g_string_i, ' '); } g_free(base_dir); break; case 'D': /* Works */ if(array_is_init == FALSE) g_ptr_array_add(out_string_array, g_string_new(out_string->str)); for(i=0; i<out_string_array->len; ++i){ curr_dir_flag = FALSE; g_string_i = (GString *)g_ptr_array_index(out_string_array, i); for(j=0; j<len_file_list; ++j){ file_info_j= fm_list_peek_nth(file_info_list, j); if(fm_file_info_is_dir(file_info_j) == TRUE){ base_dir = fm_path_to_str(fm_file_info_get_path(file_info_j)); } else { if(curr_dir_flag == FALSE){ base_dir = g_get_current_dir(); curr_dir_flag = TRUE; } else { continue; } } g_string_append(g_string_i, base_dir); g_string_append_c(g_string_i, ' '); g_free(base_dir); } } break; case 'f': /* Works */ if(array_is_init == FALSE){ for(i=0; i<len_file_list; ++i){ g_string_i = g_string_new(out_string->str); file_info_i = fm_list_peek_nth(file_info_list, i); file_name = (gchar *)fm_path_to_str(fm_file_info_get_path(file_info_i)); g_string_append(g_string_i, file_name); g_string_append_c(g_string_i, ' '); g_ptr_array_add(out_string_array, g_string_new(g_string_i->str)); g_free(file_name); g_string_free(g_string_i, TRUE); } break; } file_info_i = fm_list_peek_head(file_info_list); file_name = (gchar *)fm_path_to_str(fm_file_info_get_path(file_info_i)); for(i=0; i<out_string_array->len; ++i){ g_string_i = (GString *)g_ptr_array_index(out_string_array, i); g_string_append(g_string_i, file_name); g_string_append_c(g_string_i, ' '); } g_free(file_name); break; case 'F': /* Works */ if(array_is_init == FALSE) g_ptr_array_add(out_string_array, g_string_new(out_string->str)); for(i=0; i<out_string_array->len; ++i){ g_string_i = (GString *)g_ptr_array_index(out_string_array, i); for(j=0; j<len_file_list; ++j){ file_info_j= fm_list_peek_nth(file_info_list, j); file_name = (gchar *)fm_path_to_str(fm_file_info_get_path(file_info_j)); g_string_append(g_string_i, file_name); g_string_append_c(g_string_i, ' '); g_free(file_name); } } break; case 'h': if(array_is_init == FALSE) g_ptr_array_add(out_string_array, g_string_new(out_string->str)); for(i=0; i<out_string_array->len; ++i){ g_string_i = (GString *)g_ptr_array_index(out_string_array, i); file_info_i = fm_list_peek_nth(file_info_list, i); host_name = get_host_name(file_info_i); g_string_append(g_string_i, host_name); g_string_append_c(g_string_i, ' '); } break; case 'n': if(array_is_init == FALSE) g_ptr_array_add(out_string_array, g_string_new(out_string->str)); for(i=0; i<out_string_array->len; ++i){ g_string_i = (GString *)g_ptr_array_index(out_string_array, i); file_info_i = fm_list_peek_nth(file_info_list, i); user_name = get_user_name(file_info_i); g_string_append(g_string_i, user_name); g_string_append_c(g_string_i, ' '); } break; case 'p': if(array_is_init == FALSE) g_ptr_array_add(out_string_array, g_string_new(out_string->str)); for(i=0; i<out_string_array->len; ++i){ g_string_i = (GString *)g_ptr_array_index(out_string_array, i); file_info_i = fm_list_peek_nth(file_info_list, i); port = get_port(file_info_i); g_string_append(g_string_i, port); g_string_append_c(g_string_i, ' '); } break; case 's': if(array_is_init == FALSE) g_ptr_array_add(out_string_array, g_string_new(out_string->str)); for(i=0; i<out_string_array->len; ++i){ g_string_i = (GString *)g_ptr_array_index(out_string_array, i); file_info_i = fm_list_peek_nth(file_info_list, i); scheme = get_scheme(file_info_i); g_string_append(g_string_i, scheme); g_string_append_c(g_string_i, ' '); } break; case 'u': /* Works */ if(array_is_init == FALSE){ for(i=0; i<len_file_list; ++i){ g_string_i = g_string_new(out_string->str); file_info_i = fm_list_peek_nth(file_info_list, i); uri = fm_path_to_uri(fm_file_info_get_path(file_info_i)); g_string_append(g_string_i, uri); g_string_append_c(g_string_i, ' '); g_ptr_array_add(out_string_array, g_string_new(g_string_i->str)); g_string_free(g_string_i, TRUE); } break; } file_info_i = fm_list_peek_head(file_info_list); uri = fm_path_to_uri(fm_file_info_get_path(file_info_i)); for(i=0; i<out_string_array->len; ++i){ g_string_i = (GString *)g_ptr_array_index(out_string_array, i); g_string_append(g_string_i, uri); g_string_append_c(g_string_i, ' '); } break; case 'U': /* Works */ if(array_is_init == FALSE) g_ptr_array_add(out_string_array, g_string_new(out_string->str)); for(i=0; i<out_string_array->len; ++i){ g_string_i = (GString *)g_ptr_array_index(out_string_array, i); for(j=0; j<len_file_list; ++j){ file_info_j= fm_list_peek_nth(file_info_list, j); uri = fm_path_to_uri(fm_file_info_get_path(file_info_j)); g_string_append(g_string_i, uri); g_string_append_c(g_string_i, ' '); } } break; case 'w': /* Works */ if(array_is_init == FALSE){ for(i=0; i<len_file_list; ++i){ g_string_i = g_string_new(out_string->str); file_info_i = fm_list_peek_nth(file_info_list, i); file_name = (gchar *)fm_file_info_get_disp_name(file_info_i); //printf("%s\n", file_name); ext_pos = g_strrstr(fm_file_info_get_disp_name(fm_list_peek_nth(file_info_list, i)), "."); if(ext_pos != NULL) file_name_wo_ext = g_strndup(file_name, strlen(file_name) - strlen(ext_pos)); else file_name_wo_ext = g_strdup(file_name); g_string_append(g_string_i, file_name_wo_ext); g_string_append_c(g_string_i, ' '); g_ptr_array_add(out_string_array, g_string_new(g_string_i->str)); g_free(file_name_wo_ext); g_string_free(g_string_i, TRUE); } break; } file_info_i = fm_list_peek_head(file_info_list); file_name = (gchar *)fm_file_info_get_disp_name(file_info_i); ext_pos = g_strrstr(file_name, "."); if(ext_pos != NULL) file_name_wo_ext = g_strndup(file_name, strlen(file_name) - strlen(ext_pos)); else file_name_wo_ext = g_strdup(file_name); for(i=0; i<out_string_array->len; ++i){ g_string_i = (GString *)g_ptr_array_index(out_string_array, i); g_string_append(g_string_i, file_name_wo_ext); g_string_append_c(g_string_i, ' '); } g_free(file_name_wo_ext); break; case 'W': /* Works */ if(array_is_init == FALSE) g_ptr_array_add(out_string_array, g_string_new(out_string->str)); for(i=0; i<out_string_array->len; ++i){ g_string_i = (GString *)g_ptr_array_index(out_string_array, i); for(j=0; j<len_file_list; ++j){ file_info_j= fm_list_peek_nth(file_info_list, j); file_name = (gchar *)fm_file_info_get_disp_name(file_info_j); ext_pos = g_strrstr(file_name, "."); if(ext_pos != NULL) file_name_wo_ext = g_strndup(file_name, strlen(file_name) - strlen(ext_pos)); else file_name_wo_ext = g_strdup(file_name); g_string_append(g_string_i, file_name_wo_ext); g_string_append_c(g_string_i, ' '); g_free(file_name_wo_ext); } } break; case 'x': /* Works */ if(array_is_init == FALSE){ for(i=0; i<len_file_list; ++i){ file_info_i = fm_list_peek_nth(file_info_list, i); file_name = (gchar *)fm_file_info_get_disp_name(file_info_i); ext_pos = g_strrstr(file_name, "."); if(ext_pos != NULL){ g_string_i = g_string_new(out_string->str); g_string_append(g_string_i, ext_pos); g_string_append_c(g_string_i, ' '); g_ptr_array_add(out_string_array, g_string_new(g_string_i->str)); g_free(file_name_wo_ext); g_string_free(g_string_i, TRUE); } } break; } file_info_i = fm_list_peek_head(file_info_list); file_name = (gchar *)fm_file_info_get_disp_name(file_info_i); ext_pos = g_strrstr(file_name, "."); if(ext_pos == NULL) break; for(i=0; i<out_string_array->len;++i){ g_string_i = (GString *)g_ptr_array_index(out_string_array, i); g_string_append(g_string_i, ext_pos); g_string_append_c(g_string_i, ' '); } break; case 'X': /* Works */ if(array_is_init == FALSE) g_ptr_array_add(out_string_array, g_string_new(out_string->str)); for(i=0; i<out_string_array->len; ++i){ g_string_i = (GString *)g_ptr_array_index(out_string_array, i); for(j=0; j<len_file_list; ++j){ file_info_j= fm_list_peek_nth(file_info_list, j); file_name = (gchar *)fm_file_info_get_disp_name(file_info_j); ext_pos = g_strrstr(file_name, "."); if(ext_pos != NULL){ g_string_append(g_string_i, ext_pos); g_string_append_c(g_string_i, ' '); } } } break; case '%': /* Works */ if(array_is_init == FALSE) g_ptr_array_add(out_string_array, g_string_new(out_string->str)); for(i=0; i<out_string_array->len; ++i){ g_string_i = (GString *)g_ptr_array_index(out_string_array, i); g_string_append(g_string_i, "% "); } break; default: return NULL; } pos += 2; (array_is_init == FALSE)?array_is_init = TRUE:0; } return out_string_array; }
static void on_folder_view_sel_changed(FmFolderView* fv, FmFileInfoList* files, FmTabPage* page) { char* msg = page->status_text[FM_STATUS_TEXT_SELECTED_FILES]; g_free(msg); msg = NULL; // use SI metric by default static gboolean use_si_prefix = TRUE ; unsigned items_num = 0; if (files) items_num = fm_list_get_length(files) ; if (items_num > 1) // multiple items are selected { goffset items_totalsize = 0 ; // whether selected items contain dir gboolean items_contain_dir = FALSE ; GList* l; for (l=fm_list_peek_head_link(files);l;l=l->next) { FmFileInfo* fi = (FmFileInfo*)l->data; // ignore dir when calculating total size. because that // may take a long long time, not suitable for updating // statusbar in real time. if (fm_file_info_is_dir(fi) ) { items_contain_dir = TRUE; } else { // Non-dir items are regard as files // Should extra logic be added for different kinds of files? // hardlink, symlink, pipe, socket ? items_totalsize += fm_file_info_get_size(fi) ; } } // when the selected items contain dir, do not show size info on the // statusbar, because the calculated total size counts for files only // and showing it would be misleading to the user. if (items_contain_dir) { msg = g_strdup_printf("%d items selected", items_num); } else { char items_totalsize_str[ 64 ]; fm_file_size_to_str( items_totalsize_str, items_totalsize, use_si_prefix ); msg = g_strdup_printf("%d items selected, total size: %s", \ items_num, items_totalsize_str); } } else if (items_num == 1) { FmFileInfo* fi = fm_list_peek_head(files); const char* size_str = fm_file_info_get_disp_size(fi); gboolean is_link = fm_file_info_is_symlink(fi); if (is_link && size_str) { msg = g_strdup_printf("\"%s\" link to \"%s\" (%s)", fm_file_info_get_disp_name(fi), fm_file_info_get_target(fi), size_str); } else if (is_link) { msg = g_strdup_printf("\"%s\" link to \"%s\"", fm_file_info_get_disp_name(fi), fm_file_info_get_target(fi)); } else if (size_str) { msg = g_strdup_printf("\"%s\" (%s) %s", fm_file_info_get_disp_name(fi), size_str, fm_file_info_get_desc(fi)); } else { msg = g_strdup_printf("\"%s\" %s", fm_file_info_get_disp_name(fi), fm_file_info_get_desc(fi)); } } page->status_text[FM_STATUS_TEXT_SELECTED_FILES] = msg; g_signal_emit(page, signals[STATUS], 0, (guint)FM_STATUS_TEXT_SELECTED_FILES, msg); }
gboolean fm_dnd_dest_drag_data_received(FmDndDest* dd, GdkDragContext *drag_context, gint x, gint y, GtkSelectionData *sel_data, guint info, guint time) { FmList* files = NULL; GtkWidget *dest_widget = dd->widget; if(info == FM_DND_DEST_TARGET_FM_LIST) { if((sel_data->length >= 0) && (sel_data->format==8)) { /* get the pointer */ memcpy(&files, sel_data->data, sel_data->length); if(files) fm_list_ref(files); if(files) { FmFileInfo* fi = FM_FILE_INFO(fm_list_peek_head(files)); /* get the device of the first dragged source file */ if(fm_path_is_native(fi->path)) dd->src_dev = fi->dev; else dd->src_fs_id = fi->fs_id; } } } else if(info == FM_DND_DEST_TARGET_URI_LIST) { if((sel_data->length >= 0) && (sel_data->format==8)) { gchar **uris; uris = gtk_selection_data_get_uris( sel_data ); files = fm_path_list_new_from_uris((const char **)uris); g_free(uris); if(files) { GFileInfo* inf; FmPath* path = FM_PATH(fm_list_peek_head(files)); GFile* gf = fm_path_to_gfile(path); const char* attr = fm_path_is_native(path) ? G_FILE_ATTRIBUTE_UNIX_DEVICE : G_FILE_ATTRIBUTE_ID_FILESYSTEM; inf = g_file_query_info(gf, attr, G_FILE_QUERY_INFO_NOFOLLOW_SYMLINKS, NULL, NULL); g_object_unref(gf); if(fm_path_is_native(path)) dd->src_dev = g_file_info_get_attribute_uint32(inf, G_FILE_ATTRIBUTE_UNIX_DEVICE); else dd->src_fs_id = g_intern_string(g_file_info_get_attribute_string(inf, G_FILE_ATTRIBUTE_ID_FILESYSTEM)); g_object_unref(inf); } } } else if(info == FM_DND_DEST_TARGET_XDS) /* X direct save */ { if( sel_data->format == 8 && sel_data->length == 1 && sel_data->data[0] == 'F') { gdk_property_change(GDK_DRAWABLE(drag_context->source_window), xds_target_atom, gdk_atom_intern_static_string("text/plain"), 8, GDK_PROP_MODE_REPLACE, (const guchar *)"", 0); } else if(sel_data->format == 8 && sel_data->length == 1 && sel_data->data[0] == 'S') { /* XDS succeeds */ } gtk_drag_finish(drag_context, TRUE, FALSE, time); return TRUE; } else return FALSE; /* remove previously cached source files. */ if(G_UNLIKELY(dd->src_files)) { fm_list_unref(dd->src_files); dd->src_files = NULL; } dd->src_files = files; dd->waiting_data = FALSE; dd->info_type = info; return TRUE; }
GtkWidget *fm_file_properties_widget_new (FmFileInfoList *files, gboolean toplevel) { GtkBuilder *builder=gtk_builder_new (); GtkWidget *dlg, *total_size; FmFilePropData *data; FmPathList *paths; gtk_builder_set_translation_domain (builder, GETTEXT_PACKAGE); data = g_slice_new0 (FmFilePropData); data->files = fm_list_ref (files); data->single_type = fm_file_info_list_is_same_type (files); data->single_file = (fm_list_get_length (files) == 1); data->file_info = fm_list_peek_head (files); FmMimeType *fi_mime_type = fm_file_info_get_mime_type (data->file_info, FALSE); if (data->single_type) data->mime_type = fi_mime_type; // FIXME_pcm: do we need ref counting here? paths = fm_path_list_new_from_file_info_list (files); data->dc_job = fm_deep_count_job_new (paths, FM_DC_JOB_DEFAULT); fm_list_unref (paths); if (toplevel) { gtk_builder_add_from_string (builder, PROPERTIES_DLG, -1, NULL); GET_WIDGET (dlg); gtk_dialog_set_alternative_button_order (GTK_DIALOG (data->dlg), GTK_RESPONSE_OK, GTK_RESPONSE_CANCEL, -1); } else { #if 0 // FIXME_pcm: is this really useful? const char *names[]= {"notebook", NULL}; gtk_builder_add_objects_from_file (builder, UI_FILE, names, NULL); data->dlg = (GtkWidget*)gtk_builder_get_object (builder, "notebook"); #endif } dlg = data->dlg; GET_WIDGET (icon); GET_WIDGET (name); GET_WIDGET (dir); GET_WIDGET (target); GET_WIDGET (target_label); GET_WIDGET (type); GET_WIDGET (open_with_label); GET_WIDGET (open_with); GET_WIDGET (total_size); GET_WIDGET (size_on_disk); GET_WIDGET (mtime); GET_WIDGET (atime); GET_WIDGET (owner); GET_WIDGET (group); GET_WIDGET (owner_perm); GET_WIDGET (group_perm); GET_WIDGET (other_perm); GET_WIDGET (exec); g_object_unref (builder); init_application_list (data); data->timeout = g_timeout_add (600, (GSourceFunc)on_timeout, data); g_signal_connect (dlg, "response", G_CALLBACK (on_response), data); g_signal_connect_swapped (dlg, "destroy", G_CALLBACK (fm_file_prop_data_free), data); g_signal_connect (data->dc_job, "finished", G_CALLBACK (on_finished), data); fm_job_run_async (data->dc_job); update_ui (data); return dlg; }
static void update_ui (FmFilePropData *data) { GtkImage *img = (GtkImage*) data->icon; if ( data->single_type ) // all files are of the same mime-type { GIcon *icon = NULL; // FIXME_pcm: handle custom icons for some files /* FIXME_pcm: display special property pages for special files or * some specified mime-types. */ if ( data->single_file ) // only one file is selected. { FmFileInfo *file_info = (FmFileInfo*)fm_list_peek_head (data->files); icon = fm_file_info_get_gicon (file_info); } if (data->mime_type) { if (!icon) { FmIcon *ficon = fm_mime_type_get_icon (data->mime_type); if (ficon) icon = ficon->gicon; } gtk_label_set_text (GTK_LABEL (data->type), fm_mime_type_get_desc (data->mime_type)); } if (icon) gtk_image_set_from_gicon (img, icon, GTK_ICON_SIZE_DIALOG); if ( data->single_file && fm_file_info_is_symlink (data->file_info) ) { gtk_widget_show (data->target_label); gtk_widget_show (data->target); gtk_label_set_text (GTK_LABEL (data->target), fm_file_info_get_target (data->file_info)); // gtk_label_set_text (data->type, fm_mime_type_get_desc (data->mime_type)); } else { gtk_widget_destroy (data->target_label); gtk_widget_destroy (data->target); } } else { gtk_image_set_from_stock (img, GTK_STOCK_DND_MULTIPLE, GTK_ICON_SIZE_DIALOG); gtk_widget_set_sensitive (data->name, FALSE); gtk_label_set_text (GTK_LABEL (data->type), _("Files of different types")); gtk_widget_destroy (data->target_label); gtk_widget_destroy (data->target); gtk_widget_destroy (data->open_with_label); gtk_widget_destroy (data->open_with); data->open_with = data->open_with_label = NULL; } // FIXME_pcm: check if all files has the same parent dir, mtime, or atime if ( data->single_file ) { char buf[128]; FmPath *parent = fm_path_get_parent (fm_file_info_get_path (data->file_info)); char *parent_str = parent ? fm_path_display_name (parent, TRUE) : NULL; gtk_entry_set_text (GTK_ENTRY (data->name), fm_file_info_get_disp_name (data->file_info)); if (parent_str) { gtk_label_set_text (GTK_LABEL (data->dir), parent_str); g_free (parent_str); } else gtk_label_set_text (GTK_LABEL (data->dir), ""); gtk_label_set_text (GTK_LABEL (data->mtime), fm_file_info_get_disp_mtime (data->file_info)); // FIXME_pcm: need to encapsulate this in an libfm API. strftime ( buf, sizeof ( buf ), "%x %R", localtime ( &data->file_info->atime ) ); gtk_label_set_text (GTK_LABEL (data->atime), buf); } else { gtk_entry_set_text (GTK_ENTRY (data->name), _("Multiple Files")); gtk_widget_set_sensitive (data->name, FALSE); } update_permissions (data); on_timeout (data); }
// FIXME_pcm: this is too dirty. Need some refactor later. static void update_permissions (FmFilePropData *data) { FmFileInfo *file_info = (FmFileInfo*)fm_list_peek_head (data->files); GList *l; int sel; char *tmp; mode_t owner_perm = (file_info->mode & S_IRWXU); mode_t group_perm = (file_info->mode & S_IRWXG); mode_t other_perm = (file_info->mode & S_IRWXO); mode_t exec_perm = (file_info->mode & (S_IXUSR|S_IXGRP|S_IXOTH)); uid_t uid = file_info->uid; gid_t gid = file_info->gid; struct group *grp = NULL; struct passwd *pw = NULL; data->all_native = fm_path_is_native (fm_file_info_get_path (file_info)); data->has_dir = S_ISDIR (file_info->mode) != FALSE; for (l=fm_list_peek_head_link (data->files)->next; l; l=l->next) { FmFileInfo *file_info = (FmFileInfo*)l->data; if ( !fm_path_is_native (fm_file_info_get_path (file_info)) ) data->all_native = FALSE; if (S_ISDIR (file_info->mode)) data->has_dir = TRUE; if ( uid != file_info->uid ) uid = -1; if ( gid != file_info->gid ) gid = -1; if ( owner_perm != -1 && owner_perm != (file_info->mode & S_IRWXU) ) owner_perm = -1; if ( group_perm != -1 && group_perm != (file_info->mode & S_IRWXG) ) group_perm = -1; if ( other_perm != -1 && other_perm != (file_info->mode & S_IRWXO) ) other_perm = -1; if ( exec_perm != (file_info->mode & (S_IXUSR|S_IXGRP|S_IXOTH)) ) exec_perm = -1; } if ( data->all_native ) { if ( uid >= 0 ) { pw = getpwuid (uid); if (pw) gtk_entry_set_text (GTK_ENTRY (data->owner), pw->pw_name); } if ( gid >= 0 ) { grp = getgrgid (gid); if (grp) gtk_entry_set_text (GTK_ENTRY (data->group), grp->gr_name); } } if ( uid >=0 && !pw ) { tmp = g_strdup_printf ("%u", uid); gtk_entry_set_text (GTK_ENTRY (data->owner), tmp); g_free (tmp); } if ( gid >=0 && !grp ) { tmp = g_strdup_printf ("%u", gid); gtk_entry_set_text (GTK_ENTRY (data->group), tmp); g_free (tmp); } data->orig_owner = g_strdup (gtk_entry_get_text (GTK_ENTRY (data->owner))); data->orig_group = g_strdup (gtk_entry_get_text (GTK_ENTRY (data->group))); // on local filesystems, only root can do chown. if ( data->all_native && geteuid () != 0 ) { gtk_editable_set_editable (GTK_EDITABLE (data->owner), FALSE); gtk_editable_set_editable (GTK_EDITABLE (data->group), FALSE); } sel = NO_CHANGE; if (owner_perm != -1) { if ( (owner_perm & (S_IRUSR|S_IWUSR)) == (S_IRUSR|S_IWUSR) ) sel = READ_WRITE; else if ( (owner_perm & (S_IRUSR|S_IWUSR)) == S_IRUSR ) sel = READ_ONLY; else if ( (owner_perm & (S_IRUSR|S_IWUSR)) == S_IWUSR ) sel = WRITE_ONLY; else sel = NONE; } gtk_combo_box_set_active (GTK_COMBO_BOX (data->owner_perm), sel); data->owner_perm_sel = sel; sel = NO_CHANGE; if (group_perm != -1) { if ( (group_perm & (S_IRGRP|S_IWGRP)) == (S_IRGRP|S_IWGRP) ) sel = READ_WRITE; else if ( (group_perm & (S_IRGRP|S_IWGRP)) == S_IRGRP ) sel = READ_ONLY; else if ( (group_perm & (S_IRGRP|S_IWGRP)) == S_IWGRP ) sel = WRITE_ONLY; else sel = NONE; } gtk_combo_box_set_active (GTK_COMBO_BOX (data->group_perm), sel); data->group_perm_sel = sel; sel = NO_CHANGE; if (other_perm != -1) { if ( (other_perm & (S_IROTH|S_IWOTH)) == (S_IROTH|S_IWOTH) ) sel = READ_WRITE; else if ( (other_perm & (S_IROTH|S_IWOTH)) == S_IROTH ) sel = READ_ONLY; else if ( (other_perm & (S_IROTH|S_IWOTH)) == S_IWOTH ) sel = WRITE_ONLY; else sel = NONE; } gtk_combo_box_set_active (GTK_COMBO_BOX (data->other_perm), sel); data->other_perm_sel = sel; if (data->has_dir) gtk_widget_hide ( data->exec ); if ( exec_perm != -1 ) { gboolean xusr = (exec_perm & S_IXUSR) != 0; gboolean xgrp = (exec_perm & S_IXGRP) != 0; gboolean xoth = (exec_perm & S_IXOTH) != 0; if ( xusr == xgrp && xusr == xoth ) // executable { gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (data->exec), xusr); data->exec_state = xusr; } else // inconsistent { gtk_toggle_button_set_inconsistent (GTK_TOGGLE_BUTTON (data->exec), TRUE); g_signal_connect (data->exec, "toggled", G_CALLBACK (on_exec_toggled), data); data->exec_state = -1; } } else // inconsistent { gtk_toggle_button_set_inconsistent (GTK_TOGGLE_BUTTON (data->exec), TRUE); g_signal_connect (data->exec, "toggled", G_CALLBACK (on_exec_toggled), data); data->exec_state = -1; } }