gchar *get_scheme(FmFileInfo *file_info) { gchar *uri = fm_path_to_uri(fm_file_info_get_path(file_info)); gchar *scheme = g_uri_parse_scheme(uri); return scheme; }
gboolean save_bookmarks(FmBookmarks* bookmarks) { FILE* f; FmBookmarkItem* item; GList* l; GString* buf = g_string_sized_new(1024); char* fpath; for( l=bookmarks->items; l; l=l->next ) { char* uri; item = (FmBookmarkItem*)l->data; uri = fm_path_to_uri(item->path); g_string_append(buf, uri); g_free(uri); g_string_append_c(buf, ' '); g_string_append(buf, item->name); g_string_append_c(buf, '\n'); } fpath = get_bookmarks_file(); g_file_set_contents(fpath, buf->str, buf->len, NULL); g_free(fpath); g_string_free(buf, TRUE); return FALSE; }
gchar *get_host_name(FmFileInfo *file_info) { /* TODO: Update to support IPv6. Different rules just for IPv6. Hence, ignoring */ gchar *host_name = NULL; gsize host_length; gchar *uri = fm_path_to_uri(fm_file_info_get_path(file_info)); gchar *user_pos = strchr(uri, ':'); if(user_pos == NULL) return ""; user_pos += 1; if(strncmp(user_pos, "//", 2) == 0) user_pos += 2; gchar *host_pos = strchr(uri, '@'); if(host_pos == NULL) host_pos = user_pos; else host_pos += 1; if(strchr(host_pos, ':') != NULL){ host_length = strcspn(host_pos, ":"); host_name = g_strndup(host_pos, host_length); } else { printf("here\n"); host_length = strcspn(host_pos, "/"); host_name = g_strndup(host_pos, host_length); } return host_name; }
void fm_path_list_write_uri_list(FmPathList* pl, GString* buf) { GList* l; for(l = fm_list_peek_head_link(pl); l; l=l->next) { FmPath* path = (FmPath*)l->data; char* uri = fm_path_to_uri(path); g_string_append(buf, uri); g_free(uri); if(l->next) g_string_append(buf, "\r\n"); } }
gchar *get_port(FmFileInfo *file_info) { /* TODO: Update for IPv6 support */ gchar *uri = fm_path_to_uri(fm_file_info_get_path(file_info)); gchar *user_pos = strchr(uri, ':') + 1; user_pos += 1; if(strncmp(user_pos, "//", 2) == 0) user_pos += 2; gchar *port_pos = strchr(user_pos, ':'); if(port_pos == NULL) return ""; gsize port_length = strcspn(port_pos, "/"); gchar *port = g_strndup(port_pos, port_length) + 1; return port; }
static void on_drag_data_get ( GtkWidget *src_widget, GdkDragContext *drag_context, GtkSelectionData *sel_data, guint info, guint time, FmDndSrc* ds ) { GdkAtom type; /* Don't call the default handler */ g_signal_stop_emission_by_name( src_widget, "drag-data-get" ); drag_context->actions = GDK_ACTION_MOVE | GDK_ACTION_COPY | GDK_ACTION_LINK; type = gdk_atom_intern_static_string(fm_default_dnd_src_targets[info].target); switch( info ) { case FM_DND_SRC_TARGET_FM_LIST: /* just store the pointer in GtkSelection since this is used * within the same app. */ gtk_selection_data_set(sel_data, type, 8, &ds->files, sizeof(gpointer)); break; case FM_DND_SRC_TARGET_URI_LIST: { gchar* uri; GString* uri_list = g_string_sized_new( 8192 ); GList* l; FmFileInfo* file; char* full_path; for( l = fm_list_peek_head_link(ds->files); l; l=l->next ) { file = (FmFileInfo*)l->data; uri = fm_path_to_uri(file->path); g_string_append( uri_list, uri ); g_free( uri ); g_string_append( uri_list, "\r\n" ); } gtk_selection_data_set ( sel_data, type, 8, ( guchar* ) uri_list->str, uri_list->len + 1 ); g_string_free( uri_list, TRUE ); } break; } }
gchar *get_user_name(FmFileInfo *file_info) { gchar *uri = fm_path_to_uri(fm_file_info_get_path(file_info)); gsize user_length; gchar *user_pos = NULL, *user_name = NULL; user_pos = strchr(uri, ':'); if(user_pos == NULL) return ""; user_pos += 1; if(strncmp(user_pos, "//", 2) == 0) user_pos += 2; if(strchr(user_pos, '@') != NULL){ user_length = strcspn(user_pos, "@"); user_name = g_strndup(user_pos, user_length); } else { user_name = ""; } return user_name; }
// FIXME_pcm: error handling static gboolean launch_program (FmArchiver *archiver, GAppLaunchContext *ctx, const char *cmd, FmPathList *files, FmPath *dir) { GDesktopAppInfo *app; char *_cmd = NULL; const char *dir_place_holder; GKeyFile *dummy; char *tmp; if (dir && (dir_place_holder = strstr (cmd, "%d"))) { char *dir_str; int len; if (strstr (cmd, "%U") || strstr (cmd, "%u")) // supports URI dir_str = fm_path_to_uri (dir); else { GFile *gf = fm_path_to_gfile (dir); // FIXME_pcm: convert dir to fuse-based local path if needed. dir_str = g_file_get_path (gf); g_object_unref (gf); } // replace all % with %% so encoded URI can be handled correctly when parsing Exec key. tmp = fm_str_replace (dir_str, "%", "%%"); g_free (dir_str); dir_str = tmp; // quote the path or URI tmp = g_shell_quote (dir_str); g_free (dir_str); dir_str = tmp; len = strlen (cmd) - 2 + strlen (dir_str) + 1; _cmd = g_malloc (len); len = (dir_place_holder - cmd); strncpy (_cmd, cmd, len); strcpy (_cmd + len, dir_str); strcat (_cmd, dir_place_holder + 2); g_free (dir_str); cmd = _cmd; } // create a fake key file to cheat GDesktopAppInfo dummy = g_key_file_new (); g_key_file_set_string (dummy, G_KEY_FILE_DESKTOP_GROUP, "Type", "Application"); g_key_file_set_string (dummy, G_KEY_FILE_DESKTOP_GROUP, "Name", archiver->program); // replace all % with %% so encoded URI can be handled correctly when parsing Exec key. g_key_file_set_string (dummy, G_KEY_FILE_DESKTOP_GROUP, "Exec", cmd); app = g_desktop_app_info_new_from_keyfile (dummy); g_key_file_free (dummy); g_debug ("cmd = %s", cmd); if (app) { GList *uris = NULL, *l; for (l = fm_list_peek_head_link (files); l; l=l->next) { FmPath *path = FM_PATH (l->data); uris = g_list_prepend (uris, fm_path_to_uri (path)); } fm_app_info_launch_uris ((GAppInfo *) app, uris, ctx, NULL); g_list_foreach (uris, (GFunc)g_free, NULL); g_list_free (uris); } g_free (_cmd); return TRUE; }
gboolean fm_launch_files(GAppLaunchContext* ctx, GList* file_infos, FmFileLauncher* launcher, gpointer user_data) { GList* l; GHashTable* hash = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, NULL); GList* folders = NULL; FmFileInfo* fi; GError* err = NULL; GAppInfo* app; for(l = file_infos; l; l=l->next) { GList* fis; fi = (FmFileInfo*)l->data; if(fm_file_info_is_dir(fi)) folders = g_list_prepend(folders, fi); else { /* FIXME: handle shortcuts, such as the items in menu:// */ if(fm_path_is_native(fi->path)) { char* filename; if(fm_file_info_is_desktop_entry(fi)) { /* if it's a desktop entry file, directly launch it. */ filename = fm_path_to_str(fi->path); if(!fm_launch_desktop_entry(ctx, filename, NULL, &err)) { if(launcher->error) launcher->error(ctx, err, user_data); g_error_free(err); err = NULL; } continue; } else if(fm_file_info_is_executable_type(fi)) { /* if it's an executable file, directly execute it. */ filename = fm_path_to_str(fi->path); /* FIXME: we need to use eaccess/euidaccess here. */ if(g_file_test(filename, G_FILE_TEST_IS_EXECUTABLE)) { app = g_app_info_create_from_commandline(filename, NULL, 0, NULL); if(app) { if(!g_app_info_launch(app, NULL, ctx, &err)) { if(launcher->error) launcher->error(ctx, err, user_data); g_error_free(err); err = NULL; } g_object_unref(app); continue; } } g_free(filename); } } else /* not a native path */ { if(fm_file_info_is_shortcut(fi) && !fm_file_info_is_dir(fi)) { /* FIXME: special handling for shortcuts */ if(fm_path_is_xdg_menu(fi->path) && fi->target) { if(!fm_launch_desktop_entry(ctx, fi->target, NULL, &err)) { if(launcher->error) launcher->error(ctx, err, user_data); g_error_free(err); err = NULL; } continue; } } } if(fi->type && fi->type->type) { fis = g_hash_table_lookup(hash, fi->type->type); fis = g_list_prepend(fis, fi); g_hash_table_insert(hash, fi->type->type, fis); } } } if(g_hash_table_size(hash) > 0) { GHashTableIter it; const char* type; GList* fis; g_hash_table_iter_init(&it, hash); while(g_hash_table_iter_next(&it, &type, &fis)) { GAppInfo* app = g_app_info_get_default_for_type(type, FALSE); if(!app) { if(launcher->get_app) { FmMimeType* mime_type = ((FmFileInfo*)fis->data)->type; app = launcher->get_app(fis, mime_type, user_data, NULL); } } if(app) { for(l=fis; l; l=l->next) { char* uri; fi = (FmFileInfo*)l->data; uri = fm_path_to_uri(fi->path); l->data = uri; } fis = g_list_reverse(fis); g_app_info_launch_uris(app, fis, ctx, err); /* free URI strings */ g_list_foreach(fis, (GFunc)g_free, NULL); g_object_unref(app); } g_list_free(fis); } } g_hash_table_destroy(hash); if(folders) { folders = g_list_reverse(folders); if(launcher->open_folder) { launcher->open_folder(ctx, folders, user_data, &err); if(err) { if(launcher->error) launcher->error(ctx, err, user_data); g_error_free(err); err = NULL; } } g_list_free(folders); } return TRUE; }
/* 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; }
gboolean fm_dnd_dest_drag_drop(FmDndDest* dd, GdkDragContext *drag_context, GdkAtom target, guint time) { gboolean ret = FALSE; GtkWidget* dest_widget = dd->widget; int i; for(i = 0; i < G_N_ELEMENTS(fm_default_dnd_dest_targets); ++i) { if(gdk_atom_intern_static_string(fm_default_dnd_dest_targets[i].target) == target) { ret = TRUE; break; } } if(ret) /* we support this kind of target */ { if(i == FM_DND_DEST_TARGET_XDS) /* if this is XDS */ { guchar *data = NULL; gint len = 0; GdkAtom text_atom = gdk_atom_intern_static_string("text/plain"); /* get filename from the source window */ if(gdk_property_get(drag_context->source_window, xds_target_atom, text_atom, 0, 1024, FALSE, NULL, NULL, &len, &data) && data) { FmFileInfo* dest = fm_dnd_dest_get_dest_file(dd); if( dest && fm_file_info_is_dir(dest) ) { FmPath* path = fm_path_new_child(dest->path, data); char* uri = fm_path_to_uri(path); /* setup the property */ gdk_property_change(GDK_DRAWABLE(drag_context->source_window), xds_target_atom, text_atom, 8, GDK_PROP_MODE_REPLACE, (const guchar *)uri, strlen(uri) + 1); fm_path_unref(path); g_free(uri); } } else { fm_show_error(gtk_widget_get_toplevel(dest_widget), _("XDirectSave failed.")); gdk_property_change(GDK_DRAWABLE(drag_context->source_window), xds_target_atom, text_atom, 8, GDK_PROP_MODE_REPLACE, (const guchar *)"", 0); } g_free(data); gtk_drag_get_data(dest_widget, drag_context, target, time); /* we should call gtk_drag_finish later in data-received callback. */ return TRUE; } /* see if the drag files are cached */ if(dd->src_files) { /* emit files-dropped signal */ g_signal_emit(dd, signals[FILES_DROPPED], 0, drag_context->action, dd->info_type, dd->src_files, &ret); } else /* we don't have the data */ { if(dd->waiting_data) /* if we're still waiting for the data */ { /* FIXME: how to handle this? */ ret = FALSE; } else ret = FALSE; } gtk_drag_finish(drag_context, ret, FALSE, time); } return ret; }
/** * fm_launch_files * @ctx: (allow-none): a launch context * @file_infos: (element-type FmFileInfo): files to launch * @launcher: #FmFileLauncher with callbacks * @user_data: data supplied for callbacks * * Launches files using callbacks in @launcher. * * Returns: %TRUE in case of success. * * Since: 0.1.0 */ gboolean fm_launch_files(GAppLaunchContext* ctx, GList* file_infos, FmFileLauncher* launcher, gpointer user_data) { GList* l; GHashTable* hash = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, NULL); GList *folders = NULL; FmFileInfo* fi; GList *targets = NULL; GError* err = NULL; GAppInfo* app; const char* type; for(l = file_infos; l; l=l->next) { GList* fis; char *filename, *scheme; const char *target = NULL; fi = (FmFileInfo*)l->data; /* special handling for shortcuts */ if (!fm_file_info_is_symlink(fi)) /* symlinks also has fi->target, but we only handle shortcuts here. */ target = fm_file_info_get_target(fi); if (launcher->open_folder && fm_file_info_is_dir(fi)) { /* special handling for shortcuts */ if(target) { fi = _fetch_file_info_for_shortcut(fm_file_info_get_target(fi), ctx, launcher, user_data); if (fi == NULL) /* error was shown by job already */ continue; targets = g_list_prepend(targets, fi); } folders = g_list_prepend(folders, fi); } else if (fm_file_info_is_desktop_entry(fi)) { _launch_desktop_entry: if (!target) filename = fm_path_to_str(fm_file_info_get_path(fi)); fm_launch_desktop_entry(ctx, target ? target : filename, NULL, launcher, user_data); if (!target) g_free(filename); continue; } else { FmPath* path = fm_file_info_get_path(fi); FmMimeType* mime_type = NULL; if(fm_path_is_native(path)) { /* special handling for shortcuts */ if (target) { if (fm_file_info_get_mime_type(fi) == _fm_mime_type_get_inode_x_shortcut()) /* if we already know MIME type then use it instead */ { scheme = g_uri_parse_scheme(target); if (scheme) { /* FIXME: this is rough! */ if (strcmp(scheme, "file") != 0 && strcmp(scheme, "trash") != 0 && strcmp(scheme, "network") != 0 && strcmp(scheme, "computer") != 0 && strcmp(scheme, "menu") != 0) { /* we don't support this URI internally, try GIO */ app = g_app_info_get_default_for_uri_scheme(scheme); if (app) { fis = g_list_prepend(NULL, (char *)target); fm_app_info_launch_uris(app, fis, ctx, &err); g_list_free(fis); g_object_unref(app); } else if (launcher->error) g_set_error(&err, G_IO_ERROR, G_IO_ERROR_FAILED, _("No default application is set to launch URIs %s://"), scheme); if (err) { launcher->error(ctx, err, NULL, user_data); g_clear_error(&err); } g_free(scheme); continue; } g_free(scheme); } } else mime_type = fm_file_info_get_mime_type(fi); /* retrieve file info for target otherwise and handle it */ fi = _fetch_file_info_for_shortcut(target, ctx, launcher, user_data); if (fi == NULL) /* error was shown by job already */ continue; targets = g_list_prepend(targets, fi); path = fm_file_info_get_path(fi); /* special handling for desktop entries */ if (fm_file_info_is_desktop_entry(fi)) goto _launch_desktop_entry; } if(fm_file_info_is_executable_type(fi)) { /* if it's an executable file, directly execute it. */ filename = fm_path_to_str(path); /* FIXME: we need to use eaccess/euidaccess here. */ if(g_file_test(filename, G_FILE_TEST_IS_EXECUTABLE)) { if(launcher->exec_file) { FmFileLauncherExecAction act = launcher->exec_file(fi, user_data); GAppInfoCreateFlags flags = 0; switch(act) { case FM_FILE_LAUNCHER_EXEC_IN_TERMINAL: flags |= G_APP_INFO_CREATE_NEEDS_TERMINAL; /* NOTE: no break here */ case FM_FILE_LAUNCHER_EXEC: { /* filename may contain spaces. Fix #3143296 */ char* quoted = g_shell_quote(filename); app = fm_app_info_create_from_commandline(quoted, NULL, flags, NULL); g_free(quoted); if(app) { char* run_path = g_path_get_dirname(filename); char* cwd = NULL; /* bug #3589641: scripts are ran from $HOME. since GIO launcher is kinda ugly - it has no means to set running directory so we do workaround - change directory to it */ if(run_path && strcmp(run_path, ".")) { cwd = g_get_current_dir(); if(chdir(run_path) != 0) { g_free(cwd); cwd = NULL; if (launcher->error) { g_set_error(&err, G_IO_ERROR, g_io_error_from_errno(errno), _("Cannot set working directory to '%s': %s"), run_path, g_strerror(errno)); launcher->error(ctx, err, NULL, user_data); g_clear_error(&err); } } } g_free(run_path); if(!fm_app_info_launch(app, NULL, ctx, &err)) { if(launcher->error) launcher->error(ctx, err, NULL, user_data); g_error_free(err); err = NULL; } if(cwd) /* return back */ { if(chdir(cwd) != 0) g_warning("fm_launch_files(): chdir() failed"); g_free(cwd); } g_object_unref(app); continue; } break; } case FM_FILE_LAUNCHER_EXEC_OPEN: break; case FM_FILE_LAUNCHER_EXEC_CANCEL: continue; } } } g_free(filename); } } if (mime_type == NULL) mime_type = fm_file_info_get_mime_type(fi); if(mime_type && (type = fm_mime_type_get_type(mime_type))) { fis = g_hash_table_lookup(hash, type); fis = g_list_prepend(fis, fi); g_hash_table_insert(hash, (gpointer)type, fis); } else if (launcher->error) { g_set_error(&err, G_IO_ERROR, G_IO_ERROR_FAILED, _("Could not determine content type of file '%s' to launch it"), fm_file_info_get_disp_name(fi)); launcher->error(ctx, err, NULL, user_data); g_clear_error(&err); } } } if(g_hash_table_size(hash) > 0) { GHashTableIter it; GList* fis; g_hash_table_iter_init(&it, hash); while(g_hash_table_iter_next(&it, (void**)&type, (void**)&fis)) { GAppInfo* app = g_app_info_get_default_for_type(type, FALSE); if(!app) { if(launcher->get_app) { FmMimeType* mime_type = fm_file_info_get_mime_type((FmFileInfo*)fis->data); app = launcher->get_app(fis, mime_type, user_data, NULL); } } if(app) { for(l=fis; l; l=l->next) { char* uri; fi = (FmFileInfo*)l->data; /* special handling for shortcuts */ if (fm_file_info_is_shortcut(fi)) uri = g_strdup(fm_file_info_get_target(fi)); else uri = fm_path_to_uri(fm_file_info_get_path(fi)); l->data = uri; } fis = g_list_reverse(fis); fm_app_info_launch_uris(app, fis, ctx, &err); /* free URI strings */ g_list_foreach(fis, (GFunc)g_free, NULL); g_object_unref(app); } else if (launcher->error) g_set_error(&err, G_IO_ERROR, G_IO_ERROR_FAILED, _("No default application is set for MIME type %s"), type); if (err) { launcher->error(ctx, err, NULL, user_data); g_clear_error(&err); } g_list_free(fis); } } g_hash_table_destroy(hash); if(folders) { folders = g_list_reverse(folders); if(launcher->open_folder) { launcher->open_folder(ctx, folders, user_data, &err); if(err) { if(launcher->error) launcher->error(ctx, err, NULL, user_data); g_error_free(err); err = NULL; } } g_list_free(folders); } g_list_free_full(targets, (GDestroyNotify)fm_file_info_unref); return TRUE; }
gpointer load_thumbnail_thread(gpointer user_data) { ThumbnailTask* task; GChecksum* sum = g_checksum_new(G_CHECKSUM_MD5); gchar* normal_path = g_build_filename(thumb_dir, "normal/00000000000000000000000000000000.png", NULL); gchar* normal_basename = strrchr(normal_path, '/') + 1; gchar* large_path = g_build_filename(thumb_dir, "large/00000000000000000000000000000000.png", NULL); gchar* large_basename = strrchr(large_path, '/') + 1; /* ensure thumbnail directories exists */ g_mkdir_with_parents(normal_path, 0700); g_mkdir_with_parents(large_path, 0700); for(;;) { G_LOCK(queue); task = g_queue_pop_head(&loader_queue); cur_loading = task; if(G_LIKELY(task)) { FmThumbnailRequest* req; char* uri; char* thumb_path; const char* md5; G_UNLOCK(queue); uri = fm_path_to_uri(task->fi->path); /* generate filename for the thumbnail */ g_checksum_update(sum, uri, -1); md5 = g_checksum_get_string(sum); /* md5 sum of the URI */ task->uri = uri; if (task->flags & LOAD_NORMAL) { memcpy( normal_basename, md5, 32 ); task->normal_path = normal_path; } if (task->flags & LOAD_LARGE) { memcpy( large_basename, md5, 32 ); task->large_path = large_path; } load_thumbnails(task); g_checksum_reset(sum); g_free(uri); } else /* no task is left in the loader_queue */ { loader_thread_id = NULL; G_UNLOCK(queue); break; } } g_free(normal_path); g_free(large_path); g_checksum_free(sum); return NULL; }