/** * fm_choose_app_for_mime_type * @parent: (allow-none): a parent window * @mime_type: (allow-none): MIME type for list creation * @can_set_default: %TRUE if widget can set selected item as default for @mime_type * * Creates a dialog to choose application for @mime_type, lets user to * choose then returns the chosen application. * * If user creates custom application and @mime_type isn't %NULL then this * custom application will be added to list of supporting the @mime_type. * Otherwise that custom application file will be deleted after usage. * * Returns: user choise. * * Since: 0.1.0 */ GAppInfo* fm_choose_app_for_mime_type(GtkWindow* parent, FmMimeType* mime_type, gboolean can_set_default) { GAppInfo* app = NULL; GtkDialog* dlg = fm_app_chooser_dlg_new(mime_type, can_set_default); if(parent) gtk_window_set_transient_for(GTK_WINDOW(dlg), parent); if(gtk_dialog_run(dlg) == GTK_RESPONSE_OK) { gboolean set_default; app = fm_app_chooser_dlg_dup_selected_app(dlg, &set_default); if(app && mime_type && fm_mime_type_get_type(mime_type) && g_app_info_get_name(app)[0]) /* don't add empty name */ { GError* err = NULL; /* add this app to the mime-type */ #if GLIB_CHECK_VERSION(2, 27, 6) if(!g_app_info_set_as_last_used_for_type(app, #else if(!g_app_info_add_supports_type(app, #endif fm_mime_type_get_type(mime_type), &err)) { g_debug("error: %s", err->message); g_error_free(err); } /* if need to set default */ if(set_default) g_app_info_set_as_default_for_type(app, fm_mime_type_get_type(mime_type), NULL); }
static void init_application_list (FmFilePropData *data) { if (data->single_type && data->mime_type) { if (g_strcmp0 (fm_mime_type_get_type (data->mime_type), "inode/directory")) fm_app_chooser_combo_box_setup_for_mime_type ((GtkComboBox*) data->open_with, data->mime_type); else // shouldn't allow set file association for folders. { gtk_widget_destroy (data->open_with_label); gtk_widget_destroy (data->open_with); data->open_with = data->open_with_label = NULL; } } }
/** * fm_app_chooser_dlg_dup_selected_app * @dlg: a widget * @set_default: location to get value that was used for fm_app_chooser_dlg_new() * * Retrieves a currently selected application from @dlg. * * Before 1.0.0 this call had name fm_app_chooser_dlg_get_selected_app. * * Returns: (transfer full): selected application. * * Since: 0.1.0 */ GAppInfo* fm_app_chooser_dlg_dup_selected_app(GtkDialog* dlg, gboolean* set_default) { GAppInfo* app = NULL; AppChooserData* data = (AppChooserData*)g_object_get_qdata(G_OBJECT(dlg), fm_qdata_id); switch( gtk_notebook_get_current_page(data->notebook) ) { case 0: /* all applications */ app = fm_app_menu_view_dup_selected_app(data->apps_view); break; case 1: /* custom cmd line */ { const char* cmdline = gtk_entry_get_text(data->cmdline); const char* app_name = gtk_entry_get_text(data->app_name); if(cmdline && cmdline[0]) { char* _cmdline = NULL; gboolean arg_found = FALSE; char* bin1 = get_binary(cmdline, &arg_found); g_debug("bin1 = %s", bin1); /* see if command line contains %f, %F, %u, or %U. */ if(!arg_found) /* append %f if no %f, %F, %u, or %U was found. */ cmdline = _cmdline = g_strconcat(cmdline, " %f", NULL); /* FIXME: is there any better way to do this? */ /* We need to ensure that no duplicated items are added */ if(data->mime_type) { MenuCache* menu_cache; /* see if the command is already in the list of known apps for this mime-type */ GList* apps = g_app_info_get_all_for_type(fm_mime_type_get_type(data->mime_type)); GList* l; for(l=apps;l;l=l->next) { GAppInfo* app2 = G_APP_INFO(l->data); const char* cmd = g_app_info_get_commandline(app2); char* bin2 = get_binary(cmd, NULL); if(g_strcmp0(bin1, bin2) == 0) { app = G_APP_INFO(g_object_ref(app2)); g_debug("found in app list"); g_free(bin2); break; } g_free(bin2); } g_list_foreach(apps, (GFunc)g_object_unref, NULL); g_list_free(apps); if(app) goto _out; /* see if this command can be found in menu cache */ menu_cache = menu_cache_lookup("applications.menu"); if(menu_cache) { #if MENU_CACHE_CHECK_VERSION(0, 4, 0) MenuCacheDir *root_dir = menu_cache_dup_root_dir(menu_cache); if(root_dir) #else if(menu_cache_get_root_dir(menu_cache)) #endif { GSList* all_apps = menu_cache_list_all_apps(menu_cache); GSList* l; for(l=all_apps;l;l=l->next) { MenuCacheApp* ma = MENU_CACHE_APP(l->data); const char *exec = menu_cache_app_get_exec(ma); char* bin2; if (exec == NULL) { g_warning("application %s has no Exec statement", menu_cache_item_get_id(MENU_CACHE_ITEM(ma))); continue; } bin2 = get_binary(exec, NULL); if(g_strcmp0(bin1, bin2) == 0) { app = G_APP_INFO(g_desktop_app_info_new(menu_cache_item_get_id(MENU_CACHE_ITEM(ma)))); g_debug("found in menu cache"); menu_cache_item_unref(MENU_CACHE_ITEM(ma)); g_free(bin2); break; } menu_cache_item_unref(MENU_CACHE_ITEM(ma)); g_free(bin2); } g_slist_free(all_apps); #if MENU_CACHE_CHECK_VERSION(0, 4, 0) menu_cache_item_unref(MENU_CACHE_ITEM(root_dir)); #endif } menu_cache_unref(menu_cache); } if(app) goto _out; } /* FIXME: g_app_info_create_from_commandline force the use of %f or %u, so this is not we need */ app = app_info_create_from_commandline(cmdline, app_name ? app_name : "", bin1, data->mime_type ? fm_mime_type_get_type(data->mime_type) : NULL, gtk_toggle_button_get_active(data->use_terminal), data->keep_open && gtk_toggle_button_get_active(data->keep_open)); _out: g_free(bin1); g_free(_cmdline); } } break; } if(set_default) *set_default = gtk_toggle_button_get_active(data->set_default); return app; }
void FilePropsDialog::accept() { // applications if(mimeType && ui->openWith->isChanged()) { GAppInfo* currentApp = ui->openWith->selectedApp(); g_app_info_set_as_default_for_type(currentApp, fm_mime_type_get_type(mimeType), NULL); } // check if chown or chmod is needed guint32 newUid = uidFromName(ui->owner->text()); guint32 newGid = gidFromName(ui->ownerGroup->text()); bool needChown = (newUid != -1 && newUid != uid) || (newGid != -1 && newGid != gid); int newOwnerPermSel = ui->ownerPerm->currentIndex(); int newGroupPermSel = ui->groupPerm->currentIndex(); int newOtherPermSel = ui->otherPerm->currentIndex(); Qt::CheckState newExecCheckState = ui->executable->checkState(); bool needChmod = ((newOwnerPermSel != ownerPermSel) || (newGroupPermSel != groupPermSel) || (newOtherPermSel != otherPermSel) || (newExecCheckState != execCheckState)); if(needChmod || needChown) { FmPathList* paths = fm_path_list_new_from_file_info_list(fileInfos_); FileOperation* op = new FileOperation(FileOperation::ChangeAttr, paths); fm_path_list_unref(paths); if(needChown) { // don't do chown if new uid/gid and the original ones are actually the same. if(newUid == uid) newUid = -1; if(newGid == gid) newGid = -1; op->setChown(newUid, newGid); } if(needChmod) { mode_t newMode = 0; mode_t newModeMask = 0; // FIXME: we need to make sure that folders with "r" permission also have "x" // at the same time. Otherwise, it's not able to browse the folder later. if(newOwnerPermSel != ownerPermSel && newOwnerPermSel != ACCESS_NO_CHANGE) { // owner permission changed newModeMask |= (S_IRUSR|S_IWUSR); // affect user bits if(newOwnerPermSel == ACCESS_READ_ONLY) newMode |= S_IRUSR; else if(newOwnerPermSel == ACCESS_READ_WRITE) newMode |= (S_IRUSR|S_IWUSR); } if(newGroupPermSel != groupPermSel && newGroupPermSel != ACCESS_NO_CHANGE) { qDebug("newGroupPermSel: %d", newGroupPermSel); // group permission changed newModeMask |= (S_IRGRP|S_IWGRP); // affect group bits if(newGroupPermSel == ACCESS_READ_ONLY) newMode |= S_IRGRP; else if(newGroupPermSel == ACCESS_READ_WRITE) newMode |= (S_IRGRP|S_IWGRP); } if(newOtherPermSel != otherPermSel && newOtherPermSel != ACCESS_NO_CHANGE) { // other permission changed newModeMask |= (S_IROTH|S_IWOTH); // affect other bits if(newOtherPermSel == ACCESS_READ_ONLY) newMode |= S_IROTH; else if(newOtherPermSel == ACCESS_READ_WRITE) newMode |= (S_IROTH|S_IWOTH); } if(newExecCheckState != execCheckState && newExecCheckState != Qt::PartiallyChecked) { // executable state changed newModeMask |= (S_IXUSR|S_IXGRP|S_IXOTH); if(newExecCheckState == Qt::Checked) newMode |= (S_IXUSR|S_IXGRP|S_IXOTH); } op->setChmod(newMode, newModeMask); if(hasDir) { // if there are some dirs in our selected files QMessageBox::StandardButton r = QMessageBox::question(this, tr("Apply changes"), tr("Do you want to recursively apply these changes to all files and sub-folders?"), QMessageBox::Yes|QMessageBox::No); if(r == QMessageBox::Yes) op->setRecursiveChattr(true); } } op->setAutoDestroy(true); op->run(); } QDialog::accept(); }
void FilePropsDialog::initGeneralPage() { // update UI if(singleType) { // all files are of the same mime-type FmIcon* icon = NULL; // FIXME: handle custom icons for some files // FIXME: display special property pages for special files or // some specified mime-types. if(singleFile) { // only one file is selected. icon = fm_file_info_get_icon(fileInfo); } if(mimeType) { if(!icon) // get an icon from mime type if needed icon = fm_mime_type_get_icon(mimeType); ui->fileType->setText(QString::fromUtf8(fm_mime_type_get_desc(mimeType))); ui->mimeType->setText(QString::fromUtf8(fm_mime_type_get_type(mimeType))); } if(icon) { ui->iconButton->setIcon(IconTheme::icon(icon)); } if(singleFile && fm_file_info_is_symlink(fileInfo)) { ui->target->setText(QString::fromUtf8(fm_file_info_get_target(fileInfo))); } else { ui->target->hide(); ui->targetLabel->hide(); } } // end if(singleType) else { // not singleType, multiple files are selected at the same time ui->fileType->setText(tr("Files of different types")); ui->target->hide(); ui->targetLabel->hide(); } // FIXME: check if all files has the same parent dir, mtime, or atime if(singleFile) { // only one file is selected FmPath* parent_path = fm_path_get_parent(fm_file_info_get_path(fileInfo)); char* parent_str = parent_path ? fm_path_display_name(parent_path, true) : NULL; ui->fileName->setText(QString::fromUtf8(fm_file_info_get_disp_name(fileInfo))); if(parent_str) { ui->location->setText(QString::fromUtf8(parent_str)); g_free(parent_str); } else ui->location->clear(); ui->lastModified->setText(QString::fromUtf8(fm_file_info_get_disp_mtime(fileInfo))); // FIXME: need to encapsulate this in an libfm API. time_t atime; struct tm tm; atime = fm_file_info_get_atime(fileInfo); localtime_r(&atime, &tm); char buf[128]; strftime(buf, sizeof(buf), "%x %R", &tm); ui->lastAccessed->setText(QString::fromUtf8(buf)); } else { ui->fileName->setText(tr("Multiple Files")); ui->fileName->setEnabled(false); } initApplications(); // init applications combo box // calculate total file sizes fileSizeTimer = new QTimer(this); connect(fileSizeTimer, &QTimer::timeout, this, &FilePropsDialog::onFileSizeTimerTimeout); fileSizeTimer->start(600); g_signal_connect(deepCountJob, "finished", G_CALLBACK(onDeepCountJobFinished), this); gboolean ret = fm_job_run_async(FM_JOB(deepCountJob)); }
/** * fm_app_chooser_combo_box_setup * @combo: a #GtkComboBox * @mime_type: (allow-none): a #FmMimeType to select application * @apps: (allow-none) (element-type GAppInfo): custom list of applications * @sel: (allow-none): a selected application in @apps * * Setups a combobox for selecting default application either for * specified mime-type or from a list of pre-defined applications. * If @mime_type is %NULL, and @sel is provided and found in the @apps, * then it will be selected. If @mime_type is not %NULL then default * application for the @mime_type will be selected. * When set up, the combobox will contain a list of available applications. * * Since: 0.1.5 */ void fm_app_chooser_combo_box_setup(GtkComboBox* combo, FmMimeType* mime_type, GList* apps, GAppInfo* sel) { FmAppChooserComboBoxData* data = g_slice_new0(FmAppChooserComboBoxData); GtkListStore* store = gtk_list_store_new(3, G_TYPE_ICON, G_TYPE_STRING, G_TYPE_APP_INFO); GtkTreeIter it; GList* l; GtkCellRenderer* render; gtk_cell_layout_clear(GTK_CELL_LAYOUT(combo)); render = gtk_cell_renderer_pixbuf_new(); gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(combo), render, FALSE); gtk_cell_layout_add_attribute(GTK_CELL_LAYOUT(combo), render, "gicon", 0); render = gtk_cell_renderer_text_new(); gtk_cell_layout_pack_start(GTK_CELL_LAYOUT(combo), render, FALSE); gtk_cell_layout_add_attribute(GTK_CELL_LAYOUT(combo), render, "text", 1); if(mime_type) { data->mime_type = fm_mime_type_ref(mime_type); apps = g_app_info_get_all_for_type(fm_mime_type_get_type(data->mime_type)); sel = g_app_info_get_default_for_type(fm_mime_type_get_type(data->mime_type), FALSE); } for(l = apps; l; l = l->next) { GAppInfo* app = G_APP_INFO(l->data); gtk_list_store_insert_with_values(store, &it, -1, 0, g_app_info_get_icon(app), 1, g_app_info_get_name(app), 2, app, -1); if(sel && g_app_info_equal(app, sel)) { /* this is the initially selected app */ data->initial_sel_iter = it; data->initial_sel_app = (GAppInfo*)g_object_ref(app); } } if(mime_type) /* if this list is retrived with g_app_info_get_all_for_type() */ { if(apps) { g_list_foreach(apps, (GFunc)g_object_unref, NULL); g_list_free(apps); } if(sel) g_object_unref(sel); } gtk_list_store_append(store, &it); /* separator */ data->separator_iter = it; /* other applications */ gtk_list_store_insert_with_values(store, &it, -1, 0, NULL, 1, _("Customize"), // FIXME: should be "Customize..." 2, NULL, -1); data->other_apps_iter = it; gtk_combo_box_set_model(combo, GTK_TREE_MODEL(store)); if(data->initial_sel_iter.user_data) /* intital selection is set */ { data->prev_sel_iter = data->initial_sel_iter; gtk_combo_box_set_active_iter(combo, &data->initial_sel_iter); } gtk_combo_box_set_row_separator_func(combo, is_row_separator, data, NULL); g_object_unref(store); g_signal_connect(combo, "changed", G_CALLBACK(on_app_selected), data); g_object_set_qdata_full(G_OBJECT(combo), fm_qdata_id, data, free_data); }
/** * fm_launch_files * @ctx: (allow-none): a launch context * @file_infos: (element-type FmFileInfo): files to launch * @launcher: #FmFileLauncher with callbacks * @user_data: data supplied for callbacks * * Launches files using callbacks in @launcher. * * Returns: %TRUE in case of success. * * Since: 0.1.0 */ gboolean fm_launch_files(GAppLaunchContext* ctx, GList* file_infos, FmFileLauncher* launcher, gpointer user_data) { GList* l; GHashTable* hash = g_hash_table_new_full(g_str_hash, g_str_equal, NULL, NULL); GList *folders = NULL; FmFileInfo* fi; GList *targets = NULL; GError* err = NULL; GAppInfo* app; const char* type; for(l = file_infos; l; l=l->next) { GList* fis; char *filename, *scheme; const char *target = NULL; fi = (FmFileInfo*)l->data; /* special handling for shortcuts */ if (!fm_file_info_is_symlink(fi)) /* symlinks also has fi->target, but we only handle shortcuts here. */ target = fm_file_info_get_target(fi); if (launcher->open_folder && fm_file_info_is_dir(fi)) { /* special handling for shortcuts */ if(target) { fi = _fetch_file_info_for_shortcut(fm_file_info_get_target(fi), ctx, launcher, user_data); if (fi == NULL) /* error was shown by job already */ continue; targets = g_list_prepend(targets, fi); } folders = g_list_prepend(folders, fi); } else if (fm_file_info_is_desktop_entry(fi)) { _launch_desktop_entry: if (!target) filename = fm_path_to_str(fm_file_info_get_path(fi)); fm_launch_desktop_entry(ctx, target ? target : filename, NULL, launcher, user_data); if (!target) g_free(filename); continue; } else { FmPath* path = fm_file_info_get_path(fi); FmMimeType* mime_type = NULL; if(fm_path_is_native(path)) { /* special handling for shortcuts */ if (target) { if (fm_file_info_get_mime_type(fi) == _fm_mime_type_get_inode_x_shortcut()) /* if we already know MIME type then use it instead */ { scheme = g_uri_parse_scheme(target); if (scheme) { /* FIXME: this is rough! */ if (strcmp(scheme, "file") != 0 && strcmp(scheme, "trash") != 0 && strcmp(scheme, "network") != 0 && strcmp(scheme, "computer") != 0 && strcmp(scheme, "menu") != 0) { /* we don't support this URI internally, try GIO */ app = g_app_info_get_default_for_uri_scheme(scheme); if (app) { fis = g_list_prepend(NULL, (char *)target); fm_app_info_launch_uris(app, fis, ctx, &err); g_list_free(fis); g_object_unref(app); } else if (launcher->error) g_set_error(&err, G_IO_ERROR, G_IO_ERROR_FAILED, _("No default application is set to launch URIs %s://"), scheme); if (err) { launcher->error(ctx, err, NULL, user_data); g_clear_error(&err); } g_free(scheme); continue; } g_free(scheme); } } else mime_type = fm_file_info_get_mime_type(fi); /* retrieve file info for target otherwise and handle it */ fi = _fetch_file_info_for_shortcut(target, ctx, launcher, user_data); if (fi == NULL) /* error was shown by job already */ continue; targets = g_list_prepend(targets, fi); path = fm_file_info_get_path(fi); /* special handling for desktop entries */ if (fm_file_info_is_desktop_entry(fi)) goto _launch_desktop_entry; } if(fm_file_info_is_executable_type(fi)) { /* if it's an executable file, directly execute it. */ filename = fm_path_to_str(path); /* FIXME: we need to use eaccess/euidaccess here. */ if(g_file_test(filename, G_FILE_TEST_IS_EXECUTABLE)) { if(launcher->exec_file) { FmFileLauncherExecAction act = launcher->exec_file(fi, user_data); GAppInfoCreateFlags flags = 0; switch(act) { case FM_FILE_LAUNCHER_EXEC_IN_TERMINAL: flags |= G_APP_INFO_CREATE_NEEDS_TERMINAL; /* NOTE: no break here */ case FM_FILE_LAUNCHER_EXEC: { /* filename may contain spaces. Fix #3143296 */ char* quoted = g_shell_quote(filename); app = fm_app_info_create_from_commandline(quoted, NULL, flags, NULL); g_free(quoted); if(app) { char* run_path = g_path_get_dirname(filename); char* cwd = NULL; /* bug #3589641: scripts are ran from $HOME. since GIO launcher is kinda ugly - it has no means to set running directory so we do workaround - change directory to it */ if(run_path && strcmp(run_path, ".")) { cwd = g_get_current_dir(); if(chdir(run_path) != 0) { g_free(cwd); cwd = NULL; if (launcher->error) { g_set_error(&err, G_IO_ERROR, g_io_error_from_errno(errno), _("Cannot set working directory to '%s': %s"), run_path, g_strerror(errno)); launcher->error(ctx, err, NULL, user_data); g_clear_error(&err); } } } g_free(run_path); if(!fm_app_info_launch(app, NULL, ctx, &err)) { if(launcher->error) launcher->error(ctx, err, NULL, user_data); g_error_free(err); err = NULL; } if(cwd) /* return back */ { if(chdir(cwd) != 0) g_warning("fm_launch_files(): chdir() failed"); g_free(cwd); } g_object_unref(app); continue; } break; } case FM_FILE_LAUNCHER_EXEC_OPEN: break; case FM_FILE_LAUNCHER_EXEC_CANCEL: continue; } } } g_free(filename); } } if (mime_type == NULL) mime_type = fm_file_info_get_mime_type(fi); if(mime_type && (type = fm_mime_type_get_type(mime_type))) { fis = g_hash_table_lookup(hash, type); fis = g_list_prepend(fis, fi); g_hash_table_insert(hash, (gpointer)type, fis); } else if (launcher->error) { g_set_error(&err, G_IO_ERROR, G_IO_ERROR_FAILED, _("Could not determine content type of file '%s' to launch it"), fm_file_info_get_disp_name(fi)); launcher->error(ctx, err, NULL, user_data); g_clear_error(&err); } } } if(g_hash_table_size(hash) > 0) { GHashTableIter it; GList* fis; g_hash_table_iter_init(&it, hash); while(g_hash_table_iter_next(&it, (void**)&type, (void**)&fis)) { GAppInfo* app = g_app_info_get_default_for_type(type, FALSE); if(!app) { if(launcher->get_app) { FmMimeType* mime_type = fm_file_info_get_mime_type((FmFileInfo*)fis->data); app = launcher->get_app(fis, mime_type, user_data, NULL); } } if(app) { for(l=fis; l; l=l->next) { char* uri; fi = (FmFileInfo*)l->data; /* special handling for shortcuts */ if (fm_file_info_is_shortcut(fi)) uri = g_strdup(fm_file_info_get_target(fi)); else uri = fm_path_to_uri(fm_file_info_get_path(fi)); l->data = uri; } fis = g_list_reverse(fis); fm_app_info_launch_uris(app, fis, ctx, &err); /* free URI strings */ g_list_foreach(fis, (GFunc)g_free, NULL); g_object_unref(app); } else if (launcher->error) g_set_error(&err, G_IO_ERROR, G_IO_ERROR_FAILED, _("No default application is set for MIME type %s"), type); if (err) { launcher->error(ctx, err, NULL, user_data); g_clear_error(&err); } g_list_free(fis); } } g_hash_table_destroy(hash); if(folders) { folders = g_list_reverse(folders); if(launcher->open_folder) { launcher->open_folder(ctx, folders, user_data, &err); if(err) { if(launcher->error) launcher->error(ctx, err, NULL, user_data); g_error_free(err); err = NULL; } } g_list_free(folders); } g_list_free_full(targets, (GDestroyNotify)fm_file_info_unref); return TRUE; }
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)); }