diff --git a/krusader/Konfigurator/kggeneral.cpp b/krusader/Konfigurator/kggeneral.cpp index a160e38a..3633c93b 100644 --- a/krusader/Konfigurator/kggeneral.cpp +++ b/krusader/Konfigurator/kggeneral.cpp @@ -1,345 +1,348 @@ /*************************************************************************** kggeneral.cpp - description ------------------- copyright : (C) 2004 by Csaba Karai e-mail : krusader@users.sourceforge.net web site : http://krusader.sourceforge.net --------------------------------------------------------------------------- Description *************************************************************************** A db dD d8888b. db db .d8888. .d8b. d8888b. d88888b d8888b. 88 ,8P' 88 `8D 88 88 88' YP d8' `8b 88 `8D 88' 88 `8D 88,8P 88oobY' 88 88 `8bo. 88ooo88 88 88 88ooooo 88oobY' 88`8b 88`8b 88 88 `Y8b. 88~~~88 88 88 88~~~~~ 88`8b 88 `88. 88 `88. 88b d88 db 8D 88 88 88 .8D 88. 88 `88. YP YD 88 YD ~Y8888P' `8888Y' YP YP Y8888D' Y88888P 88 YD S o u r c e F i l e *************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "kggeneral.h" // QtCore #include // QtGui #include #include // QtWidgets #include #include #include #include #include #include #include #include #include "krresulttabledialog.h" #include "../defaults.h" #include "../kicons.h" #include "../krglobal.h" #define PAGE_GENERAL 0 #define PAGE_VIEWER 1 #define PAGE_EXTENSIONS 2 KgGeneral::KgGeneral(bool first, QWidget* parent) : KonfiguratorPage(first, parent) { if (first) slotFindTools(); tabWidget = new QTabWidget(this); setWidget(tabWidget); setWidgetResizable(true); createGeneralTab(); createViewerTab(); createExtensionsTab(); } QWidget* KgGeneral::createTab(QString name) { QScrollArea *scrollArea = new QScrollArea(tabWidget); tabWidget->addTab(scrollArea, name); scrollArea->setFrameStyle(QFrame::NoFrame); scrollArea->setWidgetResizable(true); QWidget *tab = new QWidget(scrollArea); scrollArea->setWidget(tab); return tab; } void KgGeneral::createViewerTab() { QWidget *tab = createTab(i18n("Viewer/Editor")); QGridLayout *tabLayout = new QGridLayout(tab); tabLayout->setSpacing(6); tabLayout->setContentsMargins(11, 11, 11, 11); tabLayout->addWidget(createCheckBox("General", "View In Separate Window", _ViewInSeparateWindow, i18n("Internal editor and viewer opens each file in a separate window"), tab, false, i18n("If checked, each file will open in a separate window, otherwise, the viewer will work in a single, tabbed mode"), PAGE_VIEWER)); // ------------------------- viewer ---------------------------------- QGroupBox *viewerGrp = createFrame(i18n("Viewer"), tab); tabLayout->addWidget(viewerGrp, 1, 0); QGridLayout *viewerGrid = createGridLayout(viewerGrp); QWidget * hboxWidget2 = new QWidget(viewerGrp); QHBoxLayout * hbox2 = new QHBoxLayout(hboxWidget2); QWidget * vboxWidget = new QWidget(hboxWidget2); QVBoxLayout * vbox = new QVBoxLayout(vboxWidget); vbox->addWidget(new QLabel(i18n("Default viewer mode:"), vboxWidget)); KONFIGURATOR_NAME_VALUE_TIP viewMode[] = // name value tooltip {{ i18n("Generic mode"), "generic", i18n("Use the system's default viewer") }, { i18n("Text mode"), "text", i18n("View the file in text-only mode") }, { i18n("Hex mode"), "hex", i18n("View the file in hex-mode (better for binary files)") }, { i18n("Lister mode"), "lister", i18n("View the file with lister (for huge text files)") } }; vbox->addWidget(createRadioButtonGroup("General", "Default Viewer Mode", "generic", 0, 4, viewMode, 4, vboxWidget, false, PAGE_VIEWER)); vbox->addWidget( createCheckBox("General", "UseOktetaViewer", _UseOktetaViewer, i18n("Use Okteta as Hex viewer"), vboxWidget, false, i18n("If available, use Okteta as Hex viewer instead of the internal viewer"), PAGE_VIEWER) ); QWidget * hboxWidget4 = new QWidget(vboxWidget); QHBoxLayout * hbox4 = new QHBoxLayout(hboxWidget4); QLabel *label5 = new QLabel(i18n("Use lister if the text file is bigger than:"), hboxWidget4); hbox4->addWidget(label5); KonfiguratorSpinBox *spinBox = createSpinBox("General", "Lister Limit", _ListerLimit, 0, 0x7FFFFFFF, hboxWidget4, false, PAGE_VIEWER); hbox4->addWidget(spinBox); QLabel *label6 = new QLabel(i18n("MB"), hboxWidget4); hbox4->addWidget(label6); vbox->addWidget(hboxWidget4); hbox2->addWidget(vboxWidget); viewerGrid->addWidget(hboxWidget2, 0, 0); // ------------------------- editor ---------------------------------- QGroupBox *editorGrp = createFrame(i18n("Editor"), tab); tabLayout->addWidget(editorGrp, 2, 0); QGridLayout *editorGrid = createGridLayout(editorGrp); QLabel *label1 = new QLabel(i18n("Editor:"), editorGrp); editorGrid->addWidget(label1, 0, 0); KonfiguratorURLRequester *urlReq = createURLRequester("General", "Editor", "internal editor", editorGrp, false, PAGE_VIEWER, false); editorGrid->addWidget(urlReq, 0, 1); QLabel *label2 = new QLabel(i18n("Hint: use 'internal editor' if you want to use Krusader's fast built-in editor"), editorGrp); editorGrid->addWidget(label2, 1, 0, 1, 2); } void KgGeneral::createExtensionsTab() { // ------------------------- atomic extensions ---------------------------------- QWidget *tab = createTab(i18n("Atomic extensions")); QGridLayout *tabLayout = new QGridLayout(tab); tabLayout->setSpacing(6); tabLayout->setContentsMargins(11, 11, 11, 11); QWidget * vboxWidget2 = new QWidget(tab); tabLayout->addWidget(vboxWidget2); QVBoxLayout * vbox2 = new QVBoxLayout(vboxWidget2); QWidget * hboxWidget3 = new QWidget(vboxWidget2); vbox2->addWidget(hboxWidget3); QHBoxLayout * hbox3 = new QHBoxLayout(hboxWidget3); QLabel * atomLabel = new QLabel(i18n("Atomic extensions:"), hboxWidget3); hbox3->addWidget(atomLabel); int size = QFontMetrics(atomLabel->font()).height(); QToolButton *addButton = new QToolButton(hboxWidget3); hbox3->addWidget(addButton); QPixmap icon = krLoader->loadIcon("list-add", KIconLoader::Desktop, size); addButton->setFixedSize(icon.width() + 4, icon.height() + 4); addButton->setIcon(QIcon(icon)); connect(addButton, SIGNAL(clicked()), this, SLOT(slotAddExtension())); QToolButton *removeButton = new QToolButton(hboxWidget3); hbox3->addWidget(removeButton); icon = krLoader->loadIcon("list-remove", KIconLoader::Desktop, size); removeButton->setFixedSize(icon.width() + 4, icon.height() + 4); removeButton->setIcon(QIcon(icon)); connect(removeButton, SIGNAL(clicked()), this, SLOT(slotRemoveExtension())); QStringList defaultAtomicExtensions; defaultAtomicExtensions += ".tar.gz"; defaultAtomicExtensions += ".tar.bz2"; defaultAtomicExtensions += ".tar.lzma"; defaultAtomicExtensions += ".tar.xz"; defaultAtomicExtensions += ".moc.cpp"; listBox = createListBox("Look&Feel", "Atomic Extensions", defaultAtomicExtensions, vboxWidget2, true, PAGE_EXTENSIONS); vbox2->addWidget(listBox); } void KgGeneral::createGeneralTab() { QWidget *tab = createTab(i18n("General")); QGridLayout *kgGeneralLayout = new QGridLayout(tab); kgGeneralLayout->setSpacing(6); kgGeneralLayout->setContentsMargins(11, 11, 11, 11); // -------------------------- GENERAL GROUPBOX ---------------------------------- QGroupBox *generalGrp = createFrame(i18n("General"), tab); QGridLayout *generalGrid = createGridLayout(generalGrp); KONFIGURATOR_CHECKBOX_PARAM settings[] = { // cfg_class cfg_name default text restart tooltip {"Look&Feel", "Warn On Exit", _WarnOnExit, i18n("Warn on exit"), false, i18n("Display a warning when trying to close the main window.") }, // KDE4: move warn on exit to the other confirmations }; KonfiguratorCheckBoxGroup *cbs = createCheckBoxGroup(2, 0, settings, 1 /*count*/, generalGrp, PAGE_GENERAL); generalGrid->addWidget(cbs, 0, 0); KonfiguratorCheckBox *checkBox = createCheckBox("General", "Mimetype Magic", _MimetypeMagic, i18n("Use MIME type magic"), generalGrp, false, i18n("MIME type magic allows better distinction of file types, but is slower."), PAGE_GENERAL); generalGrid->addWidget(checkBox, 1, 0, 1, 1); // temp dir QHBoxLayout *hbox = new QHBoxLayout(); hbox->addWidget(new QLabel(i18n("Temp Folder:"), generalGrp)); KonfiguratorURLRequester *urlReq3 = createURLRequester("General", "Temp Directory", _TempDirectory, generalGrp, false, PAGE_GENERAL); urlReq3->setMode(KFile::Directory); connect(urlReq3->extension(), SIGNAL(applyManually(QObject *, QString, QString)), this, SLOT(applyTempDir(QObject *, QString, QString))); hbox->addWidget(urlReq3); generalGrid->addLayout(hbox, 13, 0, 1, 1); QLabel *label4 = new QLabel(i18n("Note: you must have full permissions for the temporary folder."), generalGrp); generalGrid->addWidget(label4, 14, 0, 1, 1); kgGeneralLayout->addWidget(generalGrp, 0 , 0); // ----------------------- delete mode -------------------------------------- QGroupBox *delGrp = createFrame(i18n("Delete mode"), tab); QGridLayout *delGrid = createGridLayout(delGrp); KONFIGURATOR_NAME_VALUE_TIP deleteMode[] = // name value tooltip {{i18n("Move to trash"), "true", i18n("Files will be moved to trash when deleted.")}, {i18n("Delete files"), "false", i18n("Files will be permanently deleted.")} }; KonfiguratorRadioButtons *trashRadio = createRadioButtonGroup("General", "Move To Trash", _MoveToTrash ? "true" : "false", 2, 0, deleteMode, 2, delGrp, false, PAGE_GENERAL); delGrid->addWidget(trashRadio); kgGeneralLayout->addWidget(delGrp, 1 , 0); // ----------------------- terminal ----------------------------------------- QGroupBox *terminalGrp = createFrame(i18n("Terminal"), tab); QGridLayout *terminalGrid = createGridLayout(terminalGrp); QLabel *label3 = new QLabel(i18n("Terminal:"), generalGrp); terminalGrid->addWidget(label3, 0, 0); KonfiguratorURLRequester *urlReq2 = createURLRequester("General", "Terminal", _Terminal, generalGrp, false, PAGE_GENERAL, false); terminalGrid->addWidget(urlReq2, 0, 1); + QLabel *terminalLabel = new QLabel(i18n("%d will be replaced by the workdir."), + terminalGrp); + terminalGrid->addWidget(terminalLabel, 1, 1); KONFIGURATOR_CHECKBOX_PARAM terminal_settings[] = { // cfg_class cfg_name default text restart tooltip {"General", "Send CDs", _SendCDs, i18n("Terminal Emulator sends Chdir on panel change"), false, i18n("When checked, whenever the panel is changed (for example, by pressing Tab), Krusader changes the current folder in the terminal emulator.") }, {"Look&Feel", "Fullscreen Terminal Emulator", false, i18n("Fullscreen terminal (mc-style)"), false, i18n("Terminal is shown instead of the Krusader window (full screen).") }, }; cbs = createCheckBoxGroup(1, 0, terminal_settings, 2 /*count*/, terminalGrp, PAGE_GENERAL); - terminalGrid->addWidget(cbs, 1, 0, 1, 2); + terminalGrid->addWidget(cbs, 2, 0, 1, 2); kgGeneralLayout->addWidget(terminalGrp, 2 , 0); } void KgGeneral::applyTempDir(QObject *obj, QString cls, QString name) { KonfiguratorURLRequester *urlReq = (KonfiguratorURLRequester *)obj; QString value = urlReq->url().toDisplayString(QUrl::PreferLocalFile); KConfigGroup(krConfig, cls).writeEntry(name, value); } void KgGeneral::slotFindTools() { QPointer dlg = new KrResultTableDialog(this, KrResultTableDialog::Tool, i18n("Search results"), i18n("Searching for tools..."), "tools-wizard", i18n("Make sure to install new tools in your $PATH (e.g. /usr/bin)")); dlg->exec(); delete dlg; } void KgGeneral::slotAddExtension() { bool ok; QString atomExt = QInputDialog::getText(this, i18n("Add new atomic extension"), i18n("Extension:"), QLineEdit::Normal, QString(), &ok); if (ok) { if (!atomExt.startsWith('.') || atomExt.indexOf('.', 1) == -1) KMessageBox::error(krMainWindow, i18n("Atomic extensions must start with '.' and must contain at least one more '.' character."), i18n("Error")); else listBox->addItem(atomExt); } } void KgGeneral::slotRemoveExtension() { QList list = listBox->selectedItems(); for (int i = 0; i != list.count(); i++) listBox->removeItem(list[ i ]->text()); } diff --git a/krusader/Panel/krpopupmenu.cpp b/krusader/Panel/krpopupmenu.cpp index 02013512..7eac4a99 100644 --- a/krusader/Panel/krpopupmenu.cpp +++ b/krusader/Panel/krpopupmenu.cpp @@ -1,434 +1,430 @@ /***************************************************************************** * Copyright (C) 2003 Shie Erlich * * Copyright (C) 2003 Rafi Yanai * * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This package is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this package; if not, write to the Free Software * * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA * *****************************************************************************/ #include "krpopupmenu.h" // QtGui #include #include #include #include #include #include #include #include #include #include #include #include #include "listpanel.h" #include "krview.h" #include "krviewitem.h" #include "panelfunc.h" #include "listpanelactions.h" #include "../krservices.h" #include "../defaults.h" #include "../MountMan/kmountman.h" #include "../krusader.h" #include "../krslots.h" #include "../krusaderview.h" #include "../panelmanager.h" #include "../krtrashhandler.h" #include "../UserAction/useractionpopupmenu.h" #include "../VFS/krarchandler.h" void KrPopupMenu::run(const QPoint &pos, KrPanel *panel) { KrPopupMenu menu(panel); QAction * res = menu.exec(pos); int result = -1; if (res && res->data().canConvert()) result = res->data().toInt(); menu.performAction(result); } /** * Copied from dolphin/src/dolphincontextmenu.cpp and modified to add only compress and extract submenus. */ bool KrPopupMenu::addCompressAndExtractPluginActions() { KFileItemListProperties props(_items); QVector jsonPlugins = KPluginLoader::findPlugins("kf5/kfileitemaction", [=](const KPluginMetaData& metaData) { return metaData.pluginId() == "compressfileitemaction" || metaData.pluginId() == "extractfileitemaction"; }); foreach (const KPluginMetaData &jsonMetadata, jsonPlugins) { KAbstractFileItemActionPlugin* abstractPlugin = KPluginLoader(jsonMetadata.fileName()) .factory()->create(); if (abstractPlugin) { abstractPlugin->setParent(this); addActions(abstractPlugin->actions(props, this)); } } return !jsonPlugins.isEmpty(); } KrPopupMenu::KrPopupMenu(KrPanel *thePanel, QWidget *parent) : QMenu(parent), panel(thePanel), empty(false), multipleSelections(false), actions(0), _item(0) { KrViewItemList items; panel->view->getSelectedKrViewItems(&items); for (KrViewItemList::Iterator it = items.begin(); it != items.end(); ++it) { vfile *file = panel->func->files()->vfs_search(((*it)->name())); QUrl url = file->vfile_getUrl(); _items.append(KFileItem(url, file->vfile_getMime(), file->vfile_getMode())); } if (items.empty()) { addCreateNewMenu(); addSeparator(); addEmptyMenuEntries(); return; } else if (items.size() > 1) multipleSelections = true; QList protocols; for (int i = 0; i < items.size(); ++i) { protocols.append(panel->func->getVFile(items[ i ]) ->vfile_getUrl().scheme()); } bool inTrash = protocols.contains("trash"); bool trashOnly = (protocols.count() == 1) && (protocols[ 0 ] == "trash"); KrViewItem *item = items.first(); vfile *vf = panel->func->getVFile(item); _item = &_items.first(); // ------------ the OPEN/BROWSE option - open preferred service QAction * openAct = addAction(i18n("Open/Run")); openAct->setData(QVariant(OPEN_ID)); if (!multipleSelections) { // meaningful only if one file is selected openAct->setIcon(item->icon()); openAct->setText(vf->vfile_isExecutable() && !vf->vfile_isDir() ? i18n("Run") : i18n("Open")); // open in a new tab (if folder) if (vf->vfile_isDir()) { QAction * openTab = addAction(i18n("Open in New Tab")); openTab->setData(QVariant(OPEN_TAB_ID)); openTab->setIcon(krLoader->loadIcon("tab-new", KIconLoader::Panel)); openTab->setText(i18n("Open in New Tab")); } QUrl arcPath = panel->func->browsableArchivePath(vf->vfile_getName()); if (!arcPath.isEmpty()) { bool theArchiveMustBeBrowsedAsADirectory = KConfigGroup(krConfig, "Archives").readEntry("ArchivesAsDirectories", _ArchivesAsDirectories) && KRarcHandler::arcSupported(vf->vfile_getMime()); if (!theArchiveMustBeBrowsedAsADirectory) { // Add an option to browse the archive QAction *browseAct = addAction(i18n("Browse")); browseAct->setData(QVariant(BROWSE_ID)); browseAct->setIcon(krLoader->loadIcon("", KIconLoader::Panel)); browseAct->setText(i18n("Browse Archive")); } } addSeparator(); } // ------------- Preview - normal vfs only ? if (panel->func->files()->vfs_getType() == vfs::VFS_NORMAL) { // create the preview popup QStringList names; panel->gui->getSelectedNames(&names); preview.setUrls(panel->func->files() ->vfs_getFiles(names)); QAction *pAct = addMenu(&preview); pAct->setData(QVariant(PREVIEW_ID)); pAct->setText(i18n("Preview")); } // -------------- Open with: try to find-out which apps can open the file // this too, is meaningful only if one file is selected or if all the files // have the same mimetype ! QString mime = panel->func->getVFile(item)->vfile_getMime(); // check if all the list have the same mimetype for (int i = 1; i < items.size(); ++i) { if (panel->func->getVFile(items[ i ]) ->vfile_getMime() != mime) { mime.clear(); break; } } if (!mime.isEmpty()) { offers = KMimeTypeTrader::self()->query(mime); for (int i = 0; i < offers.count(); ++i) { QExplicitlySharedDataPointer service = offers[i]; if (service->isValid() && service->isApplication()) { openWith.addAction(krLoader->loadIcon(service->icon(), KIconLoader::Small), service->name())->setData(QVariant(SERVICE_LIST_ID + i)); } } openWith.addSeparator(); if (vf->vfile_isDir()) openWith.addAction(krLoader->loadIcon("utilities-terminal", KIconLoader::Small), i18n("Terminal"))->setData(QVariant(OPEN_TERM_ID)); openWith.addAction(i18n("Other..."))->setData(QVariant(CHOOSE_ID)); QAction *owAct = addMenu(&openWith); owAct->setData(QVariant(OPEN_WITH_ID)); owAct->setText(i18n("Open With")); addSeparator(); } // --------------- user actions QAction *uAct = new UserActionPopupMenu(panel->func->files()->vfs_getFile(item->name())); addAction(uAct); uAct->setText(i18n("User Actions")); // add compress and extract plugins (if available) bool success = addCompressAndExtractPluginActions(); /* * When KF 5.25 is adopted by all distros, we can remove these 2 lines (and corresponding code) * because since KF 5.25 compress and extract submenus are standalone plugins. */ if (!success) { fileItemActions.setItemListProperties(KFileItemListProperties(_items)); fileItemActions.addServiceActionsTo(this); } addSeparator(); // ------------- 'create new' submenu addCreateNewMenu(); addSeparator(); // ---------- COPY addAction(i18n("Copy..."))->setData(QVariant(COPY_ID)); if (panel->func->files() ->vfs_isWritable()) { // ------- MOVE addAction(i18n("Move..."))->setData(QVariant(MOVE_ID)); // ------- RENAME - only one file if (!multipleSelections && !inTrash) addAction(i18n("Rename"))->setData(QVariant(RENAME_ID)); // -------- MOVE TO TRASH KConfigGroup saver(krConfig, "General"); bool trash = saver.readEntry("Move To Trash", _MoveToTrash); if (trash && !inTrash) addAction(i18n("Move to Trash"))->setData(QVariant(TRASH_ID)); // -------- DELETE addAction(i18n("Delete"))->setData(QVariant(DELETE_ID)); // -------- SHRED - only one file /* if ( panel->func->files() ->vfs_getType() == vfs::VFS_NORMAL && !vf->vfile_isDir() && !multipleSelections ) addAction( i18n( "Shred" ) )->setData( QVariant( SHRED_ID ) );*/ } // ---------- link handling // create new shortcut or redirect links - only on local directories: if (panel->func->files() ->vfs_getType() == vfs::VFS_NORMAL) { addSeparator(); linkPopup.addAction(i18n("New Symlink..."))->setData(QVariant(NEW_SYMLINK_ID)); linkPopup.addAction(i18n("New Hardlink..."))->setData(QVariant(NEW_LINK_ID)); if (panel->func->getVFile(item)->vfile_isSymLink()) linkPopup.addAction(i18n("Redirect Link..."))->setData(QVariant(REDIRECT_LINK_ID)); QAction *linkAct = addMenu(&linkPopup); linkAct->setData(QVariant(LINK_HANDLING_ID)); linkAct->setText(i18n("Link Handling")); } addSeparator(); // ---------- calculate space if (panel->func->files() ->vfs_getType() == vfs::VFS_NORMAL && (vf->vfile_isDir() || multipleSelections)) addAction(panel->gui->actions()->actCalculate); // ---------- mount/umount/eject if (panel->func->files() ->vfs_getType() == vfs::VFS_NORMAL && vf->vfile_isDir() && !multipleSelections) { if (krMtMan.getStatus(panel->func->files() ->vfs_getFile(item->name()).path()) == KMountMan::MOUNTED) addAction(i18n("Unmount"))->setData(QVariant(UNMOUNT_ID)); else if (krMtMan.getStatus(panel->func->files() ->vfs_getFile(item->name()).path()) == KMountMan::NOT_MOUNTED) addAction(i18n("Mount"))->setData(QVariant(MOUNT_ID)); if (krMtMan.ejectable(panel->func->files() ->vfs_getFile(item->name()).path())) addAction(i18n("Eject"))->setData(QVariant(EJECT_ID)); } // --------- send by mail if (KrServices::supportedTools().contains("MAIL") && !vf->vfile_isDir()) { addAction(i18n("Send by Email"))->setData(QVariant(SEND_BY_EMAIL_ID)); } // --------- empty trash if (trashOnly) { addAction(i18n("Restore"))->setData(QVariant(RESTORE_TRASHED_FILE_ID)); addAction(i18n("Empty Trash"))->setData(QVariant(EMPTY_TRASH_ID)); } #ifdef SYNCHRONIZER_ENABLED // --------- synchronize if (panel->view->numSelected()) { addAction(i18n("Synchronize Selected Files..."))->setData(QVariant(SYNC_SELECTED_ID)); } #endif // --------- copy/paste addSeparator(); addAction(i18n("Copy to Clipboard"))->setData(QVariant(COPY_CLIP_ID)); if (panel->func->files() ->vfs_isWritable()) { addAction(i18n("Cut to Clipboard"))->setData(QVariant(MOVE_CLIP_ID)); addAction(i18n("Paste from Clipboard"))->setData(QVariant(PASTE_CLIP_ID)); } addSeparator(); // --------- properties addAction(panel->gui->actions()->actProperties); } KrPopupMenu::~KrPopupMenu() { _items.clear(); if (actions) delete actions; } void KrPopupMenu::addEmptyMenuEntries() { addAction(i18n("Paste from Clipboard"))->setData(QVariant(PASTE_CLIP_ID)); } void KrPopupMenu::addCreateNewMenu() { createNewPopup.addAction(krLoader->loadIcon("folder", KIconLoader::Small), i18n("Folder..."))->setData(QVariant(MKDIR_ID)); createNewPopup.addAction(krLoader->loadIcon("text-plain", KIconLoader::Small), i18n("Text File..."))->setData(QVariant(NEW_TEXT_FILE_ID)); QAction *newAct = addMenu(&createNewPopup); newAct->setData(QVariant(CREATE_NEW_ID)); newAct->setText(i18n("Create New")); } void KrPopupMenu::performAction(int id) { switch (id) { case - 1 : // the user clicked outside of the menu return ; case OPEN_TAB_ID : // assuming only 1 file is selected (otherwise we won't get here) panel->manager()->newTab(_item->url(), panel); break; case OPEN_ID : foreach(KFileItem fi, _items) panel->func->execute(fi.name()); break; case BROWSE_ID : panel->func->goInside(_item->url().fileName()); break; case COPY_ID : panel->func->copyFiles(); break; case MOVE_ID : panel->func->moveFiles(); break; case RENAME_ID : panel->func->rename(); break; case TRASH_ID : panel->func->deleteFiles(false); break; case DELETE_ID : panel->func->deleteFiles(true); break; case EJECT_ID : krMtMan.eject(_item->url().adjusted(QUrl::StripTrailingSlash).path()); break; /* case SHRED_ID : if ( KMessageBox::warningContinueCancel( krApp, i18n("Do you really want to shred %1? Once shred, the file is gone forever.", item->name()), QString(), KStandardGuiItem::cont(), KStandardGuiItem::cancel(), "Shred" ) == KMessageBox::Continue ) KShred::shred( panel->func->files() ->vfs_getFile( item->name() ).adjusted(QUrl::RemoveTrailingSlash).path() ); break;*/ case OPEN_KONQ_ID : KToolInvocation::startServiceByDesktopName("konqueror", _item->url().toDisplayString(QUrl::PreferLocalFile)); break; case CHOOSE_ID : // open-with dialog panel->func->displayOpenWithDialog(_items.urlList()); break; case MOUNT_ID : krMtMan.mount(_item->url().adjusted(QUrl::StripTrailingSlash).path()); break; case NEW_LINK_ID : panel->func->krlink(false); break; case NEW_SYMLINK_ID : panel->func->krlink(true); break; case REDIRECT_LINK_ID : panel->func->redirectLink(); break; case EMPTY_TRASH_ID : KrTrashHandler::emptyTrash(); break; case RESTORE_TRASHED_FILE_ID : KrTrashHandler::restoreTrashedFiles(_items.urlList()); break; case UNMOUNT_ID : krMtMan.unmount(_item->url().adjusted(QUrl::StripTrailingSlash).path()); break; case COPY_CLIP_ID : panel->func->copyToClipboard(); break; case MOVE_CLIP_ID : panel->func->copyToClipboard(true); break; case PASTE_CLIP_ID : panel->func->pasteFromClipboard(); break; case SEND_BY_EMAIL_ID : { SLOTS->sendFileByEmail(_items.urlList()); break; } case MKDIR_ID : panel->func->mkdir(); break; case NEW_TEXT_FILE_ID: panel->func->editNew(); break; #ifdef SYNCHRONIZER_ENABLED case SYNC_SELECTED_ID : { QStringList selectedNames; foreach(KFileItem item, _items) selectedNames << item.name(); if (panel->otherPanel()->view->numSelected()) { KrViewItemList otherItems; panel->otherPanel()->view->getSelectedKrViewItems(&otherItems); for (KrViewItemList::Iterator it2 = otherItems.begin(); it2 != otherItems.end(); ++it2) { QString name = (*it2) ->name(); if (!selectedNames.contains(name)) selectedNames.append(name); } } SLOTS->slotSynchronizeDirs(selectedNames); } break; #endif - case OPEN_TERM_ID : { - QStringList args; - if (!_item->isDir()) - args << _item->name(); - SLOTS->runTerminal(_item->url().path(), args); - } - break; + case OPEN_TERM_ID : + SLOTS->runTerminal(_item->url().path()); + break; } // check if something from the open-with-offered-services was selected if (id >= SERVICE_LIST_ID) { QStringList names; panel->gui->getSelectedNames(&names); panel->func->runService(*(offers[ id - SERVICE_LIST_ID ]), panel->func->files()->vfs_getFiles(names)); } } diff --git a/krusader/Panel/panelfunc.cpp b/krusader/Panel/panelfunc.cpp index da3183df..5f712233 100644 --- a/krusader/Panel/panelfunc.cpp +++ b/krusader/Panel/panelfunc.cpp @@ -1,1457 +1,1457 @@ /*************************************************************************** panelfunc.cpp ------------------- copyright : (C) 2000 by Shie Erlich & Rafi Yanai e-mail : krusader@users.sourceforge.net web site : http://krusader.sourceforge.net --------------------------------------------------------------------------- Description *************************************************************************** A db dD d8888b. db db .d8888. .d8b. d8888b. d88888b d8888b. 88 ,8P' 88 `8D 88 88 88' YP d8' `8b 88 `8D 88' 88 `8D 88,8P 88oobY' 88 88 `8bo. 88ooo88 88 88 88ooooo 88oobY' 88`8b 88`8b 88 88 `Y8b. 88~~~88 88 88 88~~~~~ 88`8b 88 `88. 88 `88. 88b d88 db 8D 88 88 88 .8D 88. 88 `88. YP YD 88 YD ~Y8888P' `8888Y' YP YP Y8888D' Y88888P 88 YD S o u r c e F i l e *************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "panelfunc.h" // QtCore #include #include #include #include #include #include // QtGui #include #include // QtWidgets #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "dirhistoryqueue.h" #include "krcalcspacedialog.h" #include "listpanel.h" #include "krerrordisplay.h" #include "listpanelactions.h" #include "../krglobal.h" #include "../krslots.h" #include "../kractions.h" #include "../defaults.h" #include "../abstractpanelmanager.h" #include "../krservices.h" #include "../VFS/vfile.h" #include "../VFS/virt_vfs.h" #include "../VFS/krarchandler.h" #include "../VFS/krpermhandler.h" #include "../VFS/krvfshandler.h" #include "../VFS/preservingcopyjob.h" #include "../VFS/virtualcopyjob.h" #include "../VFS/packjob.h" #include "../Dialogs/packgui.h" #include "../Dialogs/krdialogs.h" #include "../Dialogs/krpleasewait.h" #include "../Dialogs/krspwidgets.h" #include "../Dialogs/checksumdlg.h" #include "../KViewer/krviewer.h" #include "../GUI/syncbrowsebutton.h" #include "../Queue/queue_mgr.h" QPointer ListPanelFunc::copyToClipboardOrigin; ListPanelFunc::ListPanelFunc(ListPanel *parent) : QObject(parent), panel(parent), vfsP(0), urlManuallyEntered(false), _refreshing(false) { history = new DirHistoryQueue(panel); delayTimer.setSingleShot(true); connect(&delayTimer, SIGNAL(timeout()), this, SLOT(doRefresh())); } ListPanelFunc::~ListPanelFunc() { if (vfsP) { if (vfsP->vfs_canDelete()) delete vfsP; else { connect(vfsP, SIGNAL(deleteAllowed()), vfsP, SLOT(deleteLater())); vfsP->vfs_requestDelete(); } } delete history; } void ListPanelFunc::navigatorUrlChanged(const QUrl &url) { if (_refreshing) return; if (!ListPanel::isNavigatorEditModeSet()) { panel->urlNavigator->setUrlEditable(false); } openUrl(KrServices::escapeFileUrl(url), QString(), true); } bool ListPanelFunc::isSyncing(const QUrl &url) { if(otherFunc()->otherFunc() == this && panel->otherPanel()->gui->syncBrowseButton->state() == SYNCBROWSE_CD && !otherFunc()->syncURL.isEmpty() && otherFunc()->syncURL == url) return true; return false; } void ListPanelFunc::openFileNameInternal(const QString &name, bool theFileCanBeExecutedOrOpenedWithOtherSoftware) { if (name == "..") { dirUp(); return ; } vfile *vf = files() ->vfs_search(name); if (vf == 0) return ; QUrl url = files()->vfs_getFile(name); if (vf->vfile_isDir()) { panel->view->setNameToMakeCurrent(QString()); openUrl(url); return; } QString mime = vf->vfile_getMime(); QUrl arcPath = browsableArchivePath(name); if (!arcPath.isEmpty()) { bool theArchiveMustBeBrowsedAsADirectory = (KConfigGroup(krConfig, "Archives").readEntry("ArchivesAsDirectories", _ArchivesAsDirectories) && KRarcHandler::arcSupported(mime)) || !theFileCanBeExecutedOrOpenedWithOtherSoftware; if (theArchiveMustBeBrowsedAsADirectory) { openUrl(arcPath); return; } } if (theFileCanBeExecutedOrOpenedWithOtherSoftware) { if (KRun::isExecutableFile(url, mime)) { runCommand(KShell::quoteArg(url.path())); return; } KService::Ptr service = KMimeTypeTrader::self()->preferredService(mime); if(service) { runService(*service, QList() << url); return; } displayOpenWithDialog(QList() << url); } } #if 0 //FIXME: see if this is still needed void ListPanelFunc::popErronousUrl() { QUrl current = urlStack.last(); while (urlStack.count() != 0) { QUrl url = urlStack.takeLast(); if (!current.equals(url)) { immediateOpenUrl(url, true); return; } } immediateOpenUrl(QUrl::fromLocalFile(ROOT_DIR), true); } #endif QUrl ListPanelFunc::cleanPath(const QUrl &urlIn) { QUrl url = urlIn; url.setPath(QDir::cleanPath(url.path())); if (!url.isValid() || url.isRelative()) { if (url.url() == "~") url = QUrl::fromLocalFile(QDir::homePath()); else if (!url.url().startsWith('/')) { // possible relative URL - translate to full URL url = files()->vfs_getOrigin(); url.setPath(url.path() + '/' + urlIn.path()); } } url.setPath(QDir::cleanPath(url.path())); return url; } void ListPanelFunc::openUrl(const QUrl &url, const QString& nameToMakeCurrent, bool manuallyEntered) { if (panel->syncBrowseButton->state() == SYNCBROWSE_CD) { //do sync-browse stuff.... if(syncURL.isEmpty()) syncURL = panel->otherPanel()->virtualPath(); QString relative = QDir(panel->virtualPath().path() + '/').relativeFilePath(url.path()); syncURL.setPath(QDir::cleanPath(syncURL.path() + '/' + relative)); panel->otherPanel()->gui->setLocked(false); otherFunc()->openUrlInternal(syncURL, nameToMakeCurrent, false, false, false); } openUrlInternal(url, nameToMakeCurrent, false, false, manuallyEntered); } void ListPanelFunc::immediateOpenUrl(const QUrl &url, bool disableLock) { openUrlInternal(url, QString(), true, disableLock, false); } void ListPanelFunc::openUrlInternal(const QUrl &url, const QString& nameToMakeCurrent, bool immediately, bool disableLock, bool manuallyEntered) { QUrl cleanUrl = cleanPath(url); if (!disableLock && panel->isLocked() && !files()->vfs_getOrigin().matches(cleanUrl, QUrl::StripTrailingSlash)) { panel->_manager->newTab(url); urlManuallyEntered = false; return; } urlManuallyEntered = manuallyEntered; history->add(cleanUrl, nameToMakeCurrent); if(immediately) doRefresh(); else refresh(); } void ListPanelFunc::refresh() { panel->inlineRefreshCancel(); delayTimer.start(0); // to avoid qApp->processEvents() deadlock situaltion } void ListPanelFunc::doRefresh() { _refreshing = true; delayTimer.stop(); QUrl url = history->currentUrl(); if(!url.isValid()) { //FIXME go back in history here ? panel->slotStartUpdate(); // refresh the panel urlManuallyEntered = false; return ; } panel->inlineRefreshCancel(); // if we are not refreshing to current URL bool isEqualUrl = files()->vfs_getOrigin().matches(url, QUrl::StripTrailingSlash); if (!isEqualUrl) { panel->setCursor(Qt::WaitCursor); panel->view->clearSavedSelection(); } if(panel->vfsError) panel->vfsError->hide(); bool refreshFailed = false; while (true) { QString tmp; if (refreshFailed) { tmp = history->currentUrl().fileName(); history->goForward(); QUrl t = history->currentUrl(); QString protocol = t.scheme(); if (protocol != QStringLiteral("file") && KProtocolInfo::protocolClass(protocol).toLower() == QStringLiteral(":local")) { t.setScheme("file"); history->setCurrentUrl(t); panel->vfsError->hide(); } else { history->goBack(); } } QUrl u = history->currentUrl(); isEqualUrl = files()->vfs_getOrigin().matches(u, QUrl::StripTrailingSlash); vfs* v = KrVfsHandler::getVfs(u, panel, files()); v->setParentWindow(krMainWindow); v->setMountMan(&krMtMan); if (v != vfsP) { panel->view->setFiles(0); // disconnect older signals disconnect(vfsP, 0, panel, 0); if (vfsP->vfs_canDelete()) delete vfsP; else { connect(vfsP, SIGNAL(deleteAllowed()), vfsP, SLOT(deleteLater())); vfsP->vfs_requestDelete(); } vfsP = v; // v != 0 so this is safe } else { if (vfsP->vfs_isBusy()) { delayTimer.start(100); /* if vfs is busy try refreshing later */ return; } } // (re)connect vfs signals disconnect(files(), 0, panel, 0); connect(files(), SIGNAL(startUpdate()), panel, SLOT(slotStartUpdate())); connect(files(), SIGNAL(incrementalRefreshFinished(const QUrl&)), panel, SLOT(slotGetStats(const QUrl&))); connect(files(), SIGNAL(startJob(KIO::Job*)), panel, SLOT(slotJobStarted(KIO::Job*))); connect(files(), SIGNAL(error(QString)), panel, SLOT(slotVfsError(QString))); panel->view->setFiles(files()); if(isSyncing(url)) vfsP->vfs_setQuiet(true); if(!history->currentItem().isEmpty() && isEqualUrl) { // if the url we're refreshing into is the current one, then the // partial refresh will not generate the needed signals to actually allow the // view to use nameToMakeCurrent. do it here instead (patch by Thomas Jarosch) panel->view->setCurrentItem(history->currentItem()); panel->view->makeItemVisible(panel->view->getCurrentKrViewItem()); } if (!tmp.isEmpty()) panel->view->setNameToMakeCurrent(tmp); else panel->view->setNameToMakeCurrent(history->currentItem()); int savedHistoryState = history->state(); if (vfsP->vfs_refresh(u)) { // update the history and address bar, as the actual url might differ from the one requested history->setCurrentUrl(vfsP->vfs_getOrigin()); panel->urlNavigator->setLocationUrl(vfsP->vfs_getOrigin()); break; // we have a valid refreshed URL now } refreshFailed = true; panel->view->setNameToMakeCurrent(QString()); if(history->state() != savedHistoryState) // don't go back if the history was touched break; // prevent repeated error messages if (vfsP->vfs_isDeleting()) break; if(!history->goBack()) { // put the root dir to the beginning of history, if it's not there yet if (!u.matches(QUrl::fromLocalFile(ROOT_DIR), QUrl::StripTrailingSlash)) history->pushBackRoot(); else break; } vfsP->vfs_setQuiet(true); } vfsP->vfs_setQuiet(false); panel->view->setNameToMakeCurrent(QString()); panel->setCursor(Qt::ArrowCursor); // on local file system change the working directory if (files() ->vfs_getType() == vfs::VFS_NORMAL) QDir::setCurrent(KrServices::urlToLocalPath(files()->vfs_getOrigin())); // see if the open url operation failed, and if so, // put the attempted url in the navigator bar and let the user change it if (refreshFailed) { if(isSyncing(url)) panel->otherPanel()->gui->syncBrowseButton->setChecked(false); else if(urlManuallyEntered) { panel->urlNavigator->setLocationUrl(url); if(panel == ACTIVE_PANEL) panel->editLocation(); } } if(otherFunc()->otherFunc() == this) // not true if our tab is not active otherFunc()->syncURL = QUrl(); urlManuallyEntered = false; refreshActions(); _refreshing = false; } void ListPanelFunc::redirectLink() { if (files() ->vfs_getType() != vfs::VFS_NORMAL) { KMessageBox::sorry(krMainWindow, i18n("You can edit links only on local file systems")); return ; } vfile *vf = files() ->vfs_search(panel->getCurrentName()); if (!vf) return ; QString file = files() ->vfs_getFile(vf->vfile_getName()).path(); QString currentLink = vf->vfile_getSymDest(); if (currentLink.isEmpty()) { KMessageBox::sorry(krMainWindow, i18n("The current file is not a link, so it cannot be redirected.")); return ; } // ask the user for a new destination bool ok = false; QString newLink = QInputDialog::getText(krMainWindow, i18n("Link Redirection"), i18n("Please enter the new link destination:"), QLineEdit::Normal, currentLink, &ok); // if the user canceled - quit if (!ok || newLink == currentLink) return ; // delete the current link if (unlink(file.toLocal8Bit()) == -1) { KMessageBox::sorry(krMainWindow, i18n("Cannot remove old link: %1", file)); return ; } // try to create a new symlink if (symlink(newLink.toLocal8Bit(), file.toLocal8Bit()) == -1) { KMessageBox:: /* --=={ Patch by Heiner }==-- */sorry(krMainWindow, i18n("Failed to create a new link: %1", file)); return ; } } void ListPanelFunc::krlink(bool sym) { if (files() ->vfs_getType() != vfs::VFS_NORMAL) { KMessageBox::sorry(krMainWindow, i18n("You can create links only on local file systems")); return ; } QString name = panel->getCurrentName(); // ask the new link name.. bool ok = false; QString linkName = QInputDialog::getText(krMainWindow, i18n("New Link"), i18n("Create a new link to: %1", name), QLineEdit::Normal, name, &ok); // if the user canceled - quit if (!ok || linkName == name) return ; // if the name is already taken - quit if (files() ->vfs_search(linkName) != 0) { KMessageBox::sorry(krMainWindow, i18n("A folder or a file with this name already exists.")); return ; } if (linkName.left(1) != "/") linkName = files() ->vfs_workingDir() + '/' + linkName; if (linkName.contains("/")) name = files() ->vfs_getFile(name).path(); if (sym) { if (symlink(name.toLocal8Bit(), linkName.toLocal8Bit()) == -1) KMessageBox::sorry(krMainWindow, i18n("Failed to create a new symlink '%1' to: '%2'", linkName, name)); } else { if (link(name.toLocal8Bit(), linkName.toLocal8Bit()) == -1) KMessageBox::sorry(krMainWindow, i18n("Failed to create a new link '%1' to '%2'", linkName, name)); } } void ListPanelFunc::view() { QString fileName = panel->getCurrentName(); if (fileName.isNull()) return ; // if we're trying to view a directory, just exit vfile * vf = files() ->vfs_search(fileName); if (!vf || vf->vfile_isDir()) return ; if (!vf->vfile_isReadable()) { KMessageBox::sorry(0, i18n("No permissions to view this file.")); return ; } // call KViewer. KrViewer::view(files() ->vfs_getFile(fileName)); // nothing more to it! } void ListPanelFunc::viewDlg() { // ask the user for a url to view QUrl dest = KChooseDir::getFile(i18n("Enter a URL to view:"), panel->virtualPath(), panel->virtualPath()); if (dest.isEmpty()) return ; // the user canceled KrViewer::view(dest); // view the file } void ListPanelFunc::terminal() { - SLOTS->runTerminal(panel->realPath(), QStringList()); + SLOTS->runTerminal(panel->realPath()); } void ListPanelFunc::edit() { KFileItem tmp; if (fileToCreate.isEmpty()) { QString name = panel->getCurrentName(); if (name.isNull()) return; fileToCreate = files()->vfs_getFile(name); } tmp = KFileItem(fileToCreate); if (tmp.isDir()) { KMessageBox::sorry(krMainWindow, i18n("You cannot edit a folder")); fileToCreate = QUrl(); return ; } if (!tmp.isReadable()) { KMessageBox::sorry(0, i18n("No permissions to edit this file.")); fileToCreate = QUrl(); return; } KrViewer::edit(fileToCreate); fileToCreate = QUrl(); } void ListPanelFunc::editNew() { if(!fileToCreate.isEmpty()) return; // ask the user for the filename to edit fileToCreate = KChooseDir::getFile(i18n("Enter the filename to edit:"), panel->virtualPath(), panel->virtualPath()); if(fileToCreate.isEmpty()) return ; // the user canceled // if the file exists, edit it instead of creating a new one QFile f(fileToCreate.toLocalFile()); if(f.exists()) { edit(); } else { QTemporaryFile *tempFile = new QTemporaryFile; tempFile->open(); KIO::CopyJob *job = KIO::copy(QUrl::fromLocalFile(tempFile->fileName()), fileToCreate); job->setUiDelegate(0); job->setDefaultPermissions(true); connect(job, SIGNAL(result(KJob*)), SLOT(slotFileCreated(KJob*))); connect(job, SIGNAL(result(KJob*)), tempFile, SLOT(deleteLater())); } } void ListPanelFunc::slotFileCreated(KJob *job) { if(!job->error() || job->error() == KIO::ERR_FILE_ALREADY_EXIST) { KrViewer::edit(fileToCreate); if(KIO::upUrl(fileToCreate).matches(panel->virtualPath(), QUrl::StripTrailingSlash)) refresh(); else if(KIO::upUrl(fileToCreate).matches(panel->otherPanel()->virtualPath(), QUrl::StripTrailingSlash)) otherFunc()->refresh(); } else KMessageBox::sorry(krMainWindow, job->errorString()); fileToCreate = QUrl(); } void ListPanelFunc::moveFiles(bool enqueue) { PreserveMode pmode = PM_DEFAULT; bool queue = enqueue; QStringList fileNames; panel->getSelectedNames(&fileNames); if (fileNames.isEmpty()) return ; // safety QUrl dest = panel->otherPanel()->virtualPath(); QUrl virtualBaseURL; KConfigGroup group(krConfig, "Advanced"); if (group.readEntry("Confirm Move", _ConfirmMove)) { bool preserveAttrs = group.readEntry("PreserveAttributes", _PreserveAttributes); QString s; if (fileNames.count() == 1) s = i18n("Move %1 to:", fileNames.first()); else s = i18np("Move %1 file to:", "Move %1 files to:", fileNames.count()); // ask the user for the copy dest virtualBaseURL = getVirtualBaseURL(); dest = KChooseDir::getDir(s, dest, panel->virtualPath(), queue, preserveAttrs, virtualBaseURL); if (dest.isEmpty()) return ; // the user canceled if (preserveAttrs) pmode = PM_PRESERVE_ATTR; else pmode = PM_NONE; } if (fileNames.isEmpty()) return ; // nothing to copy QList fileUrls = files() ->vfs_getFiles(fileNames); // after the delete return the cursor to the first unmarked // file above the current item; panel->prepareToDelete(); if (queue) { KIOJobWrapper *job = 0; if (!virtualBaseURL.isEmpty()) { job = KIOJobWrapper::virtualMove(&fileNames, files(), dest, virtualBaseURL, pmode, true); job->connectTo(SIGNAL(result(KJob*)), this, SLOT(refresh())); if (dest.matches(panel->otherPanel()->virtualPath(), QUrl::StripTrailingSlash)) job->connectTo(SIGNAL(result(KJob*)), panel->otherPanel()->func, SLOT(refresh())); } else { // you can rename only *one* file not a batch, // so a batch dest must alwayes be a directory if (fileNames.count() > 1) { dest = vfs::ensureTrailingSlash(dest); } job = KIOJobWrapper::move(pmode, fileUrls, dest, true); job->setAutoErrorHandlingEnabled(true); // refresh our panel when done job->connectTo(SIGNAL(result(KJob*)), this, SLOT(refresh())); if (dest.matches(panel->virtualPath(), QUrl::StripTrailingSlash) || KIO::upUrl(dest).matches(panel->virtualPath(), QUrl::StripTrailingSlash)) // refresh our panel when done job->connectTo(SIGNAL(result(KJob*)), this, SLOT(refresh())); } QueueManager::currentQueue()->enqueue(job); } else if (!virtualBaseURL.isEmpty()) { // keep the directory structure for virtual paths VirtualCopyJob *vjob = new VirtualCopyJob(&fileNames, files(), dest, virtualBaseURL, pmode, KIO::CopyJob::Move, true); connect(vjob, SIGNAL(result(KJob*)), this, SLOT(refresh())); if (dest.matches(panel->otherPanel()->virtualPath(), QUrl::StripTrailingSlash)) connect(vjob, SIGNAL(result(KJob*)), panel->otherPanel()->func, SLOT(refresh())); } // if we are not moving to the other panel : else if (!dest.matches(panel->otherPanel()->virtualPath(), QUrl::StripTrailingSlash)) { // you can rename only *one* file not a batch, // so a batch dest must alwayes be a directory if (fileNames.count() > 1) { dest = vfs::ensureTrailingSlash(dest); } KIO::Job* job = PreservingCopyJob::createCopyJob(pmode, fileUrls, dest, KIO::CopyJob::Move, false, true); job->ui()->setAutoErrorHandlingEnabled(true); // refresh our panel when done connect(job, SIGNAL(result(KJob*)), this, SLOT(refresh())); // and if needed the other panel as well if (dest.matches(panel->otherPanel()->virtualPath(), QUrl::StripTrailingSlash)) connect(job, SIGNAL(result(KJob*)), panel->otherPanel()->func, SLOT(refresh())); } else { // let the other panel do the dirty job //check if copy is supported if (!otherFunc() ->files() ->vfs_isWritable()) { KMessageBox::sorry(krMainWindow, i18n("You cannot move files to this file system")); return ; } // finally.. otherFunc() ->files() ->vfs_addFiles(fileUrls, KIO::CopyJob::Move, files(), "", pmode); } if(KConfigGroup(krConfig, "Look&Feel").readEntry("UnselectBeforeOperation", _UnselectBeforeOperation)) { panel->view->saveSelection(); panel->view->unselectAll(); } } // called from SLOTS to begin the renaming process void ListPanelFunc::rename() { panel->view->renameCurrentItem(); } // called by signal itemRenamed() from the view to complete the renaming process void ListPanelFunc::rename(const QString &oldname, const QString &newname) { if (oldname == newname) return ; // do nothing panel->view->setNameToMakeCurrentIfAdded(newname); // as always - the vfs do the job files() ->vfs_rename(oldname, newname); } void ListPanelFunc::mkdir() { // ask the new dir name.. // suggested name is the complete name for the directories // while filenames are suggested without their extension QString suggestedName = panel->getCurrentName(); if (!suggestedName.isEmpty() && !files()->vfs_search(suggestedName)->vfile_isDir()) suggestedName = QFileInfo(suggestedName).completeBaseName(); QString dirName = QInputDialog::getText(krMainWindow, i18n("New folder"), i18n("Folder's name:"), QLineEdit::Normal, suggestedName); // if the user canceled - quit if (dirName.isEmpty()) return ; QStringList dirTree = dirName.split('/'); for (QStringList::Iterator it = dirTree.begin(); it != dirTree.end(); ++it) { if (*it == ".") continue; if (*it == "..") { immediateOpenUrl(QUrl::fromUserInput(*it, QString(), QUrl::AssumeLocalFile)); continue; } // check if the name is already taken if (files() ->vfs_search(*it)) { // if it is the last dir to be created - quit if (*it == dirTree.last()) { KMessageBox::sorry(krMainWindow, i18n("A folder or a file with this name already exists.")); return ; } // else go into this dir else { immediateOpenUrl(QUrl::fromUserInput(*it, QString(), QUrl::AssumeLocalFile)); continue; } } panel->view->setNameToMakeCurrent(*it); // as always - the vfs do the job files() ->vfs_mkdir(*it); if (dirTree.count() > 1) immediateOpenUrl(QUrl::fromUserInput(*it, QString(), QUrl::AssumeLocalFile)); } // for } QUrl ListPanelFunc::getVirtualBaseURL() { if (files()->vfs_getType() != vfs::VFS_VIRT || otherFunc()->files()->vfs_getType() == vfs::VFS_VIRT) return QUrl(); QStringList fileNames; panel->getSelectedNames(&fileNames); QList fileUrls = files() ->vfs_getFiles(fileNames); if (fileUrls.count() == 0) return QUrl(); QUrl base = KIO::upUrl(fileUrls.first()); if (base.scheme() == QStringLiteral("virt")) // is it a virtual subfolder? return QUrl(); // --> cannot keep the directory structure for (int i = 1; i < fileUrls.count(); i++) { if (base.isParentOf(fileUrls.at(i))) continue; if (base.scheme() != fileUrls.at(i).scheme()) return QUrl(); do { QUrl oldBase = base; base = KIO::upUrl(base); if (oldBase.matches(base, QUrl::StripTrailingSlash)) return QUrl(); if (base.isParentOf(fileUrls.at(i))) break; } while (true); } return base; } void ListPanelFunc::copyFiles(bool enqueue) { PreserveMode pmode = PM_DEFAULT; bool queue = enqueue; QStringList fileNames; panel->getSelectedNames(&fileNames); if (fileNames.isEmpty()) return ; // safety QUrl dest = panel->otherPanel()->virtualPath(); QUrl virtualBaseURL; // confirm copy KConfigGroup group(krConfig, "Advanced"); if (group.readEntry("Confirm Copy", _ConfirmCopy)) { bool preserveAttrs = group.readEntry("PreserveAttributes", _PreserveAttributes); QString s; if (fileNames.count() == 1) s = i18n("Copy %1 to:", fileNames.first()); else s = i18np("Copy %1 file to:", "Copy %1 files to:", fileNames.count()); // ask the user for the copy dest virtualBaseURL = getVirtualBaseURL(); dest = KChooseDir::getDir(s, dest, panel->virtualPath(), queue, preserveAttrs, virtualBaseURL); if (dest.isEmpty()) return ; // the user canceled if (preserveAttrs) pmode = PM_PRESERVE_ATTR; else pmode = PM_NONE; } QList fileUrls = files() ->vfs_getFiles(fileNames); if (queue) { KIOJobWrapper *job = 0; if (!virtualBaseURL.isEmpty()) { job = KIOJobWrapper::virtualCopy(&fileNames, files(), dest, virtualBaseURL, pmode, true); job->connectTo(SIGNAL(result(KJob*)), this, SLOT(refresh())); if (dest.matches(panel->otherPanel()->virtualPath(), QUrl::StripTrailingSlash)) job->connectTo(SIGNAL(result(KJob*)), panel->otherPanel()->func, SLOT(refresh())); } else { // you can rename only *one* file not a batch, // so a batch dest must alwayes be a directory if (fileNames.count() > 1) { dest = vfs::ensureTrailingSlash(dest); } job = KIOJobWrapper::copy(pmode, fileUrls, dest, true); job->setAutoErrorHandlingEnabled(true); if (dest.matches(panel->virtualPath(), QUrl::StripTrailingSlash) || KIO::upUrl(dest).matches(panel->virtualPath(), QUrl::StripTrailingSlash)) // refresh our panel when done job->connectTo(SIGNAL(result(KJob*)), this, SLOT(refresh())); } QueueManager::currentQueue()->enqueue(job); } else if (!virtualBaseURL.isEmpty()) { // keep the directory structure for virtual paths VirtualCopyJob *vjob = new VirtualCopyJob(&fileNames, files(), dest, virtualBaseURL, pmode, KIO::CopyJob::Copy, true); connect(vjob, SIGNAL(result(KJob*)), this, SLOT(refresh())); if (dest.matches(panel->otherPanel()->virtualPath(), QUrl::StripTrailingSlash)) connect(vjob, SIGNAL(result(KJob*)), panel->otherPanel()->func, SLOT(refresh())); } // if we are not copying to the other panel : else if (!dest.matches(panel->otherPanel()->virtualPath(), QUrl::StripTrailingSlash)) { // you can rename only *one* file not a batch, // so a batch dest must alwayes be a directory if (fileNames.count() > 1) { dest = vfs::ensureTrailingSlash(dest); } KIO::Job* job = PreservingCopyJob::createCopyJob(pmode, fileUrls, dest, KIO::CopyJob::Copy, false, true); job->ui()->setAutoErrorHandlingEnabled(true); if (dest.matches(panel->virtualPath(), QUrl::StripTrailingSlash) || KIO::upUrl(dest).matches(panel->virtualPath(), QUrl::StripTrailingSlash)) // refresh our panel when done connect(job, SIGNAL(result(KJob*)), this, SLOT(refresh())); // let the other panel do the dirty job } else { //check if copy is supported if (!otherFunc() ->files() ->vfs_isWritable()) { KMessageBox::sorry(krMainWindow, i18n("You cannot copy files to this file system")); return ; } // finally.. otherFunc() ->files() ->vfs_addFiles(fileUrls, KIO::CopyJob::Copy, 0, "", pmode); } if(KConfigGroup(krConfig, "Look&Feel").readEntry("UnselectBeforeOperation", _UnselectBeforeOperation)) { panel->view->saveSelection(); panel->view->unselectAll(); } } void ListPanelFunc::deleteFiles(bool reallyDelete) { // check that the you have write perm if (!files() ->vfs_isWritable()) { KMessageBox::sorry(krMainWindow, i18n("You do not have write permission to this folder")); return ; } // first get the selected file names list QStringList fileNames; panel->getSelectedNames(&fileNames); if (fileNames.isEmpty()) return ; KConfigGroup gg(krConfig, "General"); bool trash = gg.readEntry("Move To Trash", _MoveToTrash); // now ask the user if he want to delete: KConfigGroup group(krConfig, "Advanced"); if (group.readEntry("Confirm Delete", _ConfirmDelete)) { QString s, b; if (!reallyDelete && trash && files() ->vfs_getType() == vfs::VFS_NORMAL) { s = i18np("Do you really want to move this item to the trash?", "Do you really want to move these %1 items to the trash?", fileNames.count()); b = i18n("&Trash"); } else if (files() ->vfs_getType() == vfs::VFS_VIRT && files()->vfs_getOrigin().matches(QUrl("virt:/"), QUrl::StripTrailingSlash)) { s = i18np("Do you really want to delete this virtual item (physical files stay untouched)?", "Do you really want to delete these %1 virtual items (physical files stay untouched)?", fileNames.count()); b = i18n("&Delete"); } else if (files() ->vfs_getType() == vfs::VFS_VIRT) { s = i18np("Do you really want to delete this item physically (not just removing it from the virtual items)?", "Do you really want to delete these %1 items physically (not just removing them from the virtual items)?", fileNames.count()); b = i18n("&Delete"); } else { s = i18np("Do you really want to delete this item?", "Do you really want to delete these %1 items?", fileNames.count()); b = i18n("&Delete"); } // show message // note: i'm using continue and not yes/no because the yes/no has cancel as default button if (KMessageBox::warningContinueCancelList(krMainWindow, s, fileNames, i18n("Warning"), KGuiItem(b)) != KMessageBox::Continue) return ; } //we want to warn the user about non empty dir // and files he don't have permission to delete bool emptyDirVerify = group.readEntry("Confirm Unempty Dir", _ConfirmUnemptyDir); emptyDirVerify = ((emptyDirVerify) && (files() ->vfs_getType() == vfs::VFS_NORMAL)); QDir dir; for (QStringList::Iterator name = fileNames.begin(); name != fileNames.end();) { vfile * vf = files() ->vfs_search(*name); // verify non-empty dirs delete... (only for normal vfs) if (vf && emptyDirVerify && vf->vfile_isDir() && !vf->vfile_isSymLink()) { dir.setPath(panel->virtualPath().path() + '/' + (*name)); if (dir.entryList(QDir::TypeMask | QDir::System | QDir::Hidden).count() > 2) { switch (KMessageBox::warningYesNoCancel(krMainWindow, i18n("

Folder %1 is not empty.

Skip this one or delete all?

", *name), QString(), KGuiItem(i18n("&Skip")), KGuiItem(i18n("&Delete All")))) { case KMessageBox::No : emptyDirVerify = false; break; case KMessageBox::Yes : name = fileNames.erase(name); continue; default : return ; } } } ++name; } if (fileNames.count() == 0) return ; // nothing to delete // after the delete return the cursor to the first unmarked // file above the current item; panel->prepareToDelete(); // let the vfs do the job... files() ->vfs_delFiles(fileNames, reallyDelete); } void ListPanelFunc::goInside(const QString& name) { openFileNameInternal(name, false); } void ListPanelFunc::runCommand(QString cmd) { krOut << "Run command: " << cmd; QString workdir = panel->virtualPath().isLocalFile() ? panel->virtualPath().path() : QDir::homePath(); if(!KRun::runCommand(cmd, krMainWindow, workdir)) KMessageBox::error(0, i18n("Could not start %1", cmd)); } void ListPanelFunc::runService(const KService &service, QList urls) { krOut << "Run service: " << service.name(); KIO::DesktopExecParser parser(service, urls); QStringList args = parser.resultingArguments(); if (!args.isEmpty()) runCommand(KShell::joinArgs(args)); else KMessageBox::error(0, i18n("%1 cannot open %2", service.name(), KrServices::toStringList(urls).join(", "))); } void ListPanelFunc::displayOpenWithDialog(QList urls) { KRun::displayOpenWithDialog(urls, krMainWindow); } QUrl ListPanelFunc::browsableArchivePath(const QString &filename) { vfile *vf = files()->vfs_search(filename); QUrl url = files()->vfs_getFile(filename); QString mime = vf->vfile_getMime(); if(url.isLocalFile()) { QString protocol = KrServices::registeredProtocol(mime); if(!protocol.isEmpty()) { url.setScheme(protocol); return url; } } return QUrl(); } // this is done when you double click on a file void ListPanelFunc::execute(const QString& name) { openFileNameInternal(name, true); } void ListPanelFunc::pack() { QStringList fileNames; panel->getSelectedNames(&fileNames); if (fileNames.isEmpty()) return ; // safety if (fileNames.count() == 0) return ; // nothing to pack // choose the default name QString defaultName = panel->virtualPath().fileName(); if (defaultName.isEmpty()) defaultName = "pack"; if (fileNames.count() == 1) defaultName = fileNames.first(); // ask the user for archive name and packer new PackGUI(defaultName, panel->otherPanel()->virtualPath().toDisplayString(QUrl::PreferLocalFile | QUrl::StripTrailingSlash), fileNames.count(), fileNames.first()); if (PackGUI::type.isEmpty()) { return ; // the user canceled } // check for partial URLs if (!PackGUI::destination.contains(":/") && !PackGUI::destination.startsWith('/')) { PackGUI::destination = panel->virtualPath().toDisplayString() + '/' + PackGUI::destination; } QString destDir = PackGUI::destination; if (!destDir.endsWith('/')) destDir += '/'; bool packToOtherPanel = (destDir == vfs::ensureTrailingSlash(panel->otherPanel()->virtualPath()).toDisplayString(QUrl::PreferLocalFile)); QUrl destURL = QUrl::fromUserInput(destDir + PackGUI::filename + '.' + PackGUI::type, QString(), QUrl::AssumeLocalFile); if (destURL.isLocalFile() && QFile::exists(destURL.path())) { QString msg = i18n("

The archive %1.%2 already exists. Do you want to overwrite it?

All data in the previous archive will be lost.

", PackGUI::filename, PackGUI::type); if (PackGUI::type == "zip") { msg = i18n("

The archive %1.%2 already exists. Do you want to overwrite it?

Zip will replace identically named entries in the zip archive or add entries for new names.

", PackGUI::filename, PackGUI::type); } if (KMessageBox::warningContinueCancel(krMainWindow, msg, QString(), KGuiItem(i18n("&Overwrite"))) == KMessageBox::Cancel) return ; // stop operation } else if (destURL.scheme() == QStringLiteral("virt")) { KMessageBox::error(krMainWindow, i18n("Cannot pack files onto a virtual destination.")); return; } if (PackGUI::queue) { KIOJobWrapper *job = KIOJobWrapper::pack(files()->vfs_getOrigin(), destURL, fileNames, PackGUI::type, PackGUI::extraProps, true); job->setAutoErrorHandlingEnabled(true); if (packToOtherPanel) job->connectTo(SIGNAL(result(KJob*)), panel->otherPanel()->func, SLOT(refresh())); QueueManager::currentQueue()->enqueue(job); } else { PackJob * job = PackJob::createPacker(files()->vfs_getOrigin(), destURL, fileNames, PackGUI::type, PackGUI::extraProps); job->setUiDelegate(new KIO::JobUiDelegate()); KIO::getJobTracker()->registerJob(job); job->ui()->setAutoErrorHandlingEnabled(true); if (packToOtherPanel) connect(job, SIGNAL(result(KJob*)), panel->otherPanel()->func, SLOT(refresh())); } } void ListPanelFunc::testArchive() { QStringList fileNames; panel->getSelectedNames(&fileNames); if (fileNames.isEmpty()) return ; // safety TestArchiveJob * job = TestArchiveJob::testArchives(files()->vfs_getOrigin(), fileNames); job->setUiDelegate(new KIO::JobUiDelegate()); KIO::getJobTracker()->registerJob(job); job->ui()->setAutoErrorHandlingEnabled(true); } void ListPanelFunc::unpack() { QStringList fileNames; panel->getSelectedNames(&fileNames); if (fileNames.isEmpty()) return ; // safety QString s; if (fileNames.count() == 1) s = i18n("Unpack %1 to:", fileNames[0]); else s = i18np("Unpack %1 file to:", "Unpack %1 files to:", fileNames.count()); // ask the user for the copy dest bool queue = false; QUrl dest = KChooseDir::getDir(s, panel->otherPanel()->virtualPath(), panel->virtualPath(), queue); if (dest.isEmpty()) return ; // the user canceled bool packToOtherPanel = (dest.matches(panel->otherPanel()->virtualPath(), QUrl::StripTrailingSlash)); if (queue) { KIOJobWrapper *job = KIOJobWrapper::unpack(files()->vfs_getOrigin(), dest, fileNames, true); job->setAutoErrorHandlingEnabled(true); if (packToOtherPanel) job->connectTo(SIGNAL(result(KJob*)), panel->otherPanel()->func, SLOT(refresh())); QueueManager::currentQueue()->enqueue(job); } else { UnpackJob * job = UnpackJob::createUnpacker(files()->vfs_getOrigin(), dest, fileNames); job->setUiDelegate(new KIO::JobUiDelegate()); KIO::getJobTracker()->registerJob(job); job->ui()->setAutoErrorHandlingEnabled(true); if (packToOtherPanel) connect(job, SIGNAL(result(KJob*)), panel->otherPanel()->func, SLOT(refresh())); } } // a small ugly function, used to prevent duplication of EVERY line of // code (maybe except 3) from createChecksum and matchChecksum static void checksum_wrapper(ListPanel *panel, QStringList& args, bool &folders) { KrViewItemList items; panel->view->getSelectedKrViewItems(&items); if (items.isEmpty()) return ; // nothing to do // determine if we need recursive mode (md5deep) folders = false; for (KrViewItemList::Iterator it = items.begin(); it != items.end(); ++it) { if (panel->func->getVFile(*it)->vfile_isDir()) { folders = true; args << (*it)->name(); } else args << (*it)->name(); } } void ListPanelFunc::createChecksum() { QStringList args; bool folders; checksum_wrapper(panel, args, folders); CreateChecksumDlg dlg(args, folders, panel->realPath()); } void ListPanelFunc::matchChecksum() { QStringList args; bool folders; checksum_wrapper(panel, args, folders); QList checksumFiles = files()->vfs_search( KRQuery(MatchChecksumDlg::checksumTypesFilter) ); MatchChecksumDlg dlg(args, folders, panel->realPath(), (checksumFiles.size() == 1 ? checksumFiles[0]->vfile_getUrl().toDisplayString(QUrl::PreferLocalFile) : QString())); } void ListPanelFunc::calcSpace() { QStringList items; panel->view->getSelectedItems(&items); if (items.isEmpty()) { panel->view->selectAllIncludingDirs(); panel->view->getSelectedItems(&items); if (items.isEmpty()) return ; // nothing to do } QPointer calc = new KrCalcSpaceDialog(krMainWindow, panel, items, false); calc->exec(); panel->slotUpdateTotals(); delete calc; } bool ListPanelFunc::calcSpace(const QStringList & items, KIO::filesize_t & totalSize, unsigned long & totalFiles, unsigned long & totalDirs) { QPointer calc = new KrCalcSpaceDialog(krMainWindow, panel, items, true); calc->exec(); calc->getStats(totalSize, totalFiles, totalDirs); bool calcWasCanceled = calc->wasCanceled(); delete calc; return !calcWasCanceled; } void ListPanelFunc::calcSpace(KrViewItem *item) { // // NOTE: this is buggy incase somewhere down in the folder we're calculating, // there's a folder we can't enter (permissions). in that case, the returned // size will not be correct. // KIO::filesize_t totalSize = 0; unsigned long totalFiles = 0, totalDirs = 0; QStringList items; items.push_back(item->name()); if (calcSpace(items, totalSize, totalFiles, totalDirs)) { // did we succeed to calcSpace? we'll fail if we don't have permissions if (totalSize != 0) { // just mark it, and bail out item->setSize(totalSize); item->redraw(); } } } void ListPanelFunc::FTPDisconnect() { // you can disconnect only if connected ! if (files() ->vfs_getType() == vfs::VFS_FTP) { panel->_actions->actFTPDisconnect->setEnabled(false); panel->view->setNameToMakeCurrent(QString()); openUrl(QUrl::fromLocalFile(panel->realPath())); // open the last local URL } } void ListPanelFunc::newFTPconnection() { QUrl url = KRSpWidgets::newFTP(); // if the user canceled - quit if (url.isEmpty()) return ; panel->_actions->actFTPDisconnect->setEnabled(true); openUrl(url); } void ListPanelFunc::properties() { QStringList names; panel->getSelectedNames(&names); if (names.isEmpty()) return ; // no names... KFileItemList fi; for (int i = 0 ; i < names.count() ; ++i) { vfile* vf = files() ->vfs_search(names[ i ]); if (!vf) continue; QUrl url = files()->vfs_getFile(names[i]); fi.push_back(KFileItem(vf->vfile_getEntry(), url)); } if (fi.isEmpty()) return ; // Show the properties dialog KPropertiesDialog *dlg = new KPropertiesDialog(fi, krMainWindow); connect(dlg, SIGNAL(applied()), SLOT(refresh())); dlg->show(); } void ListPanelFunc::refreshActions() { panel->updateButtons(); if(ACTIVE_PANEL != panel) return; vfs::VFS_TYPE vfsType = files() ->vfs_getType(); QString protocol = files()->vfs_getOrigin().scheme(); krRemoteEncoding->setEnabled(protocol == "ftp" || protocol == "sftp" || protocol == "fish" || protocol == "krarc"); //krMultiRename->setEnabled( vfsType == vfs::VFS_NORMAL ); // batch rename //krProperties ->setEnabled( vfsType == vfs::VFS_NORMAL || vfsType == vfs::VFS_FTP ); // file properties /* krUnpack->setEnabled(true); // unpack archive krTest->setEnabled(true); // test archive krSelect->setEnabled(true); // select a group by filter krSelectAll->setEnabled(true); // select all files krUnselect->setEnabled(true); // unselect by filter krUnselectAll->setEnabled( true); // remove all selections krInvert->setEnabled(true); // invert the selection krFTPConnect->setEnabled(true); // connect to an ftp krFTPNew->setEnabled(true); // create a new connection krAllFiles->setEnabled(true); // show all files in list krCustomFiles->setEnabled(true); // show a custom set of files krRoot->setEnabled(true); // go all the way up krExecFiles->setEnabled(true); // show only executables */ panel->_actions->setViewActions[panel->panelType]->setChecked(true); panel->_actions->actFTPDisconnect->setEnabled(vfsType == vfs::VFS_FTP); // disconnect an FTP session panel->_actions->actCreateChecksum->setEnabled(vfsType == vfs::VFS_NORMAL); panel->_actions->actDirUp->setEnabled(!files()->isRoot()); panel->_actions->actRoot->setEnabled(!panel->virtualPath().matches(QUrl::fromLocalFile(ROOT_DIR), QUrl::StripTrailingSlash)); panel->_actions->actHome->setEnabled(!atHome()); panel->_actions->actHistoryBackward->setEnabled(history->canGoBack()); panel->_actions->actHistoryForward->setEnabled(history->canGoForward()); panel->view->op()->emitRefreshActions(); } vfs* ListPanelFunc::files() { if (!vfsP) vfsP = KrVfsHandler::getVfs(QUrl::fromLocalFile("/"), panel, 0); return vfsP; } void ListPanelFunc::clipboardChanged(QClipboard::Mode mode) { if (mode == QClipboard::Clipboard && this == copyToClipboardOrigin) { disconnect(QApplication::clipboard(), 0, this, 0); copyToClipboardOrigin = 0; } } void ListPanelFunc::copyToClipboard(bool move) { QStringList fileNames; panel->getSelectedNames(&fileNames); if (fileNames.isEmpty()) return ; // safety QList fileUrls = files() ->vfs_getFiles(fileNames); QMimeData *mimeData = new QMimeData; mimeData->setData("application/x-kde-cutselection", move ? "1" : "0"); mimeData->setUrls(fileUrls); if (copyToClipboardOrigin) disconnect(QApplication::clipboard(), 0, copyToClipboardOrigin, 0); copyToClipboardOrigin = this; QApplication::clipboard()->setMimeData(mimeData, QClipboard::Clipboard); connect(QApplication::clipboard(), SIGNAL(changed(QClipboard::Mode)), this, SLOT(clipboardChanged(QClipboard::Mode))); } void ListPanelFunc::pasteFromClipboard() { QClipboard * cb = QApplication::clipboard(); ListPanelFunc *origin = 0; if (copyToClipboardOrigin) { disconnect(QApplication::clipboard(), 0, copyToClipboardOrigin, 0); origin = copyToClipboardOrigin; copyToClipboardOrigin = 0; } bool move = false; const QMimeData *data = cb->mimeData(); if (data->hasFormat("application/x-kde-cutselection")) { QByteArray a = data->data("application/x-kde-cutselection"); if (!a.isEmpty()) move = (a.at(0) == '1'); // true if 1 } QList urls = data->urls(); if (urls.isEmpty()) return ; if(origin && KConfigGroup(krConfig, "Look&Feel").readEntry("UnselectBeforeOperation", _UnselectBeforeOperation)) { origin->panel->view->saveSelection(); for(KrViewItem *item = origin->panel->view->getFirst(); item != 0; item = origin->panel->view->getNext(item)) { if (urls.contains(item->getVfile()->vfile_getUrl())) item->setSelected(false); } } files()->vfs_addFiles(urls, move ? KIO::CopyJob::Move : KIO::CopyJob::Copy, otherFunc()->files(), "", PM_DEFAULT); } ListPanelFunc* ListPanelFunc::otherFunc() { return panel->otherPanel()->func; } void ListPanelFunc::historyGotoPos(int pos) { if(history->gotoPos(pos)) refresh(); } void ListPanelFunc::historyBackward() { if(history->goBack()) refresh(); } void ListPanelFunc::historyForward() { if(history->goForward()) refresh(); } void ListPanelFunc::dirUp() { openUrl(KIO::upUrl(files() ->vfs_getOrigin()), files() ->vfs_getOrigin().fileName()); } void ListPanelFunc::home() { openUrl(QUrl::fromLocalFile(QDir::homePath())); } void ListPanelFunc::root() { openUrl(QUrl::fromLocalFile(ROOT_DIR)); } void ListPanelFunc::cdToOtherPanel() { openUrl(panel->otherPanel()->virtualPath()); } void ListPanelFunc::syncOtherPanel() { otherFunc()->openUrl(panel->virtualPath()); } bool ListPanelFunc::atHome() { return QUrl::fromLocalFile(QDir::homePath()).matches(panel->virtualPath(), QUrl::StripTrailingSlash); } diff --git a/krusader/krslots.cpp b/krusader/krslots.cpp index 805fff7f..ab6f757c 100644 --- a/krusader/krslots.cpp +++ b/krusader/krslots.cpp @@ -1,796 +1,793 @@ /*************************************************************************** krslots.cpp ------------------- copyright : (C) 2001 by Shie Erlich & Rafi Yanai email : krusader@users.sourceforge.net web site : http://krusader.sourceforge.net --------------------------------------------------------------------------- Description *************************************************************************** A db dD d8888b. db db .d8888. .d8b. d8888b. d88888b d8888b. 88 ,8P' 88 `8D 88 88 88' YP d8' `8b 88 `8D 88' 88 `8D 88,8P 88oobY' 88 88 `8bo. 88ooo88 88 88 88ooooo 88oobY' 88`8b 88`8b 88 88 `Y8b. 88~~~88 88 88 88~~~~~ 88`8b 88 `88. 88 `88. 88b d88 db 8D 88 88 88 .8D 88. 88 `88. YP YD 88 YD ~Y8888P' `8888Y' YP YP Y8888D' Y88888P 88 YD S o u r c e F i l e *************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #include "krslots.h" // QtCore #include #include #include #include #include #include // QtGui #include #include // QtWidgets #include #include #include #include #include #include #include #include #include #include #ifdef __KJSEMBED__ #include #include "KrJS/krjs.h" #endif #include "KViewer/krviewer.h" #include "Panel/krviewfactory.h" #include "krusader.h" #include "kractions.h" #include "krusaderview.h" #include "Panel/listpanel.h" #include "Panel/krselectionmode.h" #include "Dialogs/krdialogs.h" #include "Dialogs/krspwidgets.h" #include "GUI/krusaderstatus.h" #include "Panel/panelfunc.h" #include "Konfigurator/konfigurator.h" #include "MountMan/kmountman.h" #include "defaults.h" #include "GUI/kfnkeys.h" #include "GUI/kcmdline.h" #include "GUI/terminaldock.h" #include "GUI/syncbrowsebutton.h" #include "GUI/mediabutton.h" #include "GUI/dirhistorybutton.h" #include "VFS/krquery.h" #include "Search/krsearchmod.h" #include "Search/krsearchdialog.h" #include "Locate/locate.h" #include "VFS/vfs.h" #include "VFS/vfile.h" #include "panelmanager.h" #include "Splitter/splittergui.h" #include "Splitter/splitter.h" #include "Splitter/combiner.h" #include "ActionMan/actionman.h" #include "UserMenu/usermenu.h" #include "Panel/panelpopup.h" #include "Dialogs/krspecialwidgets.h" #include "DiskUsage/diskusagegui.h" #include "krservices.h" #include "Panel/krviewitem.h" #include "Queue/queuedialog.h" #include "krtrashhandler.h" #include "BookMan/krbookmarkhandler.h" #include "BookMan/krbookmarkbutton.h" #ifdef SYNCHRONIZER_ENABLED #include "Synchronizer/synchronizergui.h" #endif #define ACTIVE_VIEW _mainWindow->activeView() KRslots::KRslots(QObject *parent) : QObject(parent), _mainWindow(krApp) { } void KRslots::sendFileByEmail(const QList &urls) { if (urls.count() == 0) { KMessageBox::error(0, i18n("No selected files to send.")); return; } QString mailProg; QStringList lst = KrServices::supportedTools(); if (lst.contains("MAIL")) mailProg = lst[lst.indexOf("MAIL") + 1]; else { KMessageBox::error(0, i18n("Krusader cannot find a supported mail client. Please install one to your path. Hint: Krusader supports KMail.")); return; } QString subject, separator; foreach(const QUrl &url, urls) { subject += separator + url.fileName(); separator = ','; } subject = i18np("Sending file: %2", "Sending files: %2", urls.count(), subject); KProcess proc; QString executable = QUrl::fromLocalFile(mailProg).fileName(); if (executable == QStringLiteral("kmail")) { proc << mailProg << "--subject" << subject; foreach(const QUrl &url2, urls) proc << "--attach" << url2.toDisplayString(); } else if (executable == QStringLiteral("thunderbird")) { QString param = "attachment=\'"; separator = ""; foreach(const QUrl &url2, urls) { param += separator + url2.toDisplayString(); separator = ','; } param += "\',subject=\'" + subject + "\'"; proc << mailProg << "--compose" << param; } else if (executable == QStringLiteral("evolution")) { QString param = "mailto:?cc=&subject=" + subject + "&attach="; separator = ""; foreach(const QUrl &url2, urls) { param += separator + url2.toDisplayString(); separator = "&attach="; } proc << mailProg << param + ""; } if (!proc.startDetached()) KMessageBox::error(0, i18n("Error executing %1.", mailProg)); } void KRslots::compareContent() { QStringList lstLeft, lstRight; QStringList* lstActive; QUrl name1, name2; LEFT_PANEL->getSelectedNames(&lstLeft); RIGHT_PANEL->getSelectedNames(&lstRight); lstActive = (ACTIVE_PANEL->gui->isLeft() ? &lstLeft : &lstRight); if (lstLeft.count() == 1 && lstRight.count() == 1) { // first, see if we've got exactly 1 selected file in each panel: name1 = LEFT_PANEL->func->files()->vfs_getFile(lstLeft[0]); name2 = RIGHT_PANEL->func->files()->vfs_getFile(lstRight[0]); } else if (lstActive->count() == 2) { // next try: are in the current panel exacty 2 files selected? name1 = ACTIVE_PANEL->func->files()->vfs_getFile((*lstActive)[0]); name2 = ACTIVE_PANEL->func->files()->vfs_getFile((*lstActive)[1]); } else if (ACTIVE_PANEL->otherPanel()->func->files()->vfs_search(ACTIVE_VIEW->getCurrentItem())) { // next try: is in the other panel a file with the same name? name1 = ACTIVE_PANEL->func->files()->vfs_getFile(ACTIVE_VIEW->getCurrentItem()); name2 = ACTIVE_PANEL->otherPanel()->func->files()->vfs_getFile(ACTIVE_VIEW->getCurrentItem()); } else { // if we got here, then we can't be sure what file to diff KMessageBox::detailedError(0, i18n("Do not know which files to compare."), "" + i18n("To compare two files by content, you can either:
  • Select one file in the left panel, and one in the right panel.
  • Select exactly two files in the active panel.
  • Make sure there is a file in the other panel, with the same name as the current file in the active panel.
") + "
"); return; } // else implied: all ok, let's call an external program to compare files // but if any of the files isn't local, download it first compareContent(name1, name2); } bool downloadToTemp(const QUrl &url, QString &dest) { QTemporaryFile tmpFile; tmpFile.setAutoRemove(false); if (tmpFile.open()) { dest = tmpFile.fileName(); KIO::Job* job = KIO::file_copy(url, QUrl::fromLocalFile(dest), -1, KIO::Overwrite | KIO::HideProgressInfo); if(!job->exec()) { KMessageBox::error(krApp, i18n("Krusader is unable to download %1", url.fileName())); return false; } return true; } return false; } void KRslots::compareContent(QUrl url1, QUrl url2) { QString diffProg; QStringList lst = KrServices::supportedTools(); if (lst.contains("DIFF")) diffProg = lst[lst.indexOf("DIFF") + 1]; else { KMessageBox::error(0, i18n("Krusader cannot find any of the supported diff-frontends. Please install one to your path. Hint: Krusader supports Kompare, KDiff3 and Xxdiff.")); return; } QString tmp1; QString tmp2; // kdiff3 sucks with spaces if (QUrl::fromLocalFile(diffProg).fileName() == "kdiff3" && !url1.toDisplayString().contains(" ") && !url2.toDisplayString().contains(" ")) { tmp1 = url1.toDisplayString(); tmp2 = url2.toDisplayString(); } else { if (!url1.isLocalFile()) { if (!downloadToTemp(url1, tmp1)) { return; } } else tmp1 = url1.path(); if (!url2.isLocalFile()) { if (!downloadToTemp(url2, tmp2)) { if (tmp1 != url1.path()) QFile::remove(tmp1); return; } } else tmp2 = url2.path(); } KrProcess *p = new KrProcess(tmp1 != url1.path() ? tmp1 : QString(), tmp2 != url2.path() ? tmp2 : QString()); *p << diffProg << tmp1 << tmp2; p->start(); if (!p->waitForStarted()) KMessageBox::error(0, i18n("Error executing %1.", diffProg)); } // GUI toggle slots void KRslots::toggleFnkeys() { if (MAIN_VIEW->fnKeys()->isVisible()) MAIN_VIEW->fnKeys()->hide(); else MAIN_VIEW->fnKeys()->show(); } void KRslots::toggleCmdline() { if (MAIN_VIEW->cmdLine()->isVisible()) MAIN_VIEW->cmdLine()->hide(); else MAIN_VIEW->cmdLine()->show(); } void KRslots::toggleStatusbar() { if (krApp->statusBar()->isVisible()) krApp->statusBar()->hide(); else krApp->statusBar()->show(); } void KRslots::toggleTerminal() { if (MAIN_VIEW->terminalDock()->isVisible()) MAIN_VIEW->slotTerminalEmulator(false); else MAIN_VIEW->slotTerminalEmulator(true); } void KRslots::insertFileName(bool full_path) { QString filename = ACTIVE_VIEW->getCurrentItem(); if (filename.isEmpty()) { return; } if (full_path) { QString path = vfs::ensureTrailingSlash(ACTIVE_FUNC->files()->vfs_getOrigin()).toDisplayString(QUrl::PreferLocalFile); filename = path + filename; } filename = KrServices::quote(filename); if (MAIN_VIEW->cmdLine()->isVisible() || !MAIN_VIEW->terminalDock()->isTerminalVisible()) { QString current = MAIN_VIEW->cmdLine()->text(); if (current.length() != 0 && !current.endsWith(' ')) current += ' '; MAIN_VIEW->cmdLine()->setText(current + filename); MAIN_VIEW->cmdLine()->setFocus(); } else if (MAIN_VIEW->terminalDock()->isTerminalVisible()) { filename = QChar(' ') + filename + QChar(' '); MAIN_VIEW->terminalDock()->sendInput(filename); MAIN_VIEW->terminalDock()->setFocus(); } } void KRslots::refresh(const QUrl &u) { ACTIVE_FUNC->openUrl(u); } void KRslots::runKonfigurator(bool firstTime) { Konfigurator *konfigurator = new Konfigurator(firstTime); connect(konfigurator, SIGNAL(configChanged(bool)), SLOT(configChanged(bool))); //FIXME - no need to exec konfigurator->exec(); delete konfigurator; } void KRslots::configChanged(bool isGUIRestartNeeded) { krConfig->sync(); if (isGUIRestartNeeded) { krApp->setUpdatesEnabled(false); KConfigGroup group(krConfig, "Look&Feel"); vfile::vfile_loadUserDefinedFolderIcons(group.readEntry("Load User Defined Folder Icons", _UserDefinedFolderIcons)); bool leftActive = ACTIVE_PANEL->gui->isLeft(); MAIN_VIEW->leftManager()->slotRecreatePanels(); MAIN_VIEW->rightManager()->slotRecreatePanels(); if(leftActive) LEFT_PANEL->slotFocusOnMe(); else RIGHT_PANEL->slotFocusOnMe(); MAIN_VIEW->fnKeys()->updateShortcuts(); KrSelectionMode::resetSelectionHandler(); krApp->setUpdatesEnabled(true); } // really ugly, but reload the Fn keys just in case - csaba: any better idea? MAIN_VIEW->fnKeys()->updateShortcuts(); bool showHidden = KConfigGroup(krConfig, "Look&Feel").readEntry("Show Hidden", KrActions::actToggleHidden->isChecked()); if (showHidden != KrActions::actToggleHidden->isChecked()) { KrActions::actToggleHidden->setChecked(showHidden); MAIN_VIEW->leftManager()->refreshAllTabs(true); MAIN_VIEW->rightManager()->refreshAllTabs(true); } } void KRslots::showHiddenFiles(bool show) { KConfigGroup group(krConfig, "Look&Feel"); group.writeEntry("Show Hidden", show); MAIN_VIEW->leftManager()->refreshAllTabs(true); MAIN_VIEW->rightManager()->refreshAllTabs(true); } void KRslots::swapPanels() { QUrl leftURL = LEFT_PANEL->func->files()->vfs_getOrigin(); QUrl rightURL = RIGHT_PANEL->func->files()->vfs_getOrigin(); LEFT_PANEL->func->openUrl(rightURL); RIGHT_PANEL->func->openUrl(leftURL); } void KRslots::toggleSwapSides() { MAIN_VIEW->swapSides(); } void KRslots::search() { if (KrSearchDialog::SearchDialog != 0) { KConfigGroup group(krConfig, "Search"); if (group.readEntry("Window Maximized", false)) KrSearchDialog::SearchDialog->showMaximized(); else KrSearchDialog::SearchDialog->showNormal(); KrSearchDialog::SearchDialog->raise(); KrSearchDialog::SearchDialog->activateWindow(); } else KrSearchDialog::SearchDialog = new KrSearchDialog(); } void KRslots::locate() { if (!KrServices::cmdExist("locate")) { KMessageBox::error(krApp, i18n("Cannot find the 'locate' command. Please install the " "findutils-locate package of GNU, or set its dependencies in " "Konfigurator")); return; } if (LocateDlg::LocateDialog != 0) { LocateDlg::LocateDialog->showNormal(); LocateDlg::LocateDialog->raise(); LocateDlg::LocateDialog->activateWindow(); LocateDlg::LocateDialog->reset(); } else LocateDlg::LocateDialog = new LocateDlg(); } -void KRslots::runTerminal(const QString & dir, const QStringList & args) +void KRslots::runTerminal(const QString & dir) { KProcess proc; proc.setWorkingDirectory(dir); KConfigGroup group(krConfig, "General"); QString term = group.readEntry("Terminal", _Terminal); QStringList sepdArgs = KShell::splitArgs(term, KShell::TildeExpand); if (sepdArgs.isEmpty()) { KMessageBox::error(krMainWindow, i18nc("Arg is a string containing the bad quoting.", "Bad quoting in terminal command:\n%1", term)); return; } for (int i = 0; i < sepdArgs.size(); i++) { if (sepdArgs[i] == "%d") { sepdArgs[i] = dir; } } proc << sepdArgs; - if (!args.isEmpty()) { - proc << "-e" << args; // FIXME this depends on term!! But works in konsole, xterm and gnome-terminal - } if (!proc.startDetached()) KMessageBox::sorry(krApp, i18n("Error executing %1.", term)); } void KRslots::homeTerminal() { - runTerminal(QDir::homePath(), QStringList()); + runTerminal(QDir::homePath()); } void KRslots::sysInfo() { KProcess proc; proc << KrServices::fullPathName("kcmshell") << "System/ksysctrl"; if (!proc.startDetached()) { KMessageBox::sorry(krApp, i18n("Cannot find \"KsysCtrl\". Please install KDE admin package")); } } void KRslots::multiRename() { QStringList lst = KrServices::supportedTools(); int i = lst.indexOf("RENAME"); if (i == -1) { KMessageBox::sorry(krApp, i18n("Cannot find a batch rename tool.\nYou can get KRename at http://www.krename.net")); return; } QString pathToRename = lst[i+1]; QStringList names; ACTIVE_PANEL->gui->getSelectedNames(&names); QList urls = ACTIVE_FUNC->files()->vfs_getFiles(names); if (urls.isEmpty()) { return; } KProcess proc; proc << pathToRename; foreach (const QUrl &url, urls) { if (QFileInfo(url.path()).isDir()) proc << "-r"; proc << url.path(); } if (!proc.startDetached()) KMessageBox::error(0, i18n("Error executing %1.", pathToRename)); } void KRslots::rootKrusader() { if (!KrServices::cmdExist("krusader") || !KrServices::cmdExist("kdesu")) { KMessageBox::sorry(krApp, i18n("Cannot start root mode Krusader, because Krusader or kdesu is missing from the path. Please configure the dependencies in Konfigurator.")); return; } KProcess proc; proc << KrServices::fullPathName("kdesu") << "-c" << KrServices::fullPathName("krusader") + " --left=" + KrServices::quote(LEFT_PANEL->func->files()->vfs_getOrigin().toDisplayString(QUrl::PreferLocalFile)) + " --right=" + KrServices::quote(RIGHT_PANEL->func->files()->vfs_getOrigin().toDisplayString(QUrl::PreferLocalFile)); if (!proc.startDetached()) KMessageBox::error(0, i18n("Error executing %1.", proc.program()[0])); } // settings slots void KRslots::configToolbar() { KConfigGroup cg(KSharedConfig::openConfig(), QString()); krApp->saveMainWindowSettings(cg); QPointer dlg = new KEditToolBar(krApp->factory()); connect(dlg, SIGNAL(newToolBarConfig()), this, SLOT(saveNewToolbarConfig())); if (dlg->exec()) { krApp->updateGUI(); } delete dlg; } void KRslots::saveNewToolbarConfig() { KConfigGroup cg(KSharedConfig::openConfig(), QString()); krApp->applyMainWindowSettings(cg); krApp->updateGUI(); } void KRslots::configKeys() { KShortcutsDialog::configure(krApp->actionCollection(), KShortcutsEditor::LetterShortcutsAllowed, krMainWindow); } void KRslots::slotSplit() { QStringList list; QString name; ACTIVE_PANEL->gui->getSelectedNames(&list); // first, see if we've got exactly 1 selected file, if not, try the current one if (list.count() == 1) name = list[0]; if (name.isEmpty()) { // if we got here, then one of the panel can't be sure what file to diff KMessageBox::error(0, i18n("Do not know which file to split.")); return; } QUrl fileURL = ACTIVE_FUNC->files()->vfs_getFile(name); if (fileURL.isEmpty()) return; if (ACTIVE_FUNC->files()->vfs_search(name)->vfile_isDir()) { KMessageBox::sorry(krApp, i18n("You cannot split a folder.")); return ; } QUrl destDir = ACTIVE_PANEL->otherPanel()->func->files()->vfs_getOrigin(); SplitterGUI splitterGUI(MAIN_VIEW, fileURL, destDir); if (splitterGUI.result() == QDialog::Accepted) { bool splitToOtherPanel = splitterGUI.getDestinationDir().matches(ACTIVE_PANEL->otherPanel()->virtualPath(), QUrl::StripTrailingSlash); Splitter split(MAIN_VIEW, fileURL, splitterGUI.getDestinationDir(), splitterGUI.overWriteFiles()); split.split(splitterGUI.getSplitSize()); if (splitToOtherPanel) ACTIVE_PANEL->otherPanel()->func->refresh(); } } void KRslots::slotCombine() { QStringList list; QUrl baseURL; bool unixStyle = false; bool windowsStyle = false; QString commonName; int commonLength = 0; ACTIVE_PANEL->gui->getSelectedNames(&list); if (list.isEmpty()) { KMessageBox::error(0, i18n("Do not know which files to combine.")); return; } /* checking splitter names */ for (QStringList::Iterator it = list.begin(); it != list.end(); ++it) { QUrl url = ACTIVE_FUNC->files()->vfs_getFile(*it); if (url.isEmpty()) return; if (ACTIVE_FUNC->files()->vfs_search(*it)->vfile_isDir()) { KMessageBox::sorry(krApp, i18n("You cannot combine a folder.")); return ; } if (!unixStyle) { QString name = url.fileName(); int extPos = name.lastIndexOf('.'); QString ext = name.mid(extPos + 1); name.truncate(extPos); url = url.adjusted(QUrl::RemoveFilename); url.setPath(url.path() + name); bool isExtInt; ext.toInt(&isExtInt, 10); if (extPos < 1 || ext.isEmpty() || (ext != "crc" && !isExtInt)) { if (windowsStyle) { KMessageBox::error(0, i18n("Not a split file: %1.", url.toDisplayString(QUrl::PreferLocalFile))); return; } unixStyle = true; } else { if (ext != "crc") windowsStyle = true; if (baseURL.isEmpty()) baseURL = url; else if (baseURL != url) { KMessageBox::error(0, i18n("Select only one split file.")); return; } } } if (unixStyle) { bool error = true; do { QString shortName = *it; QChar lastChar = shortName.at(shortName.length() - 1); if (lastChar.isLetter()) { char fillLetter = (lastChar.toUpper() == lastChar) ? 'A' : 'a'; if (commonName.isNull()) { commonLength = shortName.length(); commonName = shortName; while (commonName.length()) { QString shorter = commonName.left(commonName.length() - 1); QString testFile = shorter.leftJustified(commonLength, fillLetter); if (ACTIVE_FUNC->files()->vfs_search(testFile) == 0) break; else { commonName = shorter; baseURL = ACTIVE_FUNC->files()->vfs_getOrigin().adjusted(QUrl::StripTrailingSlash); baseURL.setPath(baseURL.path() + '/' + (testFile)); } } error = (commonName == shortName); } else if (commonLength == shortName.length() && shortName.startsWith(commonName)) error = false; } } while (false); if (error) { KMessageBox::error(0, i18n("Not a split file: %1.", url.toDisplayString(QUrl::PreferLocalFile))); return; } } } // ask the user for the copy dest QUrl dest = KChooseDir::getDir(i18n("Combining %1.* to folder:", baseURL.toDisplayString(QUrl::PreferLocalFile)), ACTIVE_PANEL->otherPanel()->virtualPath(), ACTIVE_PANEL->virtualPath()); if (dest.isEmpty()) return ; // the user canceled bool combineToOtherPanel = (dest.matches(ACTIVE_PANEL->otherPanel()->virtualPath(), QUrl::StripTrailingSlash)); Combiner combine(MAIN_VIEW, baseURL, dest, unixStyle); combine.combine(); if (combineToOtherPanel) ACTIVE_PANEL->otherPanel()->func->refresh(); } void KRslots::userMenu() { //UserMenu um; //um.exec(); krApp->userMenu->exec(); } void KRslots::manageUseractions() { ActionMan actionMan(MAIN_VIEW); } #ifdef SYNCHRONIZER_ENABLED void KRslots::slotSynchronizeDirs(QStringList selected) { new SynchronizerGUI(0, LEFT_PANEL->func->files()->vfs_getOrigin(), RIGHT_PANEL->func->files()->vfs_getOrigin(), selected); } #endif void KRslots::compareSetup() { for (int i = 0; KrActions::compareArray[i] != 0; i++) if ((*KrActions::compareArray[i])->isChecked()) { KConfigGroup group(krConfig, "Private"); group.writeEntry("Compare Mode", i); break; } } /** called by actions actExec* to choose the built-in command line mode */ void KRslots::execTypeSetup() { for (int i = 0; KrActions::execTypeArray[i] != 0; i++) if ((*KrActions::execTypeArray[i])->isChecked()) { if (*KrActions::execTypeArray[i] == KrActions::actExecTerminalEmbedded) { // if commands are to be executed in the TE, it must be loaded MAIN_VIEW->terminalDock()->initialise(); } KConfigGroup grp(krConfig, "Private"); grp.writeEntry("Command Execution Mode", i); break; } } void KRslots::slotDiskUsage() { DiskUsageGUI du(ACTIVE_FUNC->files()->vfs_getOrigin(), MAIN_VIEW); } void KRslots::slotQueueManager() { QueueDialog::showDialog(false); } void KRslots::applicationStateChanged() { if (MAIN_VIEW == 0) { /* CRASH FIX: it's possible that the method is called after destroying the main view */ return; } if(qApp->applicationState() == Qt::ApplicationActive) { LEFT_PANEL->panelActive(); RIGHT_PANEL->panelActive(); } else { LEFT_PANEL->panelInactive(); RIGHT_PANEL->panelInactive(); } } void KRslots::emptyTrash() { KrTrashHandler::emptyTrash(); } #define OPEN_ID 100001 #define EMPTY_TRASH_ID 100002 void KRslots::trashBin() { QMenu trashMenu(krApp); QAction * act = trashMenu.addAction(krLoader->loadIcon("document-open", KIconLoader::Panel), i18n("Open trash bin")); act->setData(QVariant(OPEN_ID)); act = trashMenu.addAction(krLoader->loadIcon("trash-empty", KIconLoader::Panel), i18n("Empty trash bin")); act->setData(QVariant(EMPTY_TRASH_ID)); int result = -1; QAction *res = trashMenu.exec(QCursor::pos()); if (res && res->data().canConvert ()) result = res->data().toInt(); if (result == OPEN_ID) { ACTIVE_FUNC->openUrl(QUrl(QStringLiteral("trash:/"))); } else if (result == EMPTY_TRASH_ID) { KrTrashHandler::emptyTrash(); } } //shows the JavaScript-Console void KRslots::jsConsole() { #ifdef __KJSEMBED__ if (! krJS) krJS = new KrJS(); krJS->view()->show(); #endif } void KRslots::addBookmark() { krBookMan->bookmarkCurrent(ACTIVE_PANEL->virtualPath()); } void KRslots::cmdlinePopup() { MAIN_VIEW->cmdLine()->popup(); } diff --git a/krusader/krslots.h b/krusader/krslots.h index 9c7754d8..da9931fd 100644 --- a/krusader/krslots.h +++ b/krusader/krslots.h @@ -1,132 +1,132 @@ /*************************************************************************** krslots.h ------------------- copyright : (C) 2001 by Shie Erlich & Rafi Yanai email : krusader@users.sourceforge.net web site : http://krusader.sourceforge.net --------------------------------------------------------------------------- Description *************************************************************************** A db dD d8888b. db db .d8888. .d8b. d8888b. d88888b d8888b. 88 ,8P' 88 `8D 88 88 88' YP d8' `8b 88 `8D 88' 88 `8D 88,8P 88oobY' 88 88 `8bo. 88ooo88 88 88 88ooooo 88oobY' 88`8b 88`8b 88 88 `Y8b. 88~~~88 88 88 88~~~~~ 88`8b 88 `88. 88 `88. 88b d88 db 8D 88 88 88 .8D 88. 88 `88. YP YD 88 YD ~Y8888P' `8888Y' YP YP Y8888D' Y88888P 88 YD H e a d e r F i l e *************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * ***************************************************************************/ #ifndef KRSLOTS_H #define KRSLOTS_H // QtCore #include #include #include #include class KrMainWindow; class QUrl; class KrProcess: public KProcess { Q_OBJECT QString tmp1, tmp2; public: KrProcess(QString in1, QString in2) { tmp1 = in1; tmp2 = in2; connect(this, SIGNAL(finished(int, QProcess::ExitStatus)), SLOT(processHasExited())); } public slots: void processHasExited() { if (!tmp1.isEmpty()) QFile::remove(tmp1); if (!tmp2.isEmpty()) QFile::remove(tmp2); deleteLater(); } }; class KRslots : public QObject { Q_OBJECT public: enum compareMode { full } ; KRslots(QObject *parent); ~KRslots() {} public slots: void sendFileByEmail(const QList &filename); void compareContent(); void compareContent(QUrl, QUrl); void insertFileName(bool full_path); void rootKrusader(); void swapPanels(); void showHiddenFiles(bool show); void toggleSwapSides(); void configToolbar(); void configKeys(); void toggleStatusbar(); void toggleTerminal(); void compareSetup(); void emptyTrash(); void trashBin(); /** called by actExec* actions to choose the built-in command line mode */ void execTypeSetup(); void refresh(const QUrl &u); void runKonfigurator(bool firstTime = false); void startKonfigurator() { runKonfigurator(false); } void search(); // call the search module void locate(); - void runTerminal(const QString & dir, const QStringList & args); + void runTerminal(const QString & dir); void homeTerminal(); void sysInfo(); void addBookmark(); void toggleFnkeys(); void toggleCmdline(); void multiRename(); void cmdlinePopup(); void slotSplit(); void slotCombine(); void userMenu(); void manageUseractions(); #ifdef SYNCHRONIZER_ENABLED void slotSynchronizeDirs(QStringList selected = QStringList()); #endif void slotDiskUsage(); void slotQueueManager(); void applicationStateChanged(); void jsConsole(); void saveNewToolbarConfig(); protected slots: void configChanged(bool isGUIRestartNeeded); protected: KrMainWindow *_mainWindow; }; #endif