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)); } }
/********************************************************************* * ... * * ********************************************************************/ gboolean fm_file_info_job_run (FmJob *fmjob) { FmFileInfoJob *job = (FmFileInfoJob*) fmjob; GError *err = NULL; GList *l; for (l = fm_list_peek_head_link (job->file_infos); !fm_job_is_cancelled (fmjob) && l; ) { FmFileInfo *file_info = (FmFileInfo*) l->data; GList *next = l->next; job->current = file_info->path; if (fm_path_is_native (file_info->path)) { char *path_str = fm_path_to_str (file_info->path); // FileInfo rework: new function for testing... // this one is not cancellable and doesn't handle errors... // if (!fm_file_info_job_get_info_for_native_file (FM_JOB (job), file_info, path_str, &err)) if (!fm_file_info_set_for_native_file (file_info, path_str)) { //~ FmJobErrorAction act = fm_job_emit_error (FM_JOB(job), err, FM_JOB_ERROR_MILD); //~ //~ g_error_free (err); //~ err = NULL; //~ //~ if (act == FM_JOB_RETRY) //~ continue; DEBUG ("fm_file_info_set_for_native_file: error reading %s\n", path_str); next = l->next; fm_list_delete_link (job->file_infos, l); // Also calls unref... } g_free (path_str); } else { GFile *gf; if (fm_path_is_virtual (file_info->path)) { // This is a xdg menu if (fm_path_is_xdg_menu (file_info->path)) { MenuCache *mc; MenuCacheDir *dir; char *path_str = fm_path_to_str (file_info->path); char *menu_name = path_str + 5, ch; char *dir_name; while (*menu_name == '/') ++menu_name; dir_name = menu_name; while (*dir_name && *dir_name != '/') ++dir_name; ch = *dir_name; *dir_name = '\0'; menu_name = g_strconcat (menu_name, ".menu", NULL); mc = menu_cache_lookup_sync (menu_name); g_free (menu_name); if (*dir_name && !(*dir_name == '/' && dir_name[1] == '\0')) { char *tmp = g_strconcat ("/", menu_cache_item_get_id (MENU_CACHE_ITEM(menu_cache_get_root_dir (mc))), dir_name, NULL); dir = menu_cache_get_dir_from_path (mc, tmp); g_free (tmp); } else { dir = menu_cache_get_root_dir (mc); } if (dir) { fm_file_info_set_from_menu_cache_item (file_info, (MenuCacheItem*) dir); } else { next = l->next; fm_list_delete_link (job->file_infos, l); // Also calls unref... } g_free (path_str); menu_cache_unref (mc); l = l->next; continue; } } gf = fm_path_to_gfile (file_info->path); if (!fm_file_info_job_get_info_for_gfile (FM_JOB (job), file_info, gf, &err)) { FmJobErrorAction act = fm_job_emit_error (FM_JOB (job), err, FM_JOB_ERROR_MILD); g_error_free (err); err = NULL; if (act == FM_JOB_RETRY) continue; next = l->next; fm_list_delete_link (job->file_infos, l); // Also calls unref... } g_object_unref (gf); } l = next; } return TRUE; }