/*****************************************************************************************
 *  ...
 * 
 * 
 ****************************************************************************************/
void fm_dir_tree_model_expand_row (FmDirTreeModel *dir_tree_model, GtkTreeIter *it, GtkTreePath *tree_path)
{
    //TREEVIEW_DEBUG ("TREEVIEW_DEBUG: fm_dir_tree_model_expand_row\n");
    
    GList *item_list = (GList*) it->user_data;
    
    FmDirTreeItem *dir_tree_item = (FmDirTreeItem*) item_list->data;
    
    g_return_if_fail (dir_tree_item != NULL);
    
    if (dir_tree_item->n_expand == 0)
    {
        // Dynamically load content of the folder...
        
        FmFolder *folder = fm_dir_tree_item_set_folder (item_list);

        // If the folder is already loaded, call "loaded" handler ourselves...
        if (fm_folder_get_is_loaded (folder))
        {
            FmDirTreeItem *dir_tree_item = (FmDirTreeItem*) item_list->data;
            
            GSList *files = fm_list_peek_head_link (folder->files);
            
            fm_dir_tree_item_load_folder (folder, files, item_list, FALSE);
            
            fm_dir_tree_item_on_folder_loaded (dir_tree_item);
        }
        else
        {
            //TREEVIEW_DEBUG ("NOT loaded !!!\n");
        }
    }
    
    dir_tree_item->n_expand++;
}
Exemple #2
0
void fm_folder_view_select_file_paths(FmFolderView* fv, FmPathList* paths)
{
    GList* l;
    for(l = fm_list_peek_head_link(paths);l; l=l->next)
    {
        FmPath* path = FM_PATH(l->data);
        fm_folder_view_select_file_path(fv, path);
    }
}
Exemple #3
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));
    }
}
Exemple #4
0
FmPathList* fm_path_list_new_from_file_info_list(FmFileInfoList* fis)
{
	FmPathList* list = fm_path_list_new();
	GList* l;
	for(l=fm_list_peek_head_link(fis);l;l=l->next)
	{
		FmFileInfo* fi = (FmFileInfo*)l->data;
		fm_list_push_tail(list, fi->path);
	}
	return list;
}
Exemple #5
0
GList* _fm_folder_get_file_by_name(FmFolder* folder, const char* name)
{
    GList* l = fm_list_peek_head_link(folder->files);
    for(;l;l=l->next)
    {
        FmFileInfo* fi = (FmFileInfo*)l->data;
        if(strcmp(fi->path->name, name) == 0)
            return l;
    }
    return NULL;
}
Exemple #6
0
void fm_folder_model_set_folder(FmFolderModel* model, FmFolder* dir)
{
    GSequenceIter *it;
    if( model->dir == dir )
        return;

    model->iter_age++;

    if( model->dir )
    {
        g_signal_handlers_disconnect_by_func(model->dir,
                                             _fm_folder_model_files_added, model);
        g_signal_handlers_disconnect_by_func(model->dir,
                                             _fm_folder_model_files_removed, model);
        g_signal_handlers_disconnect_by_func(model->dir,
                                             _fm_folder_model_files_changed, model);
        g_signal_handlers_disconnect_by_func(model->dir,
                                             on_folder_loaded, model);

        g_sequence_free(model->items);
        g_sequence_free(model->hidden);
        g_object_unref(model->dir);
    }
    model->dir = dir;
    model->items = g_sequence_new((GDestroyNotify)fm_folder_item_free);
    model->hidden = g_sequence_new((GDestroyNotify)fm_folder_item_free);
    if( !dir )
        return;

    model->dir = (FmFolder*)g_object_ref(model->dir);

    g_signal_connect(model->dir, "files-added",
                     G_CALLBACK(_fm_folder_model_files_added),
                     model);
    g_signal_connect(model->dir, "files-removed",
                     G_CALLBACK(_fm_folder_model_files_removed),
                     model);
    g_signal_connect(model->dir, "files-changed",
                     G_CALLBACK(_fm_folder_model_files_changed),
                     model);
    g_signal_connect(model->dir, "loaded",
                     G_CALLBACK(on_folder_loaded), model);

    if( !fm_list_is_empty(dir->files) )
    {
        GList *l;
        for( l = fm_list_peek_head_link(dir->files); l; l = l->next )
            _fm_folder_model_add_file(model, (FmFileInfo*)l->data);
    }

    if( fm_folder_get_is_loaded(model->dir) ) /* if it's already loaded */
        on_folder_loaded(model->dir, model);  /* emit 'loaded' signal */
}
Exemple #7
0
void fm_path_list_write_uri_list(FmPathList* pl, GString* buf)
{
	GList* l;
	for(l = fm_list_peek_head_link(pl); l; l=l->next)
	{
		FmPath* path = (FmPath*)l->data;
		char* uri = fm_path_to_uri(path);
		g_string_append(buf, uri);
		g_free(uri);
		if(l->next)
			g_string_append(buf, "\r\n");
	}
}
Exemple #8
0
void on_open_in_new_win(GtkAction* act, FmMainWin* win)
{
    FmPathList* sels = fm_folder_view_get_selected_file_paths(FM_FOLDER_VIEW(win->folder_view));
    GList* l;
    for( l = fm_list_peek_head_link(sels); l; l=l->next )
    {
        FmPath* path = (FmPath*)l->data;
        win = fm_main_win_new();
        gtk_window_set_default_size(GTK_WINDOW(win), 640, 480);
        fm_main_win_chdir(win, path);
        gtk_window_present(GTK_WINDOW(win));
    }
    fm_list_unref(sels);
}
Exemple #9
0
static void
on_drag_data_get ( GtkWidget *src_widget,
				   GdkDragContext *drag_context,
				   GtkSelectionData *sel_data,
				   guint info,
				   guint time,
				   FmDndSrc* ds )
{
    GdkAtom type;

    /*  Don't call the default handler  */
    g_signal_stop_emission_by_name( src_widget, "drag-data-get" );
    drag_context->actions = GDK_ACTION_MOVE | GDK_ACTION_COPY | GDK_ACTION_LINK;

	type = gdk_atom_intern_static_string(fm_default_dnd_src_targets[info].target);
	switch( info )
	{
	case FM_DND_SRC_TARGET_FM_LIST:
		/* just store the pointer in GtkSelection since this is used 
		 * within the same app. */
		gtk_selection_data_set(sel_data, type, 8,
								&ds->files, sizeof(gpointer));
		break;
	case FM_DND_SRC_TARGET_URI_LIST:
		{
			gchar* uri;
			GString* uri_list = g_string_sized_new( 8192 );
			GList* l;
			FmFileInfo* file;
			char* full_path;

			for( l = fm_list_peek_head_link(ds->files); l; l=l->next )
			{
				file = (FmFileInfo*)l->data;
				uri = fm_path_to_uri(file->path);
				g_string_append( uri_list, uri );
				g_free( uri );
				g_string_append( uri_list, "\r\n" );
			}
			gtk_selection_data_set ( sel_data, type, 8,
									 ( guchar* ) uri_list->str, uri_list->len + 1 );
			g_string_free( uri_list, TRUE );
		}
		break;
	}
}
Exemple #10
0
gboolean fm_launch_paths(GAppLaunchContext* ctx, GList* paths, FmFileLauncher* launcher, gpointer user_data)
{
    FmJob* job = fm_file_info_job_new(NULL);
    GList* l;
    gboolean ret;
    for(l=paths;l;l=l->next)
        fm_file_info_job_add(FM_FILE_INFO_JOB(job), (FmPath*)l->data);
    ret = fm_job_run_sync_with_mainloop(job);
    if(ret)
    {
        GList* file_infos = fm_list_peek_head_link(FM_FILE_INFO_JOB(job)->file_infos);
        if(file_infos)
            ret = fm_launch_files(ctx, file_infos, launcher, user_data);
        else
            ret = FALSE;
    }
    g_object_unref(job);
    return ret;
}
Exemple #11
0
void on_file_info_finished(FmFileInfoJob* job, FmFolder* folder)
{
    GList* l;
    GSList* files_to_add = NULL;
    GSList* files_to_update = NULL;

    for(l=fm_list_peek_head_link(job->file_infos);l;l=l->next)
    {
        FmFileInfo* fi = (FmFileInfo*)l->data;
        GList* l2 = _fm_folder_get_file_by_name(folder, fi->path->name);
        if(l2) /* the file is already in the folder, update */
        {
            FmFileInfo* fi2 = (FmFileInfo*)l2->data;
            /* FIXME: will fm_file_info_copy here cause problems?
             *        the file info might be referenced by others, too.
             *        we're mofifying an object referenced by others.
             *        we should redesign the API, or document this clearly
             *        in future API doc.
             */
            fm_file_info_copy(fi2, fi);
            files_to_update = g_slist_prepend(files_to_update, fi2);
        }
        else
        {
            files_to_add = g_slist_prepend(files_to_add, fi);
            fm_file_info_ref(fi);
            fm_list_push_tail(folder->files, fi);
        }
    }
    if(files_to_add)
    {
        g_signal_emit(folder, signals[FILES_ADDED], 0, files_to_add);
        g_slist_free(files_to_add);
    }
    if(files_to_update)
    {
        g_signal_emit(folder, signals[FILES_CHANGED], 0, files_to_update);
        g_slist_free(files_to_update);
    }

    folder->pending_jobs = g_slist_remove(folder->pending_jobs, job);
}
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 #13
0
gboolean on_dnd_dest_files_dropped(FmDndDest* dd, GdkDragAction action,
                               int info_type, FmFileInfoList* files, FmPlacesView* view)
{
    FmPath* dest;
    GList* l;
    gboolean ret = FALSE;

    dest = fm_dnd_dest_get_dest_path(dd);
    /* g_debug("action= %d, %d files-dropped!, info_type: %d", action, fm_list_get_length(files), info_type); */

    if(!dest && action == GDK_ACTION_LINK) /* add bookmarks */
    {
        GtkTreePath* tp = view->dest_row;
        if(tp)
        {
            const GtkTreePath* sep = fm_places_model_get_separator_path(FM_PLACES_MODEL(model));
            int idx = gtk_tree_path_get_indices(tp)[0] - gtk_tree_path_get_indices(sep)[0];

            if(view->dest_pos == GTK_TREE_VIEW_DROP_BEFORE)
                --idx;
            for( l=fm_list_peek_head_link(files); l; l=l->next, ++idx )
            {
                FmBookmarkItem* item;
                FmFileInfo* fi = FM_FILE_INFO(l->data);
                if(fm_file_info_is_dir(fi))
                    item = fm_bookmarks_insert( FM_PLACES_MODEL(model)->bookmarks, fi->path, fi->disp_name, idx);
                /* we don't need to add item to places view. Later the bookmarks will be reloaded. */
            }
        }
        ret = TRUE;
    }

    if(view->dest_row)
    {
        gtk_tree_path_free(view->dest_row);
        view->dest_row = NULL;
    }
    return ret;
}
Exemple #14
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));
}
Exemple #15
0
/*********************************************************************
 * ...
 * 
 * 
 ********************************************************************/
FmJob *fm_file_info_job_new (FmPathList *files_to_query, FmFileInfoJobFlags flags)
{
	FmFileInfoJob *job = (FmFileInfoJob*) g_object_new (FM_TYPE_FILE_INFO_JOB, NULL);

    job->flags = flags;
	
    if (!files_to_query)
        return (FmJob*) job;
	
	FmFileInfoList *file_infos = job->file_infos;
    
	GList *l;
    for (l = fm_list_peek_head_link (files_to_query); l; l=l->next)
    {
        FmPath *path = (FmPath*) l->data;
        
        FmFileInfo *file_info = fm_file_info_new_for_path (path);
        
        fm_list_push_tail_noref (file_infos, file_info);
    }
	
	return (FmJob*) job;
}
Exemple #16
0
static void on_job_finished(FmDirListJob* job, FmFolder* folder)
{
    GList* l;
    GSList* files = NULL;
    /* actually manually disconnecting from 'finished' signal is not
     * needed since the signal is only emit once, and later the job
     * object will be distroyed very soon. */
    /* g_signal_handlers_disconnect_by_func(job, on_job_finished, folder); */
    for(l = fm_list_peek_head_link(job->files); l; l=l->next)
    {
        FmFileInfo* inf = (FmFileInfo*)l->data;
        files = g_slist_prepend(files, inf);
        fm_list_push_tail(folder->files, inf);
    }
    if(G_LIKELY(files))
        g_signal_emit(folder, signals[FILES_ADDED], 0, files);

    if(job->dir_fi)
        folder->dir_fi = fm_file_info_ref(job->dir_fi);

    folder->job = NULL; /* the job object will be freed in idle handler. */
    g_signal_emit(folder, signals[LOADED], 0);
}
Exemple #17
0
static void get_data(GtkClipboard *clip, GtkSelectionData *sel, guint info, gpointer user_data)
{
	FmPathList* files = (FmPathList*)user_data;
	GString* uri_list;

    if(info == KDE_CUT_SEL)
    {
        /* set application/kde-cutselection data */
        if(is_cut)
            gtk_selection_data_set(sel, sel->target, 8, "1", 2);
        return;
    }

    uri_list = g_string_sized_new(4096);
	if(info == GNOME_COPIED_FILES)
		g_string_append(uri_list, is_cut ? "cut\n" : "copy\n");
	if(info == UTF8_STRING)
	{
		GList* l = fm_list_peek_head_link(files);
		while(l)
		{
			FmPath* path = (FmPath*)l->data;
			char* str = fm_path_to_str(path);
			g_string_append(uri_list, str);
			g_string_append_c(uri_list, '\n');
			g_free(str);
			l=l->next;
		}
	}
	else/* text/uri-list format */
	{
		fm_path_list_write_uri_list(files, uri_list);
	}
	gtk_selection_data_set(sel, sel->target, 8, uri_list->str, uri_list->len + 1);
	g_string_free(uri_list, TRUE);
}
Exemple #18
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 #19
0
void on_dnd_dest_files_dropped(FmDndDest* dd, GdkDragAction action,
                               int info_type, FmList* files, FmPlacesView* view)
{
	FmPath* dest;
    GList* l;

	dest = fm_dnd_dest_get_dest_path(dd);
    g_debug("action= %d, %d files-dropped!, info_type: %d", action, fm_list_get_length(files), info_type);

    if(action != GDK_ACTION_LINK)
    {
        if(fm_list_is_file_info_list(files))
            files = fm_path_list_new_from_file_info_list(files);
        else
            fm_list_ref(files);
    }

    switch(action)
    {
    case GDK_ACTION_MOVE:
        if(fm_path_is_trash_root(dest))
            fm_trash_files(files);
        else
            fm_move_files(files, dest);
        break;
    case GDK_ACTION_COPY:
        fm_copy_files(files, dest);
        break;
    case GDK_ACTION_LINK:
        {
            GtkTreePath* tp = view->dest_row;
            if(tp)
            {
                GtkTreePath* sep = gtk_tree_model_get_path(GTK_TREE_MODEL(model), &sep_it);
                int idx = gtk_tree_path_get_indices(tp)[0] - gtk_tree_path_get_indices(sep)[0];
                gtk_tree_path_free(sep);
                if(view->dest_pos == GTK_TREE_VIEW_DROP_BEFORE)
                    --idx;
                for( l=fm_list_peek_head_link(files); l; l=l->next, ++idx )
                {
                    FmBookmarkItem* item;
                    if(fm_list_is_file_info_list(files))
                    {
                        FmFileInfo* fi = (FmFileInfo*)l->data;
                        item = fm_bookmarks_insert( bookmarks, fi->path, fi->disp_name, idx);
                    }
                    else
                    {
                        FmPath* path = (FmPath*)l->data;
                        char* disp_name = g_filename_display_name(path->name);
                        item = fm_bookmarks_insert( bookmarks, path, disp_name, idx);
                        g_free(disp_name);
                    }
                    /* we don't need to add item to places view. Later the bookmarks will be reloaded. */
                }
            }
        }
        break;
    }
    fm_list_unref(files);

    if(view->dest_row)
    {
        gtk_tree_path_free(view->dest_row);
        view->dest_row = NULL;
    }
}
Exemple #20
0
static gboolean on_show_dlg (FmProgressDisplay *data)
{
    GtkBuilder *builder = gtk_builder_new ();
    GtkWidget *to, *to_label;
    FmPath *dest;
    const char *title = NULL;
    GtkTextTagTable *tag_table = gtk_text_tag_table_new ();

    gtk_builder_set_translation_domain (builder, GETTEXT_PACKAGE);
    gtk_builder_add_from_string (builder, PROGRESS_DLG, -1, NULL);

    data->dlg = (GtkWidget*) gtk_builder_get_object (builder, "dlg");

    g_signal_connect (data->dlg, "response", (GCallback) on_response, data);

    to_label =              (GtkWidget*) gtk_builder_get_object (builder, "to_label");
    to =                    (GtkWidget*) gtk_builder_get_object (builder, "dest");
    data->icon =            (GtkWidget*) gtk_builder_get_object (builder, "icon");
    data->msg =             (GtkWidget*) gtk_builder_get_object (builder, "msg");
    data->act =             (GtkWidget*) gtk_builder_get_object (builder, "action");
    data->src =             (GtkWidget*) gtk_builder_get_object (builder, "src");
    data->dest =            (GtkWidget*) gtk_builder_get_object (builder, "dest");
    data->current =         (GtkWidget*) gtk_builder_get_object (builder, "current");
    data->progress =        (GtkWidget*) gtk_builder_get_object (builder, "progress");
    data->error_pane =      (GtkWidget*) gtk_builder_get_object (builder, "error_pane");
    data->error_msg =       (GtkWidget*) gtk_builder_get_object (builder, "error_msg");
    data->remaining_time =  (GtkWidget*) gtk_builder_get_object (builder, "remaining_time");

    data->bold_tag = gtk_text_tag_new ("bold");
    g_object_set (data->bold_tag, "weight", PANGO_WEIGHT_BOLD, NULL);
    
    gtk_text_tag_table_add (tag_table, data->bold_tag);
    data->error_buf = gtk_text_buffer_new (tag_table);
    g_object_unref (tag_table);
    
    gtk_text_view_set_buffer (GTK_TEXT_VIEW (data->error_msg), data->error_buf);

    g_object_unref (builder);

    // set the src label
    if (data->job->srcs)
    {
        GList *l = fm_list_peek_head_link (data->job->srcs);
        int i;
        char *disp;
        FmPath *path;
        
        GString *str = g_string_sized_new (512);
        path = FM_PATH (l->data);
        disp = fm_path_display_basename (path);
        g_string_assign (str, disp);
        g_free (disp);
        
        for ( i =1, l=l->next; i < 10 && l; l=l->next, ++i)
        {
            path = FM_PATH (l->data);
            g_string_append (str, _(", "));
            disp = fm_path_display_basename (path);
            g_string_append (str, disp);
            g_free (disp);
        }
        
        if (l)
            g_string_append (str, "...");
        
        gtk_label_set_text (GTK_LABEL (data->src), str->str);
        g_string_free (str, TRUE);
    }

    // FIXME_pcm: use accessor functions instead
    switch (data->job->type)
    {
        case FM_FILE_OP_MOVE:
            title = _("Moving files");
        break;
        
        case FM_FILE_OP_COPY:
            title = _("Copying files");
        break;
        
        case FM_FILE_OP_TRASH:
            title = _("Trashing files");
        break;
        
        case FM_FILE_OP_DELETE:
            title = _("Deleting files");
        break;
        
        case FM_FILE_OP_LINK:
            title = _("Creating symlinks");
        break;
        
        case FM_FILE_OP_CHANGE_ATTR:
            title = _("Changing file attributes");
        break;
    }
    
    if (title)
    {
        gtk_window_set_title (GTK_WINDOW (data->dlg), title);
        gtk_label_set_text (GTK_LABEL (data->act), title);
    }

    if (dest = fm_file_ops_job_get_dest (data->job))
    {
        char *dest_str = fm_path_display_name (dest, TRUE);
        gtk_label_set_text (GTK_LABEL (to), dest_str);
        g_free (dest_str);
    }
    else
    {
        gtk_widget_destroy (data->dest);
        gtk_widget_destroy (to_label);
    }

    gtk_window_present (GTK_WINDOW (data->dlg));
    data->update_timeout = g_timeout_add (500,  (GSourceFunc)on_update_dlg, data);

    data->delay_timeout = 0;
    return FALSE;
}
// FIXME_pcm: this is too dirty. Need some refactor later.
static void update_permissions (FmFilePropData *data)
{
    FmFileInfo *file_info =  (FmFileInfo*)fm_list_peek_head (data->files);
    GList *l;
    int sel;
    char *tmp;
    mode_t owner_perm =  (file_info->mode & S_IRWXU);
    mode_t group_perm =  (file_info->mode & S_IRWXG);
    mode_t other_perm =  (file_info->mode & S_IRWXO);
    mode_t exec_perm =  (file_info->mode &  (S_IXUSR|S_IXGRP|S_IXOTH));
    uid_t uid = file_info->uid;
    gid_t gid = file_info->gid;
    struct group *grp = NULL;
    struct passwd *pw = NULL;

    data->all_native = fm_path_is_native (fm_file_info_get_path (file_info));
    data->has_dir = S_ISDIR (file_info->mode) != FALSE;

    for (l=fm_list_peek_head_link (data->files)->next; l; l=l->next)
    {
        FmFileInfo *file_info =  (FmFileInfo*)l->data;

        if ( !fm_path_is_native (fm_file_info_get_path (file_info)) )
            data->all_native = FALSE;

        if (S_ISDIR (file_info->mode))
            data->has_dir = TRUE;

        if ( uid != file_info->uid )
            uid = -1;
        if ( gid != file_info->gid )
            gid = -1;

        if ( owner_perm != -1 && owner_perm !=  (file_info->mode & S_IRWXU) )
            owner_perm = -1;
        if ( group_perm != -1 && group_perm !=  (file_info->mode & S_IRWXG) )
            group_perm = -1;
        if ( other_perm != -1 && other_perm !=  (file_info->mode & S_IRWXO) )
            other_perm = -1;

        if ( exec_perm !=  (file_info->mode &  (S_IXUSR|S_IXGRP|S_IXOTH)) )
            exec_perm = -1;
    }

    if ( data->all_native )
    {
        if ( uid >= 0 )
        {
            pw = getpwuid (uid);
            if (pw)
                gtk_entry_set_text (GTK_ENTRY (data->owner), pw->pw_name);
        }
        if ( gid >= 0 )
        {
            grp = getgrgid (gid);
            if (grp)
                gtk_entry_set_text (GTK_ENTRY (data->group), grp->gr_name);
        }
    }

    if ( uid >=0 && !pw )
    {
        tmp = g_strdup_printf ("%u", uid);
        gtk_entry_set_text (GTK_ENTRY (data->owner), tmp);
        g_free (tmp);
    }

    if ( gid >=0 && !grp )
    {
        tmp = g_strdup_printf ("%u", gid);
        gtk_entry_set_text (GTK_ENTRY (data->group), tmp);
        g_free (tmp);
    }

    data->orig_owner = g_strdup (gtk_entry_get_text (GTK_ENTRY (data->owner)));
    data->orig_group = g_strdup (gtk_entry_get_text (GTK_ENTRY (data->group)));

    // on local filesystems, only root can do chown.
    if ( data->all_native && geteuid () != 0 )
    {
        gtk_editable_set_editable (GTK_EDITABLE (data->owner), FALSE);
        gtk_editable_set_editable (GTK_EDITABLE (data->group), FALSE);
    }

    sel = NO_CHANGE;
    if (owner_perm != -1)
    {
        if (  (owner_perm &  (S_IRUSR|S_IWUSR)) ==  (S_IRUSR|S_IWUSR) )
            sel = READ_WRITE;
        else if (  (owner_perm &  (S_IRUSR|S_IWUSR)) == S_IRUSR )
            sel = READ_ONLY;
        else if (  (owner_perm &  (S_IRUSR|S_IWUSR)) == S_IWUSR )
            sel = WRITE_ONLY;
        else
            sel = NONE;
    }
    gtk_combo_box_set_active (GTK_COMBO_BOX (data->owner_perm), sel);
    data->owner_perm_sel = sel;

    sel = NO_CHANGE;
    if (group_perm != -1)
    {
        if (  (group_perm &  (S_IRGRP|S_IWGRP)) ==  (S_IRGRP|S_IWGRP) )
            sel = READ_WRITE;
        else if (  (group_perm &  (S_IRGRP|S_IWGRP)) == S_IRGRP )
            sel = READ_ONLY;
        else if (  (group_perm &  (S_IRGRP|S_IWGRP)) == S_IWGRP )
            sel = WRITE_ONLY;
        else
            sel = NONE;
    }
    gtk_combo_box_set_active (GTK_COMBO_BOX (data->group_perm), sel);
    data->group_perm_sel = sel;

    sel = NO_CHANGE;
    if (other_perm != -1)
    {
        if (  (other_perm &  (S_IROTH|S_IWOTH)) ==  (S_IROTH|S_IWOTH) )
            sel = READ_WRITE;
        else if (  (other_perm &  (S_IROTH|S_IWOTH)) == S_IROTH )
            sel = READ_ONLY;
        else if (  (other_perm &  (S_IROTH|S_IWOTH)) == S_IWOTH )
            sel = WRITE_ONLY;
        else
            sel = NONE;
    }
    gtk_combo_box_set_active (GTK_COMBO_BOX (data->other_perm), sel);
    data->other_perm_sel = sel;

    if (data->has_dir)
        gtk_widget_hide ( data->exec );

    if ( exec_perm != -1 )
    {
        gboolean xusr =  (exec_perm & S_IXUSR) != 0;
        gboolean xgrp =  (exec_perm & S_IXGRP) != 0;
        gboolean xoth =  (exec_perm & S_IXOTH) != 0;
        if ( xusr == xgrp && xusr == xoth ) // executable
        {
            gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (data->exec), xusr);
            data->exec_state = xusr;
        }
        else // inconsistent
        {
            gtk_toggle_button_set_inconsistent (GTK_TOGGLE_BUTTON (data->exec), TRUE);
            g_signal_connect (data->exec, "toggled", G_CALLBACK (on_exec_toggled), data);
            data->exec_state = -1;
        }
    }
    else // inconsistent
    {
        gtk_toggle_button_set_inconsistent (GTK_TOGGLE_BUTTON (data->exec), TRUE);
        g_signal_connect (data->exec, "toggled", G_CALLBACK (on_exec_toggled), data);
        data->exec_state = -1;
    }
}
Exemple #22
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 #23
0
static void on_folder_view_sel_changed(FmFolderView* fv, FmFileInfoList* files, FmTabPage* page)
{
    char* msg = page->status_text[FM_STATUS_TEXT_SELECTED_FILES];
    g_free(msg);
    msg = NULL;

    // use SI metric by default
    static gboolean use_si_prefix = TRUE ;

    unsigned items_num = 0;

    if (files)
        items_num = fm_list_get_length(files) ;

    if (items_num > 1) // multiple items are selected
    {
        goffset items_totalsize = 0 ;

        // whether selected items contain dir
        gboolean items_contain_dir  = FALSE ;

        GList* l;
        for (l=fm_list_peek_head_link(files);l;l=l->next)
        {
            FmFileInfo* fi = (FmFileInfo*)l->data;

            // ignore dir when calculating total size. because that
            // may take a long long time, not suitable for updating
            // statusbar in real time.
            if (fm_file_info_is_dir(fi) )
            {
                items_contain_dir = TRUE;
            }
            else
            {
                // Non-dir items are regard as files
                // Should extra logic be added for different kinds of files?
                // hardlink, symlink, pipe, socket ?
                items_totalsize += fm_file_info_get_size(fi) ;
            }
        }

        // when the selected items contain dir, do not show size info on the
        // statusbar, because the calculated total size counts for files only
        // and showing it would be misleading to the user.
        if (items_contain_dir)
        {
            msg = g_strdup_printf("%d items selected", items_num);
        }
        else
        {
            char items_totalsize_str[ 64 ];
            fm_file_size_to_str( items_totalsize_str, items_totalsize, use_si_prefix );

            msg = g_strdup_printf("%d items selected, total size: %s", \
                                  items_num, items_totalsize_str);
        }

    }
    else if (items_num == 1)
    {
        FmFileInfo* fi = fm_list_peek_head(files);
        const char* size_str = fm_file_info_get_disp_size(fi);
        gboolean is_link = fm_file_info_is_symlink(fi);
        if (is_link && size_str)
        {
            msg = g_strdup_printf("\"%s\" link to \"%s\" (%s)",
                                  fm_file_info_get_disp_name(fi),
                                  fm_file_info_get_target(fi),
                                  size_str);
        }
        else if (is_link)
        {
            msg = g_strdup_printf("\"%s\" link to \"%s\"",
                                  fm_file_info_get_disp_name(fi),
                                  fm_file_info_get_target(fi));
        }
        else if (size_str)
        {
            msg = g_strdup_printf("\"%s\" (%s) %s",
                                  fm_file_info_get_disp_name(fi),
                                  size_str,
                                  fm_file_info_get_desc(fi));
        }
        else
        {
            msg = g_strdup_printf("\"%s\" %s",
                                  fm_file_info_get_disp_name(fi),
                                  fm_file_info_get_desc(fi));
        }
    }

    page->status_text[FM_STATUS_TEXT_SELECTED_FILES] = msg;
    g_signal_emit(page, signals[STATUS], 0,
                  (guint)FM_STATUS_TEXT_SELECTED_FILES, msg);
}