/** * fm_trash_files * @parent: a window to place progress dialog over it * @files: list of files to move to trash * * Removes files into trash can opening progress dialog if that operation * takes some time. * * Before 0.1.15 this call had different arguments. * * Since: 0.1.0 */ void fm_trash_files(GtkWindow* parent, FmPathList* files) { FmFileOpsJob *job; char *msg, *name; int len; if (fm_config->confirm_trash) { len = fm_path_list_get_length(files); if (len == 1) { name = fm_path_display_basename(fm_path_list_peek_head(files)); msg = g_strdup_printf(_("Do you want to move the file '%s' to trash can?"), name); g_free(name); } else msg = g_strdup_printf(dngettext(GETTEXT_PACKAGE, "Do you want to move the %d selected file to trash can?", "Do you want to move the %d selected files to trash can?", (gulong)len), len); if (!fm_yes_no(parent, NULL, msg, TRUE)) { g_free(msg); return; } g_free(msg); } job = fm_file_ops_job_new(FM_FILE_OP_TRASH, files); fm_file_ops_job_run_with_progress(parent, job); /* it eats reference! */ }
/** * fm_rename_file * @parent: a window to place dialog over it * @file: the file * * Opens a dialog to choose new name for @file. If it was not cancelled * by user then renames @file. * * Before 0.1.15 this call had different arguments. * * Since: 0.1.0 */ void fm_rename_file(GtkWindow* parent, FmPath* file) { gchar *old_name, *new_name; FmPathList *files; FmFileOpsJob *job; /* NOTE: it's better to use fm_file_info_get_edit_name() to get a name but we cannot get it from FmPath */ old_name = fm_path_display_basename(file); new_name = fm_get_user_input_rename(parent, _("Rename File"), _("Please enter a new name:"), old_name); /* if file name wasn't changed then do nothing */ if (new_name == NULL || strcmp(old_name, new_name) == 0) { g_free(old_name); g_free(new_name); return; } g_free(old_name); files = fm_path_list_new(); fm_path_list_push_tail(files, file); job = fm_file_ops_job_new(FM_FILE_OP_CHANGE_ATTR, files); fm_file_ops_job_set_display_name(job, new_name); g_free(new_name); fm_path_list_unref(files); fm_file_ops_job_run_with_progress(parent, job); /* it eats reference! */ }
static void _fm_set_file_hidden(GtkWindow *parent, FmPath *file, gboolean hidden) { FmPathList *files; FmFileOpsJob *job; files = fm_path_list_new(); fm_path_list_push_tail(files, file); job = fm_file_ops_job_new(FM_FILE_OP_CHANGE_ATTR, files); fm_file_ops_job_set_hidden(job, hidden); fm_path_list_unref(files); fm_file_ops_job_run_with_progress(parent, job); /* it eats reference! */ }
static void on_finished (FmFileOpsJob *job, FmProgressDisplay *data) { GtkWidget *parent; if (data->update_timeout) { g_source_remove (data->update_timeout); data->update_timeout = 0; } parent = data->parent; if (data->dlg) { // errors happened if (data->has_error && data->dlg) { gtk_label_set_text (GTK_LABEL (data->current), ""); gtk_label_set_text (GTK_LABEL (data->remaining_time), "00:00:00"); gtk_dialog_set_response_sensitive (GTK_DIALOG (data->dlg), GTK_RESPONSE_CANCEL, FALSE); gtk_dialog_add_button (GTK_DIALOG (data->dlg), GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE); gtk_image_set_from_stock (GTK_IMAGE (data->icon), GTK_STOCK_DIALOG_WARNING, GTK_ICON_SIZE_DIALOG); gtk_widget_show (data->msg); if (fm_job_is_cancelled (FM_JOB (data->job))) { gtk_label_set_text (GTK_LABEL (data->msg), _("The file operation is cancelled and there are some errors.")); gtk_window_set_title (GTK_WINDOW (data->dlg), _("Cancelled")); } else { gtk_label_set_text (GTK_LABEL (data->msg), _("The file operation is finished, but there are some errors.")); gtk_window_set_title (GTK_WINDOW (data->dlg), _("Finished")); } } else fm_progress_display_destroy (data); g_debug ("file operation is finished!"); } else fm_progress_display_destroy (data); /* sepcial handling for trash * FIXME_pcm: need to refactor this to use a more elegant way later. */ if (job->type == FM_FILE_OP_TRASH) { FmPathList *unsupported = (FmPathList*)g_object_get_data (G_OBJECT (job), "trash-unsupported"); // some files cannot be trashed because underlying filesystems don't support it. // delete them instead if (unsupported) { if (fm_yes_no (GTK_WINDOW (parent), NULL, _("Some files cannot be moved to trash can because " "the underlying file systems don't support this operation.\n" "Do you want to delete them instead?"), TRUE)) { FmJob *job = fm_file_ops_job_new (FM_FILE_OP_DELETE, unsupported); fm_file_ops_job_run_with_progress (GTK_WINDOW (data->parent), (FmFileOpsJob*) job); } } } }
static void on_finished(FmFileOpsJob* job, FmProgressDisplay* data) { GtkWindow* parent = NULL; /* preserve pointers that fm_progress_display_destroy() will unreference as they may be requested by trash support below */ if(data->parent) parent = g_object_ref(data->parent); g_object_ref(job); if(data->dlg) { /* errors happened */ if(data->has_error) { gtk_label_set_text(data->current, ""); gtk_label_set_text(data->remaining_time, "00:00:00"); gtk_dialog_set_response_sensitive(data->dlg, GTK_RESPONSE_CANCEL, FALSE); gtk_dialog_add_button(data->dlg, GTK_STOCK_CLOSE, GTK_RESPONSE_CLOSE); gtk_image_set_from_stock(data->icon, GTK_STOCK_DIALOG_WARNING, GTK_ICON_SIZE_DIALOG); gtk_widget_show(GTK_WIDGET(data->msg)); if(fm_job_is_cancelled(FM_JOB(job))) { gtk_label_set_text(data->msg, _("The file operation is cancelled and there are some errors.")); gtk_window_set_title(GTK_WINDOW(data->dlg), _("Cancelled")); } else { gtk_label_set_text(data->msg, _("The file operation is finished, but there are some errors.")); gtk_window_set_title(GTK_WINDOW(data->dlg), _("Finished")); } } else fm_progress_display_destroy(data); g_debug("file operation is finished!"); } else fm_progress_display_destroy(data); /* if it's not destroyed yet then it will be destroyed with dialog window */ /* sepcial handling for trash * FIXME: need to refactor this to use a more elegant way later. */ if(job->type == FM_FILE_OP_TRASH) /* FIXME: direct access to job struct! */ { FmPathList* unsupported = (FmPathList*)g_object_get_data(G_OBJECT(job), "trash-unsupported"); /* some files cannot be trashed because underlying filesystems don't support it. */ g_object_unref(job); if(unsupported) /* delete them instead */ { /* FIXME: parent window might be already destroyed! */ if(fm_yes_no(parent, NULL, _("Some files cannot be moved to trash can because " "the underlying file systems don't support this operation.\n" "Do you want to delete them instead?"), TRUE)) { job = fm_file_ops_job_new(FM_FILE_OP_DELETE, unsupported); fm_file_ops_job_run_with_progress(parent, job); /* it eats reference! */ } } } else g_object_unref(job); if(parent) g_object_unref(parent); }
static void on_response (GtkDialog *dlg, int response, FmFilePropData *data) { if ( response == GTK_RESPONSE_OK ) { int sel; const char *new_owner = gtk_entry_get_text (GTK_ENTRY (data->owner)); const char *new_group = gtk_entry_get_text (GTK_ENTRY (data->group)); guint32 uid = -1, gid = -1; mode_t new_mode = 0, new_mode_mask = 0; if (!ensure_valid_owner (data) || !ensure_valid_group (data)) { g_signal_stop_emission_by_name (dlg, "response"); return; } /* FIXME_pcm: if all files are native, it's possible to check * if the names are legal user and group names on the local * machine prior to chown. */ if (new_owner && *new_owner && g_strcmp0 (data->orig_owner, new_owner)) { // change owner g_debug ("change owner to: %d", data->uid); } else data->uid = -1; if (new_group && *new_group && g_strcmp0 (data->orig_group, new_group)) { // change group g_debug ("change group to: %d", data->gid); } else data->gid = -1; // check if chmod is needed here. sel = gtk_combo_box_get_active (GTK_COMBO_BOX (data->owner_perm)); if ( sel != NO_CHANGE ) // need to change owner permission { if (data->owner_perm_sel != sel) // new value is different from original { new_mode_mask |= S_IRUSR|S_IWUSR; data->owner_perm_sel = sel; switch (sel) { case READ_WRITE: new_mode |= S_IRUSR|S_IWUSR; break; case READ_ONLY: new_mode |= S_IRUSR; break; case WRITE_ONLY: new_mode |= S_IWUSR; break; } } else // otherwise, no change data->owner_perm_sel = NO_CHANGE; } else data->owner_perm_sel = NO_CHANGE; sel = gtk_combo_box_get_active (GTK_COMBO_BOX (data->group_perm)); if ( sel != NO_CHANGE ) // need to change group permission { if (data->group_perm_sel != sel) // new value is different from original { new_mode_mask |= S_IRGRP|S_IWGRP; data->group_perm_sel = sel; switch (sel) { case READ_WRITE: new_mode |= S_IRGRP|S_IWGRP; break; case READ_ONLY: new_mode |= S_IRGRP; break; case WRITE_ONLY: new_mode |= S_IWGRP; break; } } else // otherwise, no change data->group_perm_sel = NO_CHANGE; } else data->group_perm_sel = NO_CHANGE; #if 0 sel = gtk_combo_box_get_active (GTK_COMBO_BOX (data->other_perm)); if ( sel != NO_CHANGE ) // need to change other permission { if (data->other_perm_sel != sel) // new value is different from original { new_mode_mask |= S_IROTH|S_IWOTH; switch (sel) { case READ_WRITE: new_mode |= S_IROTH|S_IWOTH; break; case READ_ONLY: new_mode |= S_IROTH; break; case WRITE_ONLY: new_mode |= S_IWOTH; break; } data->other_perm_sel = sel; } else // otherwise, no change data->other_perm_sel = NO_CHANGE; } else data->other_perm_sel = NO_CHANGE; if (!data->has_dir && !gtk_toggle_button_get_inconsistent (GTK_TOGGLE_BUTTON (data->exec)) && gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (data->exec)) != data->exec_state) { new_mode_mask |= (S_IXUSR|S_IXGRP|S_IXOTH); if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (data->exec))) new_mode |= (S_IXUSR|S_IXGRP|S_IXOTH); } if (new_mode_mask || data->uid != -1 || data->gid != -1) { FmPathList *paths = fm_path_list_new_from_file_info_list (data->files); FmFileOpsJob *job = (FmFileOpsJob*) fm_file_ops_job_new (FM_FILE_OP_CHANGE_ATTR, paths); // need to chown if (data->uid != -1 || data->gid != -1) fm_file_ops_job_set_chown (job, data->uid, data->gid); // need to do chmod if (new_mode_mask) fm_file_ops_job_set_chmod (job, new_mode, new_mode_mask); if (data->has_dir) { if (fm_yes_no (GTK_WINDOW (data->dlg), NULL, _( "Do you want to recursively apply these changes to all files and sub-folders?" ), TRUE)) fm_file_ops_job_set_recursive (job, TRUE); } // show progress dialog fm_file_ops_job_run_with_progress (GTK_WINDOW (data->dlg), job); fm_list_unref (paths); } // change default application for the mime-type if needed if (data->mime_type && fm_mime_type_get_type (data->mime_type) && data->open_with) { GAppInfo *app; gboolean default_app_changed = FALSE; GError *err = NULL; app = fm_app_chooser_combo_box_get_selected (GTK_COMBO_BOX (data->open_with), &default_app_changed); if (app) { if (default_app_changed) { g_app_info_set_as_default_for_type (app, fm_mime_type_get_type (data->mime_type), &err); if (err) { fm_show_error (GTK_WINDOW (dlg), NULL, err->message); g_error_free (err); } } g_object_unref (app); } } if (data->single_file) // when only one file is shown { // if the user has changed its name if ( g_strcmp0 (data->file_info->disp_name, gtk_entry_get_text (GTK_ENTRY (data->name))) ) { // FIXME_pcm: rename the file or set display name for it. } } #endif } gtk_widget_destroy (GTK_WIDGET (dlg)); }
static void fm_delete_files_internal(GtkWindow* parent, FmPathList* files) { FmFileOpsJob* job = fm_file_ops_job_new(FM_FILE_OP_DELETE, files); fm_file_ops_job_run_with_progress(parent, job); /* it eats reference! */ }
/** * fm_untrash_files * @parent: a window to place progress dialog over it * @files: list of files to restore * * Restores files from trash can into original place opening progress * dialog if that operation takes some time. * * Before 0.1.15 this call had different arguments. * * Since: 0.1.11 */ void fm_untrash_files(GtkWindow* parent, FmPathList* files) { FmFileOpsJob* job = fm_file_ops_job_new(FM_FILE_OP_UNTRASH, files); fm_file_ops_job_run_with_progress(parent, job); /* it eats reference! */ }
/** * fm_link_files * @parent: window to base progress dialog over it * @files: list of files to make symbolic links to * @dest_dir: directory where symbolic links should be created * * Create symbolic links for some files in the target directory with * progress dialog. * * Since: 1.0.0 */ void fm_link_files(GtkWindow* parent, FmPathList* files, FmPath* dest_dir) { FmFileOpsJob* job = fm_file_ops_job_new(FM_FILE_OP_LINK, files); fm_file_ops_job_set_dest(job, dest_dir); fm_file_ops_job_run_with_progress(parent, job); /* it eats reference! */ }