Пример #1
0
/**
 * fm_file_ops_job_run_with_progress
 * @parent: parent window to show dialog over it
 * @job: (transfer full): job descriptor to run
 *
 * Runs the file operation job with a progress dialog.
 * The returned data structure will be freed in idle handler automatically
 * when it's not needed anymore.
 *
 * NOTE: INCONSISTENCY: it takes a reference from job
 *
 * Before 0.1.15 this call had different arguments.
 *
 * Return value: (transfer none): progress data; not usable; caller should not free it either.
 *
 * Since: 0.1.0
 */
FmProgressDisplay* fm_file_ops_job_run_with_progress(GtkWindow* parent, FmFileOpsJob* job)
{
    FmProgressDisplay* data;

    g_return_val_if_fail(job != NULL, NULL);

    data = g_slice_new0(FmProgressDisplay);
    data->job = job;
    if(parent)
        data->parent = g_object_ref(parent);
    data->delay_timeout = g_timeout_add(SHOW_DLG_DELAY, on_show_dlg, data);

    g_signal_connect(job, "ask", G_CALLBACK(on_ask), data);
    g_signal_connect(job, "ask-rename", G_CALLBACK(on_ask_rename), data);
    g_signal_connect(job, "error", G_CALLBACK(on_error), data);
    g_signal_connect(job, "prepared", G_CALLBACK(on_prepared), data);
    g_signal_connect(job, "cur-file", G_CALLBACK(on_cur_file), data);
    g_signal_connect(job, "percent", G_CALLBACK(on_percent), data);
    g_signal_connect(job, "finished", G_CALLBACK(on_finished), data);
    g_signal_connect(job, "cancelled", G_CALLBACK(on_cancelled), data);

    fm_job_run_async(FM_JOB(job));

    return data;
}
Пример #2
0
static void update_vol(FmPlacesModel* model, FmPlaceItem* item, GtkTreeIter* it, FmFileInfoJob* job)
{
    FmIcon* icon;
    GIcon* gicon;
    char* name;
    GdkPixbuf* pix;
    GMount* mount;
    FmPath* path;

    name = g_volume_get_name(item->vol);
    if(item->fi->icon)
        fm_icon_unref(item->fi->icon);
    gicon = g_volume_get_icon(item->vol);
    icon = fm_icon_from_gicon(gicon);
    item->fi->icon = icon;
    g_object_unref(gicon);

    mount = g_volume_get_mount(item->vol);
    if(mount)
    {
        GFile* gf = g_mount_get_root(mount);
        path = fm_path_new_for_gfile(gf);
        g_object_unref(gf);
        g_object_unref(mount);
        item->vol_mounted = TRUE;
    }
    else
    {
        path = NULL;
        item->vol_mounted = FALSE;
    }

    if(!fm_path_equal(item->fi->path, path))
    {
        fm_file_info_set_path(item->fi, path);
        if(path)
        {
            if(job)
                fm_file_info_job_add(job, path);
            else
            {
                job = fm_file_info_job_new(NULL, FM_FILE_INFO_JOB_FOLLOW_SYMLINK);
                model->jobs = g_slist_prepend(model->jobs, job);
                g_signal_connect(job, "finished", G_CALLBACK(on_file_info_job_finished), model);
                fm_job_run_async(FM_JOB(job));
            }
            fm_path_unref(path);
        }
    }

    pix = fm_icon_get_pixbuf(item->fi->icon, fm_config->pane_icon_size);
    gtk_list_store_set(GTK_LIST_STORE(model), it, FM_PLACES_MODEL_COL_ICON, pix, FM_PLACES_MODEL_COL_LABEL, name, -1);
    g_object_unref(pix);
    g_free(name);
}
Пример #3
0
/**
 * fm_job_run_sync_with_mainloop
 * @job: a job to run
 *
 * Runs the @job in current thread in a blocking fashion and an additional
 * mainloop being created to prevent blocking of user interface. If @job
 * started successfully then #FmJob::finished signal is emitted when @job
 * is either succeeded or was cancelled.
 *
 * Returns: %TRUE if job started successfully.
 *
 * Since: 0.1.1
 */
gboolean fm_job_run_sync_with_mainloop(FmJob* job)
{
    GMainLoop* mainloop = g_main_loop_new(NULL, FALSE);
    gboolean ret;
    g_signal_connect(job, "finished", G_CALLBACK(on_sync_job_finished), mainloop);
    ret = fm_job_run_async(job);
    if(G_LIKELY(ret))
    {
        g_main_loop_run(mainloop);
    }
    g_signal_handlers_disconnect_by_func(job, on_sync_job_finished, mainloop);
    g_main_loop_unref(mainloop);
    return ret;
}
Пример #4
0
static void on_bookmarks_changed(FmBookmarks* bm, gpointer user_data)
{
    FmPlacesModel* model = FM_PLACES_MODEL(user_data);
    FmFileInfoJob* job = fm_file_info_job_new(NULL, FM_FILE_INFO_JOB_FOLLOW_SYMLINK);
    GtkTreeIter it = model->sep_it;
    /* remove all old bookmarks */
    if(gtk_tree_model_iter_next(GTK_TREE_MODEL(model), &it))
    {
        while(gtk_list_store_remove(GTK_LIST_STORE(model), &it))
            continue;
    }
    add_bookmarks(model, job);

    g_signal_connect(job, "finished", G_CALLBACK(on_file_info_job_finished), model);
    model->jobs = g_slist_prepend(model->jobs, job);
    fm_job_run_async(FM_JOB(job));
}
Пример #5
0
void fm_folder_reload(FmFolder* folder)
{
    /* FIXME: remove all items and re-run a dir list job. */
    GSList* files_to_del = NULL;
    GList* l = fm_list_peek_head_link(folder->files);
    if(l)
    {
        for(;l;l=l->next)
        {
            FmFileInfo* fi = (FmFileInfo*)l->data;
            files_to_del = g_slist_prepend(files_to_del, fi);
        }
        g_signal_emit(folder, signals[FILES_REMOVED], 0, files_to_del);
        fm_list_clear(folder->files); /* fm_file_info_unref will be invoked. */
        g_slist_free(files_to_del);
    }

    folder->job = fm_dir_list_job_new(folder->dir_path, FALSE);
    g_signal_connect(folder->job, "finished", G_CALLBACK(on_job_finished), folder);
    g_signal_connect(folder->job, "error", G_CALLBACK(on_job_err), folder);
    fm_job_run_async(FM_JOB(folder->job));
}
Пример #6
0
static void fm_places_model_init(FmPlacesModel *self)
{
    GType types[] = {GDK_TYPE_PIXBUF, G_TYPE_STRING, G_TYPE_POINTER};
    GtkTreeIter it;
    GtkTreePath* tp;
    FmPlaceItem* item;
    GList *vols, *l;
    GIcon* gicon;
    FmIcon* icon;
    GFile* gf;
    GdkPixbuf* pix;
    FmFileInfoJob* job = fm_file_info_job_new(NULL, FM_FILE_INFO_JOB_FOLLOW_SYMLINK);
    GtkListStore* model = GTK_LIST_STORE(self);

    gtk_list_store_set_column_types(GTK_LIST_STORE(self), FM_PLACES_MODEL_N_COLS, types);

    self->theme_change_handler = g_signal_connect_swapped(gtk_icon_theme_get_default(), "changed",
                                            G_CALLBACK(update_icons), self);

    self->use_trash_change_handler = g_signal_connect(fm_config, "changed::use_trash",
                                             G_CALLBACK(on_use_trash_changed), self);

    self->pane_icon_size_change_handler = g_signal_connect(fm_config, "changed::pane_icon_size",
                                             G_CALLBACK(on_pane_icon_size_changed), self);
    icon = fm_icon_from_name("media-eject");
    pix = fm_icon_get_pixbuf(icon, fm_config->pane_icon_size);
    fm_icon_unref(icon);
    self->eject_icon = pix;

    item = g_slice_new0(FmPlaceItem);
    item->type = FM_PLACES_ITEM_PATH;
    item->fi = fm_file_info_new();
    item->fi->path = fm_path_ref(fm_path_get_home());
    item->fi->icon = fm_icon_from_name("user-home");
    gtk_list_store_append(model, &it);
    pix = fm_icon_get_pixbuf(item->fi->icon, fm_config->pane_icon_size);
    gtk_list_store_set(model, &it, FM_PLACES_MODEL_COL_ICON, pix, FM_PLACES_MODEL_COL_LABEL, item->fi->path->name, FM_PLACES_MODEL_COL_INFO, item, -1);
    g_object_unref(pix);
    fm_file_info_job_add(job, item->fi->path);

    /* Only show desktop in side pane when the user has a desktop dir. */
    if(g_file_test(g_get_user_special_dir(G_USER_DIRECTORY_DESKTOP), G_FILE_TEST_IS_DIR))
    {
        item = g_slice_new0(FmPlaceItem);
        item->type = FM_PLACES_ITEM_PATH;
        item->fi = fm_file_info_new();
        item->fi->path = fm_path_ref(fm_path_get_desktop());
        item->fi->icon = fm_icon_from_name("user-desktop");
        gtk_list_store_append(model, &it);
        pix = fm_icon_get_pixbuf(item->fi->icon, fm_config->pane_icon_size);
        gtk_list_store_set(model, &it, FM_PLACES_MODEL_COL_ICON, pix, FM_PLACES_MODEL_COL_LABEL, _("Desktop"), FM_PLACES_MODEL_COL_INFO, item, -1);
        g_object_unref(pix);
        fm_file_info_job_add(job, item->fi->path);
    }

    if(fm_config->use_trash)
        create_trash_item(self); /* FIXME: how to handle trash can? */

    item = g_slice_new0(FmPlaceItem);
    item->type = FM_PLACES_ITEM_PATH;
    item->fi = fm_file_info_new();
    item->fi->path = fm_path_ref(fm_path_get_apps_menu());
    item->fi->icon = fm_icon_from_name("system-software-install");
    gtk_list_store_append(model, &it);
    pix = fm_icon_get_pixbuf(item->fi->icon, fm_config->pane_icon_size);
    gtk_list_store_set(model, &it, FM_PLACES_MODEL_COL_ICON, pix, FM_PLACES_MODEL_COL_LABEL, _("Applications"), FM_PLACES_MODEL_COL_INFO, item, -1);
    g_object_unref(pix);
    /* fm_file_info_job_add(job, item->fi->path); */

    /* volumes */
    self->vol_mon = g_volume_monitor_get();
    g_signal_connect(self->vol_mon, "volume-added", G_CALLBACK(on_vol_added), self);
    g_signal_connect(self->vol_mon, "volume-removed", G_CALLBACK(on_vol_removed), self);
    g_signal_connect(self->vol_mon, "volume-changed", G_CALLBACK(on_vol_changed), self);
    g_signal_connect(self->vol_mon, "mount-added", G_CALLBACK(on_mount_added), self);

    /* separator */
    gtk_list_store_append(model, &self->sep_it);

    /* add volumes to side-pane */
    vols = g_volume_monitor_get_volumes(self->vol_mon);
    for(l=vols;l;l=l->next)
    {
        GVolume* vol = G_VOLUME(l->data);
        add_vol(self, vol, job);
        g_object_unref(vol);
    }
    g_list_free(vols);

    /* get the path of separator */
    self->sep_tp = gtk_tree_model_get_path(GTK_TREE_MODEL(self), &self->sep_it);

    self->bookmarks = fm_bookmarks_get(); /* bookmarks */
    g_signal_connect(self->bookmarks, "changed", G_CALLBACK(on_bookmarks_changed), self);

    /* add bookmarks to side pane */
    add_bookmarks(self, job);

    g_signal_connect(job, "finished", G_CALLBACK(on_file_info_job_finished), self);
    self->jobs = g_slist_prepend(self->jobs, job);
    fm_job_run_async(FM_JOB(job));
}
Пример #7
0
gboolean on_idle(FmFolder* folder)
{
    GSList* l;
    FmFileInfoJob* job = NULL;
    FmPath* path;
    folder->idle_handler = 0;
    if(folder->files_to_update || folder->files_to_add)
        job = (FmFileInfoJob*)fm_file_info_job_new(NULL, 0);

    if(folder->files_to_update)
    {
        GSList* prev = NULL;
        for(l=folder->files_to_update;l;)
        {
            /* if a file is already in files_to_add, remove it. */
            if(g_slist_find_custom(folder->files_to_add, l->data, (GCompareFunc)strcmp))
            {
                GSList* tmp = l;
                l=l->next;
                if(G_LIKELY(prev))
                    prev->next = l;
                g_free(tmp->data);
                g_slist_free_1(tmp);
                if(G_UNLIKELY(tmp == folder->files_to_update))
                    folder->files_to_update = l;
                continue;
            }
            path = fm_path_new_child(folder->dir_path, (char*)l->data);
            fm_file_info_job_add(job, path);
            fm_path_unref(path);
            g_free(l->data);

            prev = l;
            l=l->next;
        }
        g_slist_free(folder->files_to_update);
        folder->files_to_update = NULL;
    }

    if(folder->files_to_add)
    {
        for(l=folder->files_to_add;l;l=l->next)
        {
            path = fm_path_new_child(folder->dir_path, (char*)l->data);
            fm_file_info_job_add(job, path);
            fm_path_unref(path);
            g_free(l->data);
        }
        g_slist_free(folder->files_to_add);
        folder->files_to_add = NULL;
    }

    if(job)
    {
        g_signal_connect(job, "finished", on_file_info_finished, folder);
        folder->pending_jobs = g_slist_prepend(folder->pending_jobs, job);
        fm_job_run_async(FM_JOB(job));
    }

    if(folder->files_to_del)
    {
        GSList* ll;
        for(ll=folder->files_to_del;ll;ll=ll->next)
        {
            GList* l= (GList*)ll->data;
            ll->data = l->data;
            fm_list_delete_link_nounref(folder->files , l);
        }
        g_signal_emit(folder, signals[FILES_REMOVED], 0, folder->files_to_del);
        g_slist_foreach(folder->files_to_del, (GFunc)fm_file_info_unref, NULL);
        g_slist_free(folder->files_to_del);
        folder->files_to_del = NULL;
    }

    return FALSE;
}
Пример #8
0
void FilePropsDialog::initGeneralPage() {
  // update UI
  if(singleType) { // all files are of the same mime-type
    FmIcon* icon = NULL;
    // FIXME: handle custom icons for some files
    // FIXME: display special property pages for special files or
    // some specified mime-types.
    if(singleFile) { // only one file is selected.
      icon = fm_file_info_get_icon(fileInfo);
    }
    if(mimeType) {
      if(!icon) // get an icon from mime type if needed
        icon = fm_mime_type_get_icon(mimeType);
      ui->fileType->setText(QString::fromUtf8(fm_mime_type_get_desc(mimeType)));
      ui->mimeType->setText(QString::fromUtf8(fm_mime_type_get_type(mimeType)));
    }
    if(icon) {
      ui->iconButton->setIcon(IconTheme::icon(icon));
    }

    if(singleFile && fm_file_info_is_symlink(fileInfo)) {
      ui->target->setText(QString::fromUtf8(fm_file_info_get_target(fileInfo)));
    }
    else {
      ui->target->hide();
      ui->targetLabel->hide();
    }
  } // end if(singleType)
  else { // not singleType, multiple files are selected at the same time
    ui->fileType->setText(tr("Files of different types"));
    ui->target->hide();
    ui->targetLabel->hide();
  }

  // FIXME: check if all files has the same parent dir, mtime, or atime
  if(singleFile) { // only one file is selected
    FmPath* parent_path = fm_path_get_parent(fm_file_info_get_path(fileInfo));
    char* parent_str = parent_path ? fm_path_display_name(parent_path, true) : NULL;

    ui->fileName->setText(QString::fromUtf8(fm_file_info_get_disp_name(fileInfo)));
    if(parent_str) {
      ui->location->setText(QString::fromUtf8(parent_str));
      g_free(parent_str);
    }
    else
      ui->location->clear();

    ui->lastModified->setText(QString::fromUtf8(fm_file_info_get_disp_mtime(fileInfo)));

    // FIXME: need to encapsulate this in an libfm API.
    time_t atime;
    struct tm tm;
    atime = fm_file_info_get_atime(fileInfo);
    localtime_r(&atime, &tm);
    char buf[128];
    strftime(buf, sizeof(buf), "%x %R", &tm);
    ui->lastAccessed->setText(QString::fromUtf8(buf));
  }
  else {
    ui->fileName->setText(tr("Multiple Files"));
    ui->fileName->setEnabled(false);
  }

  initApplications(); // init applications combo box

  // calculate total file sizes
  fileSizeTimer = new QTimer(this);
  connect(fileSizeTimer, &QTimer::timeout, this, &FilePropsDialog::onFileSizeTimerTimeout);
  fileSizeTimer->start(600);
  g_signal_connect(deepCountJob, "finished", G_CALLBACK(onDeepCountJobFinished), this);
  gboolean ret = fm_job_run_async(FM_JOB(deepCountJob));
}
Пример #9
0
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;
}