示例#1
0
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));
    }
}
示例#2
0
文件: fm-dnd-dest.c 项目: engla/libfm
static void fm_dnd_dest_finalize(GObject *object)
{
    FmDndDest *dd;

    g_return_if_fail(object != NULL);
    g_return_if_fail(FM_IS_DND_DEST(object));

    dd = FM_DND_DEST(object);

    fm_dnd_dest_set_widget(dd, NULL);

    if(dd->idle)
        g_source_remove(dd->idle);

    if(dd->dest_file)
        fm_file_info_unref(dd->dest_file);

    if(dd->src_files)
        fm_list_unref(dd->src_files);

    if(dd->mainloop)
        g_main_loop_unref(dd->mainloop);

    G_OBJECT_CLASS(fm_dnd_dest_parent_class)->finalize(object);
}
示例#3
0
文件: fm-dnd-dest.c 项目: engla/libfm
void fm_dnd_dest_set_dest_file(FmDndDest* dd, FmFileInfo* dest_file)
{
    if(dd->dest_file == dest_file)
        return;
    if(dd->dest_file)
        fm_file_info_unref(dd->dest_file);
    dd->dest_file = dest_file ? fm_file_info_ref(dest_file) : NULL;
}
示例#4
0
static inline void fm_folder_item_free(FmFolderItem* item)
{
    if (item->hinted_disp_name)
        g_free(item->hinted_disp_name);
    if( item->icon )
        g_object_unref(item->icon);
    fm_file_info_unref(item->inf);
    g_slice_free(FmFolderItem, item);
}
示例#5
0
static void place_item_free(FmPlaceItem* item)
{
    switch(item->type)
    {
    case FM_PLACES_ITEM_VOL:
        g_object_unref(item->vol);
        break;
    }
    fm_file_info_unref(item->fi);
    g_slice_free(FmPlaceItem, item);
}
static inline FmFileInfo *_new_info_for_native_file(FmDirListJob* job, FmPath* path, const char* path_str, GError** err)
{
    FmFileInfo *fi;

    if (fm_job_is_cancelled(FM_JOB(job)))
        return NULL;
    if (!(job->flags & FM_DIR_LIST_JOB_DETAILED))
        return fm_file_info_new_from_native_file(path, path_str, err);
    fi = fm_file_info_new();
    fm_file_info_set_path(fi, path);
    if (fm_file_info_set_from_native_file(fi, path_str, err))
        return fi;
    fm_file_info_unref(fi);
    return NULL;
}
示例#7
0
inline static void thumbnail_task_free(ThumbnailTask* task)
{
    if(task->requests)
    {
        g_list_foreach(task->requests, (GFunc)fm_thumbnail_request_free, NULL);
        g_list_free(task->requests);
    }
    fm_file_info_unref(task->fi);

    /* if those strings are dynamically allocated, free them. */
    if(task->flags & ALLOC_STRINGS)
    {
        g_free(task->uri);
        g_free(task->normal_path);
        g_free(task->large_path);
    }

    g_slice_free(ThumbnailTask, task);
}
示例#8
0
文件: fm-dnd-dest.c 项目: engla/libfm
gboolean clear_src_cache(FmDndDest* dd)
{
    /* free cached source files */
    if(dd->src_files)
    {
        fm_list_unref(dd->src_files);
        dd->src_files = NULL;
    }
    if(dd->dest_file)
    {
        fm_file_info_unref(dd->dest_file);
        dd->dest_file = NULL;
    }
    dd->src_dev = 0;
    dd->src_fs_id = NULL;

    dd->info_type = 0;
    dd->idle = 0;
    dd->waiting_data = FALSE;
    return FALSE;
}
static void fm_dir_list_job_dispose(GObject *object)
{
    FmDirListJob *job;

    g_return_if_fail(object != NULL);
    g_return_if_fail(FM_IS_DIR_LIST_JOB(object));

    job = (FmDirListJob*)object;

    if(job->dir_path)
    {
        fm_path_unref(job->dir_path);
        job->dir_path = NULL;
    }

    if(job->dir_fi)
    {
        fm_file_info_unref(job->dir_fi);
        job->dir_fi = NULL;
    }

    if(job->files)
    {
        fm_file_info_list_unref(job->files);
        job->files = NULL;
    }

    if(job->delay_add_files_handler)
    {
        g_source_remove(job->delay_add_files_handler);
        job->delay_add_files_handler = 0;
        g_slist_free_full(job->files_to_add, (GDestroyNotify)fm_file_info_unref);
        job->files_to_add = NULL;
    }

    if (G_OBJECT_CLASS(fm_dir_list_job_parent_class)->dispose)
        (* G_OBJECT_CLASS(fm_dir_list_job_parent_class)->dispose)(object);
}
/**
 * fm_dir_list_job_set_dir_info
 * @job: the job that collected listing
 * @info: a FmFileInfo of the directory being loaded.
 *
 * This API is called by the implementation of FmDirListJob only.
 * Application developers should not use this API most of the time.
 *
 * Since: 1.0.2
 */
void fm_dir_list_job_set_dir_info(FmDirListJob* job, FmFileInfo* info)
{
    if(job->dir_fi)
        fm_file_info_unref(job->dir_fi);
    job->dir_fi = fm_file_info_ref(info);
}
static gboolean fm_dir_list_job_run_gio(FmDirListJob* job)
{
    GFileEnumerator *enu;
    GFileInfo *inf;
    FmFileInfo* fi;
    GError *err = NULL;
    FmJob* fmjob = FM_JOB(job);
    GFile* gf;
    const char* query;

    gf = fm_path_to_gfile(job->dir_path);
_retry:
    inf = g_file_query_info(gf, gfile_info_query_attribs, 0, fm_job_get_cancellable(fmjob), &err);
    if(!inf )
    {
        FmJobErrorAction act = fm_job_emit_error(fmjob, err, FM_JOB_ERROR_MODERATE);
        g_error_free(err);
        if( act == FM_JOB_RETRY )
        {
            err = NULL;
            goto _retry;
        }
        else
        {
            g_object_unref(gf);
            return FALSE;
        }
    }

    if( g_file_info_get_file_type(inf) != G_FILE_TYPE_DIRECTORY)
    {
        char *path_str = fm_path_to_str(job->dir_path);
        err = g_error_new(G_IO_ERROR, G_IO_ERROR_NOT_DIRECTORY,
                          _("The specified directory '%s' is not valid"),
                          path_str);
        fm_job_emit_error(fmjob, err, FM_JOB_ERROR_CRITICAL);
        g_free(path_str);
        g_error_free(err);
        g_object_unref(gf);
        g_object_unref(inf);
        return FALSE;
    }

    /* check if FS is R/O and set attr. into inf */
    _fm_file_info_job_update_fs_readonly(gf, inf, NULL, NULL);

    job->dir_fi = fm_file_info_new_from_g_file_data(gf, inf, job->dir_path);
    g_object_unref(inf);

    if(G_UNLIKELY(job->flags & FM_DIR_LIST_JOB_DIR_ONLY))
    {
        query = G_FILE_ATTRIBUTE_STANDARD_TYPE","G_FILE_ATTRIBUTE_STANDARD_NAME","
                G_FILE_ATTRIBUTE_STANDARD_IS_HIDDEN","G_FILE_ATTRIBUTE_STANDARD_IS_BACKUP","
                G_FILE_ATTRIBUTE_STANDARD_IS_SYMLINK","G_FILE_ATTRIBUTE_STANDARD_IS_VIRTUAL","
                G_FILE_ATTRIBUTE_STANDARD_EDIT_NAME","
                G_FILE_ATTRIBUTE_STANDARD_DISPLAY_NAME","G_FILE_ATTRIBUTE_STANDARD_ICON","
                G_FILE_ATTRIBUTE_STANDARD_SIZE","G_FILE_ATTRIBUTE_STANDARD_TARGET_URI","
                "unix::*,time::*,access::*,id::filesystem";
    }
    else
        query = gfile_info_query_attribs;

    enu = g_file_enumerate_children (gf, query, 0, fm_job_get_cancellable(fmjob), &err);
    g_object_unref(gf);
    if(enu)
    {
        while( ! fm_job_is_cancelled(fmjob) )
        {
            inf = g_file_enumerator_next_file(enu, fm_job_get_cancellable(fmjob), &err);
            if(inf)
            {
                FmPath *dir, *sub;
                GFile *child;
                if(G_UNLIKELY(job->flags & FM_DIR_LIST_JOB_DIR_ONLY))
                {
                    /* FIXME: handle symlinks */
                    if(g_file_info_get_file_type(inf) != G_FILE_TYPE_DIRECTORY)
                    {
                        g_object_unref(inf);
                        continue;
                    }
                }

                /* virtual folders may return children not within them */
                dir = fm_path_new_for_gfile(g_file_enumerator_get_container(enu));
                if (fm_path_equal(job->dir_path, dir))
                    sub = fm_path_new_child(job->dir_path, g_file_info_get_name(inf));
                else
                    sub = fm_path_new_child(dir, g_file_info_get_name(inf));
                child = g_file_get_child(g_file_enumerator_get_container(enu),
                                         g_file_info_get_name(inf));
                if (g_file_info_get_file_type(inf) == G_FILE_TYPE_DIRECTORY)
                    /* for dir: check if its FS is R/O and set attr. into inf */
                    _fm_file_info_job_update_fs_readonly(child, inf, NULL, NULL);
                fi = fm_file_info_new_from_g_file_data(child, inf, sub);
                fm_path_unref(sub);
                fm_path_unref(dir);
                g_object_unref(child);
                fm_dir_list_job_add_found_file(job, fi);
                fm_file_info_unref(fi);
            }
            else
            {
                if(err)
                {
                    FmJobErrorAction act = fm_job_emit_error(fmjob, err, FM_JOB_ERROR_MILD);
                    g_error_free(err);
                    /* FM_JOB_RETRY is not supported. */
                    if(act == FM_JOB_ABORT)
                        fm_job_cancel(fmjob);
                }
                /* otherwise it's EOL */
                break;
            }
            g_object_unref(inf);
        }
        g_file_enumerator_close(enu, NULL, &err);
        g_object_unref(enu);
    }
    else
    {
        fm_job_emit_error(fmjob, err, FM_JOB_ERROR_CRITICAL);
        g_error_free(err);
        return FALSE;
    }
    return TRUE;
}
static gboolean fm_dir_list_job_run_posix(FmDirListJob* job)
{
    FmJob* fmjob = FM_JOB(job);
    FmFileInfo* fi;
    GError *err = NULL;
    char* path_str;
    GDir* dir;

    path_str = fm_path_to_str(job->dir_path);

    fi = _new_info_for_native_file(job, job->dir_path, path_str, NULL);
    if(fi)
    {
        if(! fm_file_info_is_dir(fi))
        {
            err = g_error_new(G_IO_ERROR, G_IO_ERROR_NOT_DIRECTORY,
                              _("The specified directory '%s' is not valid"),
                              path_str);
            fm_file_info_unref(fi);
            fm_job_emit_error(fmjob, err, FM_JOB_ERROR_CRITICAL);
            g_error_free(err);
            g_free(path_str);
            return FALSE;
        }
        job->dir_fi = fi;
    }
    else
    {
        err = g_error_new(G_IO_ERROR, G_IO_ERROR_NOT_DIRECTORY,
                          _("The specified directory '%s' is not valid"),
                          path_str);
        fm_job_emit_error(fmjob, err, FM_JOB_ERROR_CRITICAL);
        g_error_free(err);
        g_free(path_str);
        return FALSE;
    }

    dir = g_dir_open(path_str, 0, &err);
    if( dir )
    {
        const char* name;
        GString* fpath = g_string_sized_new(4096);
        int dir_len = strlen(path_str);
        g_string_append_len(fpath, path_str, dir_len);
        if(fpath->str[dir_len-1] != '/')
        {
            g_string_append_c(fpath, '/');
            ++dir_len;
        }
        while( ! fm_job_is_cancelled(fmjob) && (name = g_dir_read_name(dir)) )
        {
            FmPath* new_path;
            g_string_truncate(fpath, dir_len);
            g_string_append(fpath, name);

            if(job->flags & FM_DIR_LIST_JOB_DIR_ONLY) /* if we only want directories */
            {
                struct stat st;
                /* FIXME: this results in an additional stat() call, which is inefficient */
                if(stat(fpath->str, &st) == -1 || !S_ISDIR(st.st_mode))
                    continue;
            }

            new_path = fm_path_new_child(job->dir_path, name);

        _retry:
            fi = _new_info_for_native_file(job, new_path, fpath->str, &err);
            if (fi == NULL) /* we got a damaged file */
            {
                FmJobErrorAction act = fm_job_emit_error(fmjob, err, FM_JOB_ERROR_MILD);
                GFile *gf;
                GFileInfo *inf;
                gchar *disp_basename;

                g_error_free(err);
                err = NULL;
                if(act == FM_JOB_RETRY)
                    goto _retry;
                /* bug #3615271: Damaged mountpoint isn't shown
                   let make a simple file info then */
                inf = g_file_info_new();
                gf = fm_path_to_gfile(new_path);
                g_file_info_set_file_type(inf, G_FILE_TYPE_UNKNOWN);
                g_file_info_set_name(inf, name);
                disp_basename = g_filename_display_basename(fpath->str);
                g_file_info_set_display_name(inf, disp_basename);
                g_free(disp_basename);
                g_file_info_set_content_type(inf, "inode/x-corrupted");
                fi = fm_file_info_new_from_g_file_data(gf, inf, new_path);
                g_object_unref(inf);
                g_object_unref(gf);
            }
            fm_dir_list_job_add_found_file(job, fi);
            fm_file_info_unref(fi);
            fm_path_unref(new_path);
        }
        g_string_free(fpath, TRUE);
        g_dir_close(dir);
    }
    else
    {
        fm_job_emit_error(fmjob, err, FM_JOB_ERROR_CRITICAL);
        g_error_free(err);
    }
    g_free(path_str);
    return TRUE;
}
示例#13
0
文件: fm-folder.c 项目: engla/libfm
static void fm_folder_finalize(GObject *object)
{
    FmFolder *self;
    g_return_if_fail(object != NULL);
    g_return_if_fail(FM_IS_FOLDER(object));

    self = FM_FOLDER(object);

    if(self->job)
    {
        g_signal_handlers_disconnect_by_func(self->job, on_job_finished, self);
        g_signal_handlers_disconnect_by_func(self->job, on_job_err, self);
        fm_job_cancel(FM_JOB(self->job)); /* FIXME: is this ok? */
        /* the job will be freed automatically in idle handler. */
    }

    if(self->pending_jobs)
    {
        GSList* l;
        for(l = self->pending_jobs;l;l=l->next)
        {
            FmJob* job = FM_JOB(l->data);
            g_signal_handlers_disconnect_by_func(job, on_job_finished, self);
            fm_job_cancel(job);
            /* the job will be freed automatically in idle handler. */
        }
    }

    /* remove from hash table */
    g_hash_table_remove(hash, self->dir_path);
    if(self->dir_path)
        fm_path_unref(self->dir_path);

    if(self->dir_fi)
        fm_file_info_unref(self->dir_fi);

    if(self->gf)
        g_object_unref(self->gf);

    if(self->mon)
    {
        g_signal_handlers_disconnect_by_func(self->mon, on_folder_changed, self);
        g_object_unref(self->mon);
    }

    if(self->idle_handler)
    {
        g_source_remove(self->idle_handler);
        if(self->files_to_add)
        {
            g_slist_foreach(self->files_to_add, (GFunc)g_free, NULL);
            g_slist_free(self->files_to_add);
        }
        if(self->files_to_update)
        {
            g_slist_foreach(self->files_to_update, (GFunc)g_free, NULL);
            g_slist_free(self->files_to_update);
        }
        if(self->files_to_del)
            g_slist_free(self->files_to_del);
    }

    fm_list_unref(self->files);

    if (G_OBJECT_CLASS(fm_folder_parent_class)->finalize)
        (* G_OBJECT_CLASS(fm_folder_parent_class)->finalize)(object);
}
示例#14
0
ExecFileDialog::~ExecFileDialog() {
  delete ui;
  if(fileInfo_)
    fm_file_info_unref(fileInfo_);
}