void View::onNewTab() { Fm::FileMenu* menu = static_cast<Fm::FileMenu*>(sender()->parent()); for(GList* l = fm_file_info_list_peek_head_link(menu->files()); l; l = l->next) { FmFileInfo* file = FM_FILE_INFO(l->data); Q_EMIT openDirRequested(fm_file_info_get_path(file), OpenInNewTab); } }
/** * fm_launch_paths * @ctx: (allow-none): a launch context * @paths: (element-type FmPath): 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_paths(GAppLaunchContext* ctx, GList* paths, FmFileLauncher* launcher, gpointer user_data) { FmFileInfoJob* job = fm_file_info_job_new(NULL, 0); GList* l; QueryErrorData data; gboolean ret; for(l=paths;l;l=l->next) fm_file_info_job_add(job, (FmPath*)l->data); data.ctx = ctx; data.launcher = launcher; data.user_data = user_data; g_signal_connect(job, "error", G_CALLBACK(on_query_target_info_error), &data); ret = fm_job_run_sync_with_mainloop(FM_JOB(job)); g_signal_handlers_disconnect_by_func(job, on_query_target_info_error, &data); if(ret) { GList* file_infos = fm_file_info_list_peek_head_link(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; }
void View::onOpenInTerminal() { Application* app = static_cast<Application*>(qApp); Fm::FileMenu* menu = static_cast<Fm::FileMenu*>(sender()->parent()); for(GList* l = fm_file_info_list_peek_head_link(menu->files()); l; l = l->next) { FmFileInfo* file = FM_FILE_INFO(l->data); app->openFolderInTerminal(fm_file_info_get_path(file)); } }
void DesktopWindow::onRenameActivated() { if(FmFileInfoList* files = selectedFiles()) { for(GList* l = fm_file_info_list_peek_head_link(files); l; l = l->next) { FmFileInfo* info = FM_FILE_INFO(l->data); Fm::renameFile(info, NULL); fm_file_info_list_unref(files); } } }
// when the current selection in the folder view is changed void TabPage::onSelChanged(int numSel) { QString msg; if(numSel > 0) { /* FIXME: display total size of all selected files. */ if(numSel == 1) { /* only one file is selected */ FmFileInfoList* files = folderView_->selectedFiles(); FmFileInfo* fi = fm_file_info_list_peek_head(files); const char* size_str = fm_file_info_get_disp_size(fi); if(size_str) { msg = QString("\"%1\" (%2) %3") .arg(QString::fromUtf8(fm_file_info_get_disp_name(fi))) .arg(QString::fromUtf8(size_str ? size_str : "")) .arg(QString::fromUtf8(fm_file_info_get_desc(fi))); } else { msg = QString("\"%1\" %2") .arg(QString::fromUtf8(fm_file_info_get_disp_name(fi))) .arg(QString::fromUtf8(fm_file_info_get_desc(fi))); } /* FIXME: should we support statusbar plugins as in the gtk+ version? */ fm_file_info_list_unref(files); } else { goffset sum; GList* l; msg = tr("%1 item(s) selected", NULL, numSel).arg(numSel); /* don't count if too many files are selected, that isn't lightweight */ if(numSel < 1000) { sum = 0; FmFileInfoList* files = folderView_->selectedFiles(); for(l = fm_file_info_list_peek_head_link(files); l; l = l->next) { if(fm_file_info_is_dir(FM_FILE_INFO(l->data))) { /* if we got a directory then we cannot tell it's size unless we do deep count but we cannot afford it */ sum = -1; break; } sum += fm_file_info_get_size(FM_FILE_INFO(l->data)); } if(sum >= 0) { char size_str[128]; fm_file_size_to_str(size_str, sizeof(size_str), sum, fm_config->si_unit); msg += QString(" (%1)").arg(QString::fromUtf8(size_str)); } /* FIXME: should we support statusbar plugins as in the gtk+ version? */ fm_file_info_list_unref(files); } /* FIXME: can we show some more info on selection? that isn't lightweight if a lot of files are selected */ } } statusText_[StatusTextSelectedFiles] = msg; Q_EMIT statusChanged(StatusTextSelectedFiles, msg); }
static void on_open_folder_in_terminal(GtkAction* act, FmMainWin* win) { FmFileInfoList* files = fm_folder_view_dup_selected_files(win->folder_view); GList* l; for(l=fm_file_info_list_peek_head_link(files);l;l=l->next) { FmFileInfo* fi = (FmFileInfo*)l->data; if(fm_file_info_is_dir(fi) /*&& !fm_file_info_is_virtual(fi)*/) pcmanfm_open_folder_in_terminal(GTK_WINDOW(win), fm_file_info_get_path(fi)); } fm_file_info_list_unref(files); }
/* folder view popups */ static void update_files_popup(FmFolderView* fv, GtkWindow* win, GtkUIManager* ui, GtkActionGroup* act_grp, FmFileInfoList* files) { GList* l; for(l = fm_file_info_list_peek_head_link(files); l; l = l->next) if(!fm_file_info_is_dir(l->data)) return; /* actions are valid only if all selected are directories */ gtk_action_group_set_translation_domain(act_grp, NULL); gtk_action_group_add_actions(act_grp, folder_menu_actions, G_N_ELEMENTS(folder_menu_actions), win); gtk_ui_manager_add_ui_from_string(ui, folder_menu_xml, -1, NULL); }
void View::prepareFileMenu(Fm::FileMenu* menu) { Application* app = static_cast<Application*>(qApp); menu->setConfirmDelete(app->settings().confirmDelete()); menu->setConfirmTrash(app->settings().confirmTrash()); menu->setUseTrash(app->settings().useTrash()); // add some more menu items for dirs bool all_native = true; bool all_directory = true; FmFileInfoList* files = menu->files(); for(GList* l = fm_file_info_list_peek_head_link(files); l; l = l->next) { FmFileInfo* fi = FM_FILE_INFO(l->data); if(!fm_file_info_is_dir(fi)) all_directory = false; else if(fm_file_info_is_dir(fi) && !fm_file_info_is_native(fi)) all_native = false; } if (all_directory) { QAction* action = new QAction(QIcon::fromTheme("window-new"), tr("Open in New T&ab"), menu); connect(action, &QAction::triggered, this, &View::onNewTab); menu->insertAction(menu->separator1(), action); action = new QAction(QIcon::fromTheme("window-new"), tr("Open in New Win&dow"), menu); connect(action, &QAction::triggered, this, &View::onNewWindow); menu->insertAction(menu->separator1(), action); // TODO: add search // action = menu->addAction(_("Search")); if(all_native) { action = new QAction(QIcon::fromTheme("utilities-terminal"), tr("Open in Termina&l"), menu); connect(action, &QAction::triggered, this, &View::onOpenInTerminal); menu->insertAction(menu->separator1(), action); } } else { if(menu->pasteAction()) // NULL for trash menu->pasteAction()->setVisible(false); if(menu->createAction()) menu->createAction()->setVisible(false); } }
void SidePane::initDirTree() { // TODO DirTreeModel* model = new DirTreeModel(view_); FmFileInfoJob* job = fm_file_info_job_new(NULL, FM_FILE_INFO_JOB_NONE); model->setShowHidden(showHidden_); GList* l; /* query FmFileInfo for home dir and root dir, and then, * add them to dir tree model */ fm_file_info_job_add(job, fm_path_get_home()); fm_file_info_job_add(job, fm_path_get_root()); /* FIXME: maybe it's cleaner to use run_async here? */ fm_job_run_sync_with_mainloop(FM_JOB(job)); for(l = fm_file_info_list_peek_head_link(job->file_infos); l; l = l->next) { FmFileInfo* fi = FM_FILE_INFO(l->data); model->addRoot(fi); } g_object_unref(job); static_cast<DirTreeView*>(view_)->setModel(model); }
static gboolean fm_file_info_job_run(FmJob* fmjob) { GList* l; FmFileInfoJob* job = (FmFileInfoJob*)fmjob; GError* err = NULL; if(job->file_infos == NULL) return FALSE; for(l = fm_file_info_list_peek_head_link(job->file_infos); !fm_job_is_cancelled(fmjob) && l;) { FmFileInfo* fi = (FmFileInfo*)l->data; GList* next = l->next; FmPath* path = fm_file_info_get_path(fi); if(job->current) fm_path_unref(job->current); job->current = fm_path_ref(path); if(fm_path_is_native(path)) { char* path_str = fm_path_to_str(path); if(!_fm_file_info_job_get_info_for_native_file(fmjob, fi, path_str, &err)) { FmJobErrorAction act = fm_job_emit_error(fmjob, err, FM_JOB_ERROR_MILD); g_error_free(err); err = NULL; if(act == FM_JOB_RETRY) { g_free(path_str); continue; /* retry */ } fm_file_info_list_delete_link(job->file_infos, l); /* also calls unref */ } else if(G_UNLIKELY(job->flags & FM_FILE_INFO_JOB_EMIT_FOR_EACH_FILE)) fm_job_call_main_thread(fmjob, _emit_current_file, fi); g_free(path_str); /* recursively set display names for path parents */ _check_native_display_names(fm_path_get_parent(path)); } else { GFile* gf; gf = fm_path_to_gfile(path); if(!_fm_file_info_job_get_info_for_gfile(fmjob, fi, gf, &err)) { if(err->domain == G_IO_ERROR && err->code == G_IO_ERROR_NOT_MOUNTED) { GFileInfo *inf; /* location by link isn't mounted; unfortunately we cannot launch a target if we don't know what kind of target we have; lets make a simplest directory-kind GFIleInfo */ /* FIXME: this may be dirty a bit */ g_error_free(err); err = NULL; inf = g_file_info_new(); g_file_info_set_file_type(inf, G_FILE_TYPE_DIRECTORY); g_file_info_set_name(inf, fm_path_get_basename(path)); g_file_info_set_display_name(inf, fm_path_get_basename(path)); fm_file_info_set_from_g_file_data(fi, gf, inf); g_object_unref(inf); } else { FmJobErrorAction act = fm_job_emit_error(fmjob, err, FM_JOB_ERROR_MILD); g_error_free(err); err = NULL; if(act == FM_JOB_RETRY) { g_object_unref(gf); continue; /* retry */ } fm_file_info_list_delete_link(job->file_infos, l); /* also calls unref */ goto _next; } } else if(G_UNLIKELY(job->flags & FM_FILE_INFO_JOB_EMIT_FOR_EACH_FILE)) fm_job_call_main_thread(fmjob, _emit_current_file, fi); /* recursively set display names for path parents */ _check_gfile_display_names(fm_path_get_parent(path), gf); _next: g_object_unref(gf); } l = next; } return TRUE; }
void FilePropsDialog::initPermissionsPage() { // ownership handling // get owner/group and mode of the first file in the list uid = fm_file_info_get_uid(fileInfo); gid = fm_file_info_get_gid(fileInfo); mode_t mode = fm_file_info_get_mode(fileInfo); ownerPerm = (mode & (S_IRUSR|S_IWUSR|S_IXUSR)); groupPerm = (mode & (S_IRGRP|S_IWGRP|S_IXGRP)); otherPerm = (mode & (S_IROTH|S_IWOTH|S_IXOTH)); execPerm = (mode & (S_IXUSR|S_IXGRP|S_IXOTH)); allNative = fm_file_info_is_native(fileInfo); hasDir = S_ISDIR(mode); // check if all selected files belongs to the same owner/group or have the same mode // at the same time, check if all files are on native unix filesystems GList* l; for(l = fm_file_info_list_peek_head_link(fileInfos_)->next; l; l = l->next) { FmFileInfo* fi = FM_FILE_INFO(l->data); if(allNative && !fm_file_info_is_native(fi)) allNative = false; // not all of the files are native mode_t fi_mode = fm_file_info_get_mode(fi); if(S_ISDIR(fi_mode)) hasDir = true; // the files list contains dir(s) if(uid != DIFFERENT_UIDS && uid != fm_file_info_get_uid(fi)) uid = DIFFERENT_UIDS; // not all files have the same owner if(gid != DIFFERENT_GIDS && gid != fm_file_info_get_gid(fi)) gid = DIFFERENT_GIDS; // not all files have the same owner group if(ownerPerm != DIFFERENT_PERMS && ownerPerm != (fi_mode & (S_IRUSR|S_IWUSR|S_IXUSR))) ownerPerm = DIFFERENT_PERMS; // not all files have the same permission for owner if(groupPerm != DIFFERENT_PERMS && groupPerm != (fi_mode & (S_IRGRP|S_IWGRP|S_IXGRP))) groupPerm = DIFFERENT_PERMS; // not all files have the same permission for grop if(otherPerm != DIFFERENT_PERMS && otherPerm != (fi_mode & (S_IROTH|S_IWOTH|S_IXOTH))) otherPerm = DIFFERENT_PERMS; // not all files have the same permission for other if(execPerm != DIFFERENT_PERMS && execPerm != (fi_mode & (S_IXUSR|S_IXGRP|S_IXOTH))) execPerm = DIFFERENT_PERMS; // not all files have the same executable permission } // init owner/group initOwner(); // if all files are of the same type, and some of them are dirs => all of the items are dirs // rwx values have different meanings for dirs // Let's make it clear for the users // init combo boxes for file permissions here QStringList comboItems; comboItems.append("---"); // no change if(singleType && hasDir) { // all files are dirs comboItems.append(tr("View folder content")); comboItems.append(tr("View and modify folder content")); ui->executable->hide(); } else { //not all of the files are dirs comboItems.append(tr("Read")); comboItems.append(tr("Read and write")); } comboItems.append(tr("Forbidden")); QStringListModel* comboModel = new QStringListModel(comboItems, this); ui->ownerPerm->setModel(comboModel); ui->groupPerm->setModel(comboModel); ui->otherPerm->setModel(comboModel); // owner ownerPermSel = ACCESS_NO_CHANGE; if(ownerPerm != DIFFERENT_PERMS) { // permissions for owner are the same among all files if(ownerPerm & S_IRUSR) { // can read if(ownerPerm & S_IWUSR) // can write ownerPermSel = ACCESS_READ_WRITE; else ownerPermSel = ACCESS_READ_ONLY; } else { if((ownerPerm & S_IWUSR) == 0) // cannot read or write ownerPermSel = ACCESS_FORBID; } } ui->ownerPerm->setCurrentIndex(ownerPermSel); // owner and group groupPermSel = ACCESS_NO_CHANGE; if(groupPerm != DIFFERENT_PERMS) { // permissions for owner are the same among all files if(groupPerm & S_IRGRP) { // can read if(groupPerm & S_IWGRP) // can write groupPermSel = ACCESS_READ_WRITE; else groupPermSel = ACCESS_READ_ONLY; } else { if((groupPerm & S_IWGRP) == 0) // cannot read or write groupPermSel = ACCESS_FORBID; } } ui->groupPerm->setCurrentIndex(groupPermSel); // other otherPermSel = ACCESS_NO_CHANGE; if(otherPerm != DIFFERENT_PERMS) { // permissions for owner are the same among all files if(otherPerm & S_IROTH) { // can read if(otherPerm & S_IWOTH) // can write otherPermSel = ACCESS_READ_WRITE; else otherPermSel = ACCESS_READ_ONLY; } else { if((otherPerm & S_IWOTH) == 0) // cannot read or write otherPermSel = ACCESS_FORBID; } } ui->otherPerm->setCurrentIndex(otherPermSel); // set the checkbox to partially checked state // when owner, group, and other have different executable flags set. // some of them have exec, and others do not have. execCheckState = Qt::PartiallyChecked; if(execPerm != DIFFERENT_PERMS) { // if all files have the same executable permission // check if the files are all executable if((mode & (S_IXUSR|S_IXGRP|S_IXOTH)) == (S_IXUSR|S_IXGRP|S_IXOTH)) { // owner, group, and other all have exec permission. ui->executable->setTristate(false); execCheckState = Qt::Checked; } else if((mode & (S_IXUSR|S_IXGRP|S_IXOTH)) == 0) { // owner, group, and other all have no exec permission ui->executable->setTristate(false); execCheckState = Qt::Unchecked; } } ui->executable->setCheckState(execCheckState); }