Exemple #1
0
bool Launcher::openFolder(GAppLaunchContext* ctx, GList* folder_infos, GError** err) {
    GList* l = folder_infos;
    FmFileInfo* fi = FM_FILE_INFO(l->data);
    Application* app = static_cast<Application*>(qApp);
    MainWindow* mainWindow = mainWindow_;
    Fm::FilePath path{fm_path_to_gfile(fm_file_info_get_path(fi)), false};
    if(!mainWindow) {
        mainWindow = new MainWindow(std::move(path));
        mainWindow->resize(app->settings().windowWidth(), app->settings().windowHeight());

        if(app->settings().windowMaximized()) {
            mainWindow->setWindowState(mainWindow->windowState() | Qt::WindowMaximized);
        }
    }
    else {
        mainWindow->chdir(std::move(path));
    }
    l = l->next;
    for(; l; l = l->next) {
        fi = FM_FILE_INFO(l->data);
        path = Fm::FilePath{fm_path_to_gfile(fm_file_info_get_path(fi)), false};
        mainWindow->addTab(std::move(path));
    }
    mainWindow->show();
    mainWindow->raise();
    return true;
}
Exemple #2
0
FmFolder* fm_folder_get_internal(FmPath* path, GFile* gf)
{
    FmFolder* folder;
    /* FIXME: should we provide a generic FmPath cache in fm-path.c
     * to associate all kinds of data structures with FmPaths? */

    /* FIXME: should creation of the hash table be moved to fm_init()? */
    if( G_LIKELY(hash) )
        folder = (FmFolder*)g_hash_table_lookup(hash, path);
    else
    {
        hash = g_hash_table_new((GHashFunc)fm_path_hash, (GEqualFunc)fm_path_equal);
        folder = NULL;
    }

    if( G_UNLIKELY(!folder) )
    {
        GFile* _gf = NULL;
        if(!gf)
            _gf = gf = fm_path_to_gfile(path);
        folder = fm_folder_new_internal(path, gf);
        if(_gf)
            g_object_unref(_gf);
        g_hash_table_insert(hash, folder->dir_path, folder);
    }
    else
        return (FmFolder*)g_object_ref(folder);
    return folder;
}
Exemple #3
0
/**
 * fm_mount_path
 * @parent: a window to place dialog over it
 * @path: a path to the volume
 * @interactive: %TRUE to open dialog window
 *
 * Mounts a volume.
 *
 * Returns: %TRUE in case of success.
 *
 * Since: 0.1.0
 */
gboolean fm_mount_path(GtkWindow* parent, FmPath* path, gboolean interactive)
{
    GFile* gf = fm_path_to_gfile(path);
    gboolean ret = fm_do_mount(parent, G_OBJECT(gf), MOUNT_GFILE, interactive);
    g_object_unref(gf);
    return ret;
}
gboolean fm_deep_count_job_run(FmJob* job)
{
    FmDeepCountJob* dc = (FmDeepCountJob*)job;
    GList* l;

    l = fm_list_peek_head_link(dc->paths);
    for(; !fm_job_is_cancelled(job) && l; l=l->next)
    {
        FmPath* path = FM_PATH(l->data);
        if(fm_path_is_native(path)) /* if it's a native file, use posix APIs */
            deep_count_posix( dc, path );
        else
        {
            GFile* gf = fm_path_to_gfile(path);
            deep_count_gio( dc, NULL, gf );
            g_object_unref(gf);
        }
    }
    return TRUE;
}
Exemple #5
0
void renameFile(FmFileInfo *file, QWidget *parent) {
  FmPath* path = fm_file_info_get_path(file);
  FilenameDialog dlg(parent);
  dlg.setWindowTitle(QObject::tr("Rename File"));
  dlg.setLabelText(QObject::tr("Please enter a new name:"));
  // FIXME: what's the best way to handle non-UTF8 filename encoding here?
  QString old_name = QString::fromLocal8Bit(fm_path_get_basename(path));
  dlg.setTextValue(old_name);

  if(fm_file_info_is_dir(file)) // select filename extension for directories
    dlg.setSelectExtension(true);

  if(dlg.exec() != QDialog::Accepted)
    return;

  QString new_name = dlg.textValue();

  if(new_name == old_name)
    return;

  GFile* gf = fm_path_to_gfile(path);
  GFile* parent_gf = g_file_get_parent(gf);
  GFile* dest = g_file_get_child(G_FILE(parent_gf), new_name.toLocal8Bit().data());
  g_object_unref(parent_gf);

  GError* err = NULL;
  if(!g_file_move(gf, dest,
                  GFileCopyFlags(G_FILE_COPY_ALL_METADATA |
                                 G_FILE_COPY_NO_FALLBACK_FOR_MOVE |
                                 G_FILE_COPY_NOFOLLOW_SYMLINKS),
                  NULL, /* make this cancellable later. */
                  NULL, NULL, &err)) {
    QMessageBox::critical(parent, QObject::tr("Error"), err->message);
    g_error_free(err);
  }

  g_object_unref(dest);
  g_object_unref(gf);
}
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;
}
Exemple #8
0
void on_create_new(GtkAction* action, FmMainWin* win)
{
    FmFolderView* fv = FM_FOLDER_VIEW(win->folder_view);
    const char* name = gtk_action_get_name(action);
    GError* err = NULL;
    FmPath* cwd = fm_folder_view_get_cwd(fv);
    FmPath* dest;
    char* basename;
_retry:
    basename = fm_get_user_input(GTK_WINDOW(win), _("Create New..."), _("Enter a name for the newly created file:"), _("New"));
    if(!basename)
        return;

    dest = fm_path_new_child(cwd, basename);
    g_free(basename);

    if( strcmp(name, "NewFolder") == 0 )
    {
        GFile* gf = fm_path_to_gfile(dest);
        if(!g_file_make_directory(gf, NULL, &err))
        {
            if(err->domain = G_IO_ERROR && err->code == G_IO_ERROR_EXISTS)
            {
                fm_path_unref(dest);
                g_error_free(err);
                g_object_unref(gf);
                err = NULL;
                goto _retry;
            }
            fm_show_error(GTK_WINDOW(win), err->message);
            g_error_free(err);
        }

        if(!err) /* select the newly created file */
        {
            /*FIXME: this doesn't work since the newly created file will
             * only be shown after file-created event was fired on its
             * folder's monitor and after FmFolder handles it in idle
             * handler. So, we cannot select it since it's not yet in
             * the folder model now. */
            /* fm_folder_view_select_file_path(fv, dest); */
        }
        g_object_unref(gf);
    }
    else if( strcmp(name, "NewBlank") == 0 )
    {
        GFile* gf = fm_path_to_gfile(dest);
        GFileOutputStream* f = g_file_create(gf, G_FILE_CREATE_NONE, NULL, &err);
        if(f)
        {
            g_output_stream_close(G_OUTPUT_STREAM(f), NULL, NULL);
            g_object_unref(f);
        }
        else
        {
            if(err->domain = G_IO_ERROR && err->code == G_IO_ERROR_EXISTS)
            {
                fm_path_unref(dest);
                g_error_free(err);
                g_object_unref(gf);
                err = NULL;
                goto _retry;
            }
            fm_show_error(GTK_WINDOW(win), err->message);
            g_error_free(err);
        }

        if(!err) /* select the newly created file */
        {
            /*FIXME: this doesn't work since the newly created file will
             * only be shown after file-created event was fired on its
             * folder's monitor and after FmFolder handles it in idle
             * handler. So, we cannot select it since it's not yet in
             * the folder model now. */
            /* fm_folder_view_select_file_path(fv, dest); */
        }
        g_object_unref(gf);
    }
    else /* templates */
    {

    }
    fm_path_unref(dest);
}
Exemple #9
0
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;
}
static gpointer _dentry_ui_init(GtkBuilder *ui, gpointer uidata, FmFileInfoList *files)
{
    GObject *widget;
    GtkWidget *new_widget;
    FmFilePropertiesDEntryData *data;
    GtkTable *table;
    GtkLabel *label;
    GError *err = NULL;
    FmFileInfo *fi;
    GFile *gf;
    gchar *txt;
    gsize length;
    const gchar * const *langs;
    gboolean tmp_bool;

    /* disable permissions tab and open_with in any case */
#define HIDE_WIDGET(x) widget = gtk_builder_get_object(ui, x); \
        gtk_widget_hide(GTK_WIDGET(widget))
    /* HIDE_WIDGET("permissions_tab");
       TODO: made visibility of permissions_tab configurable */
    table = GTK_TABLE(gtk_builder_get_object(ui, "general_table"));
    HIDE_WIDGET("open_with");
    HIDE_WIDGET("open_with_label");
    gtk_table_set_row_spacing(table, 5, 0);
    /* we will do the thing only for single file! */
    if (fm_file_info_list_get_length(files) != 1)
        return NULL;
    fi = fm_file_info_list_peek_head(files);
    gf = fm_path_to_gfile(fm_file_info_get_path(fi));
    if (!g_file_load_contents(gf, NULL, &txt, &length, NULL, NULL))
    {
        g_warning("file properties dialog: cannot access desktop entry file");
        g_object_unref(gf);
        return NULL;
    }
    data = g_slice_new(FmFilePropertiesDEntryData);
    data->changed = FALSE;
    data->file = gf;
    data->kf = g_key_file_new();
    g_key_file_load_from_data(data->kf, txt, length,
                              G_KEY_FILE_KEEP_COMMENTS | G_KEY_FILE_KEEP_TRANSLATIONS,
                              NULL);
    g_free(txt);
    /* FIXME: handle errors, also do g_key_file_has_group() */
    /* get locale name */
    data->lang = NULL;
    langs = g_get_language_names();
    if (strcmp(langs[0], "C") != 0)
    {
        /* remove encoding from locale name */
        char *sep = strchr(langs[0], '.');
        if (sep)
            data->lang = g_strndup(langs[0], sep - langs[0]);
        else
            data->lang = g_strdup(langs[0]);
    }
    /* enable events for icon */
    widget = gtk_builder_get_object(ui, "icon_eventbox");
    data->icon = gtk_builder_get_object(ui, "icon");
    gtk_widget_set_can_focus(GTK_WIDGET(widget), TRUE);
    /* disable Name event handler in the widget */
    widget = gtk_builder_get_object(ui, "name");
    g_signal_handlers_block_matched(widget, G_SIGNAL_MATCH_DATA, 0, 0, NULL, NULL, uidata);
    g_signal_connect(widget, "changed", G_CALLBACK(_dentry_name_changed), data);
    data->name = GTK_ENTRY(widget);
    data->saved_name = g_strdup(gtk_entry_get_text(data->name));
    /* FIXME: two lines below is temporary workaround on FIXME in widget */
    gtk_widget_set_can_focus(GTK_WIDGET(widget), TRUE);
    gtk_editable_set_editable(GTK_EDITABLE(widget), TRUE);
    /* Name is set from "Name" by libfm already so don't touch it */
    /* support 'hidden' option */
    data->hidden = NULL;
    widget = gtk_builder_get_object(ui, "hidden");
    if (widget && GTK_IS_TOGGLE_BUTTON(widget) && fm_file_info_is_native(fi))
    {
        data->hidden = (GtkToggleButton*)widget;
        data->was_hidden = fm_file_info_is_hidden(fi);
        g_signal_connect(widget, "toggled", G_CALLBACK(_dentry_hidden_toggled), data);
        gtk_widget_set_can_focus(GTK_WIDGET(data->hidden), TRUE);
        /* set sensitive since it can be toggled for desktop entry */
        gtk_widget_set_sensitive(GTK_WIDGET(widget), TRUE);
        gtk_widget_show(GTK_WIDGET(data->hidden));
    }
#undef HIDE_WIDGET
    /* FIXME: migrate to GtkGrid */
    table = GTK_TABLE(gtk_table_new(8, 2, FALSE));
    gtk_table_set_row_spacings(table, 4);
    gtk_table_set_col_spacings(table, 12);
    gtk_container_set_border_width(GTK_CONTAINER(table), 4);
    /* row 0: "Exec" GtkHBox: GtkEntry+GtkButton */
    new_widget = gtk_label_new(NULL);
    label = GTK_LABEL(new_widget);
    gtk_misc_set_alignment(GTK_MISC(new_widget), 0.0, 0.0);
    gtk_label_set_markup_with_mnemonic(label, _("<b>Co_mmand:</b>"));
    gtk_table_attach(table, new_widget, 0, 1, 0, 1, GTK_FILL, 0, 0, 0);
#if GTK_CHECK_VERSION(3, 2, 0)
    /* FIXME: migrate to GtkGrid */
    widget = G_OBJECT(gtk_box_new(GTK_ORIENTATION_HORIZONTAL, 6));
#else
    widget = G_OBJECT(gtk_hbox_new(FALSE, 6));
#endif
    new_widget = gtk_button_new_with_mnemonic(_("_Browse..."));
    gtk_box_pack_end(GTK_BOX(widget), new_widget, FALSE, FALSE, 0);
    g_signal_connect(new_widget, "clicked",
                     G_CALLBACK(_dentry_browse_exec_event), data);
    new_widget = gtk_entry_new();
    data->exec = GTK_ENTRY(new_widget);
    txt = g_key_file_get_locale_string(data->kf, GRP_NAME, "Exec", NULL, NULL);
    if (txt)
    {
        gtk_entry_set_text(data->exec, txt);
        g_free(txt);
    }
    gtk_widget_set_tooltip_text(new_widget,
                                _("Command to execute when the application icon is activated"));
    gtk_box_pack_start(GTK_BOX(widget), new_widget, TRUE, TRUE, 0);
    g_signal_connect(new_widget, "changed", G_CALLBACK(_dentry_exec_changed), data);
    gtk_table_attach(table, GTK_WIDGET(widget), 1, 2, 0, 1, GTK_FILL|GTK_EXPAND, 0, 0, 0);
    gtk_label_set_mnemonic_widget(label, new_widget);
    /* row 1: "Terminal" GtkCheckButton */
    new_widget = gtk_check_button_new_with_mnemonic(_("_Execute in terminal emulator"));
    data->terminal = GTK_TOGGLE_BUTTON(new_widget);
    tmp_bool = g_key_file_get_boolean(data->kf, GRP_NAME, "Terminal", &err);
    if (err) /* no such key present */
    {
        tmp_bool = FALSE;
        g_clear_error(&err);
    }
    gtk_toggle_button_set_active(data->terminal, tmp_bool);
    g_signal_connect(new_widget, "toggled", G_CALLBACK(_dentry_terminal_toggled), data);
    gtk_table_attach(table, new_widget, 0, 2, 1, 2, GTK_FILL, 0, 18, 0);
    /* row 2: "X-KeepTerminal" GtkCheckButton */
    new_widget = gtk_check_button_new_with_mnemonic(_("_Keep terminal window open after command execution"));
    data->keep_open = GTK_TOGGLE_BUTTON(new_widget);
    gtk_widget_set_sensitive(new_widget, tmp_bool); /* disable if not in terminal */
    tmp_bool = g_key_file_get_boolean(data->kf, GRP_NAME, "X-KeepTerminal", &err);
    if (err) /* no such key present */
    {
        tmp_bool = FALSE;
        g_clear_error(&err);
    }
    gtk_toggle_button_set_active(data->keep_open, tmp_bool);
    g_signal_connect(new_widget, "toggled", G_CALLBACK(_dentry_keepterm_toggled), data);
    gtk_table_attach(table, new_widget, 0, 2, 2, 3, GTK_FILL, 0, 27, 0);
    /* row 4: "GenericName" GtkEntry */
    new_widget = gtk_label_new(NULL);
    label = GTK_LABEL(new_widget);
    gtk_misc_set_alignment(GTK_MISC(new_widget), 0.0, 0.0);
    gtk_label_set_markup_with_mnemonic(label, _("<b>D_escription:</b>"));
    gtk_table_attach(table, new_widget, 0, 1, 4, 5, GTK_FILL, 0, 0, 0);
    new_widget = gtk_entry_new();
    data->generic_name = GTK_ENTRY(new_widget);
    txt = g_key_file_get_locale_string(data->kf, GRP_NAME, "GenericName", NULL, NULL);
    if (txt)
    {
        gtk_entry_set_text(data->generic_name, txt);
        g_free(txt);
    }
    gtk_widget_set_tooltip_text(new_widget, _("Generic name of the application"));
    g_signal_connect(new_widget, "changed", G_CALLBACK(_dentry_genname_changed), data);
    gtk_table_attach(table, new_widget, 1, 2, 4, 5, GTK_FILL|GTK_EXPAND, 0, 0, 0);
    gtk_label_set_mnemonic_widget(label, new_widget);
    /* row 3: "Path" GtkEntry */
    new_widget = gtk_label_new(NULL);
    label = GTK_LABEL(new_widget);
    gtk_misc_set_alignment(GTK_MISC(new_widget), 0.0, 0.0);
    gtk_label_set_markup_with_mnemonic(label, _("<b>_Working directory:</b>"));
    gtk_table_attach(table, new_widget, 0, 1, 3, 4, GTK_FILL, 0, 0, 0);
    new_widget = gtk_entry_new();
    data->path = GTK_ENTRY(new_widget);
    txt = g_key_file_get_locale_string(data->kf, GRP_NAME, "Path", NULL, NULL);
    if (txt)
    {
        gtk_entry_set_text(data->path, txt);
        g_free(txt);
    }
    gtk_widget_set_tooltip_text(new_widget,
                                _("The working directory to run the program in"));
    g_signal_connect(new_widget, "changed", G_CALLBACK(_dentry_path_changed), data);
    gtk_table_attach(table, new_widget, 1, 2, 3, 4, GTK_FILL|GTK_EXPAND, 0, 0, 0);
    gtk_label_set_mnemonic_widget(label, new_widget);
    /* row 5: "Comment" GtkEntry */
    new_widget = gtk_label_new(NULL);
    label = GTK_LABEL(new_widget);
    gtk_misc_set_alignment(GTK_MISC(new_widget), 0.0, 0.0);
    gtk_label_set_markup_with_mnemonic(label, _("<b>_Tooltip:</b>"));
    gtk_table_attach(table, new_widget, 0, 1, 5, 6, GTK_FILL, 0, 0, 0);
    new_widget = gtk_entry_new();
    data->comment = GTK_ENTRY(new_widget);
    txt = g_key_file_get_locale_string(data->kf, GRP_NAME, "Comment", NULL, NULL);
    if (txt)
    {
        gtk_entry_set_text(data->comment, txt);
        g_free(txt);
    }
    gtk_widget_set_tooltip_text(new_widget, _("Tooltip to show on application"));
    g_signal_connect(new_widget, "changed", G_CALLBACK(_dentry_tooltip_changed), data);
    gtk_table_attach(table, new_widget, 1, 2, 5, 6, GTK_FILL|GTK_EXPAND, 0, 0, 0);
    gtk_label_set_mnemonic_widget(label, new_widget);
    /* TODO: handle "TryExec" field ? */
    /* row 7: "StartupNotify" GtkCheckButton */
    new_widget = gtk_check_button_new_with_mnemonic(_("_Use startup notification"));
    data->notification = GTK_TOGGLE_BUTTON(new_widget);
    tmp_bool = g_key_file_get_boolean(data->kf, GRP_NAME, "StartupNotify", &err);
    if (err) /* no such key present */
    {
        tmp_bool = FALSE;
        g_clear_error(&err);
    }
    gtk_toggle_button_set_active(data->notification, tmp_bool);
    g_signal_connect(new_widget, "toggled", G_CALLBACK(_dentry_notification_toggled), data);
    gtk_table_attach(table, new_widget, 0, 2, 7, 8, GTK_FILL, 0, 0, 0);
    /* put the table into third tab and enable it */
    widget = gtk_builder_get_object(ui, "extra_tab_label");
    gtk_label_set_markup_with_mnemonic(GTK_LABEL(widget), _("_Desktop Entry"));
    widget = gtk_builder_get_object(ui, "extra_tab");
    gtk_container_add(GTK_CONTAINER(widget), GTK_WIDGET(table));
    gtk_widget_show_all(GTK_WIDGET(widget));
    return data;
}
static gboolean subdir_check_job (GIOSchedulerJob *job, GCancellable *cancellable, gpointer user_data)
{
    FmDirTreeModel *dir_tree_model = FM_DIR_TREE_MODEL (user_data);

    
    // Lock ----------------------------------------------------------------------------------------
    g_mutex_lock (dir_tree_model->subdir_checks_mutex);
    
    GList *item_list = (GList*) g_queue_pop_head (&dir_tree_model->subdir_checks);
    
    FmDirTreeItem *dir_tree_item = (FmDirTreeItem*) item_list->data;
    dir_tree_model->current_subdir_check = item_list;
    
    
    // If the directory is a Drive, get it's target directory...
    //gboolean is_drive = fm_file_info_is_drive (dir_tree_item->file_info);
    GFile *gfile;
    gboolean is_mountable = fm_file_info_is_mountable (dir_tree_item->file_info);
    if (is_mountable)
    {
        gfile = g_file_new_for_path (fm_file_info_get_target (dir_tree_item->file_info));
    }
    else
    {
        gfile = fm_path_to_gfile (fm_file_info_get_path (dir_tree_item->file_info));
    }
    
    g_mutex_unlock (dir_tree_model->subdir_checks_mutex);
    // Unlock --------------------------------------------------------------------------------------
    
    //~ GError *gerror = NULL;
    //~ gfile_info = g_file_query_info (gfile, gfile_info_query_attribs, 0, fm_job_get_cancellable (fmjob), &gerror);
    
    /**
     * Parse input directory...
     * 
     */
    char *directory = fm_file_info_get_name (dir_tree_item->file_info);
    JOB_DEBUG ("\n----------------------------------------------------------------------------------------------\n");
    JOB_DEBUG ("JOB_DEBUG: subdir_check_job: check \"%s\"\n", directory);
    JOB_DEBUG ("----------------------------------------------------------------------------------------------\n");
	if (is_mountable)
    {
        JOB_DEBUG ("JOB_DEBUG: subdir_check_job: %s is mountable type !!!\n\n", directory);
    }
    
    
    GFileEnumerator *enumerator = g_file_enumerate_children (gfile,
                                                             G_FILE_ATTRIBUTE_STANDARD_NAME","
                                                             G_FILE_ATTRIBUTE_STANDARD_TYPE","
                                                             G_FILE_ATTRIBUTE_STANDARD_IS_HIDDEN,
                                                             0, cancellable, NULL);
    
    gboolean has_subdir = FALSE;
    if (enumerator)
    {
        while (!g_cancellable_is_cancelled (cancellable))
        {
            GFileInfo *gfile_info = g_file_enumerator_next_file (enumerator, cancellable, NULL);
            if (G_LIKELY (gfile_info))
            {
                GFileType g_file_type = g_file_info_get_file_type (gfile_info);
                gboolean is_hidden = g_file_info_get_is_hidden (gfile_info);
                
                //~ TREEVIEW_DEBUG ("TREEVIEW_DEBUG: subdir_check_job: GFileInfo for %s = %d\n",
                                //~ g_file_info_get_name (gfile_info), g_file_type);
                
                g_object_unref (gfile_info);
                
                if (g_file_type == G_FILE_TYPE_DIRECTORY || g_file_type == G_FILE_TYPE_MOUNTABLE)
                {
                    if (dir_tree_model->show_hidden || !is_hidden)
                    {
                        JOB_DEBUG ("JOB_DEBUG: subdir_check_job: A directory found in \"%s\" !!!\n\n", directory);
                        has_subdir = TRUE;
                        break;
                    }
                }
            }
            else
            {
                break;
            }
        }
        
        GError *error = NULL;
        g_file_enumerator_close (enumerator, cancellable, &error);
        g_object_unref (enumerator);
    }
    else
    {
        JOB_DEBUG ("JOB_DEBUG: subdir_check_job: Error: can't read \"%s\"...\n", directory);
    }
    
    // NO_DEBUG ("check result - %s has_dir: %d\n", g_file_get_parse_name (gfile), has_subdir);
    g_object_unref (gfile);
    
    if (!has_subdir)
    {
        JOB_DEBUG ("JOB_DEBUG: subdir_check_job: No directory found in \"%s\"\n\t\t\t  > Remove place holder\n\n",
                   directory);
        
        return g_io_scheduler_job_send_to_mainloop (job,
                                                    (GSourceFunc) subdir_check_remove_place_holder,
                                                    dir_tree_model, NULL);
    }
    
    return subdir_check_finish (dir_tree_model);
}
gboolean _fm_file_ops_job_move_run(FmFileOpsJob* job)
{
    GFile *dest_dir;
    GFileInfo* inf;
    GList* l;
    GError* err = NULL;
    FmJob* fmjob = FM_JOB(job);
    dev_t dest_dev = 0;
    gboolean ret = TRUE;
    FmDeepCountJob* dc;
    FmPath *parent = NULL;
    FmFolder *df, *sf = NULL;

    /* get information of destination folder */
    g_return_val_if_fail(job->dest, FALSE);
    dest_dir = fm_path_to_gfile(job->dest);
_retry_query_dest_info:
    inf = g_file_query_info(dest_dir, G_FILE_ATTRIBUTE_STANDARD_IS_VIRTUAL","
                                  G_FILE_ATTRIBUTE_UNIX_DEVICE","
                                  G_FILE_ATTRIBUTE_ID_FILESYSTEM","
                                  G_FILE_ATTRIBUTE_UNIX_DEVICE, 0,
                                  fm_job_get_cancellable(fmjob), &err);
    if(inf)
    {
        job->dest_fs_id = g_intern_string(g_file_info_get_attribute_string(inf, G_FILE_ATTRIBUTE_ID_FILESYSTEM));
        dest_dev = g_file_info_get_attribute_uint32(inf, G_FILE_ATTRIBUTE_UNIX_DEVICE); /* needed by deep count */
        g_object_unref(inf);
    }
    else
    {
        FmJobErrorAction act = fm_job_emit_error(fmjob, err, FM_JOB_ERROR_MODERATE);
        g_error_free(err);
        err = NULL;
        if(act == FM_JOB_RETRY)
            goto _retry_query_dest_info;
        else
        {
            g_object_unref(dest_dir);
            return FALSE;
        }
    }

    /* prepare the job, count total work needed with FmDeepCountJob */
    dc = fm_deep_count_job_new(job->srcs, FM_DC_JOB_PREPARE_MOVE);
    fm_deep_count_job_set_dest(dc, dest_dev, job->dest_fs_id);
    fm_job_run_sync(FM_JOB(dc));
    job->total = dc->total_size;

    if( fm_job_is_cancelled(FM_JOB(dc)) )
    {
        g_object_unref(dest_dir);
        g_object_unref(dc);
        return FALSE;
    }
    g_object_unref(dc);
    g_debug("total size to move: %llu, dest_fs: %s",
            (long long unsigned int)job->total, job->dest_fs_id);

    fm_file_ops_job_emit_prepared(job);
    /* suspend updates for destination */
    df = fm_folder_find_by_path(job->dest);
    if (df)
        fm_folder_block_updates(df);

    for(l = fm_path_list_peek_head_link(job->srcs); !fm_job_is_cancelled(fmjob) && l; l=l->next)
    {
        FmPath* path = FM_PATH(l->data);
        GFile* src = fm_path_to_gfile(path);
        GFile* dest;
        char* tmp_basename;

        /* do with updates for source */
        if (fm_path_get_parent(path) != parent && fm_path_get_parent(path) != NULL)
        {
            FmFolder *pf;

            pf = fm_folder_find_by_path(fm_path_get_parent(path));
            if (pf != sf)
            {
                if (sf)
                {
                    fm_folder_unblock_updates(sf);
                    g_object_unref(sf);
                }
                if (pf)
                    fm_folder_block_updates(pf);
                sf = pf;
            }
            else if (pf)
                g_object_unref(pf);
        }
        parent = fm_path_get_parent(path);
        if(g_file_is_native(src) && g_file_is_native(dest_dir))
            /* both are native */
            tmp_basename = NULL;
        else if(g_file_is_native(src)) /* move from native to virtual */
            tmp_basename = g_filename_to_utf8(fm_path_get_basename(path),
                                              -1, NULL, NULL, NULL);
            /* gvfs escapes it itself */
        else /* move from virtual to native/virtual */
            tmp_basename = fm_uri_subpath_to_native_subpath(fm_path_get_basename(path), NULL);
        dest = g_file_get_child(dest_dir,
                        tmp_basename ? tmp_basename : fm_path_get_basename(path));
        g_free(tmp_basename);

        if(!_fm_file_ops_job_move_file(job, src, NULL, dest, path, sf, df))
            ret = FALSE;
        g_object_unref(src);
        g_object_unref(dest);

        if(!ret)
            break;
    }
    /* restore updates for destination and source */
    if (df)
    {
        fm_folder_unblock_updates(df);
        g_object_unref(df);
    }
    if (sf)
    {
        fm_folder_unblock_updates(sf);
        g_object_unref(sf);
    }

    g_object_unref(dest_dir);
    return ret;
}
gboolean _fm_file_ops_job_copy_run(FmFileOpsJob* job)
{
    gboolean ret = TRUE;
    GFile *dest_dir;
    GList* l;
    FmJob* fmjob = FM_JOB(job);
    /* prepare the job, count total work needed with FmDeepCountJob */
    FmDeepCountJob* dc = fm_deep_count_job_new(job->srcs, FM_DC_JOB_DEFAULT);
    FmFolder *df;

    /* let the deep count job share the same cancellable object. */
    fm_job_set_cancellable(FM_JOB(dc), fm_job_get_cancellable(fmjob));
    fm_job_run_sync(FM_JOB(dc));
    job->total = dc->total_size;
    if(fm_job_is_cancelled(fmjob))
    {
        g_object_unref(dc);
        return FALSE;
    }
    g_object_unref(dc);
    g_debug("total size to copy: %llu", (long long unsigned int)job->total);

    dest_dir = fm_path_to_gfile(job->dest);
    /* suspend updates for destination */
    df = fm_folder_find_by_path(job->dest);
    if (df)
        fm_folder_block_updates(df);

    fm_file_ops_job_emit_prepared(job);

    for(l = fm_path_list_peek_head_link(job->srcs); !fm_job_is_cancelled(fmjob) && l; l=l->next)
    {
        FmPath* path = FM_PATH(l->data);
        GFile* src = fm_path_to_gfile(path);
        GFile* dest;
        char* tmp_basename;

        if(g_file_is_native(src) && g_file_is_native(dest_dir))
            /* both are native */
            tmp_basename = NULL;
        else if(g_file_is_native(src)) /* copy from native to virtual */
            tmp_basename = g_filename_to_utf8(fm_path_get_basename(path),
                                              -1, NULL, NULL, NULL);
            /* gvfs escapes it itself */
        else /* copy from virtual to native/virtual */
        {
            /* if we drop URI query onto native filesystem, omit query part */
            const char *basename = fm_path_get_basename(path);
            char *sub_name;

            sub_name = strchr(basename, '?');
            if (sub_name)
            {
                sub_name = g_strndup(basename, sub_name - basename);
                basename = strrchr(sub_name, G_DIR_SEPARATOR);
                if (basename)
                    basename++;
                else
                    basename = sub_name;
            }
            tmp_basename = fm_uri_subpath_to_native_subpath(basename, NULL);
            g_free(sub_name);
        }
        dest = g_file_get_child(dest_dir,
                        tmp_basename ? tmp_basename : fm_path_get_basename(path));
        g_free(tmp_basename);
        if(!_fm_file_ops_job_copy_file(job, src, NULL, dest, NULL, df))
            ret = FALSE;
        g_object_unref(src);
        g_object_unref(dest);
    }

    /* g_debug("finished: %llu, total: %llu", job->finished, job->total); */
    fm_file_ops_job_emit_percent(job);

    /* restore updates for destination */
    if (df)
    {
        fm_folder_unblock_updates(df);
        g_object_unref(df);
    }
    g_object_unref(dest_dir);
    return ret;
}
Exemple #14
0
/*********************************************************************
 * ...
 * 
 * 
 ********************************************************************/
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;
}
Exemple #15
0
void generate_thumbnails_with_gdk_pixbuf(ThumbnailTask* task)
{
    /* FIXME: only formats supported by GdkPixbuf should be handled this way. */
    GFile* gf = fm_path_to_gfile(task->fi->path);
    GFileInputStream* ins;
    GdkPixbuf* normal_pix = NULL;
    GdkPixbuf* large_pix = NULL;

    DEBUG("generate thumbnail for %s", task->fi->path->name);

    if( ins = g_file_read(gf, generator_cancellable, NULL) )
    {
        GdkPixbuf* ori_pix;
        gssize len;
        ori_pix = gdk_pixbuf_new_from_stream(G_INPUT_STREAM(ins), generator_cancellable, NULL);
        if(ori_pix) /* if the original image is successfully loaded */
        {
            const char* orientation_str = gdk_pixbuf_get_option(ori_pix, "orientation");
            int width = gdk_pixbuf_get_width(ori_pix);
            int height = gdk_pixbuf_get_height(ori_pix);
            gboolean need_save;

            if(task->flags & GENERATE_NORMAL)
            {
                /* don't create thumbnails for images which are too small */
                if(width <=128 && height <= 128)
                {
                    normal_pix = (GdkPixbuf*)g_object_ref(ori_pix);
                    need_save = FALSE;
                }
                else
                {
                    normal_pix = scale_pix(ori_pix, 128);
                    need_save = TRUE;
                }
                if(orientation_str)
                {
                    GdkPixbuf* rotated;
                    gdk_pixbuf_set_option(normal_pix, "orientation", orientation_str);
                    rotated = gdk_pixbuf_apply_embedded_orientation(normal_pix);
                    g_object_unref(normal_pix);
                    normal_pix = rotated;
                }
                if(need_save)
                    save_thumbnail_to_disk(task, normal_pix, task->normal_path);
            }

            if(task->flags & GENERATE_LARGE)
            {
                /* don't create thumbnails for images which are too small */
                if(width <=256 && height <= 256)
                {
                    large_pix = (GdkPixbuf*)g_object_ref(ori_pix);
                    need_save = FALSE;
                }
                else
                {
                    large_pix = scale_pix(ori_pix, 256);
                    need_save = TRUE;
                }
                if(orientation_str)
                {
                    GdkPixbuf* rotated;
                    gdk_pixbuf_set_option(large_pix, "orientation", orientation_str);
                    rotated = gdk_pixbuf_apply_embedded_orientation(large_pix);
                    g_object_unref(large_pix);
                    large_pix = rotated;
                }
                if(need_save)
                    save_thumbnail_to_disk(task, large_pix, task->large_path);
            }
            g_object_unref(ori_pix);
        }
        g_input_stream_close(G_INPUT_STREAM(ins), NULL, NULL);
    }

    G_LOCK(queue);
    thumbnail_task_finish(task, normal_pix, large_pix);
    cur_generating = NULL;
    G_UNLOCK(queue);

    if(normal_pix)
        g_object_unref(normal_pix);
    if(large_pix)
        g_object_unref(large_pix);

    g_object_unref(gf);
}
Exemple #16
0
static gboolean fm_file_info_job_run(FmJob* fmjob)
{
    GList* l;
    FmFileInfoJob* job = (FmFileInfoJob*)fmjob;
    GError* err = NULL;

    if(job->file_infos == NULL)
        return FALSE;

    for(l = fm_file_info_list_peek_head_link(job->file_infos); !fm_job_is_cancelled(fmjob) && l;)
    {
        FmFileInfo* fi = (FmFileInfo*)l->data;
        GList* next = l->next;
        FmPath* path = fm_file_info_get_path(fi);

        if(job->current)
            fm_path_unref(job->current);
        job->current = fm_path_ref(path);

        if(fm_path_is_native(path))
        {
            char* path_str = fm_path_to_str(path);
            if(!_fm_file_info_job_get_info_for_native_file(fmjob, fi, path_str, &err))
            {
                FmJobErrorAction act = fm_job_emit_error(fmjob, err, FM_JOB_ERROR_MILD);
                g_error_free(err);
                err = NULL;
                if(act == FM_JOB_RETRY)
                {
                    g_free(path_str);
                    continue; /* retry */
                }

                fm_file_info_list_delete_link(job->file_infos, l); /* also calls unref */
            }
            else if(G_UNLIKELY(job->flags & FM_FILE_INFO_JOB_EMIT_FOR_EACH_FILE))
                fm_job_call_main_thread(fmjob, _emit_current_file, fi);
            g_free(path_str);
            /* recursively set display names for path parents */
            _check_native_display_names(fm_path_get_parent(path));
        }
        else
        {
            GFile* gf;

            gf = fm_path_to_gfile(path);
            if(!_fm_file_info_job_get_info_for_gfile(fmjob, fi, gf, &err))
            {
              if(err->domain == G_IO_ERROR && err->code == G_IO_ERROR_NOT_MOUNTED)
              {
                GFileInfo *inf;
                /* location by link isn't mounted; unfortunately we cannot
                   launch a target if we don't know what kind of target we
                   have; lets make a simplest directory-kind GFIleInfo */
                /* FIXME: this may be dirty a bit */
                g_error_free(err);
                err = NULL;
                inf = g_file_info_new();
                g_file_info_set_file_type(inf, G_FILE_TYPE_DIRECTORY);
                g_file_info_set_name(inf, fm_path_get_basename(path));
                g_file_info_set_display_name(inf, fm_path_get_basename(path));
                fm_file_info_set_from_g_file_data(fi, gf, inf);
                g_object_unref(inf);
              }
              else
              {
                FmJobErrorAction act = fm_job_emit_error(fmjob, err, FM_JOB_ERROR_MILD);
                g_error_free(err);
                err = NULL;
                if(act == FM_JOB_RETRY)
                {
                    g_object_unref(gf);
                    continue; /* retry */
                }

                fm_file_info_list_delete_link(job->file_infos, l); /* also calls unref */
                goto _next;
              }
            }
            else if(G_UNLIKELY(job->flags & FM_FILE_INFO_JOB_EMIT_FOR_EACH_FILE))
                    fm_job_call_main_thread(fmjob, _emit_current_file, fi);
            /* recursively set display names for path parents */
            _check_gfile_display_names(fm_path_get_parent(path), gf);
_next:
            g_object_unref(gf);
        }
        l = next;
    }
    return TRUE;
}
Exemple #17
0
// 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;
}
Exemple #18
0
// templateFile is a file path used as a template of the new file.
void createFile(CreateFileType type, FmPath* parentDir, FmTemplate* templ, QWidget* parent) {
  QString defaultNewName;
  QString prompt;

  switch(type) {
  case CreateNewTextFile:
    prompt = QObject::tr("Please enter a new file name:");
    defaultNewName = QObject::tr("New text file");
    break;

  case CreateNewFolder:
    prompt = QObject::tr("Please enter a new folder name:");
    defaultNewName = QObject::tr("New folder");
    break;

  case CreateWithTemplate: {
    FmMimeType* mime = fm_template_get_mime_type(templ);
    prompt = QObject::tr("Enter a name for the new %1:").arg(QString::fromUtf8(fm_mime_type_get_desc(mime)));
    defaultNewName = QString::fromUtf8(fm_template_get_name(templ, NULL));
  }
  break;
  }

_retry:
  // ask the user to input a file name
  bool ok;
  QString new_name = QInputDialog::getText(parent, QObject::tr("Create File"),
                     prompt,
                     QLineEdit::Normal,
                     defaultNewName,
                     &ok);

  if(!ok)
    return;

  GFile* parent_gf = fm_path_to_gfile(parentDir);
  GFile* dest_gf = g_file_get_child(G_FILE(parent_gf), new_name.toLocal8Bit().data());
  g_object_unref(parent_gf);

  GError* err = NULL;
  switch(type) {
  case CreateNewTextFile: {
    GFileOutputStream* f = g_file_create(dest_gf, G_FILE_CREATE_NONE, NULL, &err);
    if(f) {
      g_output_stream_close(G_OUTPUT_STREAM(f), NULL, NULL);
      g_object_unref(f);
    }
    break;
  }
  case CreateNewFolder:
    g_file_make_directory(dest_gf, NULL, &err);
    break;
  case CreateWithTemplate:
    fm_template_create_file(templ, dest_gf, &err, false);
    break;
  }
  g_object_unref(dest_gf);

  if(err) {
    if(err->domain == G_IO_ERROR && err->code == G_IO_ERROR_EXISTS) {
      g_error_free(err);
      err = NULL;
      goto _retry;
    }

    QMessageBox::critical(parent, QObject::tr("Error"), err->message);
    g_error_free(err);
  }
}