void ptk_clipboard_copy_name( const char* working_dir, GList* files ) //MOD added { GtkClipboard* clip = gtk_clipboard_get( GDK_SELECTION_CLIPBOARD ); GtkClipboard* clip_primary = gtk_clipboard_get( GDK_SELECTION_PRIMARY ); GList *l; VFSFileInfo* file; char* file_text; gint fcount = 0; char* str; file_text = g_strdup( "" ); for ( l = files; l; l = l->next ) { file = ( VFSFileInfo* ) l->data; str = file_text; if ( fcount == 0 ) file_text = g_strdup_printf( "%s", vfs_file_info_get_name( file ) ); else if ( fcount == 1 ) file_text = g_strdup_printf( "%s\n%s\n", file_text, vfs_file_info_get_name( file ) ); else file_text = g_strdup_printf( "%s%s\n", file_text, vfs_file_info_get_name( file ) ); fcount++; g_free( str ); } gtk_clipboard_set_text( clip, file_text , -1 ); gtk_clipboard_set_text( clip_primary, file_text , -1 ); g_free( file_text ); }
void ptk_clipboard_copy_as_text( const char* working_dir, GList* files ) //MOD added { // aka copy path GtkClipboard* clip = gtk_clipboard_get( GDK_SELECTION_CLIPBOARD ); GtkClipboard* clip_primary = gtk_clipboard_get( GDK_SELECTION_PRIMARY ); GList *l; VFSFileInfo* file; char* file_path; char* file_text; char* str; char* quoted; file_text = g_strdup( "" ); for ( l = files; l; l = l->next ) { file = ( VFSFileInfo* ) l->data; file_path = g_build_filename( working_dir, vfs_file_info_get_name( file ), NULL ); quoted = bash_quote( file_path ); str = file_text; file_text = g_strdup_printf( "%s %s", str, quoted ); g_free( str ); g_free( quoted ); g_free( file_path ); } gtk_clipboard_set_text ( clip, file_text , -1 ); gtk_clipboard_set_text ( clip_primary, file_text , -1 ); g_free( file_text ); }
static gboolean filter_func( GtkTreeModel *model, GtkTreeIter *iter, gpointer data ) { VFSFileInfo * file; const char* name; GtkTreeView* view = ( GtkTreeView* ) data; gboolean show_hidden = ( gboolean ) g_object_get_qdata( G_OBJECT( view ), dir_tree_view_data ); if ( show_hidden ) return TRUE; gtk_tree_model_get( model, iter, COL_DIR_TREE_INFO, &file, -1 ); if ( G_LIKELY( file ) ) { name = vfs_file_info_get_name( file ); if ( G_UNLIKELY( name && name[ 0 ] == '.' ) ) { vfs_file_info_unref( file ); return FALSE; } vfs_file_info_unref( file ); } return TRUE; }
void ptk_file_list_file_changed( VFSDir* dir, VFSFileInfo* file, PtkFileList* list ) { GList* l; GtkTreeIter it; GtkTreePath* path; if( ! list->show_hidden && vfs_file_info_get_name(file)[0] == '.' ) return; l = g_list_find( list->files, file ); if( ! l ) return; it.stamp = list->stamp; it.user_data = l; it.user_data2 = l->data; path = gtk_tree_path_new_from_indices( g_list_index(list->files, l->data), -1 ); gtk_tree_model_row_changed( GTK_TREE_MODEL(list), path, &it ); gtk_tree_path_free( path ); }
static void reload_mime_type( char* key, VFSDir* dir, gpointer user_data ) { GList* l; VFSFileInfo* file; char* full_path; if( G_UNLIKELY( ! dir || ! dir->file_list ) ) return; g_mutex_lock( dir->mutex ); for( l = dir->file_list; l; l = l->next ) { file = (VFSFileInfo*)l->data; full_path = g_build_filename( dir->path, vfs_file_info_get_name( file ), NULL ); vfs_file_info_reload_mime_type( file, full_path ); /* g_debug( "reload %s", full_path ); */ g_free( full_path ); } for( l = dir->file_list; l; l = l->next ) { file = (VFSFileInfo*)l->data; g_signal_emit( dir, signals[FILE_CHANGED_SIGNAL], 0, file ); } g_mutex_unlock( dir->mutex ); }
gboolean ptk_file_list_find_iter( PtkFileList* list, GtkTreeIter* it, VFSFileInfo* fi ) { GList* l; for( l = list->files; l; l = l->next ) { VFSFileInfo* fi2 = (VFSFileInfo*)l->data; if( G_UNLIKELY( fi2 == fi || 0 == strcmp( vfs_file_info_get_name(fi), vfs_file_info_get_name(fi2) ) ) ) { it->stamp = list->stamp; it->user_data = l; it->user_data2 = fi2; return TRUE; } } return FALSE; }
void ptk_clipboard_cut_or_copy_files( const char* working_dir, GList* files, gboolean copy ) { GtkClipboard * clip = gtk_clipboard_get( GDK_SELECTION_CLIPBOARD ); GtkTargetList* target_list = gtk_target_list_new( NULL, 0 ); GList* target; gint i, n_targets; GtkTargetEntry* targets; GtkTargetPair* pair; GList *l; VFSFileInfo* file; char* file_path; GList* file_list = NULL; gtk_target_list_add_text_targets( target_list, 0 ); n_targets = g_list_length( target_list->list ) + 2; targets = g_new0( GtkTargetEntry, n_targets ); target = target_list->list; for ( i = 0; target; ++i, target = g_list_next( target ) ) { pair = ( GtkTargetPair* ) target->data; targets[ i ].target = gdk_atom_name ( pair->target ); } targets[ i ].target = "x-special/gnome-copied-files"; targets[ i + 1 ].target = "text/uri-list"; gtk_target_list_unref ( target_list ); for ( l = g_list_last( files ); l; l = l->prev ) //sfm was reverse order { file = ( VFSFileInfo* ) l->data; file_path = g_build_filename( working_dir, vfs_file_info_get_name( file ), NULL ); file_list = g_list_prepend( file_list, file_path ); } gtk_clipboard_set_with_data ( clip, targets, n_targets, clipboard_get_data, clipboard_clean_data, NULL ); g_free( targets ); clipboard_file_list = file_list; clipboard_action = copy ? GDK_ACTION_COPY : GDK_ACTION_MOVE; }
void ptk_file_list_file_created( VFSDir* dir, VFSFileInfo* file, PtkFileList* list ) { GList* l; GtkTreeIter it; GtkTreePath* path; VFSFileInfo* file2; if( ! list->show_hidden && vfs_file_info_get_name(file)[0] == '.' ) return; for( l = list->files; l; l = l->next ) { file2 = (VFSFileInfo*)l->data; if( G_UNLIKELY( file == file2 || ptk_file_list_compare( file2, file, list ) == 0 ) ) { /* The file is already in the list */ return; } if( ptk_file_list_compare( file2, file, list ) > 0 ) { break; } } list->files = g_list_insert_before( list->files, l, vfs_file_info_ref( file ) ); ++list->n_files; if( l ) l = l->prev; else l = g_list_last( list->files ); it.stamp = list->stamp; it.user_data = l; it.user_data2 = file; path = gtk_tree_path_new_from_indices( g_list_index(list->files, l->data), -1 ); gtk_tree_model_row_inserted( GTK_TREE_MODEL(list), path, &it ); gtk_tree_path_free( path ); }
void ptk_file_list_file_deleted( VFSDir* dir, VFSFileInfo* file, PtkFileList* list ) { GList* l; GtkTreePath* path; /* If there is no file info, that means the dir itself was deleted. */ if( G_UNLIKELY( ! file ) ) { /* Clear the whole list */ path = gtk_tree_path_new_from_indices(0, -1); for( l = list->files; l; l = list->files ) { gtk_tree_model_row_deleted( GTK_TREE_MODEL(list), path ); file = (VFSFileInfo*)l->data; list->files = g_list_delete_link( list->files, l ); vfs_file_info_unref( file ); --list->n_files; } gtk_tree_path_free( path ); return; } if( ! list->show_hidden && vfs_file_info_get_name(file)[0] == '.' ) return; l = g_list_find( list->files, file ); if( ! l ) return; path = gtk_tree_path_new_from_indices( g_list_index(list->files, l->data), -1 ); gtk_tree_model_row_deleted( GTK_TREE_MODEL(list), path ); gtk_tree_path_free( path ); list->files = g_list_delete_link( list->files, l ); vfs_file_info_unref( file ); --list->n_files; }
static gpointer calc_size( gpointer user_data ) { FilePropertiesDialogData * data = ( FilePropertiesDialogData* ) user_data; GList* l; char* path; VFSFileInfo* file; for ( l = data->file_list; l; l = l->next ) { if ( data->cancel ) break; file = ( VFSFileInfo* ) l->data; path = g_build_filename( data->dir_path, vfs_file_info_get_name( file ), NULL ); if ( path ) { calc_total_size_of_files( path, data ); g_free( path ); } } data->done = TRUE; return NULL; }
static gboolean open_file( char* dir, GList* files, PtkFileBrowser* file_browser ) { if( files ) { ptk_open_files_with_app( dir, files, NULL, NULL, FALSE, TRUE ); //sfm open selected dirs if ( file_browser ) { GList * l; gchar* full_path; VFSFileInfo* file; for ( l = files; l; l = l->next ) { file = ( VFSFileInfo* ) l->data; if ( G_UNLIKELY( ! file ) ) continue; full_path = g_build_filename( dir, vfs_file_info_get_name( file ), NULL ); if ( G_LIKELY( full_path ) ) { if ( g_file_test( full_path, G_FILE_TEST_IS_DIR ) ) { ptk_file_browser_emit_open( file_browser, full_path, PTK_OPEN_NEW_TAB ); } g_free( full_path ); } } } vfs_file_info_list_free( files ); //sfm moved free list to here return TRUE; } return FALSE; }
gboolean ptk_dir_tree_view_chdir( GtkTreeView* dir_tree_view, const char* path ) { GtkTreeModel * model; GtkTreeIter it, parent_it; GtkTreePath* tree_path = NULL; gchar **dirs, **dir; gboolean found; VFSFileInfo* info; if ( !path || *path != '/' ) return FALSE; dirs = g_strsplit( path + 1, "/", -1 ); if ( !dirs ) return FALSE; model = gtk_tree_view_get_model( dir_tree_view ); if ( ! gtk_tree_model_iter_children ( model, &parent_it, NULL ) ) { g_strfreev( dirs ); return FALSE; } /* special case: root dir */ if ( ! dirs[ 0 ] ) { it = parent_it; tree_path = gtk_tree_model_get_path ( model, &parent_it ); goto _found; } for ( dir = dirs; *dir; ++dir ) { if ( ! gtk_tree_model_iter_children ( model, &it, &parent_it ) ) { g_strfreev( dirs ); return FALSE; } found = FALSE; do { gtk_tree_model_get( model, &it, COL_DIR_TREE_INFO, &info, -1 ); if ( !info ) continue; if ( 0 == strcmp( vfs_file_info_get_name( info ), *dir ) ) { tree_path = gtk_tree_model_get_path( model, &it ); if( dir[1] ) { gtk_tree_view_expand_row ( dir_tree_view, tree_path, FALSE ); gtk_tree_model_get_iter( model, &parent_it, tree_path ); } found = TRUE; vfs_file_info_unref( info ); break; } vfs_file_info_unref( info ); } while ( gtk_tree_model_iter_next( model, &it ) ); if ( ! found ) return FALSE; /* Error! */ if ( tree_path && dir[ 1 ] ) { gtk_tree_path_free( tree_path ); tree_path = NULL; } } _found: g_strfreev( dirs ); gtk_tree_selection_select_path ( gtk_tree_view_get_selection( dir_tree_view ), tree_path ); gtk_tree_view_scroll_to_cell ( dir_tree_view, tree_path, NULL, FALSE, 0.5, 0.5 ); gtk_tree_path_free( tree_path ); return TRUE; }
gpointer thumbnail_loader_thread( VFSAsyncTask* task, VFSThumbnailLoader* loader ) { ThumbnailRequest* req; int i; gboolean load_big, need_update; while( G_LIKELY( ! vfs_async_task_is_cancelled(task) )) { vfs_async_task_lock( task ); req = (ThumbnailRequest*)g_queue_pop_head( loader->queue ); vfs_async_task_unlock( task ); if( G_UNLIKELY( ! req ) ) break; /* g_debug("pop: %s", req->file->name); */ /* Only we have the reference. That means, no body is using the file */ if( req->file->n_ref == 1 ) { thumbnail_request_free( req ); continue; } need_update = FALSE; for ( i = 0; i < 2; ++i ) { if ( 0 == req->n_requests[ i ] ) continue; load_big = ( i == LOAD_BIG_THUMBNAIL ); if ( ! vfs_file_info_is_thumbnail_loaded( req->file, load_big ) ) { char* full_path; full_path = g_build_filename( loader->dir->path, vfs_file_info_get_name( req->file ), NULL ); vfs_file_info_load_thumbnail( req->file, full_path, load_big ); g_free( full_path ); /* Slow down for displaying. */ g_usleep(G_USEC_PER_SEC/1000); /* g_debug( "thumbnail loaded: %s", req->file ); */ } need_update = TRUE; } if( ! vfs_async_task_is_cancelled(task) && need_update ) { vfs_async_task_lock( task ); g_queue_push_tail( loader->update_queue, vfs_file_info_ref(req->file) ); if( 0 == loader->idle_handler) loader->idle_handler = g_idle_add_full( G_PRIORITY_LOW, (GSourceFunc) on_thumbnail_idle, loader, NULL ); vfs_async_task_unlock( task ); } /* g_debug( "NEED_UPDATE: %d", need_update ); */ thumbnail_request_free( req ); } if( vfs_async_task_is_cancelled(task) ) { /* g_debug( "THREAD CANCELLED!!!" ); */ vfs_async_task_lock( task ); if( loader->idle_handler) { g_source_remove( loader->idle_handler ); loader->idle_handler = 0; } vfs_async_task_unlock( task ); } else { if( 0 == loader->idle_handler) { /* g_debug( "ADD IDLE HANDLER BEFORE THREAD ENDING" ); */ loader->idle_handler = g_idle_add_full( G_PRIORITY_LOW, (GSourceFunc) on_thumbnail_idle, loader, NULL ); } } /* g_debug("THREAD ENDED!"); */ return NULL; }
void on_dlg_response ( GtkDialog *dialog, gint response_id, gpointer user_data ) { FilePropertiesDialogData * data; PtkFileTask* task; gboolean mod_change; uid_t uid = -1; gid_t gid = -1; const char* owner_name; const char* group_name; int i; GList* l; GList* file_list; char* file_path; GtkWidget* ask_recursive; VFSFileInfo* file; GtkAllocation allocation; gtk_widget_get_allocation ( GTK_WIDGET( dialog ), &allocation ); int width = allocation.width; int height = allocation.height; if ( width && height ) { char* str = g_strdup_printf( "%d", width ); xset_set( "app_dlg", "s", str ); g_free( str ); str = g_strdup_printf( "%d", height ); xset_set( "app_dlg", "z", str ); g_free( str ); } data = ( FilePropertiesDialogData* ) g_object_get_data( G_OBJECT( dialog ), "DialogData" ); if ( data ) { if ( data->update_label_timer ) g_source_remove( data->update_label_timer ); data->cancel = TRUE; if ( data->calc_size_thread ) g_thread_join( data->calc_size_thread ); if ( response_id == GTK_RESPONSE_OK ) { GtkWidget* open_with; /* Set default action for mimetype */ if( ( open_with = (GtkWidget*)g_object_get_data( G_OBJECT(dialog), "open_with" ) ) ) { GtkTreeModel* model = gtk_combo_box_get_model( GTK_COMBO_BOX(open_with) ); GtkTreeIter it; if( model && gtk_combo_box_get_active_iter( GTK_COMBO_BOX(open_with), &it ) ) { char* action; gtk_tree_model_get( model, &it, 2, &action, -1 ); if( action ) { file = ( VFSFileInfo* ) data->file_list->data; VFSMimeType* mime = vfs_file_info_get_mime_type( file ); vfs_mime_type_set_default_action( mime, action ); vfs_mime_type_unref( mime ); g_free( action ); } } } /* Check if we need chown */ owner_name = gtk_entry_get_text( data->owner ); if ( owner_name && *owner_name && (!data->owner_name || strcmp( owner_name, data->owner_name ) ) ) { uid = uid_from_name( owner_name ); if ( uid == -1 ) { ptk_show_error( GTK_WINDOW( dialog ), _("Error"), _( "Invalid User" ) ); return ; } } group_name = gtk_entry_get_text( data->group ); if ( group_name && *group_name && (!data->group_name || strcmp( group_name, data->group_name ) ) ) { gid = gid_from_name( group_name ); if ( gid == -1 ) { ptk_show_error( GTK_WINDOW( dialog ), _("Error"), _( "Invalid Group" ) ); return ; } } for ( i = 0; i < N_CHMOD_ACTIONS; ++i ) { if ( gtk_toggle_button_get_inconsistent( data->chmod_btns[ i ] ) ) { data->chmod_states[ i ] = 2; /* Don't touch this bit */ } else if ( data->chmod_states[ i ] != gtk_toggle_button_get_active( data->chmod_btns[ i ] ) ) { mod_change = TRUE; data->chmod_states[ i ] = gtk_toggle_button_get_active( data->chmod_btns[ i ] ); } else /* Don't change this bit */ { data->chmod_states[ i ] = 2; } } if ( uid != -1 || gid != -1 || mod_change ) { file_list = NULL; for ( l = data->file_list; l; l = l->next ) { file = ( VFSFileInfo* ) l->data; file_path = g_build_filename( data->dir_path, vfs_file_info_get_name( file ), NULL ); file_list = g_list_prepend( file_list, file_path ); } task = ptk_file_task_new( VFS_FILE_TASK_CHMOD_CHOWN, file_list, NULL, GTK_WINDOW(gtk_widget_get_parent( GTK_WIDGET( dialog ) )), NULL ); //MOD ptk_file_task_set_recursive( task, gtk_toggle_button_get_active( GTK_TOGGLE_BUTTON( data->recurse ) ) ); /* for ( l = data->file_list; l; l = l->next ) { file = ( VFSFileInfo* ) l->data; if ( vfs_file_info_is_dir( file ) ) { ask_recursive = gtk_message_dialog_new( GTK_WINDOW( data->dlg ), GTK_DIALOG_MODAL, GTK_MESSAGE_QUESTION, GTK_BUTTONS_YES_NO, _( "Do you want to recursively apply these changes to all files and sub-folders?" ) ); ptk_file_task_set_recursive( task, ( GTK_RESPONSE_YES == gtk_dialog_run( GTK_DIALOG( ask_recursive ) ) ) ); gtk_widget_destroy( ask_recursive ); break; } } */ if ( mod_change ) { /* If the permissions of file has been changed by the user */ ptk_file_task_set_chmod( task, data->chmod_states ); } /* For chown */ ptk_file_task_set_chown( task, uid, gid ); ptk_file_task_run( task ); /* * This file list will be freed by file operation, so we don't * need to do this. Just set the pointer to NULL. */ data->file_list = NULL; } } g_free( data->owner_name ); g_free( data->group_name ); /* *NOTE: File operation chmod/chown will free the list when it's done, *and we only need to free it when there is no file operation applyed. */ g_slice_free( FilePropertiesDialogData, data ); } gtk_widget_destroy( GTK_WIDGET( dialog ) ); }
void ptk_file_list_file_created( VFSDir* dir, VFSFileInfo* file, PtkFileList* list ) { GList* l, *ll = NULL; GtkTreeIter it; GtkTreePath* path; VFSFileInfo* file2; if( ! list->show_hidden && vfs_file_info_get_name(file)[0] == '.' ) return; gboolean is_desktop = vfs_file_info_is_desktop_entry( file ); //sfm gboolean is_desktop2; for( l = list->files; l; l = l->next ) { file2 = (VFSFileInfo*)l->data; if( G_UNLIKELY( file == file2 ) ) { /* The file is already in the list */ return; } is_desktop2 = vfs_file_info_is_desktop_entry( file2 ); if ( is_desktop || is_desktop2 ) { // at least one is a desktop file, need to compare filenames if ( file->name && file2->name ) { if ( !strcmp( file->name, file2->name ) ) return; } } else if ( ptk_file_list_compare( file2, file, list ) == 0 ) { // disp_name matches ? // ptk_file_list_compare may return 0 on differing display names // if case-insensitive - need to compare filenames if ( list->sort_natural && list->sort_case ) return; else if ( !strcmp( file->name, file2->name ) ) return; } if ( !ll && ptk_file_list_compare( file2, file, list ) > 0 ) { if ( !is_desktop && !is_desktop2 ) break; else ll = l; // store insertion location based on disp_name } } if ( ll ) l = ll; list->files = g_list_insert_before( list->files, l, vfs_file_info_ref( file ) ); ++list->n_files; if( l ) l = l->prev; else l = g_list_last( list->files ); it.stamp = list->stamp; it.user_data = l; it.user_data2 = file; path = gtk_tree_path_new_from_indices( g_list_index(list->files, l->data), -1 ); gtk_tree_model_row_inserted( GTK_TREE_MODEL(list), path, &it ); gtk_tree_path_free( path ); }