Index: trunk/kdereview/krusader/krusader/krusader.cpp =================================================================== --- trunk/kdereview/krusader/krusader/krusader.cpp (revision 975118) +++ trunk/kdereview/krusader/krusader/krusader.cpp (revision 975119) @@ -1,1268 +1,1272 @@ /*************************************************************************** krusader.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 #include #include #include #ifdef BSD #include #endif // KDE includes #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include // QT includes #include #include #include #include #include #include #include #include #include #include #include #include #include #include // Krusader includes #include "krusader.h" #include "kicons.h" #include "VFS/krpermhandler.h" #include "GUI/krusaderstatus.h" #include "Dialogs/krpleasewait.h" #include "krusaderview.h" #include "Panel/listpanel.h" #include "Panel/panelfunc.h" #include "Konfigurator/konfigurator.h" #include "Konfigurator/kgprotocols.h" #include "MountMan/kmountman.h" #include "Panel/panelpopup.h" #include "Queue/queue_mgr.h" #include "defaults.h" #include "resources.h" #include "GUI/kfnkeys.h" #include "GUI/kcmdline.h" #include "GUI/terminaldock.h" #include "krslots.h" #include "krservices.h" #include "UserAction/useraction.h" #include "Panel/krviewfactory.h" // This makes gcc-4.1 happy. Warning about possible problem with KrAction's dtor not called #include "UserAction/kraction.h" #include "UserAction/expander.h" #include "UserMenu/usermenu.h" #include "panelmanager.h" #include "MountMan/kmountman.h" #include "BookMan/krbookmarkhandler.h" #include "Dialogs/popularurls.h" #include "GUI/krremoteencodingmenu.h" #include "Dialogs/checksumdlg.h" #include "VFS/vfile.h" #ifdef __KJSEMBED__ #include "KrJS/krjs.h" #endif // define the static members Krusader *Krusader::App = 0; QString Krusader::AppName; KAction *Krusader::actProperties = 0; KAction *Krusader::actPack = 0; KAction *Krusader::actUnpack = 0; KAction *Krusader::actTest = 0; KAction *Krusader::actCopy = 0; KAction *Krusader::actPaste = 0; KAction *Krusader::actCompare = 0; KAction *Krusader::actCalculate = 0; KAction *Krusader::actCreateChecksum = 0; KAction *Krusader::actMatchChecksum = 0; KAction *Krusader::actSelect = 0; KAction *Krusader::actSelectAll = 0; KAction *Krusader::actUnselect = 0; KAction *Krusader::actUnselectAll = 0; KAction *Krusader::actInvert = 0; KAction *Krusader::actCompDirs = 0; KAction *Krusader::actSync = 0; KAction *Krusader::actDiskUsage = 0; KAction *Krusader::actQueueManager = 0; KAction *Krusader::actHomeTerminal = 0; KAction *Krusader::actFTPConnect = 0; KAction *Krusader::actFTPNewConnect = 0; KAction *Krusader::actFTPDisconnect = 0; KAction *Krusader::actRemoteEncoding = 0; KAction *Krusader::actProfiles = 0; KAction *Krusader::actMultiRename = 0; KAction *Krusader::actAllFilter = 0; KAction *Krusader::actExecFilter = 0; KAction *Krusader::actCustomFilter = 0; KAction *Krusader::actMountMan = 0; KAction *Krusader::actNewTool = 0; KAction *Krusader::actKonfigurator = 0; KAction *Krusader::actToolsSetup = 0; KAction *Krusader::actSwapPanels = 0; KAction *Krusader::actSwapSides = 0; KAction *Krusader::actBack = 0; KAction *Krusader::actRoot = 0; KAction *Krusader::actFind = 0; KAction *Krusader::actLocate = 0; KAction *Krusader::actSwitchFullScreenTE = 0; //KAction *Krusader::actAddBookmark = 0; KAction *Krusader::actSavePosition = 0; KAction *Krusader::actSelectColorMask = 0; KAction *Krusader::actOpenLeftBm = 0; KAction *Krusader::actOpenRightBm = 0; KAction *Krusader::actDirUp = 0; KAction *Krusader::actCmdlinePopup = 0; KAction *Krusader::actNewTab = 0; KAction *Krusader::actDupTab = 0; KAction *Krusader::actCloseTab = 0; KAction *Krusader::actNextTab = 0; KAction *Krusader::actPreviousTab = 0; KAction *Krusader::actSplit = 0; KAction *Krusader::actCombine = 0; KAction *Krusader::actUserMenu = 0; KAction *Krusader::actManageUseractions = 0; KAction *Krusader::actSyncDirs = 0; KAction *Krusader::actSyncBrowse = 0; KAction *Krusader::actF2 = 0; KAction *Krusader::actF3 = 0; KAction *Krusader::actF4 = 0; KAction *Krusader::actF5 = 0; KAction *Krusader::actF6 = 0; KAction *Krusader::actF7 = 0; KAction *Krusader::actF8 = 0; KAction *Krusader::actF9 = 0; KAction *Krusader::actF10 = 0; +KAction *Krusader::actShiftF5 = 0; +KAction *Krusader::actShiftF6 = 0; KAction *Krusader::actLocationBar = 0; KAction *Krusader::actPopularUrls = 0; KAction *Krusader::actJumpBack = 0; KAction *Krusader::actSetJumpBack = 0; KAction *Krusader::actView0 = 0; KAction *Krusader::actView1 = 0; KAction *Krusader::actView2 = 0; KAction *Krusader::actView3 = 0; KAction *Krusader::actView4 = 0; KAction *Krusader::actView5 = 0; KToggleAction *Krusader::actToggleTerminal = 0; KAction *Krusader::actVerticalMode = 0; KAction *Krusader::actSelectNewerAndSingle = 0; KAction *Krusader::actSelectSingle = 0; KAction *Krusader::actSelectNewer = 0; KAction *Krusader::actSelectDifferentAndSingle = 0; KAction *Krusader::actSelectDifferent = 0; KAction **Krusader::compareArray[] = {&actSelectNewerAndSingle, &actSelectNewer, &actSelectSingle, &actSelectDifferentAndSingle, &actSelectDifferent, 0}; KAction *Krusader::actExecStartAndForget = 0; KAction *Krusader::actExecCollectSeparate = 0; KAction *Krusader::actExecCollectTogether = 0; KAction *Krusader::actExecTerminalExternal = 0; KAction *Krusader::actExecTerminalEmbedded = 0; KAction **Krusader::execTypeArray[] = {&actExecStartAndForget, &actExecCollectSeparate, &actExecCollectTogether, &actExecTerminalExternal, &actExecTerminalEmbedded, 0}; KMenu *Krusader::userActionMenu = 0; UserAction *Krusader::userAction = 0; UserMenu *Krusader::userMenu = 0; KrBookmarkHandler *Krusader::bookman = 0; int Krusader::viewIds[ MAX_VIEWS ] = { -1, -1, -1, -1, -1, -1 }; //QTextOStream *Krusader::_krOut = QTextOStream(::stdout); #ifdef __KJSEMBED__ KrJS *Krusader::js = 0; KAction *Krusader::actShowJSConsole = 0; #endif // construct the views, statusbar and menu bars and prepare Krusader to start Krusader::Krusader() : KParts::MainWindow(0, Qt::Window | Qt::WindowTitleHint | Qt::WindowContextHelpButtonHint), status(NULL), sysTray( 0 ), isStarting( true ), isExiting( false ), directExit( false ) { setAttribute(Qt::WA_DeleteOnClose); // parse command line arguments KCmdLineArgs * args = KCmdLineArgs::parsedArgs(); // create the "krusader" App = this; slot = new KRslots(this); setXMLFile( "krusaderui.rc" ); // kpart-related xml file plzWait = new KRPleaseWaitHandler(); bool runKonfig = versionControl(); QString message; switch ( config->accessMode() ) { case KConfigBase::NoAccess : message = "Krusader's configuration file can't be found. Default values will be used."; break; case KConfigBase::ReadOnly : message = "Krusader's configuration file is in READ ONLY mode (why is that!?) Changed values will not be saved"; break; case KConfigBase::ReadWrite : message = ""; break; } if ( message != "" ) { KMessageBox::error( krApp, message ); } // create an icon loader iconLoader = KIconLoader::global(); // iconLoader->addExtraDesktopThemes(); // create MountMan mountMan = new KMountMan(); // create bookman bookman = new KrBookmarkHandler(); popularUrls = new PopularUrls(this); queueManager = new QueueManager(); // create the main view mainView = new KrusaderView( this ); // setup all the krusader's actions setupActions(); // init the permmision handler class KRpermHandler::init(); // init the protocol handler KgProtocols::init(); // init the checksum tools initChecksumModule(); KConfigGroup gl( krConfig, "Look&Feel"); KConfigGroup glgen( krConfig, "General"); int defaultType = gl.readEntry( "Default Panel Type", KrViewFactory::defaultViewId() ); vfile::vfile_loadUserDefinedFolderIcons( gl.readEntry( "Load User Defined Folder Icons", _UserDefinedFolderIcons ) ); vfile::vfile_enableMimeTypeMagic( glgen.readEntry( "Mimetype Magic", _MimetypeMagic ) ); KConfigGroup gs( krConfig, "Startup" ); QStringList leftTabs = gs.readPathEntry( "Left Tab Bar",QStringList() ); QStringList rightTabs = gs.readPathEntry( "Right Tab Bar", QStringList() ); QList leftTabTypes = gs.readEntry( "Left Tab Bar Types", QList() ); QList rightTabTypes = gs.readEntry( "Right Tab Bar Types", QList() ); QList leftTabProps = gs.readEntry( "Left Tab Bar Props", QList() ); QList rightTabProps = gs.readEntry( "Right Tab Bar Props", QList() ); int leftActiveTab = gs.readEntry( "Left Active Tab", 0 ); int rightActiveTab = gs.readEntry( "Right Active Tab", 0 ); QString startProfile = gs.readEntry("Starter Profile Name", QString() ); bool leftActive = gs.readEntry( "Left Side Is Active", false ); // get command-line arguments if ( args->isSet( "left" ) ) { leftTabs = args->getOption( "left" ).split( ',' ); leftTabTypes.clear(); leftTabProps.clear(); leftActiveTab = 0; // make sure left or right are not relative paths for(int i = 0; i != leftTabs.count(); i++ ) { leftTabs[ i ] = leftTabs[ i ].trimmed(); if( !leftTabs[ i ].startsWith( "/" ) && leftTabs[ i ].indexOf( ":/" ) < 0 ) leftTabs[ i ] = QDir::currentPath() + "/" + leftTabs[ i ]; } startProfile = QString(); } if ( args->isSet( "right" ) ) { rightTabs = args->getOption( "right" ).split( ',' ); rightTabTypes.clear(); rightTabProps.clear(); rightActiveTab = 0; // make sure left or right are not relative paths for(int i = 0; i != rightTabs.count(); i++ ) { rightTabs[ i ] = rightTabs[ i ].trimmed(); if( !rightTabs[ i ].startsWith( "/" ) && rightTabs[ i ].indexOf( ":/" ) < 0 ) rightTabs[ i ] = QDir::currentPath() + "/" + rightTabs[ i ]; } startProfile = QString(); } while( leftTabTypes.count() < leftTabs.count() ) leftTabTypes += defaultType; while( rightTabTypes.count() < rightTabs.count() ) rightTabTypes += defaultType; while( leftTabProps.count() < leftTabs.count() ) leftTabProps += 0; while( rightTabProps.count() < rightTabs.count() ) rightTabProps += 0; if ( args->isSet( "profile" ) ) startProfile = args->getOption( "profile" ); if( !startProfile.isEmpty() ) { leftTabs.clear(); leftTabTypes.clear(); leftTabProps.clear(); rightTabs.clear(); rightTabTypes.clear(); rightTabProps.clear(); leftActiveTab = rightActiveTab = 0; } if( leftTabs.count() == 0 ) { leftTabs.push_back( QDir::homePath() ); leftTabTypes.push_back( defaultType ); leftTabProps.push_back( 0 ); } if( rightTabs.count() == 0 ) { rightTabs.push_back( QDir::homePath() ); rightTabTypes.push_back( defaultType ); rightTabProps.push_back( 0 ); } // starting the panels mainView->start( leftTabs, leftTabTypes, leftTabProps, leftActiveTab, rightTabs, rightTabTypes, rightTabProps, rightActiveTab, leftActive ); // create the user menu userMenu = new UserMenu( this ); userMenu->hide(); // setup keyboard accelerators setupAccels(); // create a status bar status = new KrusaderStatus( this ); setStatusBar( status ); status->setWhatsThis( i18n( "Statusbar will show basic information " "about file below mouse pointer." ) ); KGlobal::ref(); // FIX: krusader exits at closing the viewer when minimized to tray // This enables Krusader to show a tray icon sysTray = new KSystemTrayIcon( this ); // Krusader::privIcon() returns either "krusader_blue" or "krusader_red" if the user got root-privileges sysTray->setIcon( iconLoader->loadIcon( privIcon(), KIconLoader::Panel, 22 ) ); sysTray->hide(); connect( sysTray, SIGNAL( quitSelected() ), this, SLOT( setDirectExit() ) ); setCentralWidget( mainView ); bool startToTray = gs.readEntry( "Start To Tray", _StartToTray ); bool minimizeToTray = gl.readEntry( "Minimize To Tray", _MinimizeToTray ); bool singleInstanceMode = gl.readEntry( "Single Instance Mode", _SingleInstanceMode ); startToTray = startToTray && minimizeToTray; if( singleInstanceMode && minimizeToTray ) sysTray->show(); // manage our keyboard short-cuts //KAcceleratorManager::manage(this,true); setCursor( Qt::ArrowCursor ); if ( ! startProfile.isEmpty() ) mainView->profiles( startProfile ); // let the good times rool :) updateGUI( true ); if ( runKonfig ) slot->runKonfigurator( true ); if (!runKonfig) { KConfigGroup cfg( config, "Private" ); if ( cfg.readEntry( "Maximized", false ) ) restoreWindowSize(cfg); else { move( oldPos = cfg.readEntry( "Start Position", _StartPosition ) ); resize( oldSize = cfg.readEntry( "Start Size", _StartSize )); } } if( startToTray ) { sysTray->show(); hide(); } else show(); isStarting = false; } Krusader::~Krusader() { delete queueManager; if( !isExiting ) // save the settings if it was not saved (SIGTERM) saveSettings(); delete mainView; mainView = 0; App = 0; } bool Krusader::versionControl() { #define FIRST_RUN "First Time" bool retval = false; // create config file // TODO: according to docs, KGlobal::config() should return KConfig*, but in reality (in beta1), it returns KSharedPtr or something ?! config = KGlobal::config().data(); KConfigGroup nogroup( config, QString()); bool firstRun = nogroup.readEntry(FIRST_RUN, true); #if 0 QString oldVerText = nogroup.readEntry( "Version", "10.0" ); oldVerText.truncate( oldVerText.lastIndexOf( "." ) ); // remove the third dot float oldVer = oldVerText.toFloat(); // older icompatible version if ( oldVer <= 0.9 ) { KMessageBox::information( krApp, i18n( "A configuration of 1.51 or older was detected. Krusader has to reset your configuration to default values.\nNote: Your bookmarks and keybindings will remain intact.\n Krusader will now run Konfigurator." ) ); /*if ( !QDir::home().remove( ".kde/share/config/krusaderrc" ) ) { KMessageBox::error( krApp, i18n( "Unable to remove your krusaderrc file! Please remove it manually and rerun Krusader." ) ); exit( 1 ); }*/ retval = true; config->reparseConfiguration(); } #endif // first installation of krusader if ( firstRun ) { KMessageBox::information( krApp, i18n( "Welcome to Krusader!

As this is your first run, your machine will now be checked for external applications. Then the Konfigurator will be launched where you can customize Krusader to your needs.

" ) ); retval = true; } nogroup.writeEntry( "Version", VERSION ); nogroup.writeEntry( FIRST_RUN, false); config->sync(); return retval; } void Krusader::statusBarUpdate( QString& mess ) { // change the message on the statusbar for 2 seconds if (status) // ugly!!!! But as statusBar() creates a status bar if there is no, I have to ask status to prevent // the creation of the KDE default status bar instead of KrusaderStatus. statusBar() ->showMessage( mess, 5000 ); } void Krusader::showEvent ( QShowEvent * ) { if( isExiting ) return; KConfigGroup group( config, "Look&Feel"); bool showTrayIcon = group.readEntry( "Minimize To Tray", _MinimizeToTray ); bool singleInstanceMode = group.readEntry( "Single Instance Mode", _SingleInstanceMode ); if( showTrayIcon && !singleInstanceMode && sysTray) sysTray->hide(); show(); // needed to make sure krusader is removed from // the taskbar when minimizing (system tray issue) } void Krusader::hideEvent ( QHideEvent *e ) { if( isExiting ) { KParts::MainWindow::hideEvent( e ); if (sysTray) sysTray->hide(); return; } KConfigGroup group( config, "Look&Feel"); bool showTrayIcon = group.readEntry( "Minimize To Tray", _MinimizeToTray ); bool isModalTopWidget = false; QWidget *actWnd = qApp->activeWindow(); if ( actWnd ) isModalTopWidget = actWnd->isModal(); #ifdef Q_WS_X11 // KWindowSystem::windowInfo is only available for X11 if ( showTrayIcon && !isModalTopWidget && KWindowSystem::windowInfo( winId(), NET::WMDesktop ).isOnCurrentDesktop() ) { #else if ( showTrayIcon && !isModalTopWidget ) { #endif if ( sysTray ) sysTray->show(); hide(); // needed to make sure krusader is removed from // the taskbar when minimizing (system tray issue) } else KParts::MainWindow::hideEvent( e ); } void Krusader::moveEvent ( QMoveEvent *e ) { oldPos = e->oldPos(); KParts::MainWindow::moveEvent( e ); } void Krusader::resizeEvent ( QResizeEvent *e ) { oldSize = e->oldSize(); KParts::MainWindow::resizeEvent( e ); } void Krusader::setupAccels() { KAction * tab = new KAction( "Tab-Switch panel", this); tab->setShortcut(Qt::Key_Tab); connect(tab, SIGNAL(triggered(bool)), mainView, SLOT( panelSwitch() )); actionCollection()->addAction("tab", tab); } // Moving from Pixmap actions to generic filenames - thanks to Carsten Pfeiffer void Krusader::setupActions() { #define NEW_KACTION(VAR, TEXT, ICON_NAME, SHORTCUT, RECV_OBJ, SLOT_NAME, NAME) \ if (ICON_NAME == 0) VAR = new KAction(TEXT, this); \ else VAR = new KAction( KIcon(ICON_NAME), TEXT, this); \ VAR->setShortcut(SHORTCUT); \ connect(VAR, SIGNAL(triggered(bool)), RECV_OBJ, SLOT_NAME); \ actionCollection()->addAction(NAME, VAR); #define NEW_KTOGGLEACTION(VAR, TEXT, ICON_NAME, SHORTCUT, RECV_OBJ, SLOT_NAME, NAME) \ if (ICON_NAME == 0) VAR = new KToggleAction(TEXT, this); \ else VAR = new KToggleAction( KIcon(ICON_NAME), TEXT, this); \ VAR->setShortcut(SHORTCUT); \ connect(VAR, SIGNAL(triggered(bool)), RECV_OBJ, SLOT_NAME); \ actionCollection()->addAction(NAME, VAR); // first come the TODO actions //actSync = 0;//new KAction(i18n("S&yncronize Dirs"), 0, this, 0, actionCollection(), "sync dirs"); //actNewTool = 0;//new KAction(i18n("&Add a new tool"), 0, this, 0, actionCollection(), "add tool"); //actToolsSetup = 0;//new KAction(i18n("&Tools Menu Setup"), 0, 0, this, 0, actionCollection(), "tools setup"); //KStandardAction::print(SLOTS, 0,actionCollection(),"std_print"); //KStandardAction::showMenubar( SLOTS, SLOT( showMenubar() ), actionCollection(), "std_menubar" ); // second, the KDE standard action //PORTME: second shortcut for up: see actDirUp // KStandardAction::up( SLOTS, SLOT( dirUp() ), actionCollection() )->setShortcut(Qt::Key_Backspace); /* Shortcut disabled because of the Terminal Emulator bug. */ KConfigGroup group( krConfig, "Private" ); int compareMode = group.readEntry( "Compare Mode", 0 ); int cmdExecMode = group.readEntry( "Command Execution Mode", 0 ); KStandardAction::home( SLOTS, SLOT( home() ), actionCollection()/*, "std_home"*/ )->setText( i18n("Home") ); /*->setShortcut(Qt::Key_QuoteLeft);*/ KAction *reloadAct; NEW_KACTION(reloadAct, i18n( "&Reload" ), "view-refresh", Qt::CTRL + Qt::Key_R, SLOTS, SLOT(refresh()), "std_redisplay"); actShowToolBar = (KToggleAction*)KStandardAction::create( KStandardAction::ShowToolbar, SLOTS, SLOT( toggleToolbar() ), actionCollection()/*, "std_toolbar"*/ ); KToggleAction *toggleActToolbar; NEW_KTOGGLEACTION(toggleActToolbar, i18n("Show Actions Toolbar"), 0, 0, SLOTS, SLOT(toggleActionsToolbar()), "toggle actions toolbar"); actShowStatusBar = KStandardAction::showStatusbar( SLOTS, SLOT( toggleStatusbar() ), actionCollection() ); KStandardAction::quit( this, SLOT( slotClose() ), actionCollection() ); KStandardAction::configureToolbars( SLOTS, SLOT( configToolbar() ), actionCollection() ); KStandardAction::keyBindings( SLOTS, SLOT( configKeys() ), actionCollection() ); KStandardAction::cut( SLOTS, SLOT( cut() ), actionCollection() )->setText( i18n("Cut to Clipboard") ); (actCopy = KStandardAction::copy( SLOTS, SLOT( copy() ), actionCollection() ))->setText( i18n("Copy to Clipboard") ); (actPaste = KStandardAction::paste( SLOTS, SLOT( paste() ), actionCollection() ))->setText( i18n("Paste from Clipboard") ); // the toggle actions NEW_KTOGGLEACTION(actToggleFnkeys, i18n( "Show &FN Keys Bar" ), 0, 0, SLOTS, SLOT( toggleFnkeys() ), "toggle fn bar"); NEW_KTOGGLEACTION(actToggleCmdline, i18n( "Show &Command Line" ), 0, 0, SLOTS, SLOT( toggleCmdline() ), "toggle command line"); NEW_KTOGGLEACTION(actToggleTerminal, i18n( "Show Terminal &Emulator" ), 0, Qt::ALT + Qt::CTRL + Qt::Key_T, SLOTS, SLOT( toggleTerminal() ), "toggle terminal emulator"); int cnt = 0; QList views = KrViewFactory::registeredViews(); foreach( KrViewInstance * inst, views ) { if( cnt == MAX_VIEWS ) break; int id = inst->id(); viewIds[ cnt ] = id; switch( id ) { case 0: NEW_KACTION(actView0, i18n( inst->description().toUtf8() ), 0, inst->shortcut(), SLOTS, SLOT( setView0() ), "view0"); break; case 1: NEW_KACTION(actView1, i18n( inst->description().toUtf8() ), 0, inst->shortcut(), SLOTS, SLOT( setView1() ), "view1"); break; case 2: NEW_KACTION(actView2, i18n( inst->description().toUtf8() ), 0, inst->shortcut(), SLOTS, SLOT( setView2() ), "view2"); break; case 3: NEW_KACTION(actView3, i18n( inst->description().toUtf8() ), 0, inst->shortcut(), SLOTS, SLOT( setView3() ), "view3"); break; case 4: NEW_KACTION(actView4, i18n( inst->description().toUtf8() ), 0, inst->shortcut(), SLOTS, SLOT( setView4() ), "view4"); break; case 5: NEW_KACTION(actView5, i18n( inst->description().toUtf8() ), 0, inst->shortcut(), SLOTS, SLOT( setView5() ), "view5"); break; default: break; } cnt++; } NEW_KTOGGLEACTION(actToggleHidden, i18n( "Show &Hidden Files" ), 0, Qt::CTRL + Qt::Key_Period, SLOTS, SLOT( toggleHidden() ), "toggle hidden files"); NEW_KACTION(actSwapPanels, i18n( "S&wap Panels" ), 0, Qt::CTRL + Qt::Key_U, SLOTS, SLOT( swapPanels() ), "swap panels"); NEW_KACTION(actSwapSides, i18n( "Sw&ap Sides" ), 0, Qt::CTRL + Qt::SHIFT + Qt::Key_U, SLOTS, SLOT( toggleSwapSides() ), "toggle swap sides" ); actToggleHidden->setChecked( KConfigGroup( krConfig, "Look&Feel" ).readEntry( "Show Hidden", _ShowHidden ) ); // and then the DONE actions NEW_KACTION(actCmdlinePopup, i18n( "popup cmdline" ), 0, Qt::CTRL + Qt::Key_Slash, SLOTS, SLOT( cmdlinePopup() ), "cmdline popup" ); /* Shortcut disabled because of the Terminal Emulator bug. */ NEW_KACTION(actDirUp, i18n( "Up" ), "go-up", Qt::CTRL + Qt::Key_PageUp /*Qt::Key_Backspace*/, SLOTS, SLOT( dirUp() ), "dirUp" ); KAction *tmp1, *tmp2, *tmp3; NEW_KACTION( tmp1, i18n( "&New Text File..." ), "document-new", Qt::SHIFT + Qt::Key_F4, SLOTS, SLOT( editDlg() ), "edit_new_file" ); NEW_KACTION( tmp2, i18n( "Start &Root Mode Krusader" ), "krusader_root", Qt::ALT + Qt::Key_K, SLOTS, SLOT( rootKrusader() ), "root krusader" ); NEW_KACTION( tmp3, i18n( "F3 View Dialog" ), 0, Qt::SHIFT + Qt::Key_F3, SLOTS, SLOT( viewDlg() ), "F3_ViewDlg" ); NEW_KACTION(actTest, i18n( "T&est Archive" ), "ark", Qt::ALT + Qt::Key_E, SLOTS, SLOT( testArchive() ), "test archives" ); NEW_KACTION(actFTPNewConnect, i18n( "New Net &Connection..." ), "connect_creating", Qt::CTRL + Qt::Key_N, SLOTS, SLOT( newFTPconnection() ), "ftp new connection" ); NEW_KACTION(actProfiles, i18n( "Pro&files" ), "kr_profile", Qt::ALT + Qt::Key_L, MAIN_VIEW, SLOT( profiles() ), "profile" ); NEW_KACTION(actCalculate, i18n( "Calculate &Occupied Space" ), "kcalc", 0, SLOTS, SLOT( calcSpace() ), "calculate" ); NEW_KACTION(actCreateChecksum, i18n( "Create Checksum..." ), "binary", 0, SLOTS, SLOT( createChecksum() ), "create checksum" ); NEW_KACTION(actMatchChecksum, i18n( "Verify Checksum..." ), "match_checksum", 0, SLOTS, SLOT( matchChecksum() ), "match checksum" ); NEW_KACTION(actProperties, i18n( "&Properties..." ), 0, Qt::ALT+Qt::Key_Enter, SLOTS, SLOT( properties() ), "properties" ); NEW_KACTION(actPack, i18n( "Pac&k..." ), "kr_arc_pack", Qt::ALT + Qt::Key_P, SLOTS, SLOT( slotPack() ), "pack" ); NEW_KACTION(actUnpack, i18n( "&Unpack..." ), "kr_arc_unpack", Qt::ALT + Qt::Key_U, SLOTS, SLOT( slotUnpack() ), "unpack" ); NEW_KACTION(actSplit, i18n( "Sp&lit File..." ), "kr_split", Qt::CTRL + Qt::Key_P, SLOTS, SLOT( slotSplit() ), "split" ); NEW_KACTION(actCombine, i18n( "Com&bine Files..." ), "kr_combine", Qt::CTRL + Qt::Key_B, SLOTS, SLOT( slotCombine() ), "combine" ); NEW_KACTION(actSelect, i18n( "Select &Group..." ), "kr_select", Qt::CTRL + Qt::Key_Plus, SLOTS, SLOT( markGroup() ), "select group" ); NEW_KACTION(actSelectAll, i18n( "&Select All" ), "kr_selectall", Qt::ALT + Qt::Key_Plus, SLOTS, SLOT( markAll() ), "select all" ); NEW_KACTION(actUnselect, i18n( "&Unselect Group..." ), "kr_unselect", Qt::CTRL + Qt::Key_Minus, SLOTS, SLOT( unmarkGroup() ), "unselect group" ); NEW_KACTION(actUnselectAll, i18n( "U&nselect All" ), "kr_unselectall", Qt::ALT + Qt::Key_Minus, SLOTS, SLOT( unmarkAll() ), "unselect all" ); NEW_KACTION(actInvert, i18n( "&Invert Selection" ), "kr_invert", Qt::ALT + Qt::Key_Asterisk, SLOTS, SLOT( invert() ), "invert" ); NEW_KACTION(actCompDirs, i18n( "&Compare Directories" ), "view_left_right", Qt::ALT + Qt::Key_C, SLOTS, SLOT( compareDirs() ), "compare dirs" ); NEW_KACTION(actSelectNewerAndSingle, i18n( "&Select Newer and Single" ), 0, 0, SLOTS, SLOT( compareSetup() ), "select_newer_and_single" ); NEW_KACTION(actSelectNewer, i18n( "Select &Newer" ), 0, 0, SLOTS, SLOT( compareSetup() ), "select_newer" ); NEW_KACTION(actSelectSingle, i18n( "Select &Single" ), 0, 0, SLOTS, SLOT( compareSetup() ), "select_single" ); NEW_KACTION(actSelectDifferentAndSingle, i18n( "Select Different &and Single" ), 0, 0, SLOTS, SLOT( compareSetup() ), "select_different_and_single" ); NEW_KACTION(actSelectDifferent, i18n( "Select &Different" ), 0, 0, SLOTS, SLOT( compareSetup() ), "select_different" ); QActionGroup *selectGroup = new QActionGroup(this); selectGroup->setExclusive(true); selectGroup->addAction(actSelectNewerAndSingle); selectGroup->addAction(actSelectNewer); selectGroup->addAction(actSelectSingle); selectGroup->addAction(actSelectDifferentAndSingle); selectGroup->addAction(actSelectDifferent); if( compareMode < (int)( sizeof( compareArray ) / sizeof( KAction ** ) ) -1 ) (*compareArray[ compareMode ])->setChecked( true ); NEW_KACTION(actExecStartAndForget, i18n( "Start and &Forget" ), 0, 0, SLOTS, SLOT( execTypeSetup() ), "exec_start_and_forget" ); NEW_KACTION(actExecCollectSeparate, i18n( "Display &Separated Standard and Error Output" ), 0, 0, SLOTS, SLOT( execTypeSetup() ), "exec_collect_separate" ); NEW_KACTION(actExecCollectTogether, i18n( "Display &Mixed Standard and Error Output" ), 0, 0, SLOTS, SLOT( execTypeSetup() ), "exec_collect_together" ); NEW_KACTION(actExecTerminalExternal, i18n( "Start in &New Terminal" ), 0, 0, SLOTS, SLOT( execTypeSetup() ), "exec_terminal_external" ); NEW_KACTION(actExecTerminalEmbedded, i18n( "Send to &Embedded Terminal Emulator" ), 0, 0, SLOTS, SLOT( execTypeSetup() ), "exec_terminal_embedded" ); actExecStartAndForget->setCheckable( true ); actExecCollectSeparate->setCheckable( true ); actExecCollectTogether->setCheckable( true ); actExecTerminalExternal->setCheckable( true ); actExecTerminalEmbedded->setCheckable( true ); QActionGroup *actionGroup = new QActionGroup(this); actionGroup->setExclusive(true); actionGroup->addAction(actExecStartAndForget); actionGroup->addAction(actExecCollectSeparate); actionGroup->addAction(actExecCollectTogether); actionGroup->addAction(actExecTerminalExternal); actionGroup->addAction(actExecTerminalEmbedded); if( cmdExecMode < (int)( sizeof( execTypeArray ) / sizeof( KAction ** ) ) -1 ) (*execTypeArray[ cmdExecMode ])->setChecked( true ); NEW_KACTION(actHomeTerminal, i18n( "Start &Terminal" ), "terminal", 0, SLOTS, SLOT( homeTerminal() ), "terminal@home" ); NEW_KACTION(actFTPDisconnect, i18n( "Disconnect &from Net" ), "kr_ftp_disconnect", Qt::SHIFT + Qt::CTRL + Qt::Key_F, SLOTS, SLOT( FTPDisconnect() ), "ftp disconnect" ); actMountMan = new KToolBarPopupAction( KIcon("kr_mountman"), i18n( "&MountMan..." ), this); actMountMan->setShortcut(Qt::ALT + Qt::Key_Slash); connect(actMountMan, SIGNAL(triggered(bool)), SLOTS, SLOT( runMountMan() )); connect( ( ( KToolBarPopupAction* ) actMountMan ) ->menu(), SIGNAL( aboutToShow() ), mountMan, SLOT( quickList() ) ); actionCollection()->addAction("mountman", actMountMan); NEW_KACTION(actFind, i18n( "&Search..." ), "system-search", Qt::CTRL + Qt::Key_S, SLOTS, SLOT( search() ), "find" ); NEW_KACTION(actLocate, i18n( "&Locate..." ), "edit-find", Qt::SHIFT+ Qt::CTRL + Qt::Key_L, SLOTS, SLOT( locate() ), "locate" ); NEW_KACTION(actSyncDirs, i18n( "Synchronize &Directories..." ), "kr_syncdirs", Qt::CTRL + Qt::Key_Y, SLOTS, SLOT( slotSynchronizeDirs() ), "sync dirs" ); NEW_KACTION(actSyncBrowse, i18n( "S&ynchron Directory Changes" ), "kr_syncbrowse_off", Qt::ALT + Qt::Key_Y, SLOTS, SLOT( slotSyncBrowse() ), "sync browse" ); NEW_KACTION(actDiskUsage, i18n( "D&isk Usage..." ), "kr_diskusage", Qt::ALT + Qt::Key_D, SLOTS, SLOT( slotDiskUsage() ), "disk usage" ); NEW_KACTION(actQueueManager, i18n( "&Queue Manager..." ), "document-multiple", Qt::ALT + Qt::Key_Q, SLOTS, SLOT( slotQueueManager() ), "queue manager" ); NEW_KACTION(actKonfigurator, i18n( "Configure &Krusader..." ), "configure", 0, SLOTS, SLOT( startKonfigurator() ), "konfigurator" ); NEW_KACTION(actBack, i18n( "Back" ), "go-previous", 0, SLOTS, SLOT( back() ), "back" ); NEW_KACTION(actRoot, i18n( "Root" ), "go-top", Qt::CTRL + Qt::Key_Backspace, SLOTS, SLOT( root() ), "root" ); NEW_KACTION(actSavePosition, i18n( "Save &Position" ), 0, 0, krApp, SLOT( savePosition() ), "save position" ); NEW_KACTION(actAllFilter, i18n( "&All Files" ), 0, Qt::SHIFT + Qt::Key_F10, SLOTS, SLOT( allFilter() ), "all files" ); //actExecFilter = new KAction( i18n( "&Executables" ), SHIFT + Qt::Key_F11, // SLOTS, SLOT( execFilter() ), actionCollection(), "exec files" ); NEW_KACTION(actCustomFilter, i18n( "&Custom" ), 0, Qt::SHIFT + Qt::Key_F12, SLOTS, SLOT( customFilter() ), "custom files" ); NEW_KACTION(actCompare, i18n( "Compare b&y Content..." ), "kmultiple", 0, SLOTS, SLOT( compareContent() ), "compare" ); NEW_KACTION(actMultiRename, i18n( "Multi &Rename..." ), "krename", Qt::SHIFT + Qt::Key_F9, SLOTS, SLOT( multiRename() ), "multirename" ); KAction *t3, *t4, *t5, *t6, *t7, *t8, *t9, *t10, *t11, *t12, *t13, *t14, *t15, *t16; NEW_KACTION(t3, i18n( "Right-click Menu" ), 0, Qt::Key_Menu, SLOTS, SLOT( rightclickMenu() ), "rightclick menu" ); NEW_KACTION(t4, i18n( "Right Bookmarks" ), 0, Qt::ALT + Qt::Key_Right,SLOTS, SLOT( openRightBookmarks() ), "right bookmarks" ); NEW_KACTION(t5, i18n( "Left Bookmarks" ), 0, Qt::ALT + Qt::Key_Left, SLOTS, SLOT( openLeftBookmarks() ), "left bookmarks" ); NEW_KACTION(t6, i18n( "Bookmarks" ), 0, Qt::CTRL + Qt::Key_D, SLOTS, SLOT( openBookmarks() ), "bookmarks" ); NEW_KACTION(t7, i18n( "Bookmark Current" ), 0, Qt::CTRL + Qt::SHIFT + Qt::Key_D, SLOTS, SLOT( bookmarkCurrent() ), "bookmark current" ); NEW_KACTION(t8, i18n( "History" ), 0, Qt::CTRL + Qt::Key_H, SLOTS, SLOT( openHistory() ), "history" ); NEW_KACTION(t9, i18n( "Sync Panels" ), 0, Qt::ALT + Qt::Key_O, SLOTS, SLOT( syncPanels() ), "sync panels"); NEW_KACTION(t10, i18n( "Left History" ), 0, Qt::ALT + Qt::CTRL + Qt::Key_Left, SLOTS, SLOT( openLeftHistory() ), "left history" ); NEW_KACTION(t11, i18n( "Right History" ), 0, Qt::ALT + Qt::CTRL + Qt::Key_Right, SLOTS, SLOT( openRightHistory() ), "right history" ); NEW_KACTION(t12, i18n( "Media" ), 0, Qt::CTRL + Qt::Key_M, SLOTS, SLOT( openMedia() ), "media" ); NEW_KACTION(t13, i18n( "Left Media" ), 0, Qt::CTRL + Qt::SHIFT + Qt::Key_Left, SLOTS, SLOT( openLeftMedia() ), "left media" ); NEW_KACTION(t14, i18n( "Right Media" ), 0, Qt::CTRL + Qt::SHIFT + Qt::Key_Right, SLOTS, SLOT( openRightMedia() ), "right media" ); NEW_KACTION(t15, i18n( "New Symlink..." ), 0, Qt::CTRL + Qt::ALT + Qt::Key_S, SLOTS, SLOT( newSymlink() ), "new symlink"); NEW_KTOGGLEACTION(t16, i18n( "Toggle Popup Panel" ), 0, Qt::ALT + Qt::Key_Down, SLOTS, SLOT( togglePopupPanel() ), "toggle popup panel" ); NEW_KACTION(actVerticalMode, i18n( "Vertical Mode" ), "view-split-top-bottom", Qt::ALT + Qt::CTRL + Qt::Key_R, MAIN_VIEW, SLOT( toggleVerticalMode() ), "toggle vertical mode" ); NEW_KACTION(actNewTab, i18n( "New Tab" ), "tab-new", Qt::ALT + Qt::CTRL + Qt::Key_N, SLOTS, SLOT( newTab() ), "new tab" ); NEW_KACTION(actDupTab, i18n( "Duplicate Current Tab" ), "tab_duplicate", Qt::ALT + Qt::CTRL + Qt::SHIFT + Qt::Key_N, SLOTS, SLOT( duplicateTab() ), "duplicate tab" ); NEW_KACTION(actCloseTab, i18n( "Close Current Tab" ), "tab-close", Qt::CTRL + Qt::Key_W, SLOTS, SLOT( closeTab() ), "close tab" ); NEW_KACTION(actNextTab, i18n( "Next Tab" ), 0, Qt::SHIFT + Qt::Key_Right, SLOTS, SLOT( nextTab() ), "next tab" ); NEW_KACTION(actPreviousTab, i18n( "Previous Tab" ), 0, Qt::SHIFT + Qt::Key_Left, SLOTS, SLOT( previousTab() ), "previous tab" ); #if 0 actUserMenu = new KAction( i18n( "User Menu" ), ALT + Qt::Key_QuoteLeft, SLOTS, SLOT( userMenu() ), actionCollection(), "user menu" ); #else actUserMenu = new KActionMenu( i18n( "User&actions" ), this); actionCollection()->addAction( "useractionmenu", actUserMenu ); #endif NEW_KACTION(actManageUseractions, i18n( "Manage User Actions..." ), 0, 0, SLOTS, SLOT( manageUseractions() ), "manage useractions" ); actRemoteEncoding = new KrRemoteEncodingMenu(i18n("Select Remote Charset"), "character-set", actionCollection() ); // setup the Fn keys NEW_KACTION(actF2, i18n( "Start Terminal Here" ), "terminal", Qt::Key_F2, SLOTS, SLOT( terminal() ) , "F2_Terminal" ); NEW_KACTION(actF3, i18n( "View File" ), 0, Qt::Key_F3, SLOTS, SLOT( view() ), "F3_View" ); NEW_KACTION(actF4, i18n( "Edit File" ), 0, Qt::Key_F4, SLOTS, SLOT( edit() ) , "F4_Edit" ); NEW_KACTION(actF5, i18n( "Copy..." ), 0, Qt::Key_F5, SLOTS, SLOT( copyFiles() ) , "F5_Copy" ); NEW_KACTION(actF6, i18n( "Move..." ), 0, Qt::Key_F6, SLOTS, SLOT( moveFiles() ) , "F6_Move" ); + NEW_KACTION(actShiftF5, i18n( "Copy by queue..." ), 0, Qt::SHIFT + Qt::Key_F5, SLOTS, SLOT( copyFilesByQueue() ) , "F5_Copy_Queue" ); + NEW_KACTION(actShiftF6, i18n( "Move by queue..." ), 0, Qt::SHIFT + Qt::Key_F6, SLOTS, SLOT( moveFilesByQueue() ) , "F6_Move_Queue" ); NEW_KACTION(actF7, i18n( "New Directory..." ), "folder-new", Qt::Key_F7, SLOTS, SLOT( mkdir() ) , "F7_Mkdir" ); NEW_KACTION(actF8, i18n( "Delete" ), "edit-delete", Qt::Key_F8, SLOTS, SLOT( deleteFiles() ) , "F8_Delete" ); NEW_KACTION(actF9, i18n( "Rename" ), 0, Qt::Key_F9, SLOTS, SLOT( rename() ) , "F9_Rename" ); NEW_KACTION(actF10, i18n( "Quit" ), 0, Qt::Key_F10, this, SLOT( slotClose() ) , "F10_Quit" ); NEW_KACTION(actPopularUrls, i18n("Popular URLs..."), 0, Qt::CTRL + Qt::Key_Z, popularUrls, SLOT( showDialog() ), "Popular_Urls"); NEW_KACTION(actLocationBar, i18n("Go to Location Bar"), 0, Qt::CTRL + Qt::Key_L, SLOTS, SLOT( slotLocationBar() ), "location_bar"); NEW_KACTION(actJumpBack, i18n("Jump Back"), "kr_jumpback", Qt::CTRL + Qt::Key_J, SLOTS, SLOT( slotJumpBack() ), "jump_back"); NEW_KACTION(actSetJumpBack, i18n("Set Jump Back Point"), "kr_setjumpback", Qt::CTRL + Qt::SHIFT + Qt::Key_J,SLOTS, SLOT( slotSetJumpBack() ), "set_jump_back"); NEW_KACTION(actSwitchFullScreenTE, i18n( "Toggle Fullwidget Terminal Emulator" ), 0, Qt::CTRL + Qt::Key_F, MAIN_VIEW, SLOT( switchFullScreenTE() ), "switch_fullscreen_te" ); // and at last we can set the tool-tips actSelect->setToolTip( i18n( "Select files using a filter" ) ); actSelectAll->setToolTip( i18n("Select all files in the current directory" ) ); actUnselectAll->setToolTip( i18n( "Unselect all selected files" ) ); actKonfigurator->setToolTip( i18n( "Setup Krusader the way you like it" ) ); actBack->setToolTip( i18n( "Back to the place you came from" ) ); actRoot->setToolTip( i18n( "ROOT (/)" ) ); actFind->setToolTip( i18n( "Search for files" ) ); // setup all UserActions userAction = new UserAction(); #ifdef __KJSEMBED__ actShowJSConsole = new KAction( i18n( "JavaScript Console..." ), Qt::ALT + Qt::CTRL + Qt::Key_J, SLOTS, SLOT( jsConsole() ), actionCollection(), "JS_Console" ); #endif } /////////////////////////////////////////////////////////////////////////// //////////////////// implementation of slots ////////////////////////////// /////////////////////////////////////////////////////////////////////////// void Krusader::savePosition() { KConfigGroup cfg( config, "Private" ); cfg.writeEntry( "Maximized", isMaximized() ); if (isMaximized()) saveWindowSize(config->group("Private")); else { cfg.writeEntry( "Start Position", isMaximized() ? oldPos : pos() ); cfg.writeEntry( "Start Size", isMaximized() ? oldSize : size() ); } QList lst = mainView->horiz_splitter->sizes(); cfg.writeEntry( "Splitter Sizes", lst ); mainView->left->popup->saveSizes(); mainView->right->popup->saveSizes(); if( !MAIN_VIEW->getTerminalEmulatorSplitterSizes().isEmpty() ) cfg.writeEntry( "Terminal Emulator Splitter Sizes", MAIN_VIEW->getTerminalEmulatorSplitterSizes() ); // save view settings ---> fix when we have tabbed-browsing mainView->left->view->saveSettings(); mainView->right->view->saveSettings(); cfg = config->group( "Startup" ); cfg.writeEntry( "Vertical Mode", mainView->isVertical()); config->sync(); } void Krusader::saveSettings() { KConfigGroup cfg( krConfig, "Main Toolbar"); toolBar() ->saveSettings( cfg ); cfg = krConfig->group("Actions Toolbar"); toolBar("actionsToolBar")->saveSettings( cfg ); cfg = config->group( "Startup" ); cfg.writeEntry( "Left Active Tab", mainView->leftMng->activeTab() ); cfg.writeEntry( "Right Active Tab", mainView->rightMng->activeTab() ); cfg.writeEntry( "Left Side Is Active", mainView->activePanel->isLeft() ); mainView->leftMng->saveSettings( &cfg, "Left Tab Bar" ); mainView->rightMng->saveSettings( &cfg, "Right Tab Bar" ); bool rememberpos = cfg.readEntry( "Remember Position", _RememberPos ); bool uisavesettings = cfg.readEntry( "UI Save Settings", _UiSave ); // save the popup panel's page of the CURRENT tab cfg.writeEntry( "Left Panel Popup", mainView->left->popup->currentPage() ); cfg.writeEntry( "Right Panel Popup", mainView->right->popup->currentPage() ); // save size and position if ( rememberpos || uisavesettings ) { savePosition(); } // save the gui if ( uisavesettings ) { cfg = krConfig->group( "Startup" ); cfg.writeEntry( "Show status bar", actShowStatusBar->isChecked() ); cfg.writeEntry( "Show tool bar", actShowToolBar->isChecked() ); cfg.writeEntry( "Show FN Keys", actToggleFnkeys->isChecked() ); cfg.writeEntry( "Show Cmd Line", actToggleCmdline->isChecked() ); cfg.writeEntry( "Show Terminal Emulator", actToggleTerminal->isChecked() ); cfg.writeEntry( "Vertical Mode", mainView->isVertical()); cfg.writeEntry( "Start To Tray", isHidden()); } // save popular links popularUrls->save(); config->sync(); } void Krusader::refreshView() { delete mainView; mainView = new KrusaderView( this ); setCentralWidget( mainView ); KConfigGroup cfg( config, "Private" ); resize( cfg.readEntry( "Start Size", _StartSize ) ); move( cfg.readEntry( "Start Position", _StartPosition ) ); mainView->show(); show(); } void Krusader::configChanged() { KConfigGroup group( config, "Look&Feel"); bool minimizeToTray = group.readEntry( "Minimize To Tray", _MinimizeToTray ); bool singleInstanceMode = group.readEntry( "Single Instance Mode", _SingleInstanceMode ); if ( sysTray ) { if( !isHidden() ) { if( singleInstanceMode && minimizeToTray ) sysTray->show(); else sysTray->hide(); } else { if( minimizeToTray ) sysTray->show(); } } } void Krusader::slotClose() { directExit = true; close(); } bool Krusader::queryClose() { if ( isStarting || isExiting ) return false; if ( kapp->sessionSaving() ) // KDE is logging out, accept the close { saveSettings(); // Removes the DBUS registration of the application. Single instance mode requires unique appid. // As Krusader is exiting, we release that unique appid, so new Krusader instances // can be started. QDBusConnection dbus = QDBusConnection::sessionBus(); dbus.unregisterObject( "/Instances/" + Krusader::AppName ); KGlobal::deref(); // FIX: krusader exits at closing the viewer when minimized to tray sysTray->hide(); delete sysTray; // In KDE 4.1, KGlobal::ref() and deref() is done in KSystray constructor/destructor sysTray=NULL; KGlobal::deref(); // and close the application return isExiting = true; // this will also kill the pending jobs } KConfigGroup cfg = krConfig->group ( "Look&Feel" ); if ( !directExit && cfg.readEntry ( "Single Instance Mode", _SingleInstanceMode ) && cfg.readEntry ( "Minimize To Tray", _MinimizeToTray ) ) { hide(); return false; } // the shutdown process can be cancelled. That's why // the directExit variable is set to normal here. directExit = false; bool quit = true; if ( cfg.readEntry ( "Warn On Exit", _WarnOnExit ) ) { switch ( KMessageBox::warningYesNo ( this, i18n ( "Are you sure you want to quit?" ) ) ) { case KMessageBox::Yes : quit = true; break; case KMessageBox::No : quit = false; break; default: quit = false; } } if ( quit ) { /* First try to close the child windows, because it's the safer way to avoid crashes, then close the main window. If closing a child is not successful, then we cannot let the main window close. */ for ( ;; ) { QWidgetList list = QApplication::topLevelWidgets(); QWidget *activeModal = QApplication::activeModalWidget(); QWidget *w = list.at ( 0 ); if ( activeModal && activeModal != this && activeModal != menuBar() && /*activeModal != sysTray && ==> TODO: commented since KSystemTrayIcon is no longer a QWidget */ list.contains ( activeModal ) && !activeModal->isHidden() ) { w = activeModal; } else { int i=1; for ( ; iisHidden() || w==menuBar() ) ) ) break; } if( i == list.count() ) w = 0; } if ( !w ) break; bool hid = false; if ( w->inherits ( "KDialog" ) ) { // KDE is funny and rejects the close event for w->hide(); // playing a fancy animation with the CANCEL button. hid = true; // if we hide the widget, KDialog accepts the close event } if ( !w->close() ) { if ( hid ) w->show(); if ( w->inherits ( "QDialog" ) ) fprintf ( stderr, "Failed to close: %s\n", w->metaObject()->className() ); return false; } } saveSettings(); isExiting = true; hide(); // hide // Removes the DBUS registration of the application. Single instance mode requires unique appid. // As Krusader is exiting, we release that unique appid, so new Krusader instances // can be started. QDBusConnection dbus = QDBusConnection::sessionBus(); dbus.unregisterObject( "/Instances/" + Krusader::AppName ); KGlobal::deref(); // FIX: krusader exits at closing the viewer when minimized to tray sysTray->hide(); delete sysTray; // In KDE 4.1, KGlobal::ref() and deref() is done in KSystray constructor/destructor sysTray=NULL; KGlobal::deref(); // and close the application return false; // don't let the main widget close. It stops the pendig copies! //FIXME: The above intention does not work (at least in KDE 4.1), because the job //progress window (class KWidgetJobTracker::Private::ProgressWidget) //is closed above among other top level windows, and when closed //stops the copy. } else return false; } // the please wait dialog functions void Krusader::startWaiting( QString msg, int count , bool cancel ) { plzWait->startWaiting( msg , count, cancel ); } bool Krusader::wasWaitingCancelled() const { return plzWait->wasCancelled(); } void Krusader::stopWait() { plzWait->stopWait(); } void Krusader::updateUserActions() { KActionMenu *userActionMenu = (KActionMenu *) actUserMenu; if ( userActionMenu ) { userActionMenu->menu()->clear(); userActionMenu->addAction( krApp->actManageUseractions ); userActionMenu->addSeparator(); userAction->populateMenu( userActionMenu, NULL ); } } void Krusader::updateGUI( bool enforce ) { // now, check if we need to create a konsole_part // call the XML GUI function to draw the UI createGUI( mainView->terminal_dock->part() ); // this needs to be called AFTER createGUI() !!! updateUserActions(); KConfigGroup cfg_toolbar( krConfig, "Main Toolbar"); toolBar()->applySettings( cfg_toolbar ); KConfigGroup cfg_act( krConfig->group( "Actions Toolbar" ) ); toolBar("actionsToolBar") ->applySettings( cfg_act ); static_cast(actionCollection()->action("toggle actions toolbar"))-> setChecked(toolBar("actionsToolBar")->isVisible()); KConfigGroup cfg( krConfig, "Startup" ); if ( enforce ) { // now, hide what need to be hidden if ( !cfg.readEntry( "Show tool bar", _ShowToolBar ) ) { toolBar() ->hide(); actShowToolBar->setChecked( false ); } else { toolBar() ->show(); actShowToolBar->setChecked( true ); } if ( !cfg.readEntry( "Show status bar", _ShowStatusBar ) ) { statusBar() ->hide(); actShowStatusBar->setChecked( false ); } else { statusBar() ->show(); actShowStatusBar->setChecked( true ); } if ( !cfg.readEntry( "Show Cmd Line", _ShowCmdline ) ) { mainView->cmdLine->hide(); actToggleCmdline->setChecked( false ); } else { mainView->cmdLine->show(); actToggleCmdline->setChecked( true ); } // update the Fn bar to the shortcuts selected by the user mainView->fnKeys->updateShortcuts(); if ( !cfg.readEntry( "Show FN Keys", _ShowFNkeys ) ) { mainView->fnKeys->hide(); actToggleFnkeys->setChecked( false ); } else { mainView->fnKeys->show(); actToggleFnkeys->setChecked( true ); } // set vertical mode if (cfg.readEntry( "Vertical Mode", false)) { mainView->toggleVerticalMode(); } if ( cfg.readEntry( "Show Terminal Emulator", _ShowTerminalEmulator ) ) { mainView->slotTerminalEmulator( true ); // create konsole_part mainView->vert_splitter->setSizes( mainView->verticalSplitterSizes ); } else if ( actExecTerminalEmbedded->isChecked() ) { //create (but not show) terminal emulator, //if command-line commands are to be run there mainView->terminal_dock->initialise(); } } // popular urls popularUrls->load(); } // Adds one tool to the list in the supportedTools method void Krusader::supportedTool(QStringList &tools, QString toolType, QStringList names, QString confName) { QString foundTool = KrServices::chooseFullPathName( names, confName ); if (! foundTool.isEmpty() ) { tools.append( toolType ); tools.append( foundTool ); } } // return a list in the format of TOOLS,PATH. for example // DIFF,kdiff,TERMINAL,konsole,... // // currently supported tools: DIFF, MAIL, RENAME // // to use it: QStringList lst = supportedTools(); // int i = lst.indexOf("DIFF"); // if (i!=-1) pathToDiff=lst[i+1]; QStringList Krusader::supportedTools() { QStringList tools; // first, a diff program: kdiff supportedTool( tools, "DIFF", QStringList() << "kdiff3" << "kompare" << "xxdiff", "diff utility" ); // a mailer: kmail or thunderbird supportedTool( tools, "MAIL", QStringList() << "thunderbird" << "kmail", "mailer" ); // rename tool: krename supportedTool( tools, "RENAME", QStringList() << "krename", "krename" ); // checksum utility supportedTool( tools, "MD5", QStringList() << "md5deep" << "md5sum" << "sha1deep" << "sha256deep" << "tigerdeep" << "whirlpooldeep" << "cfv", "checksum utility" ); return tools; } QString Krusader::getTempDir() { // try to make krusader temp dir KConfigGroup group( krConfig, "General" ); QString tmpDir = group.readEntry( "Temp Directory", _TempDirectory ); if ( ! QDir( tmpDir ).exists() ) { for ( int i = 1 ; i != -1 ; i = tmpDir.indexOf( '/', i + 1 ) ) QDir().mkdir( tmpDir.left( i ) ); QDir().mkdir( tmpDir ); chmod( tmpDir.toLocal8Bit(), 0777 ); } // add a secure sub dir under the user UID QString uid; uid.sprintf( "%d", getuid() ); QDir( tmpDir ).mkdir( uid ); tmpDir = tmpDir + "/" + uid + "/"; chmod( tmpDir.toLocal8Bit(), S_IRUSR | S_IWUSR | S_IXUSR ); // add a random sub dir to use while ( QDir().exists( tmpDir ) ) tmpDir = tmpDir + KRandom::randomString( 8 ); QDir().mkdir( tmpDir ); if ( !QDir( tmpDir ).isReadable() ) { KMessageBox::error( krApp, "Could not create a temporary directory. Handling of Archives will not be possible until this is fixed." ); return QString(); } return tmpDir; } QString Krusader::getTempFile() { // try to make krusader temp dir KConfigGroup group( krConfig, "General" ); QString tmpDir = group.readEntry( "Temp Directory", _TempDirectory ); if ( ! QDir( tmpDir ).exists() ) { for ( int i = 1 ; i != -1 ; i = tmpDir.indexOf( '/', i + 1 ) ) QDir().mkdir( tmpDir.left( i ) ); QDir().mkdir( tmpDir ); chmod( tmpDir.toLocal8Bit(), 0777 ); } // add a secure sub dir under the user UID QString uid; uid.sprintf( "%d", getuid() ); QDir( tmpDir ).mkdir( uid ); tmpDir = tmpDir + "/" + uid + "/"; chmod( tmpDir.toLocal8Bit(), S_IRUSR | S_IWUSR | S_IXUSR ); while ( QDir().exists( tmpDir ) ) tmpDir = tmpDir + KRandom::randomString( 8 ); return tmpDir; } const char* Krusader::privIcon() { if ( geteuid() ) return "krusader_user"; else return "krusader_root"; } void Krusader::moveToTop() { if( isHidden() ) show(); KWindowSystem::forceActiveWindow( winId() ); } bool Krusader::isRunning() { moveToTop(); return true; } #include "krusader.moc" Index: trunk/kdereview/krusader/krusader/krslots.h =================================================================== --- trunk/kdereview/krusader/krusader/krslots.h (revision 975118) +++ trunk/kdereview/krusader/krusader/krslots.h (revision 975119) @@ -1,220 +1,224 @@ /*************************************************************************** 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 #include #include #include // the 2 following #includes should go away with the ugly stubs on the bottom #include "krusader.h" #include "krusaderview.h" #include "Panel/listpanel.h" #include "Panel/panelfunc.h" #include "BookMan/krbookmarkbutton.h" #include "GUI/kcmdline.h" #include "GUI/dirhistorybutton.h" #include "GUI/mediabutton.h" class ListPanel; class KUrl; 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() ) KIO::NetAccess::removeTempFile( tmp1 ); if( !tmp2.isEmpty() ) KIO::NetAccess::removeTempFile( tmp2 ); deleteLater(); } }; class KRslots : public QObject { Q_OBJECT public: enum compareMode { full } ; KRslots(QObject *parent): QObject(parent) {} ~KRslots() {} public slots: void createChecksum(); void matchChecksum(); void sendFileByEmail( const KUrl::List &filename ); void compareContent(); void compareContent( KUrl, KUrl ); void rightclickMenu(); void insertFileName(bool full_path); void rootKrusader(); void swapPanels(); void setView0(); void setView1(); void setView2(); void setView3(); void setView4(); void setView5(); void toggleHidden(); void toggleSwapSides(); void togglePopupPanel(); void configToolbar(); void configKeys(); void toggleToolbar(); void toggleActionsToolbar(); void toggleStatusbar(); void toggleTerminal(); void home(); void root(); void dirUp(); void markAll(); void unmarkAll(); void markGroup(); void markGroup(const QString &, bool select); void unmarkGroup(); void invert(); void compareDirs(); void compareSetup(); /** called by actExec* actions to choose the built-in command line mode */ void execTypeSetup(); void refresh(); void refresh( const KUrl& u ); void properties(); void back(); void slotPack(); void slotUnpack(); void cut(); void copy(); void paste(); void testArchive(); void calcSpace(); void FTPDisconnect(); void allFilter(); void execFilter(); void customFilter(); void newFTPconnection(); 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 homeTerminal(); void sysInfo(); void addBookmark(); void runMountMan(); void toggleFnkeys(); void toggleCmdline(); void changeTrashIcon(); void multiRename(); void openRightBookmarks() { RIGHT_PANEL->slotFocusOnMe(); RIGHT_PANEL->bookmarksButton->showMenu(); } void openLeftBookmarks() { LEFT_PANEL->slotFocusOnMe(); LEFT_PANEL->bookmarksButton->showMenu(); } void openBookmarks() { ACTIVE_PANEL->bookmarksButton->showMenu(); } void bookmarkCurrent(); void openHistory() { ACTIVE_PANEL->historyButton->showMenu(); } void openLeftHistory() { LEFT_PANEL->historyButton->showMenu(); } void openRightHistory() { RIGHT_PANEL->historyButton->showMenu(); } void openMedia() { ACTIVE_PANEL->mediaButton->showMenu(); } void openLeftMedia() { LEFT_PANEL->mediaButton->showMenu(); } void openRightMedia() { RIGHT_PANEL->mediaButton->showMenu(); } void syncPanels() { ListPanel *t = ACTIVE_PANEL; OTHER_FUNC->openUrl(ACTIVE_PANEL->virtualPath()); t->slotFocusOnMe(); } void cmdlinePopup() { MAIN_VIEW->cmdLine->popup(); } void duplicateTab(); void newTab(const KUrl& url = KUrl()); void newTab(KrViewItem *item); void closeTab(); void nextTab(); void previousTab(); void slotSplit(); void slotCombine(); void userMenu(); void manageUseractions(); void slotSynchronizeDirs( QStringList selected = QStringList() ); void slotSyncBrowse(); void slotDiskUsage(); void slotQueueManager(); void slotLocationBar(); void slotJumpBack(); void slotSetJumpBack(); void newSymlink() { ACTIVE_PANEL->func->krlink(true); } void updatePopupPanel(KrViewItem *); void windowActive(); // called when krusader's window becomes focussed void windowInactive(); // called when another application steals the focus // F2 void terminal(); // F3 void view(); // Shift F3 void viewDlg(); // F4 void edit(); // Shift F4 void editDlg(); // F5 void copyFiles(); // F6 void moveFiles(); + // SHIFT + F5 + void copyFilesByQueue(); + // SHIFT + F6 + void moveFilesByQueue(); // F7 void mkdir(); // F8 void deleteFiles(bool reallyDelete=false); // F9 void rename(); // ugly stubs, remove later ? void slotCurrentChanged( QString p ) { MAIN_VIEW->slotCurrentChanged( p ); } void slotSetActivePanel( ListPanel *p ) { MAIN_VIEW->slotSetActivePanel( p ); } void jsConsole(); void saveNewToolbarConfig(); }; #endif Index: trunk/kdereview/krusader/krusader/krusader.h =================================================================== --- trunk/kdereview/krusader/krusader/krusader.h (revision 975118) +++ trunk/kdereview/krusader/krusader/krusader.h (revision 975119) @@ -1,284 +1,285 @@ /*************************************************************************** krusader.h ------------------- begin : Thu May 4 2000 copyright : (C) 2000 by Shie Erlich & Rafi Yanai e-mail : krusader@users.sourceforge.net web site : http://krusader.sourceforge.net --------------------------------------------------------------------------- The main application ! what's more to say ? *************************************************************************** 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 KRUSADER_H #define KRUSADER_H #ifdef HAVE_CONFIG_H #include #endif // KDE includes #include #include #include #include #include #include #include #include #include #include #include #include #include "VFS/kiojobwrapper.h" #ifdef __KJSEMBED__ class KrJS; #endif class KrusaderStatus; class KRPleaseWaitHandler; class KrusaderView; class KRslots; class KIconLoader; class KSystemTrayIcon; class UserMenu; class UserAction; class Expander; class KMountMan; class KrBookmarkHandler; class PopularUrls; class QueueManager; //static QTextOStream krOut(stdout); #define krOut kDebug(50010) #define MAX_VIEWS 6 class Krusader : public KParts::MainWindow { Q_OBJECT Q_CLASSINFO("D-Bus Interface", "org.krusader.Instance") public: Krusader(); virtual ~Krusader(); void refreshView(); // re-create the main view void configChanged(); /** * This returns a defferent icon if krusader runs with root-privileges * @return a character string with the specitif icon-name */ static const char* privIcon(); static QStringList supportedTools(); // find supported tools void moveToTop(); public slots: void statusBarUpdate( QString& mess ); // in use by Krusader only void saveSettings(); void savePosition(); void updateUserActions(); void updateGUI( bool enforce = false ); void slotClose(); void setDirectExit() { directExit = true; } protected: bool queryExit() { config->sync(); return true; } bool queryClose(); void setupActions(); void setupAccels(); bool versionControl(); // handle version differences in krusaderrc void showEvent ( QShowEvent * ); void hideEvent ( QHideEvent * ); void moveEvent ( QMoveEvent * ); void resizeEvent ( QResizeEvent * ); public Q_SLOTS: Q_SCRIPTABLE bool isRunning(); public: static Krusader *App; // a kApp style pointer static QString AppName; // the name of the application KMountMan *mountMan; // krusader's Mount Manager KrusaderView *mainView; // The GUI KConfig *config; // allow everyone to access the config KIconLoader *iconLoader; // the app's icon loader PopularUrls *popularUrls; // holds a sorted list of the most popular urls visited QueueManager *queueManager; // Actions static KAction *actProperties, *actPack, *actUnpack, *actTest, *actCompare, *actCmdlinePopup; static KAction *actCalculate, *actSelect, *actUnselect, *actSelectAll, *actLocate, *actSwitchFullScreenTE; static KAction *actUnselectAll, *actInvert, *actSync, *actDiskUsage, *actSavePosition, *actCompDirs; static KAction *actHomeTerminal, *actFTPConnect, *actFTPNewConnect, *actFTPDisconnect, *actProfiles; static KAction *actExecFilter, *actCustomFilter, *actMountMan, *actNewTool, *actSwapPanels, *actSwapSides; static KAction *actKonfigurator, *actToolsSetup, *actBack, *actRoot, *actFind, *actDirUp, *actRemoteEncoding; static KAction *actSelectColorMask, *actMultiRename, *actAllFilter, *actOpenLeftBm, *actOpenRightBm; static KAction *actNewTab, *actDupTab, *actCloseTab, *actPreviousTab, *actNextTab, *actSplit, *actQueueManager; static KAction *actCombine, *actUserMenu, *actManageUseractions, *actSyncDirs, *actSyncBrowse; static KAction *actF2, *actF3, *actF4, *actF5, *actF6, *actF7, *actF8, *actF9, *actF10, *actVerticalMode; + static KAction *actShiftF5, *actShiftF6; static KAction *actPopularUrls, *actLocationBar, *actJumpBack, *actSetJumpBack, *actCreateChecksum, *actMatchChecksum; static KAction *actView0, *actView1, *actView2, *actView3, *actView4, *actView5, *actCopy, *actPaste; static KToggleAction *actToggleTerminal; static KAction *actSelectNewerAndSingle, *actSelectNewer, *actSelectSingle, *actSelectDifferentAndSingle, *actSelectDifferent; /** actions for setting the execution mode of commands from commanddline */ static KAction *actExecStartAndForget, *actExecCollectSeparate,*actExecCollectTogether, *actExecTerminalExternal,*actExecTerminalEmbedded; KToggleAction *actToggleFnkeys, *actToggleCmdline, *actShowToolBar, *actShowStatusBar, *actToggleHidden, *actCompareDirs; static KAction **compareArray[]; /** actions for setting the execution mode of commands from commanddline */ static KAction **execTypeArray[]; static int viewIds[ MAX_VIEWS ]; // return a path to a temp dir or file we can use. QString getTempDir(); QString getTempFile(); // the internal progress bar variales + functions KRPleaseWaitHandler* plzWait; void startWaiting( QString msg = "Please Wait", int count = 0 , bool cancel = false ); void stopWait(); bool wasWaitingCancelled() const; KrusaderStatus *status; KRslots *slot; static KMenu *userActionMenu; static UserMenu *userMenu; static UserAction *userAction; static KrBookmarkHandler *bookman; #ifdef __KJSEMBED__ static KrJS *js; static KAction *actShowJSConsole; #endif signals: void changeMessage( QString ); private: KSystemTrayIcon *sysTray; QPoint oldPos; QSize oldSize; bool isStarting; bool isExiting; bool directExit; KrJobStarter jobStarter; static void supportedTool(QStringList &tools, QString toolType, QStringList names, QString confName); }; // main modules #define krApp Krusader::App #define krConfig Krusader::App->config #define krMtMan (*(Krusader::App->mountMan)) #define krBookMan Krusader::App->bookman #define SLOTS Krusader::App->slot #define krLoader Krusader::App->iconLoader #define MAIN_VIEW (krApp->mainView) #define ACTIVE_MNG (MAIN_VIEW->activeManager()) #define ACTIVE_PANEL (MAIN_VIEW->activePanel) #define ACTIVE_FUNC (ACTIVE_PANEL->func) #define OTHER_MNG (MAIN_VIEW->inactiveManager()) #define OTHER_PANEL (ACTIVE_PANEL->otherPanel) #define OTHER_FUNC (OTHER_PANEL->func) #define LEFT_PANEL (MAIN_VIEW->left) #define LEFT_FUNC (LEFT_PANEL->func) #define LEFT_MNG (MAIN_VIEW->leftMng) #define RIGHT_PANEL (MAIN_VIEW->right) #define RIGHT_FUNC (RIGHT_PANEL->func) #define RIGHT_MNG (MAIN_VIEW->rightMng) // krusader's actions - things krusader can do! #define krProperties Krusader::App->actProperties // file properties #define krPack Krusader::App->actPack // pack files into an archive #define krUnpack Krusader::App->actUnpack // unpack archive #define krTest Krusader::App->actTest // test archive #define krCompare Krusader::App->actCompare // compare 2 files by content #define krCalculate Krusader::App->actCalculate // calculate occupied space #define krCreateCS Krusader::App->actCreateChecksum #define krMatchCS Krusader::App->actMatchChecksum #define krSelect Krusader::App->actSelect // select a group by filter #define krSelectAll Krusader::App->actSelectAll // select all files #define krUnselect Krusader::App->actUnselect // unselect by filter #define krUnselectAll Krusader::App->actUnselectAll // remove all selections #define krInvert Krusader::App->actInvert // invert the selection #define krSyncDirs Krusader::App->actSync // syncronize directories #define krHomeTerm Krusader::App->actHomeTerminal // open terminal@home dir #define krFTPConnect Krusader::App->actFTPConnect // connect to an ftp #define krFTPNew Krusader::App->actFTPNewConnect // create a new connection #define krFTPDiss Krusader::App->actFTPDisconnect // disconnect an FTP session #define krRemoteEncoding Krusader::App->actRemoteEncoding // remote encoding menu #define krAllFiles Krusader::App->actAllFilter // show all files in list #define krExecFiles Krusader::App->actExecFilter // show only executables #define krCustomFiles Krusader::App->actCustomFilter // show a custom set of files #define krMountMan Krusader::App->actMountMan // run Mount-manager #define krNewTool Krusader::App->actNewTool // Add a new tool to menu #define krKonfigurator Krusader::App->actKonfigurator #define krToolsSetup Krusader::App->actToolsSetup // setup the tools menu #define krBack Krusader::App->actBack #define krRoot Krusader::App->actRoot #define krFind Krusader::App->actFind // find files #define krMultiRename Krusader::App->actMultiRename #define krToggleTerminal Krusader::App->actToggleTerminal #define krToggleSortByExt Krusader::App->actToggleSortByExt// Sort by extention #define krOpenLeftBm Krusader::App->actOpenLeftBm // open left bookmarks #define krOpenRightBm Krusader::App->actOpenRightBm // open left bookmarks #define krDirUp Krusader::App->actDirUp #define krCmdlinePopup Krusader::App->actCmdlinePopup #define krNewTab Krusader::App->actNewTab #define krDupTab Krusader::App->actDupTab #define krCloseTab Krusader::App->actCloseTab #define krNextTab Krusader::App->actNextTab #define krPreviousTab Krusader::App->actPreviousTab #define krSplit Krusader::App->actSplit #define krCombine Krusader::App->actCombine #define krUserMenu Krusader::App->actUserMenu #define krUserActionMenu Krusader::App->userActionMenu #define krUserAction Krusader::App->userAction #define krF2 Krusader::App->actF2 #define krF3 Krusader::App->actF3 #define krF4 Krusader::App->actF4 #define krF5 Krusader::App->actF5 #define krF6 Krusader::App->actF6 #define krF7 Krusader::App->actF7 #define krF8 Krusader::App->actF8 #define krF9 Krusader::App->actF9 #define krF10 Krusader::App->actF10 #define krPopularUrls Krusader::App->actPopularUrls #define krLocationBar Krusader::App->actLocationBar #define krJumpBack Krusader::App->actJumpBack #define krSetJumpBack Krusader::App->actSetJumpBack #ifdef __KJSEMBED__ #define krJS Krusader::App->js #define krJSConsole Krusader::App->actShowJSConsole #endif #endif Index: trunk/kdereview/krusader/krusader/krslots.cpp =================================================================== --- trunk/kdereview/krusader/krusader/krslots.cpp (revision 975118) +++ trunk/kdereview/krusader/krusader/krslots.cpp (revision 975119) @@ -1,973 +1,977 @@ /*************************************************************************** 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 #include #include #include #include #include #include // KDE includes #include #include #include #include #include #include #include #include "KViewer/krviewer.h" #include "Panel/krviewfactory.h" #ifdef __KJSEMBED__ #include "KrJS/krjs.h" #include #endif // Krusader includes #include "krslots.h" #include "krusader.h" #include "krusaderview.h" #include "Panel/listpanel.h" #include "Panel/krselectionmode.h" #include "Dialogs/krdialogs.h" #include "Dialogs/krspwidgets.h" #include "Dialogs/krkeydialog.h" #include "GUI/krusaderstatus.h" #include "Panel/panelfunc.h" #include "Konfigurator/konfigurator.h" #include "MountMan/kmountman.h" #include "defaults.h" #include "resources.h" #include "GUI/kfnkeys.h" #include "GUI/kcmdline.h" #include "GUI/terminaldock.h" #include "GUI/syncbrowsebutton.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 "Synchronizer/synchronizergui.h" #include "DiskUsage/diskusagegui.h" #include "krservices.h" #include "Panel/krviewitem.h" #include "Queue/queuedialog.h" #define REFRESH_BOTH_PANELS { ListPanel *p=ACTIVE_PANEL; \ MAIN_VIEW->left->func->refresh(); \ MAIN_VIEW->right->func->refresh();\ p->slotFocusOnMe(); } #define ACTIVE_PANEL_MANAGER (ACTIVE_PANEL == krApp->mainView->left ? krApp->mainView->leftMng : \ krApp->mainView->rightMng) void KRslots::sendFileByEmail(const KUrl::List &urls) { if( urls.count() == 0 ) { KMessageBox::error(0,i18n("No selected files to send!")); return; } QString mailProg; QStringList lst = Krusader::supportedTools(); if (lst.contains("MAIL")) mailProg=lst[lst.indexOf("MAIL") + 1]; else { KMessageBox::error(0,i18n("Krusader can't find a supported mail client. Please install one to your path. Hint: Krusader supports Kmail.")); return; } QString subject, separator; foreach( KUrl url, urls ) { subject += separator + url.fileName(); separator=","; } subject = i18np("Sending file: %2", "Sending files: %2", urls.count(), subject); KProcess proc; if ( KUrl( mailProg ).fileName() == "kmail") { proc << mailProg << "--subject" << subject; foreach( KUrl url2, urls ) proc << "--attach" << url2.prettyUrl(); } else if ( KUrl( mailProg ).fileName() == "thunderbird") { QString param="attachment=\'"; separator = ""; foreach( KUrl url2, urls ) { param += separator + url2.prettyUrl(); separator=","; } param+="\',subject=\'" + subject + "\'"; proc << mailProg << "--compose" << param; } else if ( KUrl( mailProg ).fileName() == "evolution") { QString param="mailto:?cc=&subject=" + subject + "&attach="; separator = ""; foreach( KUrl url2, urls ){ param += separator + url2.prettyUrl(); separator = "&attach="; } proc << mailProg << param + ""; } if (!proc.startDetached()) KMessageBox::error(0, i18n("Error executing %1!", mailProg)); } void KRslots::compareContent() { QStringList lstLeft, lstRight; QStringList* lstActive; KUrl name1, name2; MAIN_VIEW->left->getSelectedNames( &lstLeft ); MAIN_VIEW->right->getSelectedNames( &lstRight ); lstActive = ( ACTIVE_PANEL->isLeft() ? &lstLeft : &lstRight ); if ( lstLeft.count() == 1 && lstRight.count() == 1 ) { // first, see if we've got exactly 1 selected file in each panel: name1 = MAIN_VIEW->left->func->files()->vfs_getFile( lstLeft[0] ); name2 = MAIN_VIEW->right->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_PANEL->view->getCurrentItem() ) ) { // next try: is in the other panel a file with the same name? name1 = ACTIVE_PANEL->func->files()->vfs_getFile( ACTIVE_PANEL->view->getCurrentItem() ); name2 = ACTIVE_PANEL->otherPanel->func->files()->vfs_getFile( ACTIVE_PANEL->view->getCurrentItem() ); } else { // if we got here, then we can't be sure what file to diff KMessageBox::detailedError(0, i18n("Don't 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 kdiff // but if one of the files isn't local, download them first compareContent( name1, name2 ); } void KRslots::compareContent( KUrl url1, KUrl url2 ) { QString diffProg; QStringList lst = Krusader::supportedTools(); if (lst.contains("DIFF")) diffProg=lst[lst.indexOf("DIFF") + 1]; else { KMessageBox::error(0,i18n("Krusader can't 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 = QString(); // kdiff3 sucks with spaces if( KUrl( diffProg ).fileName() == "kdiff3" && !url1.prettyUrl().contains(" ") && !url2.prettyUrl().contains(" ") ) { tmp1 = url1.prettyUrl(); tmp2 = url2.prettyUrl(); } else { if (!url1.isLocalFile()) { if( !KIO::NetAccess::download( url1, tmp1, 0 ) ){ KMessageBox::sorry(krApp, i18n("Krusader is unable to download %1", url1.fileName())); return; } } else tmp1 = url1.path(); if (!url2.isLocalFile()) { if( !KIO::NetAccess::download( url2, tmp2, 0 ) ){ KMessageBox::sorry(krApp,i18n("Krusader is unable to download %1", url2.fileName())); if( tmp1 != url1.path() ) KIO::NetAccess::removeTempFile( 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)); } void KRslots::rightclickMenu() { if( ACTIVE_PANEL->view->getCurrentKrViewItem() ) { ACTIVE_PANEL->popRightClickMenu( ACTIVE_PANEL->mapToGlobal( ACTIVE_PANEL->view->getCurrentKrViewItem()->itemRect().topLeft() ) ); } } void KRslots::addBookmark(){ // TODO: this no longer works! } // 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::toggleToolbar() { if (krApp->toolBar()->isVisible()) krApp->toolBar()->hide(); else krApp->toolBar()->show(); } void KRslots::toggleActionsToolbar() { if (krApp->toolBar("actionsToolBar")->isVisible()) krApp->toolBar("actionsToolBar")->hide(); else krApp->toolBar("actionsToolBar")->show(); } void KRslots::toggleStatusbar() { if (krApp->statusBar()->isVisible()) krApp->statusBar()->hide(); else krApp->statusBar()->show(); } void KRslots::toggleTerminal() { if( MAIN_VIEW->terminal_dock->isVisible() ) MAIN_VIEW->slotTerminalEmulator(false); else MAIN_VIEW->slotTerminalEmulator(true); } void KRslots::insertFileName(bool full_path) { QString filename = ACTIVE_PANEL->view->getCurrentItem(); if( filename == QString() ) return; if( full_path ){ QString path=vfs::pathOrUrl(ACTIVE_FUNC->files()->vfs_getOrigin(), KUrl::AddTrailingSlash ); filename = path+filename; } filename = KrServices::quote( filename ); if(MAIN_VIEW->cmdLine->isVisible() || !MAIN_VIEW->terminal_dock->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->terminal_dock->isTerminalVisible() ){ filename = QString( " " ) + filename + QString( " " ); MAIN_VIEW->terminal_dock->sendInput( filename ); MAIN_VIEW->terminal_dock->setFocus(); } } // directory list functions void KRslots::allFilter() { ACTIVE_PANEL->setFilter(KrViewProperties::All); } void KRslots::execFilter() { ACTIVE_PANEL->setFilter(KrViewProperties::All); } void KRslots::customFilter() { ACTIVE_PANEL->setFilter(KrViewProperties::Custom); } void KRslots::markAll() { ACTIVE_PANEL->select(true,true); } void KRslots::unmarkAll() { ACTIVE_PANEL->select(false,true); } void KRslots::markGroup() { ACTIVE_PANEL->select(true,false); } void KRslots::markGroup(const QString& mask, bool select) { ACTIVE_PANEL->select( KRQuery( mask ), select); } void KRslots::unmarkGroup() { ACTIVE_PANEL->select(false,false); } void KRslots::invert() { ACTIVE_PANEL->invertSelection(); } void KRslots::root() { ACTIVE_FUNC->openUrl(KUrl("/"));} void KRslots::refresh(const KUrl& u){ ACTIVE_FUNC->openUrl(u); } void KRslots::home() { ACTIVE_FUNC->openUrl(QDir::homePath()); } void KRslots::refresh() { ACTIVE_FUNC->refresh(); } void KRslots::properties() { ACTIVE_FUNC->properties(); } void KRslots::dirUp() { ACTIVE_FUNC->dirUp(); } void KRslots::back() { ACTIVE_FUNC->goBack(); } void KRslots::slotPack() { ACTIVE_FUNC->pack(); } void KRslots::slotUnpack() { ACTIVE_FUNC->unpack(); } void KRslots::testArchive() { ACTIVE_FUNC->testArchive(); } void KRslots::calcSpace() { ACTIVE_FUNC->calcSpace(); } void KRslots::FTPDisconnect() { ACTIVE_FUNC->FTPDisconnect(); } void KRslots::newFTPconnection(){ ACTIVE_FUNC->newFTPconnection(); } void KRslots::cut() { ACTIVE_FUNC->copyToClipboard( true ); } void KRslots::copy() { ACTIVE_FUNC->copyToClipboard( false ); } void KRslots::paste() { ACTIVE_FUNC->pasteFromClipboard(); } void KRslots::createChecksum() { ACTIVE_FUNC->createChecksum(); } void KRslots::matchChecksum() { ACTIVE_FUNC->matchChecksum(); } // run external modules / programs void KRslots::runKonfigurator(bool firstTime) { KConfigGroup group( krConfig, "Look&Feel"); KConfigGroup groupgen( krConfig, "General"); int size = (group.readEntry("Filelist Icon Size",_FilelistIconSize)).toInt(); Konfigurator *konfigurator = new Konfigurator(firstTime); vfile::vfile_enableMimeTypeMagic( groupgen.readEntry( "Mimetype Magic", _MimetypeMagic ) ); if( konfigurator->isGUIRestartNeeded() ) { vfile::vfile_loadUserDefinedFolderIcons( group.readEntry( "Load User Defined Folder Icons", _UserDefinedFolderIcons ) ); if((group.readEntry("Filelist Icon Size",_FilelistIconSize)).toInt() != size ) QPixmapCache::clear(); QList views = KrViewFactory::registeredViews(); foreach( KrViewInstance * inst, views ) KrViewFactory::itemHeightChanged( inst->id() ); MAIN_VIEW->leftMng->slotRecreatePanels(); MAIN_VIEW->rightMng->slotRecreatePanels(); MAIN_VIEW->fnKeys->updateShortcuts(); KrSelectionMode::resetSelectionHandler(); } krApp->configChanged(); delete konfigurator; } void KRslots::setView0() { if( ACTIVE_PANEL && ACTIVE_PANEL->getType() != Krusader::viewIds[ 0 ] ) ACTIVE_PANEL->changeType( Krusader::viewIds[ 0 ] ); } void KRslots::setView1() { if( ACTIVE_PANEL && ACTIVE_PANEL->getType() != Krusader::viewIds[ 1 ] ) ACTIVE_PANEL->changeType( Krusader::viewIds[ 1 ] ); } void KRslots::setView2() { if( ACTIVE_PANEL && ACTIVE_PANEL->getType() != Krusader::viewIds[ 2 ] ) ACTIVE_PANEL->changeType( Krusader::viewIds[ 2 ] ); } void KRslots::setView3() { if( ACTIVE_PANEL && ACTIVE_PANEL->getType() != Krusader::viewIds[ 3 ] ) ACTIVE_PANEL->changeType( Krusader::viewIds[ 3 ] ); } void KRslots::setView4() { if( ACTIVE_PANEL && ACTIVE_PANEL->getType() != Krusader::viewIds[ 4 ] ) ACTIVE_PANEL->changeType( Krusader::viewIds[ 4 ] ); } void KRslots::setView5() { if( ACTIVE_PANEL && ACTIVE_PANEL->getType() != Krusader::viewIds[ 5 ] ) ACTIVE_PANEL->changeType( Krusader::viewIds[ 5 ] ); } void KRslots::toggleHidden(){ KConfigGroup group( krConfig, "Look&Feel"); bool show = !group.readEntry("Show Hidden",_ShowHidden); krApp->actToggleHidden->setChecked(show); group.writeEntry("Show Hidden",show); MAIN_VIEW->leftMng->refreshAllTabs( true ); MAIN_VIEW->rightMng->refreshAllTabs( true ); } void KRslots::swapPanels(){ KUrl leftURL = MAIN_VIEW->left->func->files()->vfs_getOrigin(); KUrl rightURL = MAIN_VIEW->right->func->files()->vfs_getOrigin(); MAIN_VIEW->left->func->openUrl( rightURL ); MAIN_VIEW->right->func->openUrl( leftURL ); } void KRslots::toggleSwapSides(){ QList lst = MAIN_VIEW->horiz_splitter->sizes(); MAIN_VIEW->horiz_splitter->addWidget( MAIN_VIEW->leftMng ); int old = lst[ 0 ]; lst[ 0 ] = lst [ 1 ]; lst[ 1 ] = old; MAIN_VIEW->horiz_splitter->setSizes( lst ); ListPanel *tmpPanel; // temporary variables for swapping PanelManager *tmpMng; tmpMng = MAIN_VIEW->leftMng; MAIN_VIEW->leftMng = MAIN_VIEW->rightMng; MAIN_VIEW->rightMng = tmpMng; tmpPanel = MAIN_VIEW->left; MAIN_VIEW->left = MAIN_VIEW->right; MAIN_VIEW->right = tmpPanel; MAIN_VIEW->leftMng->swapPanels(); MAIN_VIEW->rightMng->swapPanels(); MAIN_VIEW->left->updateGeometry(); MAIN_VIEW->right->updateGeometry(); } 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( "Can't 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::runMountMan() { // left as a precaution, although we use kde's services now if( !KrServices::cmdExist( "df" ) || !KrServices::cmdExist( "mount" ) ) { KMessageBox::error(0, i18n("Can't start 'mount'! Check the 'Dependencies' page in konfigurator.")); return; } krApp->mountMan->mainWindow(); } void KRslots::runTerminal( const QString & dir, const QStringList & args ){ KProcess proc; proc.setWorkingDirectory( dir ); KConfigGroup group( krConfig, "General"); QString term = group.readEntry("Terminal",_Terminal); QStringList sepdArgs = KrServices::separateArgs( term ); 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 0 // I hope this is no longer needed... if( term.contains( "konsole" ) ) /* KDE 3.2 bug (konsole is killed by pressing Ctrl+C) */ { /* Please remove the patch if the bug is corrected */ proc << "&"; proc.setUseShell( true ); } #endif if(!proc.startDetached()) KMessageBox::sorry(krApp,i18n("Error executing %1!", term)); } void KRslots::homeTerminal(){ runTerminal( QDir::homePath(), QStringList() ); } void KRslots::sysInfo(){ KProcess proc; proc << KrServices::fullPathName("kcmshell") << "System/ksysctrl"; if (!proc.startDetached()){ KMessageBox::sorry(krApp,i18n("Can't find \"KsysCtrl\". Please install KDE admin package")); } } void KRslots::multiRename(){ QStringList lst = Krusader::supportedTools(); int i = lst.indexOf("RENAME"); if (i == -1){ KMessageBox::sorry(krApp,i18n("Can't find a batch rename tool.\nYou can get Krename at http://www.krename.net")); return; } QString pathToRename = lst[i+1]; QStringList names; ((ListPanel*)ACTIVE_PANEL)->getSelectedNames(&names); KUrl::List* urls = ACTIVE_FUNC->files()->vfs_getFiles(&names); if( urls->isEmpty() ){ delete urls; return; } KProcess proc; proc << pathToRename; for( KUrl::List::iterator u=urls->begin(); u != urls->end(); ++u){ if( QFileInfo((*u).path()).isDir() ) proc << "-r"; proc << (*u).path(); } if (!proc.startDetached()) KMessageBox::error(0,i18n("Error executing %1!", pathToRename)); delete urls; } void KRslots::rootKrusader() { if( !KrServices::cmdExist( "krusader" ) || !KrServices::cmdExist( "kdesu" ) ) { KMessageBox::sorry( krApp, i18n( "Can't 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" ) << KrServices::fullPathName( "krusader" ) + " --left=" + MAIN_VIEW->left->func->files()->vfs_getOrigin().url() + " --right=" + MAIN_VIEW->right->func->files()->vfs_getOrigin().url(); if (!proc.startDetached()) KMessageBox::error(0,i18n("Error executing %1!", proc.program()[0])); } // settings slots void KRslots::configToolbar(){ KConfigGroup cg(KGlobal::config(), QString()); krApp->saveMainWindowSettings(cg); KEditToolBar dlg(krApp->factory()); connect( &dlg, SIGNAL( newToolBarConfig() ), this, SLOT( saveNewToolbarConfig() ) ); if (dlg.exec()) krApp->updateGUI(); } void KRslots::saveNewToolbarConfig() { KConfigGroup cg(KGlobal::config(), QString()); krApp->applyMainWindowSettings(cg); krApp->updateGUI(); } void KRslots::configKeys(){ KrKeyDialog( MAIN_VIEW ); } // misc void KRslots::changeTrashIcon(){ #if 0 // TODO: is this needed? // update trash bin icon - this is "stolen" konqi code // Copyright (C) 2000 David Faure KUrl trash; trash.setPath(KGlobalSettings::trashPath()); KUrl::List lst; lst.append(trash); KDirNotify_stub allDirNotify("*","KDirNotify*"); allDirNotify.FilesChanged( lst ); // end of konqi code #endif } // F2 void KRslots::terminal() { ACTIVE_FUNC->terminal(); } // F3 void KRslots::view() { ACTIVE_FUNC->view(); } // F4 void KRslots::edit() { ACTIVE_FUNC->editFile(); } // F5 void KRslots::copyFiles() { ACTIVE_FUNC->copyFiles(); } // F6 void KRslots::moveFiles() { ACTIVE_FUNC->moveFiles(); } +// SHIFT + F5 +void KRslots::copyFilesByQueue() { ACTIVE_FUNC->copyFiles( true ); } +// SHIFT + F6 +void KRslots::moveFilesByQueue() { ACTIVE_FUNC->moveFiles( true ); } // F7 void KRslots::mkdir() { ACTIVE_FUNC->mkdir(); } // F8 void KRslots::deleteFiles(bool reallyDelete) { ACTIVE_FUNC->deleteFiles(reallyDelete);} // F9 void KRslots::rename() { ACTIVE_FUNC->rename(); } // Shift F3 void KRslots::viewDlg(){ // ask the user for a url to view KUrl dest = KChooseDir::getDir(i18n("Enter a URL to view:"), ACTIVE_PANEL->virtualPath(), ACTIVE_PANEL->virtualPath()); if ( dest.isEmpty() ) return ; // the user canceled KrViewer::view( dest ); // view the file // } // nothing more to it! } // Shift F4 void KRslots::editDlg(){ // ask the user for the filename to edit KUrl dest = KChooseDir::getDir(i18n("Enter the filename to edit:"), ACTIVE_PANEL->virtualPath(), ACTIVE_PANEL->virtualPath()); if ( dest.isEmpty() ) return ; // the user canceled KrViewer::edit( dest ); if( dest.upUrl().equals( ACTIVE_PANEL->virtualPath(), KUrl::CompareWithoutTrailingSlash ) ) refresh(); } void KRslots::duplicateTab() { ACTIVE_PANEL_MANAGER->slotNewTab(ACTIVE_PANEL->virtualPath()); } // ugly: do this right before release! void KRslots::newTab(const KUrl& url) { if (url.isValid()) ACTIVE_PANEL_MANAGER->slotNewTab(url); else ACTIVE_PANEL_MANAGER->slotNewTab(); } void KRslots::nextTab() { ACTIVE_PANEL_MANAGER->slotNextTab(); } void KRslots::previousTab() { ACTIVE_PANEL_MANAGER->slotPreviousTab(); } void KRslots::newTab(KrViewItem *it) { if (!it) return; if( it->name() == ".." ) { KUrl url = ACTIVE_PANEL->virtualPath(); ACTIVE_PANEL_MANAGER->slotNewTab( url.upUrl() ); } else if (ITEM2VFILE(ACTIVE_PANEL, it)->vfile_isDir()) { KUrl url = ACTIVE_PANEL->virtualPath(); url.addPath( it->name() ); ACTIVE_PANEL_MANAGER->slotNewTab( url ); } } void KRslots::closeTab() { ACTIVE_PANEL_MANAGER->slotCloseTab(); } void KRslots::slotSplit() { QStringList list; QString name; ((ListPanel*)ACTIVE_PANEL)->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("Don't know which file to split.")); return; } KUrl 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 can't split a directory!" ) ); return ; } KUrl destDir = ACTIVE_PANEL->otherPanel->func->files()->vfs_getOrigin(); SplitterGUI splitterGUI( MAIN_VIEW, fileURL, destDir ); if( splitterGUI.result() == QDialog::Accepted ) { bool splitToOtherPanel = ( splitterGUI.getDestinationDir().equals( ACTIVE_PANEL->otherPanel->virtualPath(), KUrl::CompareWithoutTrailingSlash ) ); Splitter split( MAIN_VIEW, fileURL, splitterGUI.getDestinationDir() ); split.split( splitterGUI.getSplitSize() ); if ( splitToOtherPanel ) ACTIVE_PANEL->otherPanel->func->refresh(); } } void KRslots::slotCombine(){ QStringList list; KUrl baseURL; bool unixStyle = false; bool windowsStyle = false; QString commonName = QString(); int commonLength = 0; ((ListPanel*)ACTIVE_PANEL)->getSelectedNames(&list); if ( list.isEmpty() ) { KMessageBox::error(0,i18n("Don't know which files to combine.")); return; } /* checking splitter names */ for ( QStringList::Iterator it = list.begin(); it != list.end(); ++it ) { KUrl 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 can't combine a directory!" ) ); return ; } if( !unixStyle ) { QString name = url.fileName(); int extPos = name.lastIndexOf( '.' ); QString ext = name.mid( extPos + 1 ); name.truncate( extPos ); url.setFileName( 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.pathOrUrl() )); 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(); baseURL.addPath( testFile ); } } error = ( commonName == shortName ); } else if( commonLength == shortName.length() && shortName.startsWith( commonName ) ) error = false; } }while ( false ); if( error ) { KMessageBox::error(0,i18n("Not a splitted file %1!", url.pathOrUrl() )); return; } } } // ask the user for the copy dest KUrl dest = KChooseDir::getDir(i18n("Combining %1.* to directory:", baseURL.pathOrUrl() ), ACTIVE_PANEL->otherPanel->virtualPath(), ACTIVE_PANEL->virtualPath()); if ( dest.isEmpty() ) return ; // the user canceled bool combineToOtherPanel = ( dest.equals( ACTIVE_PANEL->otherPanel->virtualPath(), KUrl::CompareWithoutTrailingSlash ) ); 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 ); } void KRslots::slotSynchronizeDirs( QStringList selected ) { new SynchronizerGUI( 0, MAIN_VIEW->left->func->files()->vfs_getOrigin(), MAIN_VIEW->right->func->files()->vfs_getOrigin(), selected ); } void KRslots::slotSyncBrowse() { ACTIVE_PANEL->syncBrowseButton->toggle(); } void KRslots::updatePopupPanel(KrViewItem *item) { // which panel to display on? ListPanel *lp = 0; if (ACTIVE_PANEL->popup->isHidden() && ACTIVE_PANEL->otherPanel->popup->isHidden()) return; if (!ACTIVE_PANEL->popup->isHidden()) lp = ACTIVE_PANEL; else if (!ACTIVE_PANEL->otherPanel->popup->isHidden()) lp = ACTIVE_PANEL->otherPanel; KUrl url; if (item->name()!="..") // updir url = ACTIVE_FUNC->files()->vfs_getFile(item->name()); lp->popup->update(url); } void KRslots::compareDirs() { ACTIVE_PANEL->compareDirs(); ACTIVE_PANEL->otherPanel->compareDirs(); } void KRslots::compareSetup() { for( int i=0; Krusader::compareArray[i] != 0; i++ ) if( (*Krusader::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; Krusader::execTypeArray[i] != 0; i++ ) if( (*Krusader::execTypeArray[i])->isChecked() ) { if( *Krusader::execTypeArray[i] == Krusader::actExecTerminalEmbedded ){ // if commands are to be executed in the TE, it must be loaded MAIN_VIEW->terminal_dock->initialise(); } KConfigGroup grp(krConfig, "Private" ); grp.writeEntry( "Command Execution Mode", i ); break; } } void KRslots::togglePopupPanel() { ACTIVE_PANEL->togglePanelPopup(); } void KRslots::slotDiskUsage() { DiskUsageGUI du( ACTIVE_FUNC->files()->vfs_getOrigin(), MAIN_VIEW ); } void KRslots::slotQueueManager() { QueueDialog::showDialog( false ); } // when window becomes focused, enable the refresh in the visible panels void KRslots::windowActive() { if( MAIN_VIEW != 0 ) { /* CRASH FIX: it's possible that the method is called after destroying the main view */ MAIN_VIEW->left->panelActive(); MAIN_VIEW->right->panelActive(); } } // when another application becomes focused, do a windows-commander style refresh: don't // refresh at all until krusader becomes focused again void KRslots::windowInactive() { if( MAIN_VIEW != 0 ) { /* CRASH FIX: it's possible that the method is called after destroying the main view */ MAIN_VIEW->left->panelInactive(); MAIN_VIEW->right->panelInactive(); } } void KRslots::slotLocationBar() { ACTIVE_PANEL->origin->lineEdit()->selectAll(); ACTIVE_PANEL->origin->setFocus(); } void KRslots::slotJumpBack() { ACTIVE_PANEL->jumpBack(); } void KRslots::slotSetJumpBack() { ACTIVE_PANEL->setJumpBack( ACTIVE_PANEL->virtualPath() ); } //shows the JavaScript-Console void KRslots::jsConsole() { #ifdef __KJSEMBED__ if ( ! krJS ) krJS = new KrJS(); krJS->view()->show(); #endif } void KRslots::bookmarkCurrent() { krBookMan->bookmarkCurrent(ACTIVE_PANEL->virtualPath()); } #include "krslots.moc" Index: trunk/kdereview/krusader/krusader/Queue/queue.cpp =================================================================== --- trunk/kdereview/krusader/krusader/Queue/queue.cpp (revision 975118) +++ trunk/kdereview/krusader/krusader/Queue/queue.cpp (revision 975119) @@ -1,205 +1,199 @@ #include "queue.h" #include "../krusader.h" #include #include #include #include Queue::Queue(const QString& name): _name(name), _suspended( false ), _percent( PERCENT_UNUSED ) { connect( &_scheduleTimer, SIGNAL( timeout() ), this, SLOT( resume() ) ); } Queue::~Queue() { foreach( KIOJobWrapper * job, _jobs ) { job->abort(); delete job; } _jobs.clear(); // TODO: save queue on delete? or just delete jobs } void Queue::enqueue(KIOJobWrapper *job) { bool isRunning = _jobs.count(); _jobs.append(job); connect( job, SIGNAL( destroyed( QObject * ) ), this, SLOT( slotJobDestroyed( QObject * ) ) ); job->connectTo( SIGNAL( result( KJob* ) ), this, SLOT( slotResult( KJob* ) ) ); job->connectTo( SIGNAL( percent( KJob*, unsigned long ) ), this, SLOT( slotPercent( KJob*, unsigned long ) ) ); if( !_suspended && !isRunning ) { job->start(); slotPercent( 0, PERCENT_UNKNOWN ); } emit changed(); emit showQueueDialog(); - dumpQueue(); -} - -void Queue::dumpQueue() -{ - kDebug() << "Queue: " << name().toLatin1(); } void Queue::slotJobDestroyed( QObject * obj ) { KIOJobWrapper * jw = (KIOJobWrapper*) obj; bool current = false; if( _jobs.count() > 0 && _jobs[ 0 ] == jw ) current = true; _jobs.removeAll( jw ); if( current ) slotPercent( 0, PERCENT_UNUSED ); if( !_suspended && current && _jobs.count() > 0 ) { _jobs[ 0 ]->start(); slotPercent( 0, PERCENT_UNKNOWN ); } emit changed(); } void Queue::slotResult( KJob * job ) { if( _jobs.count() > 0 ) { KIOJobWrapper * jw = _jobs[ 0 ]; KIO::Job * kjob = jw->job(); if( kjob && kjob == job ) { slotPercent( 0, PERCENT_UNUSED ); _jobs.removeAll( jw ); if( job->error() && _jobs.count() > 0 ) { // what to do with the other elements in the queue QString message = i18n( "An error occurred during processing the queue.\n" ); if( job->error() == KIO::ERR_USER_CANCELED ) message = i18n( "The last processed element in the queue was aborted.\n" ); message += i18n( "Do you wish to continue with the next element, delete the queue or suspend the queue?" ); int res = KMessageBox::questionYesNoCancel(krApp, message, i18n( "Krusader::Queue" ), KStandardGuiItem::cont(), KStandardGuiItem::del(), KGuiItem( i18n( "Suspend" ) ) ); switch( res ) { case KMessageBox::Yes: // continue break; case KMessageBox::No: // delete the queue foreach( KIOJobWrapper * job, _jobs ) { job->abort(); delete job; } _jobs.clear(); emit changed(); emit emptied(); return; default: // suspend emit changed(); suspend(); return; } } emit changed(); if( !_suspended ) { if( _jobs.count() > 0 ) { _jobs[ 0 ]->start(); slotPercent( 0, PERCENT_UNKNOWN ); } else emit emptied(); } } } } QList Queue::items() { return _jobs; } QList Queue::itemDescriptions() { QList ret; foreach( KIOJobWrapper *job, _jobs ) { ret.append( job->typeStr() + " : " + job->url().prettyUrl() ); } return ret; } void Queue::suspend() { _suspended = true; if(( _jobs.count() > 0 ) && _jobs[ 0 ]->isStarted() ) _jobs[ 0 ]->suspend(); emit stateChanged(); } void Queue::resume() { _suspended = false; _scheduleTimer.stop(); if( _jobs.count() > 0 ) { if( _jobs[ 0 ]->isSuspended() ) _jobs[ 0 ]->resume(); else if( !_jobs[ 0 ]->isStarted() ) { _jobs[ 0 ]->start(); slotPercent( 0, PERCENT_UNKNOWN ); } } emit stateChanged(); } void Queue::schedule( const QTime &time ) { QTime nowTime = QTime::currentTime(); _suspended = true; if(( _jobs.count() > 0 ) && _jobs[ 0 ]->isStarted() ) _jobs[ 0 ]->suspend(); int now = ((nowTime.hour() * 60) + nowTime.minute() ) * 60 + nowTime.second(); int schedule = ((time.hour() * 60) + time.minute() ) * 60 + time.second(); int diff = schedule - now; if( diff < 0 ) diff += 24 * 60 * 60; // 1 day plus diff *= 1000; // milliseconds _scheduleTime = time; _scheduleTimer.stop(); _scheduleTimer.setSingleShot( true ); _scheduleTimer.start( diff ); emit stateChanged(); } QTime Queue::scheduleTime() { if( _suspended && _scheduleTimer.isActive() ) return _scheduleTime; else return QTime(); } void Queue::slotPercent( KJob *, unsigned long percent_ ) { _percent = percent_; emit percent( this, percent_ ); } void Queue::remove( KIOJobWrapper * jw ) { bool current = false; if( _jobs.count() > 0 && _jobs[ 0 ] == jw ) current = true; _jobs.removeAll( jw ); jw->abort(); delete jw; if( current ) slotPercent( 0, PERCENT_UNUSED ); if( !_suspended && current && _jobs.count() > 0 ) { _jobs[ 0 ]->start(); slotPercent( 0, PERCENT_UNKNOWN ); } emit changed(); } Index: trunk/kdereview/krusader/krusader/Queue/queue.h =================================================================== --- trunk/kdereview/krusader/krusader/Queue/queue.h (revision 975118) +++ trunk/kdereview/krusader/krusader/Queue/queue.h (revision 975119) @@ -1,68 +1,66 @@ #ifndef QUEUE_H #define QUEUE_H #include #include "../VFS/kiojobwrapper.h" #include #include #include class KJob; #define PERCENT_UNUSED -2 #define PERCENT_UNKNOWN -1 /** * Queue can hold anything which inherits KIO::Job, and schedule it, start it, stop etc... * the main reason to hold the Job itself (at least for phase 1) is to keep the code * in krusader relatively unchaged, and allow to create the job as usual and choose if * to start it, or queue it. * */ class Queue: public QObject { Q_OBJECT public: Queue(const QString& name); virtual ~Queue(); inline const QString& name() const { return _name; } void enqueue(KIOJobWrapper *job); int count() { return _jobs.size(); } bool isSuspended() { return _suspended; } QTime scheduleTime(); int getPercent() { return _percent; } void remove( KIOJobWrapper * ); QList itemDescriptions(); QList items(); public slots: void suspend(); void resume(); void schedule( const QTime & ); protected slots: void slotJobDestroyed( QObject * ); void slotResult( KJob * ); void slotPercent( KJob *, unsigned long percent ); protected: - void dumpQueue(); - QString _name; QList _jobs; bool _suspended; QTimer _scheduleTimer; QTime _scheduleTime; int _percent; signals: void showQueueDialog(); void changed(); void emptied(); void stateChanged(); void percent( Queue *, int value ); }; #endif // QUEUE_H Index: trunk/kdereview/krusader/krusader/useraction_examples.xml =================================================================== --- trunk/kdereview/krusader/krusader/useraction_examples.xml (revision 975118) +++ trunk/kdereview/krusader/krusader/useraction_examples.xml (revision 975119) @@ -1,90 +1,90 @@ Equal panel-size Sets the ratio between the two panels to 50/50 view_left_right Samples %aPanelSize("50")% Alt+Ctrl+Equal Edit as root Edit a file as root kwrite Samples Edit a file with root permissions kwrite %aCurrent% Ctrl+E Mount Mount a new filesystem hdd_mount Samples mount -t %_Ask("Filesystem Type?")% %_Ask("Device ?")% %_Ask("Mount Point ?")% Alt+Ctrl+M Enqueue in Amarok Append selected item(s) to Amarok playlist amarok Multimedia amarok --append %aList("Selected")% Win+A Copy current item to clipboard editpaste Samples %_Clipboard("%aCurrent%")% Alt+Ctrl+C Sort by Name Sort by Name view_text User Interface Sorts the active panel by Name %aColSort("Name")% Win+1 Sort by Extension Sort by Extension view_text User Interface Sorts the active panel by Extension %aColSort("Ext")% Win+2 Sort by Size Sort by Size view_text User Interface Sorts the active panel by Size %aColSort("Size")% Win+3 Sort by Modified Sort by Modified view_text User Interface Sorts the active panel by Modified %aColSort("Modified")% Win+4 Backup current Backup current file in current directory filesaveas System Backups current file in current directory and asks the user for a new filename. By default ".old" is appended to the original filename. %_Copy("%aCurrent%", "%_Ask("New filename", "%aCurrent%.old")%")% - Shift+F5 + Win+F5 Index: trunk/kdereview/krusader/krusader/Panel/panelfunc.h =================================================================== --- trunk/kdereview/krusader/krusader/Panel/panelfunc.h (revision 975118) +++ trunk/kdereview/krusader/krusader/Panel/panelfunc.h (revision 975119) @@ -1,106 +1,106 @@ /*************************************************************************** panelfunc.h ------------------- begin : Thu May 4 2000 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 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 PANELFUNC_H #define PANELFUNC_H #include "listpanel.h" #include "krviewitem.h" #include #include class ListPanelFunc : public QObject{ friend class ListPanel; Q_OBJECT public slots: inline vfile* getVFile(KrViewItem *item) { return files()->vfs_search(item->name()); } inline vfile* getVFile(const QString& name) { return files()->vfs_search(name); } void execute(const QString&); void goInside(const QString&); void openUrl(const KUrl& path, const QString& nameToMakeCurrent = QString()); void openUrl(const QString& path, const QString& nameToMakeCurrent = QString()); void immediateOpenUrl( const KUrl& path); void doOpenUrl(); void refresh(); void rename(const QString &oldname, const QString &newname); public: ListPanelFunc(class ListPanel *parent); ~ListPanelFunc(); vfs* files(); // return a pointer to the vfs void refreshActions(); void redirectLink(); void krlink(bool sym); void goBack(); void dirUp(); void properties(); void terminal(); void editFile(); void view(); void rename(); void mkdir(); - void moveFiles(); + void moveFiles( bool enqueue=false ); void pack(); void unpack(); void testArchive(); - void copyFiles(); + void copyFiles( bool enqueue=false ); void deleteFiles(bool reallyDelete=false); void calcSpace(); // calculate the occupied space and show it in a dialog void createChecksum(); void matchChecksum(); void copyToClipboard( bool move=false ); void pasteFromClipboard(); // calculate the occupied space. A dialog appears, if calculation lasts more than 3 seconds // and disappears, if the calculation is done. Returns true, if the result is ok and false // otherwise (Cancel was pressed). bool calcSpace(const QStringList & items,KIO::filesize_t & totalSize,unsigned long & totalFiles,unsigned long & totalDirs); void FTPDisconnect(); void newFTPconnection(); inline ListPanelFunc* otherFunc(){ return panel->otherPanel->func; } private: KUrl getVirtualBaseURL(); protected: ListPanel* panel; // our ListPanel QList urlStack; // Path stack for the "go-previous" button bool inRefresh; // true when we are in refresh() vfs* vfsP; // pointer to vfs. QTimer delayTimer; KUrl delayURL; QString nameToMakeCurrent; bool canGoBack(); }; #endif Index: trunk/kdereview/krusader/krusader/Panel/panelfunc.cpp =================================================================== --- trunk/kdereview/krusader/krusader/Panel/panelfunc.cpp (revision 975118) +++ trunk/kdereview/krusader/krusader/Panel/panelfunc.cpp (revision 975119) @@ -1,1285 +1,1285 @@ /*************************************************************************** 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 // Qt Includes #include #include #include #include // KDE Includes #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include // Krusader Includes #include "panelfunc.h" #include "krcalcspacedialog.h" #include "../krusader.h" #include "../krslots.h" #include "../defaults.h" #include "../VFS/vfile.h" #include "../VFS/vfs.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 "../Dialogs/packgui.h" #include "../Dialogs/krdialogs.h" #include "../Dialogs/krpleasewait.h" #include "../Dialogs/krspwidgets.h" #include "../Dialogs/checksumdlg.h" #include "../KViewer/krviewer.h" #include "../resources.h" #include "../krservices.h" #include "../GUI/syncbrowsebutton.h" #include "../Queue/queue_mgr.h" #include #include ////////////////////////////////////////////////////////// ////// ---------- List Panel ------------- //////// ////////////////////////////////////////////////////////// ListPanelFunc::ListPanelFunc( ListPanel *parent ) : panel( parent ), inRefresh( false ), vfsP( 0 ) { urlStack.push_back( KUrl( "file:/" ) ); connect( &delayTimer, SIGNAL( timeout() ), this, SLOT( doOpenUrl() ) ); } void ListPanelFunc::openUrl( const QString& url, const QString& nameToMakeCurrent ) { openUrl( KUrl( // KUrlRequester is buggy: it should return a string containing "/home/shie/downloads" // but it returns "~/downloads" which is parsed incorrectly by KUrl. // replacedPath should replace ONLY $HOME and environment variables panel->origin->completionObject()->replacedPath(url) ) , nameToMakeCurrent ); } void ListPanelFunc::immediateOpenUrl( const KUrl& urlIn ) { KUrl url = urlIn; url.cleanPath(); // check for special cases first - don't refresh here ! // you may call openUrl or vfs_refresh() if ( !url.isValid() || url.isRelative() ) { if ( url.url() == "~" ) { return openUrl( QDir::homePath() ); } else if ( !url.url().startsWith( "/" ) ) { // possible relative URL - translate to full URL url = files() ->vfs_getOrigin(); url.addPath( urlIn.url() ); //kDebug()<< urlIn.url() << "," << url.url() <slotStartUpdate(); // refresh the panel return ; } } // if we are not refreshing to current URL bool is_equal_url = files() ->vfs_getOrigin().equals( url, KUrl::CompareWithoutTrailingSlash ); if ( !is_equal_url ) { // change the cursor to busy panel->setCursor( Qt::WaitCursor ); } if ( !nameToMakeCurrent.isEmpty() ) { panel->view->setNameToMakeCurrent( nameToMakeCurrent ); // if the url we're refreshing into is the current one, then the // partial url will not generate the needed signals to actually allow the // view to use nameToMakeCurrent. do it here instead (patch by Thomas Jarosch) if ( is_equal_url ) { panel->view->setCurrentItem( nameToMakeCurrent ); panel->view->makeItemVisible( panel->view->getCurrentKrViewItem() ); } } vfs* v = 0; if ( !urlStack.last().equals( url ) ) urlStack.push_back( url ); // count home many urls is in the stack, so later on, we'll know if the refresh was a success int stackSize = urlStack.count(); bool refreshFailed = true; // assume the worst while ( true ) { KUrl u = urlStack.takeLast(); //u.adjustPath(KUrl::RemoveTrailingSlash); // remove trailing "/" u.cleanPath(); // Resolves "." and ".." components in path. v = KrVfsHandler::getVfs( u, panel, files() ); if ( !v ) continue; //this should not happen ! if ( v != vfsP ) { 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() ) { delayURL = url; /* this function is useful for FTP url-s and bookmarks */ delayTimer.setSingleShot( true ); delayTimer.start( 100 ); /* if vfs is busy try refreshing later */ return; } } connect( files(), SIGNAL(startJob(KIO::Job* )), panel, SLOT(slotJobStarted(KIO::Job* ))); if ( vfsP->vfs_refresh( u ) ) { break; // we have a valid refreshed URL now } if ( vfsP == 0 ) // the object was deleted during vfs_refresh? Hoping the best... return; // prevent repeated error messages if ( vfsP->vfs_isDeleting() ) break; vfsP->vfs_setQuiet( true ); } vfsP->vfs_setQuiet( false ); // if we popped exactly 1 url from the stack, it means the url we were // given was refreshed successfully. if (stackSize == urlStack.count() + 1) refreshFailed = false; // update the urls stack if ( urlStack.isEmpty() || !files() ->vfs_getOrigin().equals( urlStack.last() ) ) { urlStack.push_back( files() ->vfs_getOrigin() ); } // disconnect older signals disconnect( files(), SIGNAL( addedVfile( vfile* ) ), 0, 0 ); disconnect( files(), SIGNAL( updatedVfile( vfile* ) ), 0, 0 ); disconnect( files(), SIGNAL( deletedVfile( const QString& ) ), 0, 0 ); disconnect( files(), SIGNAL( cleared() ), 0, 0 ); // connect to the vfs's dirwatch signals connect( files(), SIGNAL( addedVfile( vfile* ) ), panel, SLOT( slotItemAdded( vfile* ) ) ); connect( files(), SIGNAL( updatedVfile( vfile* ) ), panel, SLOT( slotItemUpdated( vfile* ) ) ); connect( files(), SIGNAL( deletedVfile( const QString& ) ), panel, SLOT( slotItemDeleted( const QString& ) ) ); connect( files(), SIGNAL( cleared() ), panel, SLOT( slotCleared() ) ); // on local file system change the working directory if ( files() ->vfs_getType() == vfs::VFS_NORMAL ) QDir::setCurrent( files() ->vfs_getOrigin().path() ); // see if the open url operation failed, and if so, // put the attempted url in the origin bar and let the user change it if (refreshFailed) { panel->origin->setUrl(urlIn.prettyUrl()); panel->origin->setFocus(); } refreshActions(); } void ListPanelFunc::openUrl( const KUrl& url, const QString& nameToMakeCurrent ) { panel->inlineRefreshCancel(); // first the other dir, then the active! Else the focus changes and the other becomes active if ( panel->syncBrowseButton->state() == SYNCBROWSE_CD ) { // prevents that the sync-browsing circles itself to death static bool inSync = false; if( ! inSync ){ inSync = true; //do sync-browse stuff.... ListPanel *other_panel = OTHER_PANEL; KUrl otherDir = other_panel->virtualPath(); QString otherText = other_panel->origin->lineEdit()->text(); OTHER_FUNC->files() ->vfs_setQuiet( true ); // the trailing slash is nessesary because krusader provides Dir's without it // we can't use openUrl because the delay don't allow a check if the panel has realy changed! OTHER_FUNC->immediateOpenUrl( KUrl::relativeUrl( panel->virtualPath().url() + "/", url.url() ) ); OTHER_FUNC->files() ->vfs_setQuiet( false ); // now we need to test ACTIVE_PANEL because the openURL has changed the active panel!! if ( other_panel->virtualPath().equals( otherDir ) ) { // deactivating the sync-browse if syncbrowse not possible panel->syncBrowseButton->setChecked( false ); other_panel->origin->lineEdit()->setText( otherText ); } inSync = false; } } this->nameToMakeCurrent = nameToMakeCurrent; delayURL = url; /* this function is useful for FTP url-s and bookmarks */ delayTimer.setSingleShot( true ); delayTimer.start( 0 ); /* to avoid qApp->processEvents() deadlock situaltion */ } void ListPanelFunc::refresh() { openUrl(panel->virtualPath()); // re-read the files } void ListPanelFunc::doOpenUrl() { immediateOpenUrl( delayURL ); } void ListPanelFunc::goBack() { if ( !canGoBack()) return ; if ( urlStack.last().equals( files() ->vfs_getOrigin() ) ) urlStack.pop_back(); openUrl( urlStack.last(), files() ->vfs_getOrigin().fileName() ); if ( urlStack.isEmpty() ) krBack->setEnabled( false ); } void ListPanelFunc::redirectLink() { if ( files() ->vfs_getType() != vfs::VFS_NORMAL ) { KMessageBox::sorry( krApp, 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( KUrl::RemoveTrailingSlash ); QString currentLink = vf->vfile_getSymDest(); if ( currentLink.isEmpty() ) { KMessageBox::sorry( krApp, i18n( "The current file is not a link, so I can't redirect it." ) ); return ; } // ask the user for a new destination bool ok = false; QString newLink = KInputDialog::getText( i18n( "Link Redirection" ), i18n( "Please enter the new link destination:" ), currentLink, &ok, krApp ); // if the user canceled - quit if ( !ok || newLink == currentLink ) return ; // delete the current link if ( unlink( file.toLocal8Bit() ) == -1 ) { KMessageBox::sorry( krApp, i18n( "Can't remove old link: " ) + file ); return ; } // try to create a new symlink if ( symlink( newLink.toLocal8Bit(), file.toLocal8Bit() ) == -1 ) { KMessageBox:: /* --=={ Patch by Heiner }==-- */sorry( krApp, i18n( "Failed to create a new link: " ) + file ); return ; } } void ListPanelFunc::krlink( bool sym ) { if ( files() ->vfs_getType() != vfs::VFS_NORMAL ) { KMessageBox::sorry( krApp, 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 = KInputDialog::getText( i18n( "New link" ), i18n( "Create a new link to: " ) + name, name, &ok, krApp ); // 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( krApp, i18n( "A directory 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( KUrl::RemoveTrailingSlash ); if ( sym ) { if ( symlink( name.toLocal8Bit(), linkName.toLocal8Bit() ) == -1 ) KMessageBox::sorry( krApp, i18n( "Failed to create a new symlink: " ) + linkName + i18n( " To: " ) + name ); } else { if ( link( name.toLocal8Bit(), linkName.toLocal8Bit() ) == -1 ) KMessageBox::sorry( krApp, i18n( "Failed to create a new link: " ) + linkName + i18n( " To: " ) + 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::terminal() { SLOTS->runTerminal( panel->realPath(), QStringList() ); } void ListPanelFunc::editFile() { QString name = panel->getCurrentName(); if ( name.isNull() ) return ; if ( files() ->vfs_search( name ) ->vfile_isDir() ) { KMessageBox::sorry( krApp, i18n( "You can't edit a directory" ) ); return ; } if ( !files() ->vfs_search( name ) ->vfile_isReadable() ) { KMessageBox::sorry( 0, i18n( "No permissions to edit this file." ) ); return ; } KrViewer::edit( files() ->vfs_getFile( name ) ); } -void ListPanelFunc::moveFiles() { +void ListPanelFunc::moveFiles( bool enqueue ) { PreserveMode pmode = PM_DEFAULT; - bool queue = false; + bool queue = enqueue; QStringList fileNames; panel->getSelectedNames( &fileNames ); if ( fileNames.isEmpty() ) return ; // safety KUrl dest = panel->otherPanel->virtualPath(); KUrl virtualBaseURL; QString destProtocol = dest.protocol(); if ( destProtocol == "krarc" || destProtocol == "tar" || destProtocol == "zip" ) { KMessageBox::sorry( krApp, i18n( "Moving into archive is disabled" ) ); return ; } 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 KUrl::List* 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.equals( panel->otherPanel->virtualPath(), KUrl::CompareWithoutTrailingSlash ) ) 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.adjustPath(KUrl::AddTrailingSlash); 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.equals( panel->virtualPath(), KUrl::CompareWithoutTrailingSlash ) || dest.upUrl().equals( panel->virtualPath(), KUrl::CompareWithoutTrailingSlash ) ) // 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.equals( panel->otherPanel->virtualPath(), KUrl::CompareWithoutTrailingSlash ) ) connect( vjob, SIGNAL( result( KJob* ) ), panel->otherPanel->func, SLOT( refresh() ) ); } // if we are not moving to the other panel : else if ( !dest.equals( panel->otherPanel->virtualPath(), KUrl::CompareWithoutTrailingSlash ) ) { // you can rename only *one* file not a batch, // so a batch dest must alwayes be a directory if ( fileNames.count() > 1 ) dest.adjustPath(KUrl::AddTrailingSlash); 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.equals( panel->otherPanel->virtualPath(), KUrl::CompareWithoutTrailingSlash ) ) 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( krApp, i18n( "You can't move files to this file system" ) ); return ; } // finally.. otherFunc() ->files() ->vfs_addFiles( fileUrls, KIO::CopyJob::Move, files(), "", pmode ); } } // 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.. bool ok = false; QString dirName = KInputDialog::getText( i18n( "New directory" ), i18n( "Directory's name:" ), "", &ok, krApp ); // if the user canceled - quit if ( !ok || dirName.isEmpty() ) return ; QStringList dirTree = dirName.split( "/" ); for ( QStringList::Iterator it = dirTree.begin(); it != dirTree.end(); ++it ) { if( *it == "." ) continue; if( *it == ".." ) { immediateOpenUrl( *it ); 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( krApp, i18n( "A directory or a file with this name already exists." ) ); return ; } // else go into this dir else { immediateOpenUrl( *it ); continue; } } panel->view->setNameToMakeCurrent( *it ); // as always - the vfs do the job files() ->vfs_mkdir( *it ); if ( dirTree.count() > 1 ) immediateOpenUrl( *it ); } // for } KUrl ListPanelFunc::getVirtualBaseURL() { if( files()->vfs_getType() != vfs::VFS_VIRT || otherFunc()->files()->vfs_getType() == vfs::VFS_VIRT ) return KUrl(); QStringList fileNames; panel->getSelectedNames( &fileNames ); KUrl::List* fileUrls = files() ->vfs_getFiles( &fileNames ); if( fileUrls->count() == 0 ) return KUrl(); KUrl base = (*fileUrls)[ 0 ].upUrl(); if( base.protocol() == "virt" ) // is it a virtual subfolder? return KUrl(); // --> cannot keep the directory structure for( int i=1; i < fileUrls->count(); i++ ) { if( base.isParentOf( (*fileUrls)[ i ] ) ) continue; if( base.protocol() != (*fileUrls)[ i ].protocol() ) return KUrl(); do { KUrl oldBase = base; base = base.upUrl(); if( oldBase.equals( base, KUrl::CompareWithoutTrailingSlash ) ) return KUrl(); if( base.isParentOf( (*fileUrls)[ i ] ) ) break; }while( true ); } return base; } -void ListPanelFunc::copyFiles() { +void ListPanelFunc::copyFiles( bool enqueue ) { PreserveMode pmode = PM_DEFAULT; - bool queue = false; + bool queue = enqueue; QStringList fileNames; panel->getSelectedNames( &fileNames ); if ( fileNames.isEmpty() ) return ; // safety KUrl dest = panel->otherPanel->virtualPath(); KUrl 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; } KUrl::List* 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.equals( panel->otherPanel->virtualPath(), KUrl::CompareWithoutTrailingSlash ) ) 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.adjustPath(KUrl::AddTrailingSlash); job = KIOJobWrapper::copy( pmode, *fileUrls, dest, true ); job->setAutoErrorHandlingEnabled( true ); if ( dest.equals( panel->virtualPath(), KUrl::CompareWithoutTrailingSlash ) || dest.upUrl().equals( panel->virtualPath(), KUrl::CompareWithoutTrailingSlash ) ) // 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.equals( panel->otherPanel->virtualPath(), KUrl::CompareWithoutTrailingSlash ) ) connect( vjob, SIGNAL( result( KJob* ) ), panel->otherPanel->func, SLOT( refresh() ) ); } // if we are not copying to the other panel : else if ( !dest.equals( panel->otherPanel->virtualPath(), KUrl::CompareWithoutTrailingSlash ) ) { // you can rename only *one* file not a batch, // so a batch dest must alwayes be a directory if ( fileNames.count() > 1 ) dest.adjustPath(KUrl::AddTrailingSlash); KIO::Job* job = PreservingCopyJob::createCopyJob( pmode, *fileUrls, dest, KIO::CopyJob::Copy, false, true ); job->ui()->setAutoErrorHandlingEnabled( true ); if ( dest.equals( panel->virtualPath(), KUrl::CompareWithoutTrailingSlash ) || dest.upUrl().equals( panel->virtualPath(), KUrl::CompareWithoutTrailingSlash ) ) // 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( krApp, i18n( "You can't copy files to this file system" ) ); return ; } // finally.. otherFunc() ->files() ->vfs_addFiles( fileUrls, KIO::CopyJob::Copy, 0, "", pmode ); } } void ListPanelFunc::deleteFiles(bool reallyDelete) { // check that the you have write perm if ( !files() ->vfs_isWritable() ) { KMessageBox::sorry( krApp, i18n( "You do not have write permission to this directory" ) ); 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().equals( KUrl("virt:/"), KUrl::CompareWithoutTrailingSlash ) ) { 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( krApp, 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 ( 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( krApp, i18n( "

Directory %1 is not empty!

Skip this one or Delete All?

", *name), QString(), KGuiItem( i18n( "&Skip" )), KGuiItem( i18n( "&Delete All" ) ) ) ) { case KMessageBox::Cancel : return ; case KMessageBox::No : emptyDirVerify = false; break; case KMessageBox::Yes : name = fileNames.erase( name ); continue; } } } ++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... if (reallyDelete) { // if reallyDelete, then make sure nothing gets moved to trash group.writeEntry( "Move To Trash", false ); } files() ->vfs_delFiles( &fileNames ); if (reallyDelete) { group.writeEntry( "Move To Trash", trash); } } void ListPanelFunc::goInside( const QString& name ) { if ( name == ".." ) { dirUp(); return ; } vfile *vf = files() ->vfs_search( name ); if ( vf == 0 ) return ; KUrl origin = files() ->vfs_getOrigin(); KUrl url = vf->vfile_getUrl(); if ( vf->vfile_isDir() ) { // we create a return-pressed event, execute(name); // thereby emulating a chdir } else if( url.isLocalFile() ) { bool encrypted; QString mime = vf->vfile_getMime(); QString type = KRarcHandler::getType( encrypted, url.path(), mime, false ); if( KRarcHandler::arcSupported( type ) ) { // archive autodetection // here we check whether KDE supports tar if( type == "-tlz" ) { KTar tapeArchive( url.path() ); if( tapeArchive.open( QIODevice::ReadOnly ) ) url.setProtocol( "tar" ); else url.setProtocol( "krarc" ); } else if( type == "-tar" || type == "-tgz" || type == "-tbz" ) url.setProtocol( "tar" ); else url.setProtocol( "krarc" ); openUrl( url ); } else { QString protocol = KrServices::registerdProtocol( mime ); if ( protocol == "iso" ) { url.setProtocol( protocol ); openUrl( url ); } } } } // this is done when you double click on a file void ListPanelFunc::execute( const QString& name ) { if ( name == ".." ) { dirUp(); return ; } vfile *vf = files() ->vfs_search( name ); if ( vf == 0 ) return ; KUrl origin = files() ->vfs_getOrigin(); QString protocol = origin.isLocalFile() ? KrServices::registerdProtocol( vf->vfile_getMime() ) : ""; if ( protocol == "tar" || protocol == "krarc" ) { bool encrypted; QString type = KRarcHandler::getType( encrypted, vf->vfile_getUrl().path(), vf->vfile_getMime(), false ); if ( !KRarcHandler::arcHandled( type ) ) // if the specified archive is disabled delete the protocol protocol = ""; } if ( vf->vfile_isDir() ) { origin = files() ->vfs_getFile( name ); panel->view->setNameToMakeCurrent( QString() ); openUrl( origin ); } else if ( !protocol.isEmpty() ) { KUrl path = files() ->vfs_getFile( vf->vfile_getName() ); path.setProtocol( protocol ); openUrl( path ); } else { KUrl url = files() ->vfs_getFile( name ); KFileItem kfi( vf->vfile_getEntry(), url,true ); kfi.run(); } } void ListPanelFunc::dirUp() { openUrl( files() ->vfs_getOrigin().upUrl(), files() ->vfs_getOrigin().fileName() ); } 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 == "" ) defaultName = "pack"; if ( fileNames.count() == 1 ) defaultName = fileNames.first(); // ask the user for archive name and packer new PackGUI( defaultName, vfs::pathOrUrl( panel->otherPanel->virtualPath(), KUrl::RemoveTrailingSlash ), fileNames.count(), fileNames.first() ); if ( PackGUI::type == QString() ) return ; // the user canceled // check for partial URLs if( !PackGUI::destination.contains(":/") && !PackGUI::destination.startsWith("/") ){ PackGUI::destination = panel->virtualPath().prettyUrl()+"/"+PackGUI::destination; } QString destDir = PackGUI::destination; if( !destDir.endsWith( "/" ) ) destDir += "/"; bool packToOtherPanel = ( destDir == panel->otherPanel->virtualPath().prettyUrl(KUrl::AddTrailingSlash) ); // on remote URL-s first pack into a temp file then copy to its right place KUrl destURL = KUrl( destDir + PackGUI::filename + "." + PackGUI::type ); KTemporaryFile *tempDestFile = 0; QString arcFile; if ( destURL.isLocalFile() ) arcFile = destURL.path(); else if( destURL.protocol() == "virt" ) { KMessageBox::error( krApp, i18n( "Cannot pack files onto a virtual destination!" ) ); return; } else { tempDestFile = new KTemporaryFile(); tempDestFile->setSuffix( QString(".") + PackGUI::type ); tempDestFile->open(); arcFile = tempDestFile->fileName(); tempDestFile->close(); // nessesary to create the filename QFile::remove ( arcFile ); } if ( QFileInfo( arcFile ).exists() ) { 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( krApp,msg,QString(),KGuiItem( i18n( "&Overwrite" ))) == KMessageBox::Cancel ) return ; // stop operation } // tell the user to wait krApp->startWaiting( i18n( "Counting files to pack" ), 0, true ); // get the files to be packed: files() ->vfs_getFiles( &fileNames ); KIO::filesize_t totalSize = 0; unsigned long totalDirs = 0, totalFiles = 0; if( !calcSpace( fileNames, totalSize, totalFiles, totalDirs ) ) return; // download remote URL-s if necessary QString arcDir; KTempDir *tempDir = 0; if ( files() ->vfs_getOrigin().isLocalFile() ) arcDir = files() ->vfs_workingDir(); else { tempDir = new KTempDir(); arcDir = tempDir->name(); KUrl::List *urlList = files() ->vfs_getFiles( &fileNames ); KIO::NetAccess::dircopy( *urlList, KUrl( arcDir ), 0 ); delete urlList; } // pack the files // we must chdir() first because we supply *names* not URL's QString save = QDir::currentPath(); QDir::setCurrent( arcDir ); KRarcHandler::pack( fileNames, PackGUI::type, arcFile, totalFiles + totalDirs, PackGUI::extraProps ); QDir::setCurrent( save ); // delete the temporary directory if created if ( tempDir ) delete tempDir; // copy from the temp file to it's right place if ( tempDestFile ) { KIO::NetAccess::move( KUrl( arcFile ), destURL ); delete tempDestFile; } if ( packToOtherPanel ) panel->otherPanel->func->refresh(); } void ListPanelFunc::testArchive() { QString arcName = panel->getCurrentName(); if ( arcName.isNull() ) return ; if ( arcName == ".." ) return ; // safety KUrl arcURL = files() ->vfs_getFile( arcName ); QString url = QString(); // download the file if it's on a remote filesystem if ( !arcURL.isLocalFile() ) { url = KStandardDirs::locateLocal( "tmp", QString( arcName ) ); if ( !KIO::NetAccess::download( arcURL, url, 0 ) ) { KMessageBox::sorry( krApp, i18n( "Krusader is unable to download: " ) + arcURL.fileName() ); return ; } } else url = arcURL.path( KUrl::RemoveTrailingSlash ); QString mime = files() ->vfs_search( arcName ) ->vfile_getMime(); bool encrypted = false; QString type = KRarcHandler::getType( encrypted, url, mime ); // check we that archive is supported if ( !KRarcHandler::arcSupported( type ) ) { KMessageBox::sorry( krApp, i18n( "%1, unknown archive type.", arcName ) ); return ; } QString password = encrypted ? KRarcHandler::getPassword( url ) : QString(); // test the archive if ( KRarcHandler::test( url, type, password ) ) KMessageBox::information( krApp, i18n( "%1, test passed.", arcName ) ); else KMessageBox::error( krApp, i18n( "%1, test failed!", arcName ) ); // remove the downloaded file if necessary if ( url != arcURL.path( KUrl::RemoveTrailingSlash ) ) QFile( url ).remove(); } 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 KUrl dest = KChooseDir::getDir(s, panel->otherPanel->virtualPath(), panel->virtualPath()); if ( dest.isEmpty() ) return ; // the user canceled bool packToOtherPanel = ( dest.equals( panel->otherPanel->virtualPath(), KUrl::CompareWithoutTrailingSlash ) ); for ( int i = 0; i < fileNames.count(); ++i ) { QString arcName = fileNames[ i ]; if ( arcName.isNull() ) return ; if ( arcName == ".." ) return ; // safety // download the file if it's on a remote filesystem KUrl arcURL = files() ->vfs_getFile( arcName ); QString url = QString(); if ( !arcURL.isLocalFile() ) { url = KStandardDirs::locateLocal( "tmp", QString( arcName ) ); if ( !KIO::NetAccess::download( arcURL, url, 0 ) ) { KMessageBox::sorry( krApp, i18n( "Krusader is unable to download: " ) + arcURL.fileName() ); continue; } } else url = arcURL.path( KUrl::RemoveTrailingSlash ); // if the destination is in remote directory use temporary one instead dest.adjustPath(KUrl::AddTrailingSlash); KUrl originalDestURL; KTempDir *tempDir = 0; if ( !dest.isLocalFile() ) { originalDestURL = dest; tempDir = new KTempDir(); dest = tempDir->name(); } // determining the type QString mime = files() ->vfs_search( arcName ) ->vfile_getMime(); bool encrypted = false; QString type = KRarcHandler::getType( encrypted, url, mime ); // check we that archive is supported if ( !KRarcHandler::arcSupported( type ) ) { KMessageBox::sorry( krApp, i18n( "%1, unknown archive type", arcName ) ); continue; } QString password = encrypted ? KRarcHandler::getPassword( url ) : QString(); // unpack the files KRarcHandler::unpack( url, type, password, dest.path( KUrl::RemoveTrailingSlash ) ); // remove the downloaded file if necessary if ( url != arcURL.path( KUrl::RemoveTrailingSlash ) ) QFile( url ).remove(); // copy files to the destination directory at remote files if ( tempDir ) { QStringList nameList = QDir( dest.path( KUrl::RemoveTrailingSlash ) ).entryList(); KUrl::List urlList; for ( int i = 0; i != nameList.count(); i++ ) if ( nameList[ i ] != "." && nameList[ i ] != ".." ) urlList.append( KUrl( dest.path( KUrl::AddTrailingSlash ) + nameList[ i ] ) ); if ( urlList.count() > 0 ) KIO::NetAccess::dircopy( urlList, originalDestURL, 0 ); delete tempDir; } } if ( packToOtherPanel ) panel->otherPanel->func->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().prettyUrl() : 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 } KrCalcSpaceDialog calc( krApp, panel, items, false ); calc.exec(); for ( QStringList::ConstIterator it = items.begin(); it != items.end(); ++it ) { KrViewItem *viewItem = panel->view->findItemByName( *it ); if ( viewItem ) panel->view->updateItem(viewItem); } panel->slotUpdateTotals(); } bool ListPanelFunc::calcSpace( const QStringList & items, KIO::filesize_t & totalSize, unsigned long & totalFiles, unsigned long & totalDirs ) { KrCalcSpaceDialog calc( krApp, panel, items, true ); calc.exec(); totalSize = calc.getTotalSize(); totalFiles = calc.getTotalFiles(); totalDirs = calc.getTotalDirs(); return !calc.wasCanceled(); } void ListPanelFunc::FTPDisconnect() { // you can disconnect only if connected ! if ( files() ->vfs_getType() == vfs::VFS_FTP ) { krFTPDiss->setEnabled( false ); panel->view->setNameToMakeCurrent( QString() ); openUrl( panel->realPath() ); // open the last local URL } } void ListPanelFunc::newFTPconnection() { KUrl url = KRSpWidgets::newFTP(); // if the user canceled - quit if ( url.isEmpty() ) return ; krFTPDiss->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; KUrl 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, krApp ); connect( dlg, SIGNAL( applied() ), SLOTS, SLOT( refresh() ) ); dlg->show(); } bool ListPanelFunc::canGoBack() { return (urlStack.count() > 1); } void ListPanelFunc::refreshActions() { vfs::VFS_TYPE vfsType = files() ->vfs_getType(); // set up actions //krMultiRename->setEnabled( vfsType == vfs::VFS_NORMAL ); // batch rename //krProperties ->setEnabled( vfsType == vfs::VFS_NORMAL || vfsType == vfs::VFS_FTP ); // file properties krFTPDiss ->setEnabled( vfsType == vfs::VFS_FTP ); // disconnect an FTP session krCreateCS->setEnabled( vfsType == vfs::VFS_NORMAL ); QString protocol = files()->vfs_getOrigin().protocol(); krRemoteEncoding->setEnabled( protocol == "ftp" || protocol == "sftp" || protocol == "fish" || protocol == "krarc" ); /* 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 */ krBack->setEnabled(canGoBack()); // go back } ListPanelFunc::~ListPanelFunc() { if( !vfsP ) { if( vfsP->vfs_canDelete() ) delete vfsP; else { connect( vfsP, SIGNAL( deleteAllowed() ), vfsP, SLOT( deleteLater() ) ); vfsP->vfs_requestDelete(); } } vfsP = 0; } vfs* ListPanelFunc::files() { if ( !vfsP ) vfsP = KrVfsHandler::getVfs( KUrl( "/" ), panel, 0 ); return vfsP; } void ListPanelFunc::copyToClipboard( bool move ) { if( files()->vfs_getOrigin().equals( KUrl("virt:/"), KUrl::CompareWithoutTrailingSlash ) ) { if( move ) KMessageBox::error( krApp, i18n( "Cannot cut a virtual URL collection to the clipboard!" ) ); else KMessageBox::error( krApp, i18n( "Cannot copy a virtual URL collection onto the clipboard!" ) ); return; } QStringList fileNames; panel->getSelectedNames( &fileNames ); if ( fileNames.isEmpty() ) return ; // safety KUrl::List* fileUrls = files() ->vfs_getFiles( &fileNames ); if ( fileUrls ) { QMimeData *mimeData = new QMimeData; mimeData->setData( "application/x-kde-cutselection", move ? "1" : "0"); fileUrls->populateMimeData(mimeData); QApplication::clipboard()->setMimeData( mimeData, QClipboard::Clipboard ); if( move && files()->vfs_getType() == vfs::VFS_VIRT ) ( static_cast( files() ) )->vfs_removeFiles( &fileNames ); delete fileUrls; } } void ListPanelFunc::pasteFromClipboard() { QClipboard * cb = QApplication::clipboard(); 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 } KUrl::List urls = KUrl::List::fromMimeData( data ); if ( urls.isEmpty() ) return ; KUrl destUrl = panel->virtualPath(); files()->vfs_addFiles( &urls, move ? KIO::CopyJob::Move : KIO::CopyJob::Copy, otherFunc()->files(), "", PM_DEFAULT ); } #include "panelfunc.moc" Index: trunk/kdereview/krusader/ChangeLog =================================================================== --- trunk/kdereview/krusader/ChangeLog (revision 975118) +++ trunk/kdereview/krusader/ChangeLog (revision 975119) @@ -1,1387 +1,1388 @@ + ADDED: shortcuts: copy by queue (SHIFT+F5), move by queue (SHIFT+F6) ADDED: Krusader support for tar.lzma (KDE's tar protocol doesn't support it yet) ADDED: Possibility to choose one of five sorting methods (thanks to Jacek Jaworski) ADDED: compare by content for search / locate ADDED: New mouse selection mode ADDED: Evolution can be used as the default e-mail sender (thanks to Agustin Henze) ADDED: enqueue operation for copy / move ADDED: Konfigurator mouse selection mode: Possibility to select a predefined mode and change a detail. ADDED: [ 1704953 ] highlight quick search match ADDED: Useractions: added checkbox "enabled" and run mode option "Run in embedded terminal emulator" ADDED: the description of a dir contains its size if it is known ARCH: MediaButton uses Solid for medium detection ARCH: QuickSearch is moved to KrView from Detailed/Brief views ARCH: Keyboard handling is moved to KrView from Detailed/Brief views FIXED: When neither "kompare", "kdiff3" nor "xxdiff" in PATH, the program set in "diff utility" was ignored. Under Windows, look for them with ".exe" suffix FIXED: [ 2243628 ] Synchronizer overlooks files FIXED: [ 2202522 ] newly created hidden files are shown for a short time FIXED: calc space doesn't work on remote file systems FIXED: searcher doesn't start because of corrupt config files FIXED: Konfigurator doesn't detect every mimetype for "zip" files FIXED: Konfigurator keeps its original size FIXED: Konfigurator has scrollbars if necessary. FIXED: [ 2027518 ] Does not build with -DBUILD_SHARED_LIBS:BOOL=ON (thanks to Funda Wang) FIXED: [ 2041732 ] Krusader 2.0.0 beta1 missing title bar under Compiz (thanks to Danny Baumann for the patch) FIXED: [ 2023623 ] Krusader kept running after closing the main window FIXED: [ 1671543 ] horizontal/vertical mode fix in the Window menu FIXED: [ 1845105 ] mimetype magic can be disabled again FIXED: [ 2062651 ] Ctrl+Up selects the URL in the origin editbox FIXED: [ 1988893 ] konsole is started in a wrong directory please set "konsole --workdir %d" for the terminal (Konfigurator) as Krusader won't fix your config automatically FIXED: KDE4 workaround: no colors for synchronizer FIXED: MediaButton doesn't notice unmounted pen drives+CD/DVD-s FIXED: "local network" bookmark didn't work FIXED: bookmark menu was not always closed after opening a bookmark FIXED: [ 2017011 ] Crash when changing the Qt theme FIXED: icons for symlinks are corrupted FIXED: [ 2023599 ] start root mode Krusader works again (thanks to gladiac) FIXED: [ 1980765 ] error at creating ../dir directory FIXED: [ 2014344 ] CTRL-C (copy) does not work in internal editor FIXED: Viewing directories are disabled to prevent KDE 4 crash FIXED: [Debian: 492955] useraction's availability section was dumped to "command" element. (thanks Iván Forcada Atienza) FIXED: Do not duplicate menu entries in UserAction menu while still not crashing when configuring toolbars. I18N: Updated German translation I18N: Updated Dutch translation I18N: Updated Czech translation I18N: Updated Ukrainian translation (thanks Yuri Chornoivan) I18N: Updated Slovenian translation (thanks Matej Urbancic) 2.0.0-beta1 "Phoenix Egg" ========================= ADDED: [ 1962519 ] searching by regexp ADDED: [ 1172426 ] loading user defined folder icons (can be turned off) ADDED: Posibility to remove default useractions ADDED: Thunderbird can be used as the default e-mail sender ADDED: Sending more than one file in e-mail is possible ADDED: Submenus for categories in UserAction menu and context menu ADDED: Character encoding for content search ADDED: Select remote encoding for krarc ADDED: New synchronizer shortcuts for modifying the synchronizer tasks ARCH: Ported to KDE4! ARCH: Removed all dependencies to the Qt3 support libs ARCH: Codebase in sync with last KDE3 release (krusader-1.90.0) ARCH: Added experimental support for the Windows platform FIXED: [ 1506205 ] krviewer crash at urls with non-existing redirection FIXED: [ 1854760 ] [ 1516619 ] inconsistent search FIXED: [ 1920084 ] kdiff3 is allowed to handle remote URL-s FIXED: [ 1638817 ] toolbar loses orientation when modified FIXED: [ 1578310 ] can't open ISO image by symbolic link FIXED: Enabled KRename on remote files FIXED: Right arrow in the detailed view can now go even inside iso files FIXED: Konfigurator: Dependency lists are now scrollable FIXED: Filter: Don't list comments in user/group chooser FIXED: Current working directory not returned in populateVfsList FIXED: Eject DVD with right-click menu FIXED: Actionman, sometimes the command field is empty (the text was rolled) FIXED: GCC 4.3: missing #includes (thanks to Fathi Boudra) FIXED: Searcher doesn't always find content in binary files FIXED: [ 1619452 ] Profile doesn't save status of sync-browse mode FIXED: [ 1681270 ] right clicking pops context menu immediately FIXED: [ 1645179 ] shortcut keys are not sent to the terminal FIXED: [ 1736496 ] always sort dirs by name not working I18N: Added Korean translation (thanks Seongnam Jee) I18N: Merged krarc.pot and iso.pot into krusader.pot (thanks Vaclav Juza) I18N: Updated Hungarian translation I18N: Updated French translation (thanks Henry Nicolas) I18N: Fixed [ 1725003 ] bad spanish translation I18N: Fixed untranslatable strings (thanks Vaclav Juza) I18N: Updated Ukrainian translation (thanks Yuri Chornoivan) I18N: Updated Catalan translation (thanks Joaquim Perez) I18N: Updated French translation (thanks Tourneur Henry-Nicolas) REMOVED: Clear location button (in KDE4 it is part of the KLineEdit) (thanks Fathi Boudra) 1.90.0 "Power Stone" ==================== ADDED: Useraction, Unpack multiple zip archives (thanks Ernest Beinrohr [OERNii] and Jonas) ADDED: Useraction, uuencode and uudecode (thanks Andrew Svet) ADDED: Useraction, Unpack current tar.7z ADDED: Useraction, tar.7z selected files ADDED: Useraction, Unpack current tar.lzma ADDED: Useraction, tar.lzma selected files ADDED: Useraction, Unpack current lzma ADDED: Useraction, Lzma current file ADDED: Useraction, 7zip current (thanks Vaclav Juza) ADDED: Javascript useraction, select from file ADDED: Useraction, tar.gz selected files (thanks Fathi Boudra) ADDED: Useraction, gzip current (thanks Vaclav Juza) ADDED: Useraction, Eject cd/dvd (thanks Andrew Svet) ADDED: Javascript useraction, calculator ADDED: Javascript useraction, Mount as root ADDED: Javascript useraction, Recode files using GNU recode (thanks Vaclav Juza) ADDED: Javascript useraction, Recode files using iconv (thanks Vaclav Juza) ADDED: Useraction, (Un)Pack an ar archive (.a, .deb,...) (thanks Vaclav Juza) ADDED: Useraction, Verify signature with kgpg ADDED: Useraction, Sign with kgpg ADDED: Useraction, Decrypt with kgpg ADDED: Useraction, Encrypt with kgpg ADDED: Useraction, Split large mp3 (thanks Andrew Svet) ADDED: Useraction, Archive to Dir ADDED: Useraction, Copy as root (thanks Andrew Svet and MaxiPunkt) ADDED: Useraction, Unmount (thanks Stefan Endrullis) ADDED: Useraction, Search and Replace in file ADDED: Midnight commander keymap (thanks Alejandro Hamann) ADDED: Alpa-yellow color scheme (thanks Aldo Palmeri [alpa]) ADDED: Bash color scheme (thanks Alejandro Hamann) ADDED: Improved midnight commander color scheme (thanks Alejandro Hamann) ADDED: Pleasent total commander color scheme ADDED: DOS Navigator color scheme (thanks to Vovan [Koqep]) FIXED: Useractions, after pwd command current workdir was not changed (thanks Vaclav Juza ) FIXED: Eject DVD with right-click menu FIXED: Actionman, sometimes the command field is empty, (thanks Vaclav Juza) FIXED: GCC 4.3: missing #includes (thanks Fathi Boudra) FIXED: krpermhandler.cpp didn't compile on kde 3.2.x I18N: Updated Catalan translation (thanks Joaquim Perez) I18N: Updated French translation (thanks Tourneur Henry-Nicolas) 1.80.0 "Final 3rd Stone" ======================== FIXED: searcher doesn't always find content in binary files FIXED: [ 1619452 ] Profile doesn't save status of sync-browse mode FIXED: [ 1681270 ] right clicking pops context menu immediately FIXED: [ 1645179 ] shortcut keys are not sent to the terminal FIXED: [ 1736496 ] always sort dirs by name not working I18N: Updated Hungarian translation I18N: Updated French translation (thanks Henry Nicolas) I18N: Fixed [ 1725003 ] bad spanish translation I18N: Fixed untranslatable strings, patch by Vaclav Juza, thanks 1.80.0-beta2 "Last Unstable Stone" ================================== ADDED: Terminal Emulator, paste with SHIFT+INSERT and CTRL+V ADDED: Vaclav's checksum patches (added sha* tools, fixed bugs etc...) ADDED: Synchronizer: ignore hidden files option ADDED: Synchronizer-results: drag [left], SHIFT+drag [right], Copy left/right selected items to clipboard ADDED: Locate-results: dragging items, copy to clipboard (CTRL+C) ADDED: Searcher-results: dragging items, copy to clipboard (CTRL+C) ADDED: Support for useraction placeholders in Krusader's commandline patches by Jiri Palacek and Vaclav Juza, thanks a lot! ADDED: New default user action "Backup current" http://www.kde-files.org/content/show.php?content=29801 ADDED: ALT+C as default shortcut for compare directories ADDED: Brief view ADDED: GUI for configuring the atomic extensions in Konfigurator CHANGED: Useractions: much better handling of the Each-placeholder patch by Jiri Palacek, thanks! CHANGED: Icons in the 3rd hand (preview, quick and view) FIXED: [ 1684478 ] buggy configure check for klineedit FIXED: Krusader wouldn't start after the "first time wizard" was launched FIXED: krarc, problem with application/x-zip-compressed mime FIXED: [ 1665209 ] can't see the modified flag (*) if many tabs are used FIXED: [ 1678927 ] archive operation - copy to relative path fails FIXED: [ 1659215 ] does not Quit when using Mac Menu style FIXED: [ 1629447 ] can not view file in an archive with perm 600 FIXED: KrServices::separateArgs bug, thanks to Jiri Palacek FIXED: Broken 3rd hand disk usage icon on systems with basic installation FIXED: [ 1649705 ] "Deleting non-empty directories" confirmation bug FIXED: keyboard problems in synchronizer, locate, searcher FIXED: [ 1601632 ] Esc don't work in KrViewer on SVG files FIXED: 'preserve attributes' sometimes fails setting the file mode FIXED: clicking on the 3rd hand widget's header, doesn't set focus FIXED: [ 1647279 ] out-of-bounds array access in the Filelight widget FIXED: Broken view panel icon in 3rd hand when Crystal icon theme is used FIXED: [ 1629450 ] Editing files in a separate window FIXED: Valgrind: Invalid Read at switching to a panel profile FIXED: [ 1631578 ] Config error (caused by italian handbook) FIXED: Problems with zip file names containing '[' character FIXED: Autoconfigure doesn't tell that packing is enabled by 7z FIXED: Problem with unpacking passworded ZIP files FIXED: Compile problem with automake-1.10 (thanks to Sausi at the forums) FIXED: FTP crash at slow servers FIXED: ACL compile problem on FreeBSD FIXED: in pack dialog, if two passwords are empty, a message would say "passwords are equal" I18N: Fixed [ 1650677 ] German: Wrong apostrophs I18N: Broke and fixed the plurals again! (in the latter case, thanks to Vaclav Juza for the help ;)) I18N: Updated a feature description in Konfigurator to match the new menubar (thanks Doutor Zero) REMOVED: Outdated and unused Italian handbook translation 1.80.0-beta1 "The Last Krusade" =============================== ADDED: quotation mark handling at search (ex. "Program Files") ADDED: full support for ACL permissions (properties, preserve attrs, synchronizer) ADDED: credit for Vaclav Juza and Jiri Palecek in the about box ADDED: Experimental input method support in quick search (patch by Jiri Palecek) ADDED: TerminalEmulator: Ctrl+F switches between full-widget TE, normal TE (thanks to Vaclav Juza) ADDED: Ctrl+Up from panel focuses the origin editbox, Ctrl+Down from origin editbox focuses the panel (thanks to Vaclav Juza) ADDED: TerminalEmulator: Ctrl+Shift+Up/Down always focus/unfocus TE independently whether the command line is shown or not ADDED: TerminalEmulator: if the command line is hidden, TE receives Ctrl+Up / Ctrl+Down (thanks to Vaclav Juza) ADDED: Pimped KDE's KeyDialog in order to provide import/export abilities ADDED: UserAction: Outputcollectionwindow can now save the buffer ADDED: UserAction: Outputcollection now supports fonts with fixed or variable width ADDED: synchronizer: double click on a file calls the diff utility (kompare) ADDED: terminal emulator: Ctrl+Enter,Ctrl+Shift+Enter paste the filename ADDED: atomic extensions (see CVSNEWS) ADDED: archive packing / unpacking are now in the background ADDED: renaming of just the filename, without extension ADDED: full screen terminal window (mc-style) ADDED: Inactive panel color dimming (thanks to Heiner) ADDED: ActionMan for useraction configuration ADDED: single instance mode ADDED: start to system tray ADDED: right click menu for bookmarks ADDED: enable/disable special bookmarks by right clicking on them ADDED: keeping the directory structures for virt folders at copy/move ADDED: synchronizer, parallel threads for slow FTP servers ADDED: an option for directories to be always sorted by name ADDED: packing with encryption, multiple volume archives, compress level ADDED: krarc, 7z, 7za handling ADDED: media button ADDED: swap panels / swap sides ADDED: synchronizer, threshold for equality, time offset between sides ADDED: synchronizer, faster "compare by content" for local files ADDED: synchronizer, Feed to listbox ADDED: searcher, synchronizer: directory name filters (ex. '* | CVS/') ADDED: searcher is able to search content on remote URLs ADDED: panel splitter shows the percent values at moving ADDED: Copy/Move: preserve all attributes (time, owner, group) ADDED: viewer, print + copy actions ADDED: new krarc (password handling, type autodetection, writing out archiver error messages, step into hidden archives,...) ARCH: refactoring in the useractions, see CVSNEWS CHANGED: atomic extensions are configurable through krusaderrc CHANGED: Better quick navigation: first move mouse over subdir, then press ctrl + left mouse button (patch by Jiri Palecek) CHANGED: Better subdir calculation on quick navigation CHANGED: Color cache redesigned. Konfigurator preview and actual colors should now match CHANGED: Heavily extended and reordered menubar (honouring the KDE HIG where possible). All available actions are connected to the menus now. CHANGED: Konfigurator: MouseMode got now it's own Tab in Look&Feel CHANGED: Shortcut- and Toolbardialogs are removed from Konfigurator CHANGED: Shortcuts are now exported in as plaintext, legacy import still works. CHANGED: UserActions are now managed with ActionMan. In Konfigurator you can change settings _about_ useractions. FIXED: problems at starting maximized, without splash screen FIXED: [ 1500411 ] Crash when R-click on free space and drag on files FIXED: [ 1579847 ] launch command line in console not saved FIXED: media button would display encoded paths (http://krusader.sourceforge.net/phpBB/viewtopic.php?t=1789) FIXED: crash when viewing file properties due to class name clash (thanks to Stephan Binner) FIXED: .tar.bz2 was not treated as atomic extension, while .tar.gz.test was FIXED: disk usage: other filelight bugfixes FIXED: disk usage: filelight crash because of missing null pointer checks FIXED: media button always writes out the mounted location FIXED: [ 1495465 ] packing dialog, 'MIN' and 'MAX' labels below the slider FIXED: [ 1436725 ] Status bar is not updated after RIGHT-ARROW is pressed FIXED: [ 1578768 ] Wrong sorting by Date column in search dialog FIXED: [ 1599142 ] problem with "Rename selects extension" and directories FIXED: wrong name after cancelling inplace rename by Esc FIXED: locate jumps onto the file after double click FIXED: When a refresh fails, the attempted URL is kept in the origin bar, and focus remains there for the user to fix. Idea by Vaclav Juza FIXED: TerminalEmulator didn't hide for all shortcuts FIXED: Konfigurator layout: should fit into 800x600 again FIXED: KeyDialog: alternative shortcuts are ex-/imported as well FIXED: KeyDialog: canceling the dialog undoes import FIXED: ActionMan: creating a new actions doesn't seem to modify the current FIXED: ActionMan: Save modifications on current action FIXED: [Debian: 378138] Changed the location of the .desktop-files to match freedesktop.org's standards FIXED: Useractions: outputcollections works again FIXED: inconsistences and possible memoryleaks in useractions (thanks to Jiri Palacek) FIXED: Nice shutdown at SIGTERM,SIGHUP,SIGQUIT (thanks toJiri Palacek) FIXED: QLayout warnings in ListPanel (patch by Jiri Palecek) FIXED: memory leaks in KRpermHandler (patch by Jiri Palecek) FIXED: shutdown bugs (thanks to Jiri Palacek) FIXED: const char * compiler warnings removed (patch by Jiri Palecek) FIXED: memory leaks in KrDetailedView (patch by Jiri Palecek) FIXED: terminal emulator sends the CD commands too frequently FIXED: terminal emulator scrolls up its content after hide/show FIXED: [ 1501740 ] can not link from a search result's virtfs FIXED: rare compile problem where exit() isn't defined FIXED: [ 1519955 ] wrong permission handling in vfs::vfs_calcSpaceLocal FIXED: viewer gives back the focus to the search/locate widgets after ESC FIXED: problems with local directory names containing '@' character FIXED: security: sometimes the passwords are stored in cleartext in bookmarks.xml FIXED: cannot close Krusader when "menubar on top of the screen" is chosen FIXED: URL duplication is disabled in the virtual URL collection FIXED: cut/copy/paste also works for virtual URLs FIXED: [ 1483172 ] crash at refreshing the view during rename FIXED: [ 1144729 ] Krusader doesn't remember popup panel splitter position FIXED: [ 1479034 ] Crashes after clicking home button, when quicksearch is active (patch by Heiner Eichmann) FIXED: wrong character set is used on the radial map labels FIXED: TC style rename does not work with "Obey KDE's global selection policy" FIXED: [ 1189341 ] minimize to tray problems with GNOME FIXED: set duplicate exclusion and maximum count for all KHistoryCombos FIXED: [ 984936 ] Wrong file cursor position when entering protected directory FIXED: [ 1232507 ] panel focus change problems at using the keyboard FIXED: bookmark separators get corrupted after adding a new bookmark FIXED: [ 1116161 ] more detailed error message at opening FTP URLs via HTTP proxy FIXED: [ 1103646 ] MountMan exits after umount and a fast click on the device FIXED: single click doesn't work in TC selection mode FIXED: disk usage crash at deleting files FIXED: valgrind: Free Memory Read - KMountManGUI::clicked() FIXED: valgrind: Free Memory Read - SynchronizerGUI::loadFromProfile() FIXED: valgrind: Free Memory Read - RadialMap::Widget::paintExplodedLabels() FIXED: valgrind: Free Memory Read - DULines::slotChanged() FIXED: valgrind: Free Memory Read - DULines::slotDeleted() FIXED: valgrind: Free Memory Read - KrDetailedView::contentsMousePressEvent() FIXED: valgrind: Mismatched delete/delete[]- RadialMap::Builder::Builder() FIXED: valgrind: Uninitialized Memory Read - DUFileLight::slotAboutToShow() FIXED: valgrind: Free Memory Read - KViewer::tabCloseRequest() FIXED: valgrind: Uninitialized Memory Read - KViewer::tabChanged() FIXED: valgrind: Free Memory Read - PanelManager::slotCloseTab() FIXED: [ 1435352 ] crash after NewPanel->Ctrl+U->DeletePanel FIXED: HTML tags cause problem to the searcher FIXED: [ 1415250 ] searching large directories, doesn't process UI events FIXED: search by content goes into infinite loop if the file cannot be opened FIXED: after exiting the pending jobs stall FIXED: [ 1193239 ] crash at 'Closing Current Session' FIXED: synchronizer is always on the top of the panels FIXED: [Debian: 352367] useractions with terminal output ignores configured terminal FIXED: last tabs are not saved, if an old config value is present FIXED: panel popup gets focus at opening, gives focus to panel at hiding FIXED: viewer, detaching tab changes 'Editing' to 'Viewing' I18N: Added a russian handbook (translation is work in progress) (thanks to Roman Batejkin) I18N: Fixed clash with unpack shortcut in useractions string (Alt+U) (thanks Hideki Kimura) I18N: Updated Japanese translation (thanks Hideki Kimura) I18N: Renamed remaining instances of 'mark' to 'select' I18N: Many consistency changes in the menu names I18N: Fixed [ 1480646 ] Home button tooltip has a wrong default translation I18N: Updated Russian translation (thanks Dmitry A. Bugay) I18N: Updated Swedish translation (thanks Peter Landgren) I18N: Updated Serbian translations (thanks Sasa Tomic) I18N: Updated Brazilian Portuguese translation (thanks Doutor Zero) I18N: Updated French translation (thanks Guillerm David) I18N: Updated Polish translation (thanks Tomek Grzejszczyk and Marcin Garski) I18N: Updated Lithuanian translation (thanks Dovydas Sankauskas) I18N: Menu items which open a new window, indicate that with trailing dots (KDE standard) I18N: Plural fixes in Synchronizer I18N: Updated Dutch translation I18N: Updated Slovenian translation (thanks Matej Urbancic) I18N: Added Turkish translation (thanks Bekir Sonat) I18N: Updated Greek translation (thanks Spiros Georgaras) I18N: Updated Czech translation (thanks Vaclav Juza) I18N: Updated Spanish translation (thanks Alejandro Araiza Alvarado) I18N: Updated German translation I18N: viewer: 'Editing', 'Viewing' can be translated I18N: Don't omit paragraphs and close all tags in strings to avoid errors in translation tools (based on patch by Giuseppe Bordoni) 1.70.0 "Round Robin" ========================== ADDED: new splashscreen + button to disable it in the look&feel section ADDED: winning icons, SVGs and fixed code to use them ADDED: DUMMY splash screen (krusader/splash.jpg) which will be replaced later CHANGED: UserActions: addPlaceholderButton now only adds a space after an executable. Not after normal placeholders. FIXED: [ 1413503 ] detach tab shortcut changed Ctrl+Shift+D FIXED: [ 1407656 ] bookmark problem with identical names in different folders FIXED: [ 1421473 ] viewer doesn't notice that the URL was changed FIXED: [ 1235959 ] problems at viewing 600 permission files FIXED: cannot umount devices because of a watcher bug (thanks to vaclavj) FIXED: 1076857 & 1384529 - thanks to heiner FIXED: [ 1409160 ] Edited bookmarks require restart to become fully updated FIXED: missing dpkg from Konfigurator-Dependencies FIXED: [ 1234213 ] synchronizer keeps owner,group if possible FIXED: [ 1365423 ] synchronizer does not copy symlinks FIXED: [ 1393227 ] KURLListRequester uses url completion instead of shell completion (caused problems at spaces) FIXED: [ 1391892 ] problem with international characters in the destination of a symlink FIXED: [ 1393215 ] searcher, synchronizer: ~,$HOME,... is accepted now FIXED: [ 1413503 ] viewer: detach wasn't disabled when 1 tab remained FIXED: [ 1417969 ] Keybindings: reset to default keybinding fails FIXED: Konfigurator 'Defaults' button works only on the actual subpage FIXED: [ 1411561 ] renaming bug (thanks Heiner Eichmann) FIXED: [ 1381770 ] Status bar is not updated after TAB is pressed (thanks Heiner Eichmann) FIXED: [ 1365053 ] krservices.h: invalid member function declaration (thanks Heiner Eichmann) FIXED: [ 1400642 ] possible data loss (thanks Heiner Eichmann) FIXED: [ 1352107 ] File search "as you type" (thanks Heiner Eichmann) FIXED: [ 1401005 ] F10 doesn't close KrViewer FIXED: [ 1390116 ] CTRL+G duplicate action in viewer FIXED: [ 1362632 ] Ctrl-Alt-C does not work FIXED: [Debian: 343960] outdated libtool prevents from building (thanks to Aurelien Jarno ) FIXED: [ 1398540 ] wrong font in the new network connection dialog FIXED: [ 1398442 ] Column 'rwx' wrong data when column 'Type' is on (thanks Spiros Georgaras) FIXED: UserActions: addPlaceholderButton's popup-position FIXED: 'match whole word only' flag doesn't work in search FIXED: [ 1352107 ] File search "as you type" FIXED: [ 1351641 ] Krusader 1.70.0-beta2 on Sparc/Solaris: checksumdlg.h FIXED: terminal emulator saves its size from now FIXED: hiding the full size terminal emulator cannot restore the panels FIXED: terminal emulator has no focus after toggling it on FIXED: preserve dates doesn't copy the dates of folders I18N: [ 1397828 ] i18n: "dir" is not translated I18N: Added Greek translation (thanks Spiros Georgaras) I18N: Updated French translation (thanks Guillerm David) I18N: Updated Danish translation (thanks Peter H. Sorensen) I18N: Updated Hungarian translation (thanks Arpad Biro) 1.70.0-beta2 "Afterburner" ========================== ADDED: you can now cancel creating and verifying checksums ADDED: a (missing) shortcut to bookmark current item (ctrl-shift-d) ADDED: you can turn off sending CDs to the terminal emulator (general tab) ADDED: unpacking from RPM packages (much faster than using krarc) CHANGED: our write-enabled tar KIO-slave is only build when --with-kiotar is passed to ./configure. In this case the KDE-version will may be overwritten! FIXED: [ 1345220 ] bookmarks: separators shown as folders FIXED: new viewer tabs were sometimes added to windows different from the previously used ones FIXED: [ 1323613 ] SECURITY!!! PopularUrls stores cleartext passwords in krusaderrc FIXED: [ 1329044 ] krarc, missed similar file names belonging to different rpm-s FIXED: krarc doesn't notice the change of the rpm file to create new contents.cpio FIXED: iso protocol cannot step into files larger than 2 GByte FIXED: KDE 3.4, starting from profile misses the active tab which causes inconsistent state FIXED: krarc reports 000 permission for bz2 files FIXED: bug in checksum module regarding names with spaces FIXED: konfigurator minor fixes FIXED: viewer, the tabs were identified by its page index, which can change FIXED: searcher: space means logical OR "text1 text2" == "*text1* || *text2*" FIXED: krarc cannot step into those archives which name contains '#' FIXED: viewer doesn't warning to save the window at close, and ignores "Cancel" button FIXED: locate dialog doesn't close when exiting krusader FIXED: UserAction: Crash when a programm wrote to stderr but only stdout was collected (Thanks to Shao Lo) FIXED: searcher crash when clicking onto an empty field after the results FIXED: disk usage crash on remote vfs because of recursion FIXED: [ 1262907 ] crash when closing an sftp tab which is loading I18N: Added Lithuanian translation (thanks Dovydas Sankauskas) 1.70.0-beta1 "Hellfire" ========================== ADDED: KrSqueezedTextLabel can now specify the area in the string to be always visible ADDED: when searching for text inside file, the first line containing the text is displayed ADDED: checksum module now supports the cfv tool (for md5 and sha1) ADDED: QuickNavigation: hold ctrl and move the mouse over the url bar to see! ADDED: new checksum creation/verification mechanism (see mail titled "new checksum feature" to krusader-devel) ADDED: alt-ctrl-s creates a new symlink ADDED: ctrl-h opens history on the current panel ADDED: Nicer application search results ADDED: right click menu -> trash, delete, shred options ADDED: column types can be changed and saved individually to each panel (each side) ADDED: select remote encoding menu for fish, ftp and sftp protocols ADDED: clear-location-bar button a-la konqueror (configurable) ADDED: permissions column as octal numbers ADDED: right-click menu now has a "create new..." submenu ADDED: ctrl-alt-enter opens the current folder in a new tab ADDED: calculate space in archives and remote FS (KDE >= 3.3.0) ADDED: experimental support for mimetype-on-demand ADDED: experimental support for icon-on-demand ADDED: when custom filter is set, the Totals line will show the filter. example: [*.cpp] ADDED: useraction: Drop a warning on JavaScript-errors ADDED: set krusaders icon acording to the users privileges ADDED: preserve date for local targets at copy / move ADDED: useraction: For JS-extensions the global variable scriptDir is available, indicating the location of the current script ADDED: synchronize selected files ADDED: colorful synchronizer :-) ADDED: starting more tabs with --left=tab1,tab2,tab3 --right=tab4,tab5 ADDED: vertical mode is saved with 'ui save settings' or 'save position' and restored ADDED: A Safari-like Jump-Back feature (Ctrl-J and in the bookmark-menu) ADDED: CTRL-L shortcut to go to the location bar (origin) as in firefox and konqueror ADDED: filters for selecting files ADDED: New zip/tar slave - based on KDE's but support writing to archive ARCH: refactoring in the view. enforcement of getVfile and getMutableVfile ARCH: removed a lot of KrViewItem's API ARCH: right-click menu code moved to a new class KrPopupMenu ARCH: moved JavaScript-stuff into it's own module KrJS ARCH: Makefile.am's for /krusader and /pics revised CHANGED: Use WhatsThis in favour of tooltips where reasonable CHANGED: the panel startup is profile based instead of directory based FIXED: krarc error, when the filename contains '$' or '&' FIXED: synchronizer, compare by content can be terminated by FIXED: preserve date fails at moving FIXED: bookmark issues (http://www.krusader.org/phpBB/viewtopic.php?p=6357#6357) FIXED: [ 1278534 ] Krusader hangs when packing search results FIXED: [ 1169980 ] User Actions Titles are not stored in system encoding (thanks Vaclav Juza) FIXED: '-icon' as well as '--icon' as command-line arguments are handled FIXED: [ 1272583 ] fixes on the .desktop files, thanks Marcin Garski FIXED: [ 1253323 ] middle click crash on ".." directory FIXED: burst refresh if FAM is enabled FIXED: crash when "run in terminal mode" was active on a directory with insufficient permissions (thanks Oleksandr Shneyder) FIXED: [ 1213137 ] javascript self.close() causes crash in the viewer FIXED: Control+Delete can be used in those distributions where Shift+Delete doesn't work FIXED: [ 1186534 ] problems with the new network connection (port, path, password, username) FIXED: renaming does not change the view, until VFS sends a signal about the rename actually being done FIXED: [ 1174273 ] updating the status bar at pressing the arrow keys FIXED: calcspace and diskusage shows the same size FIXED: [ 1180202 ] calcspace calculates wrong size for symbolic links FIXED: [ 1196779 ] searcher, sorting by size is broken FIXED: changing the 'show hidden files' sets the active tab to right, untouches the inactive ones FIXED: the default value of moving to trash is wrong in Konfigurator FIXED: problems with moving to trash at virt_fs and diskusage module FIXED: gcc 2.95 compiler fix FIXED: changed locate-gui shortcut from ctrl-l to shift+ctrl+l FIXED: bookmark icons were not saved correctly FIXED: clicking a search result won't jump to it, if it's in the current directory (patch by Thomas Jarosch) I18N: [ 1201586 ] Wrong encoding of slovenian translation I18N: [ 1243409 ] Encoding problem and bad plural in trash files dialog I18N: [ 1217697 ] Can't translate some Bookman II menu entries I18N: Added multiple plural support (thanks Vaclav Juza for all the help) I18N: Added Serbian translation (thanks Sasa Tomic) I18N: Added Brazilian Portuguese translation (thanks Doutor Zero) I18N: Updated Russian translation (thanks Denis Koryavov) I18N: Updated Portuguese translation (thanks Bruno Queiros) I18N: Updated Czech translation (thanks Vaclav Juza) I18N: Updated Dutch translation I18N: Updated French translation (thanks David Guillerm) I18N: Updated Spanish translation (thanks Alejandro Araiza Alvarado) I18N: Updated Swedish translation (thanks Peter Landgren) I18N: Updated Chinese Simplified translation (thanks Jinghua Luo) I18N: Updated Italian translation (thanks Giuseppe Bordoni) I18N: Updated Polish translation (thanks Pawel Salawa) I18N: Updated Slovenian translation (thanks Matej Urbancic) I18N: Updated German translation 1.60.0 ====================== ADDED: New Gorilla-style icon by www.OnExige.com FIXED: Crash if the useractions.xml contains invalid data FIXED: quick selection doesn't work FIXED: synchronizer, content filter doesn't work FIXED: synchronizer, consistency bug of the filter combos FIXED: advanced filter hides the searcher window at errors FIXED: combiner, smoother interoperability with Total Commander FIXED: UserActionMenu gets updated after Konfigurator applys FIXED: can't sort by extension when "Case Sensitive sort" is on FIXED: move to trash didn't work on kde 3.4.0 FIXED: [ 1123995 ] custom selection mode misfunction UPDATED: Italian translation (thanks Giuseppe Bordoni) UPDATED: Hungarian translation (thanks Arpad Biro) UPDATED: Chinese Simplified translation (thanks Jinghua Luo) UPDATED: Bulgarian translation (thanks Milen Ivanov) 1.60.0-beta2 ====================== FIXED: devices:/ is changed to media:/ in 3.4 FIXED: konfigurator crash on KDE 3.4 at checking 'save settings' FIXED: no refresh after splitting files FIXED: splitter doesn't handle sizes bigger than 2 GB properly FIXED: problem at restart if virtual folders were saved at last exit FIXED: locate / search feed to listbox number generation 1.60.0-beta1 ====================== ADDED: useraction: new placeholder: %_ListFile()% ADDED: total commander color scheme ADDED: Custom Selection Mode. dirk: a dream comming true? ;-) ADDED: synchronizer, exclude directories from the comparation ADDED: some nice sample useractions ADDED: PopularUrls was rewritten for a nice-like algorithm ADDED: Useractions in the menubar (need an update of krusaderui.rc) ADDED: searcher: ask for a collection-name on feed to listbox ADDED: popular urls is now persistent ADDED: popular-urls - krusader's answer to google-ranking ;-) ADDED: better completion in the origin box: constructs such as ~/src and $QTDIR/bin should work now. ADDED: Slovenian translation (thanks Matej Urbancic) ADDED: bookmarks can now be placed into toolbars ADDED: searcher, feed to listbox (with virtual folders) ADDED: Primitive scripting support; Warning: very alpha!! ADDED: new toolbar for actions. use view->show actions toolbar. you'll need to remove ~/.kde/share/apps/krusaderui.rc to see it ADDED: refresh-in-the-background for remote urls and for archives ADDED: changing the coloumns by right clicking on the panel's header ADDED: color scheme export/import ADDED: an other .desktop-file with the red icon that starts krusader as root ADDED: useraction: now every placeholder can cancel the execution. (-> %_ask(..)%) ADDED: useraction: new placeholder: %_PanelSize(percent)% ADDED: Synchronizer, pause/resume button for synchronize with kget ADDED: disk usage (tools menu + 3rd panel) ADDED: useraction: new placeholder: %_Move(src, dest)% ADDED: useraction: new placeholder: %_Each% ADDED: full viewer in the 3rd hand ADDED: shift-del deletes and doesn't move to trash ADDED: splitter: pre-defined 650MB and 700MB CD-R ADDED: more Konfigurator Tooltips ADDED: usermenu: entry to open konfigurator with the useraction-page directly ADDED: import/export of keyboard shortcuts ADDED: mouse selection modes are back! thanks to heiner for doing the work ADDED: virtual VFS (try virt:/somthing/) ARCH: KChooseDir was rewritten. plz have a look at the code/email ARCH: move listpanel from qstring to kurl. plz read email before continuing! FIXED: useraction: cancel a useraction now works for recursive expansion too FIXED: useraction: problems with international characters FIXED: panel profiles sometimes hang FIXED: new ftp dialog was broken FIXED: [ 1073940 ] no refresh after the exclusion filter is modified FIXED: [ 1108444 ] no error message if copy or move fails FIXED: auto filesystems cannot be mounted FIXED: krusader fails to refresh at copying to the source directory on different name FIXED: color "Inactive Marked Current Foreground" was ignored (thx heiner) FIXED: searcher gets behind the main window, if file browse is pressed FIXED: [ 1120827 ] dir copy / move with F5 / F6 doesn't work FIXED: [ 1064578 ] remote URL-s are saved in panel profiles FIXED: Creatring dir-trees on the fly (mkdir /foo/bar/test) is working again FIXED: Syncbrowse is working again and is deactivated automaticly if no longer possible FIXED: [ 1107141 ] view throws error at editing new files on remote fs FIXED: [ 1110507 ] cannot open rpm package if path contains space FIXED: command line alters its height at opening/closing the popup panel FIXED: [ 1037003 ] konqueror style drag and drop FIXED: [ 1076865 ] the default search text is '*' FIXED: [ 976598 ] krusader occasionally crashes at closing the viewer FIXED: [ 1033319 ] Relative paths dont get auto-completed FIXED: [ 971831 ] space calculation failure if the file is bigger than 4 GByte FIXED: [ 1089450 ] synchronizer copies the date information for local files FIXED: [ 1109249 ] drag and drop doesn't work with international characters FIXED: viewer cannot open 600 files, when the owner column is enabled FIXED: ftp_vfs overloads the CPU at stepping into a slow server on the network FIXED: krusader's detection of old or incompatible versions FIXED: dirk's patch for better looking icons FIXED: cannot open FTP proxy bookmarks FIXED: [ 1101237 ] the reload shortcut is always set to Ctrl+R at startup FIXED: rename extension bug in kde 3.3 FIXED: crash on startup due to restoring of last size and position FIXED: couldn't sort case sensative on some systems (see KDE bug #40131) FIXED: resizing of the main window produces strange effencts FIXED: double dragging in Krusader and Konqueror selection modes FIXED: right click menu and user action ID turmoil FIXED: [ 1074393 ] Crashes sometimes on startup (thanks Heiner) FIXED: custom icons in bookmarks weren't shown FIXED: All openUrl() calls are now delayed to avoid deadlocks... UPDATED: remoteman was disabled. from now on, bookmark manager only UPDATED: Hungarian translation (thanks Arpad Biro) UPDATED: Catalan translation (thanks Quim Perez Noguer) UPDATED: Portuguese translation (thanks Bruno Queiros) UPDATED: Dutch translation UPDATED: Swedish translation (thanks Peter Landgren) UPDATED: Russian translation UPDATED: German translation 1.51 ====================== ADDED: Portuguese translation (thanks Bruno Queiros) ADDED: Fn keys can have custom shortcuts ADDED: krusader can be resized to a small size even with Fn keys showing ADDED: Total-commander style refresh (at last) ADDED: ctrl-up arrow (from the panel) goes up to the origin bar ADDED: New commandline option: --profile ADDED: Heiner's selection mode patch. Still alpha. ADDED: Ukrainian translation (thanks Ivan Petrouchtchak) ADDED: disk usage tool (alpha version) ADDED: vertical krusader: hit alt+ctrl+v to test ADDED: extra information in the totals bar FIXED: separators were not displayed in the bookmarks list FIXED: deleting a folder didn't update the bottom stats correctly FIXED: useraction: parse the default-value "__goto" again FIXED: useraction: Crash when filename contained brackets '(...)' FIXED: world-class-annoying-bug when sometimes while using quicksearch, the file that was selected by quicksearch got hidden beneath the bar FIXED: mime types are shown only in english FIXED: when using quicksearch, current item wasn't visible FIXED: a crash when packing/unpacking to partial URL UPDATED: Dutch translation (thanks Frank Schoolmeesters) UPDATED: Hungarian translation (thanks Arpad Biro) UPDATED: German translation 1.50 ====================== FIXED: mountman now blocks and wait for mount/umount to complete FIXED: sorting got borked because locale-aware-compare isn't handling files that start with '.' well FIXED: possible opendir leakage, fish works only when moving the mouse FIXED: taken KDE's KDiskFreeSp class to optimize DF handling FIXED: Krusader overloads the CPU with panel refreshing FIXED: Wrong Danish language code (dk.po->da.po) UPDATED: Catalan translation (thanks Quim Perez) UPDATED: Italian translation (thanks Giuseppe Bordoni) UPDATED: Bulgarian translation (thanks Milen Ivanov) UPDATED: Slovak translation (thanks Zdenko Podobny) UPDATED: Hungarian translation (thanks Arpad Biro) UPDATED: German translation UPDATED: Dutch translation (thanks Frank Schoolmeesters) 1.50-beta1 ====================== ADDED: if view is human-readable, status bar is normal (bytes) and vice versa ADDED: Human-readable file sizes is implemented (located in look&feel->panel) ADDED: useraction: available via rightclick-menu ADDED: importing the right click menu of konqueror ADDED: cut(CTRL+X), copy(CTRL+C), paste(CTRL+V) ADDED: useraction: new Placeholder %_Profile("panel-profile")% ADDED: useraction: new Placeholder %_NewSearch("search-profile")% ADDED: useraction: run as different user ADDED: alt-O now sync the panels (like ctrl-left/right arrows) ADDED: new shortcut (ctrl-d) to open bookmarks on current panel ADDED: panel costum colors: new Current Marked Foreground ADDED: compare by content: the action is now smarter in finding the right files ADDED: profiles for the panels ADDED: mkdir (F7) can now create whole trees on the fly ("foo/bar/test") ADDED: synchronizer uses the search filters ADDED: search profiles ADDED: searcher: TC like search ( 'text' == '*text*' ) excluding files with '|' (ex. '*.cpp *.h | *.moc.cpp' ) ADDED: search on remote file systems ADDED: konfigurator|advanced has a new entry: just enter mountpoints there, and mountman won't try to mount/unmount them. ADDED: mountman got a big nose-job ;-) plz test ADDED: dropping on the tree panel (copy,move,link) ADDED: packing / unpacking to/from remote URL-s ADDED: short tab names ADDED: compare directories (mark menu) ADDED: shift+left/right changes tabs (thanks to Dmitry Suzdalev) ADDED: linking mimes and protocols ADDED: new delete dialog box: lists the file names to be deleted (thanks to dirk for the idea) ADDED: iso protocol for viewing .iso cd/dvd images (thanks to Szombathelyi Gyorgy) ADDED: full handling of arj, ace and lha packers ADDED: useraction: new Placeholder %_Sync("synchronizer-profile")% ADDED: synchronizer: profile handling ADDED: synchronizer: swap sides ADDED: useraction: new Placeholder %_Copy("from", "to")% ADDED: 3rd hand: new panel that does quick selection ADDED: 3rd hand: look n feel changed to fit krusader ADDED: credit for jonas in the about box ADDED: panels now save the tabs at shutdown (thanks to Donat Martin) ADDED: dropping URL-s onto the status / totals line ADDED: Bosnian translation ADDED: synchronizer: excluding files with '|' in the file filter (ex. '*.cpp *.h | *.moc.cpp' ) ADDED: tooltips for squeezed tabs ADDED: sync-browse mode (if on, a directory-change in the active is also performed in the inactive panel) ADDED: beta-state incremental refresh. test it with fam enabled! ADDED: synchronizer: ability to give more files in the file filter (ex. '*.cpp *.h') ADDED: Two single click rename (Total Commander rename) ADDED: The 3rd hand of krusader. click the litle arrow below the panel's scrollbar to see.. ADDED: showing suid, sgid and sticky bits in the permissions column ADDED: New useraction-system (partly based on Shies usermenu-prototype) REACTIVATED: usermenu (now using the new useraction-system) FIXED: synchronizer fails at case insensitive (Windows) file systems FIXED: crash when deleting an useraction created in the same session FIXED: locale aware ABC sorting (for non-english languages) FIXED: useraction: startpath is now working FIXED: useraction: i18n is now working in the add-placeholder-menu FIXED: searcher corrupts international characters FIXED: searcher cannot open remote URL-s for editing/viewing (archives) FIXED: the File/Properties function writes incorrect group name FIXED: krarc doesn't keep the date/time information at extracting to local fs FIXED: jar files aren't handled + problems with dirs in windows zips FIXED: problem with the windows created rar permissions FIXED: performance increasing: faster sorting, directory leaving FIXED: compare content error at remote urls (problem with sleep 2) FIXED: totals bar didn't update when an incremental refresh happened FIXED: locate doesn't report the errors occured during the search FIXED: the viewer size is forgotten in maximized mode (KDE hack) FIXED: internationalization bugs, illegal usage of QString::latin1() FIXED: krarc, ignores the packer dependencies FIXED: krarc, rar: mkdir does not work, illegal time and permission info FIXED: krarc, problem with copying / moving inside the archive FIXED: krarc, problem with international characters in put/mkdir FIXED: krarc, problems at copying subdirectories from the archive FIXED: [ 1005533 ] stepping onto a subfs device crashes krusader FIXED: [ 988835 ] window size of synchronize dirs is not stored FIXED: [ 946567 ] krusader minimizes to tray on desktop change FIXED: mountman changes... read the email ;-) REMOVED: Dupe Japanese translation (ja.po is used nowadays) UPDATED: Bosnian translation (thanks Asim Husanovic) UPDATED: Chinese Simplified translation (thanks Jinghua Luo) UPDATED: Hungarian translation (thanks Kukk Zolt�) UPDATED: German translation 1.40 ====================== ADDED: when searching in files (grep), push the string we're searching for into the clipboard when pressing F3 or F4. this saves an extra copy when searching inside the file ADDED: Catalan translation DISABLED: usermenu for 1.40 FIXED: [ 962340 ] Alt-T broken to call Tools menu FIXED: [ 980252 ] Compare by Content: right/left position swapped FIXED: [ 990141 ] F3/F4 in root mode trouble with permissions FIXED: [ 959916 ] Krusader window too large on startup FIXED: username and group information are wrong for ftp_vfs FIXED: UMR (uninitialized memory read) in vfs::fromPathOrURL UPDATED: Polish translation 1.40-beta2 ====================== ADDED: Chinese Simplified translation FIXED: the new ftp dialog URLs are saved into a stochastic configuration group FIXED: [ 960003 ] Swapped letters in quick-search FIXED: KIO::Slave url redirection handling (e.g. now devices:/ and settings:/ works !) FIXED: [ 962598 ] viewer didn't display XML files FIXED: [ 960595 ] problem with paths containing more '@' characters (FTP proxy hack) FIXED: [ 957145 ] krusader closes editor without asking FIXED: ports cannot be added for fish, sftp in the new connection GUI FIXED: [ 943962 ] the summary status is not updated after calc space FIXED: [ 950762 ] missing pemission check on entering a folder FIXED: setting "xterm -e vim" as editor didn't work... FIXED: [ 953874 ] allowing editors which are not url-aware to be used as default editor FIXED: [ 948315 ] security hole, krusader changes its temp directory's rights to 0777 FIXED: the UI settings are not saved at exit FIXED: [ 951274 ] shift+home and shift+end does not work FIXED: [ 948726 ] problem with ctrl+left from the left panel and ctrl+right from the right panel FIXED: extension is separated from the dirname after renaming directories containing '.' FIXED: locate does not call kdesu any more FIXED: [ 950052 ] synchronizer: the left and right side depends of the active panel FIXED: [ 770676 ] krarc does not handle password zips FIXED: [ 928746 ] symlinks pointing to directories using fish protocol fail FIXED: [ 939214 ] synchronizer, wrong behaviour of compare by content FIXED: moving into archives is dangerous. it is disabled (for now at least) FIXED: synchronizer gui size policy bugs FIXED: [ 934498 ] problem at dropping files into the '..' directory FIXED: [ 939612 ] F9 moves file, if new name already exists as directory FIXED: krusader does not handle filenames containing '#' character FIXED: krusader exits at viewing dvi files (missing arguments from KPart). FIXED: drag line remains visible after dropping an URL FIXED: panel swapping corrupts ctrl+arrow and alt+arrow FIXED: error at dropping URLs containing non-english characters from konqueror FIXED: KDE 3.2, right justified tabs bug FIXED: dragging over a new tab changes active tab FIXED: crash at pressing space on the '..' directory UPDATED: Bulgarian translation UPDATED: Czech translation UPDATED: Danish translation UPDATED: Dutch translation UPDATED: French translation UPDATED: German translation UPDATED: Hungarian translation UPDATED: Italian translation UPDATED: Slovak translation 1.40-beta1 ====================== ADDED: configuring the colors of the panel ADDED: (a bug fix really) ability to "not test archives before unpacking" ADDED: new icons (thanks to adios for providing them) ADDED: quickmode for mountman. press and HOLD the mountman icon for new functionality ADDED: Bulgarian translation (thanks to Milen Ivanov) ADDED: krusader restart is not necessary from now after changing the configuration ADDED: ability to give arguments for the terminal ADDED: enable/disable icons in the filenames ADDED: ability to configure the fields of the panel (Ext, Size, Perm, ...) ADDED: single click selects / executes ADDED: panel level toolbar ('..', '/', '~', '=' buttons), thanks to David Harel ADDED: Locate (integrating the findutils-locate package of GNU into Krusader). TEST IT ADDED: Heiner's patch for 'logical selection mode' is applied and used as default. TEST IT ADDED: application dependency setting in konfigurator ADDED: Csaba's new konfigurator is here, boys and girls! ADDED: heiner's quicksearch patch ADDED: calculate occupied space prints the directory's size (wincmd-style) - thanks heiner! ADDED: current directory in history menu is checked ADDED: a working user menu (try alt+~), but a bit rough on the edges ADDED: KrSearch edit/view file in the result list window (F3, F4, right click) ADDED: a folder-history button, a-la-total commander. thanks to Hans Loffler! ADDED: selectall at rename ADDED: new shortcuts to search dialog (heiner) ADDED: directory synchronizer ADDED: file splitter ADDED: a missing credit for Frank in the about box FIXED: krusader exits at closing the viewer when minimized to tray FIXED: KDE 3.2 terminal exit at Ctrl+C FIXED: bug [ 906386 ] regarding refreshes of dirwatch with fam enabled FIXED: bug [ 906538 ] which now makes a faster unpacking process FIXED: bug [ 894771 ] regarding over-expanding window due to long command line FIXED: edit new file on KDE 3.2 FIXED: permission handling for FTP URL-s FIXED: calc space crash at vfs refresh (thanks to Heiner) FIXED: krarc created non-executable directories (0666) FIXED: reimplementing the 'allow move into archive' setting FIXED: no restart at changing the icon tray's state in konfigurator FIXED: krusader freezes if the `df` process does not terminate (at network errors, IO wait) FIXED: krusaderui.rc bug, new menuitems does not appear after a krusader update FIXED: sort by EXT did not obey the 'case sensative sort' flag FIXED: 2 items on the view menu had the same shortcuts FIXED: increased speed of search, by emitting lesssignals (thanks to Lars) FIXED: statusbar updated only on mouse clicks, not on keyboard FIXED: translation: forcing non-english languages with a strange structure FIXED: freeze at modal dialogs and icon tray FIXED: crash at rename if the directory is refreshed by the watcher FIXED: stepping to the file below after delete (heiner) FIXED: window size and position saving at maximized mode FIXED: more freedom to give FTP proxy URL-s in "New FTP Connection" menu FIXED: crash at ftp://user@server@proxy:port FTP URL-s FIXED: no parent directory at tar://... and zip://... URL-s FIXED: font size problems in KCmdLine and KrMaskChoice FIXED: internal editor quits without notification even if the edited file was not saved FIXED: no i18n for Name, Ext, Size, Modified FIXED: obsolete QT header files FIXED: crash at closing the progressbar window at packing FIXED: no or uninformative error message at packing to a readonly directory FIXED: crash at middle clicking on the last tab FIXED: KrSearch permissions panel placing bug FIXED: ftp port limit changed from 999 to 65535 REMOVED: arc_vfs support completly replaced with KIO:Slave technolegy. UPDATED: new package description - Thanks to Jonas B�r UPDATED: Krusader Handbook (read ./doc/ChangeLog for more info) UPDATED: Japanese translation UPDATED: Dutch translation UPDATED: Czech translation (thanks to Martin Sixta) UPDATED: Spanish translation UPDATED: Krename url http://www.krename.net 1.30 ====================== ADDED: middle mouse button: click on a folder, and create a new tab. ADDED: middle mouse button: click on a tab, and close it FIXED: krarc QByteArray buffer freeing bug FIXED: mountman watches 'mount' instead of the directories FIXED: keyboard-shortcuts issues for new-tab(alt+ctrl+n), close-tab(alt+ctrl+c) and duplicate-tab(alt+ctrl+shift+n) FIXED: mountman FreeBSD bug (/etc/mtab does not exist in FreeBSD) FIXED: All files / Custom files. Executable was removed. FIXED: when selecting something from the combobox in "mark files" dialog, combo doesn't close immediatly FIXED: mark files dialog added the same selection more than once FIXED: disabled panel-types in konfigurator FIXED: font size problems with the Select dialog, and New Net Connection FIXED: mountman detects those devices as supermount, which are mounted and missing from fstab FIXED: mountman inserts '/dev/' before NFS shares and mounted devices which are missing from fstab FIXED: mountman does not watch readonly directories (mount can change its permissions!) FIXED: mountman does not stop dirwatch after close + memory leak FIXED: compare fix at directories with escape characters FIXED: Sorry - Archive test passed FIXED: FTP proxy bug (more than one @ characters in the URL) REMOVED: SortByExtention menu item (which did nothing) REMOVED: KrSearch-Help + Pack-Move into archive (did nothing) UPDATED: Dutch translation UPDATED: Danish translation UPDATED: Hungarian translation UPDATED: Italian translation UPDATED: Slovak translation 1.29-beta ====================== ADDED: KrSearch Match whole word only feature ADDED: Tab-browsing shortens tabs when more tabs are created ADDED: Starting Krusader with root privileges by pressing Alt+K ADDED: Open-in-a-new-tab available in right-click menu ADDED: Creating new files with SHIFT+F4 ADDED: Russian translation (thanks to Dmitry Chernyak) ADDED: Ctrl+Enter and Ctrl+Shift+Enter keyboard shortcuts ADDED: default shortcut for refreshing the panel is Ctrl+R ADDED: ctrl-left/right arrow checks if we're on a folder, if so it refreshes the other panel with the contents of the folder, otherwise to the same path as current one (Wincmd style) ADDED: tabbed-browsing beta ADDED: SHIFT-F3 view dialog. ADDED: The internal viewer follow links on HTML pages. ADDED: panel swapping by Ctrl+U ADDED: command line improvments: ctrl+/ opens history list, up&down keys work again, and general usability ADDED: krusader can now be started from commandline with new options: try: krusader --left=/mnt/cdrom --right=ftp://downloads@myserver.net! ADDED: new command line widget. should fix some issues and requests ADDED: Missing WhatsThis information (thanks to Mikolaj!) ADDED: a new shortcut for 'show hidden files' - ctrl+. (ctrl plus dot) ADDED: rar support to krArc KIO slave. ADDED: open with in the right click menu for multiple files with the same mimetype. ADDED: Patch by Heiner which adds a cancel button to the calculate space action. FIXED: KrSearch does not find texts at the last row FIXED: Strange KrSearch GUI (SearchIn and DontSearchIn adding) FIXED: KrSearch crash at pressing Escape or Closing the window during search FIXED: cmdline would start-up focused on the wrong panel FIXED: when pressing ctrl-enter (or ctrl-shift-enter), focus goes to command line FIXED: Terminal Emulator bug at ` and Backspace keys FIXED: internal editor / viewer crash at invalid symlinks FIXED: run-in-terminal would cause the terminal to close prematuraly and results would be lost. FIXED: free disk capacity miscalculation for Ext2 and Ext3 file systems. FIXED: crash when editing a file with # in the filename FIXED: inplace renaming bug with extention when pressing ctrl+click FIXED: whenever the folder gets refreshed, the current file would be lost FIXED: problematic behavior when trying to SPACE a folder without permissions FIXED: Ctrl-A didn't work properly FIXED: crash when unmounting a busy mountpoint FIXED: date-time sorting bug FIXED: changed pop-up delay of the history button on the command line to zero FIXED: right-click menu via keyboard appeared in the wrong place FIXED: crash when using spacebar on the ".." (thanks to heiner) FIXED: automark directories didn't work (thanks to Anarky) FIXED: bug when using space to calculate space of directory FIXED: crash when viewing files with # in their name. FIXED: compilation problem with GCC >= 3.3 (thanks to Adios) FIXED: Force refresh when creating a new directory. FIXED: a crash when trying to repaint when the VFS was deleted. REMOVED: Device Manager action UPDATED: many usability issues (thanks to Mikolaj) UPDATED: German translation UPDATED: Hungarian translation UPDATED: Dutch translation UPDATED: Spanish translation 1.25-beta1 ====================== ADDED: Finally, the new bookmark system is here! courtasy of Jan Halasa ADDED: new Hungarian translation, thanks to Kukk Zolt� FIXED: mountMan bug - didn't allow to umount/mount filesystem with trailing / FIXED: width of modified column for i18n (thanks to heiner) FIXED: dirUp() bug - selection goes to top. FIXED: the @ in ftp passwords bug. UPDATED: Slovak translation UPDATED: Dutch translation 1.21-beta1 ====================== ADDED: Opening left/right bookmarks (alt+left/right arrow) is now an action, and can be remapped. ADDED: In-place renaming (thanks to Heiner Eichmann) ADDED: New KIO slaves to handle archives. ADDED: multi-file properties. ADDED: Krusader now obeys KDE's date time format ADDED: Total-Commander style directory selection. Press SPACE to check it out! Thanks goes (again) to Heiner Eichmann! FIXED: column sizes are saved when doing 'save postion', or if 'save settings' is set in konfigurator. FIXED: double-catching of the ~ (tilda) key FIXED: double-catching of the backspace key FIXED: closing krusader using Alt-F4 or clicking X didn't save settings FIXED: Wrong focus after renaming FIXED: Error using KRename with filenames containing spaces (thanks to Tobias Vogele) FIXED: FreeBSD compatability in KrARC (thanks to Heiner Eichmann) FIXED: a crash in the dirUp() function. FIXED: when opening bookmarks using keyboard, active panel didn't change properly FIXED: in search dialog - you can now simply click text, and press ENTER. no need to click Search FIXED: a lot of usability issues (thanks to Mikolaj Machowski) FIXED: double-click in search dialog bug (thanks to heiner eichmann for the patch) FIXED: i18n issues - thanks to Frank Schoolmeesters FIXED: Panel flicker patch (thanks to Gabor Takacs for the patch) FIXED: Krusader failed to report permission errors while deleting files FIXED: issue with Japanesse translation FIXED: ctrl+arrows is caught by panel and not the view FIXED: removed unsafe debug messages FIXED: proper properties and owner/group for non-local files UPDATED: Dutch translation UPDATED: German translation BUG: krArc slow when unpacking large files 1.20 - KDE 3 ====================== ADDED: Clicking on the status or totals bars (above and below file list) changes focus ADDED: Each panel remembers the way it was sorted (might be different for each) ADDED: Each panel remembers the column width (might be different for each) ADDED: Dutch translation, thanks to Frank Schoolmeesters FIXED: Crash when saying NO to "really exit krusader?" UPDATED: German translation UPDATED: Polish translation 1.20 ====================== ADDED: Japanese translation, thanks to UTUMI Hirosi ADDED: error window when attempting to drag-n-drop to a target without enough permissions FIXED: crash when viewing/editing a file without permissions to read FIXED: icon touchup - to make the thing look more consistent FIXED: removed the ftp disconnect and root actions from the toolbar FIXED: updated polish translation FIXED: date sorting with files older than the year 2000 FIXED: crash on remote connections if there is a @ in the password FIXED: the remote connections rename function FIXED: blank hex viewer with short text files FIXED: anonymous checkbox in remote-man not respected 1.12 beta2 ====================== ADDED: Introducing extention column ADDED: Italian translation (thanks to Giuseppe Bordoni) ADDED: Preview to the right-click menu. FIXED: minimize to tray didn't behave correctly FIXED: crash when mounting failed (no cdrom in drive) FIXED: icon too big when minimized to tray FIXED: origin bar now accepts local urls (file:/) gracefully FIXED: origin bug, which caused the focus to go to the panel too soon. FIXED: right click menu in mountman (thanx to Heiner). FIXED: new 'admin' folder (support automake 1.7). FIXED: ESC key close the viewer. FIXED: crash when trying to open non-existing directory. FIXED: directory sorting. TODO: automark directories won't work in 1.12!!! TODO: can we add a krProgress to normal-vfs refreshes ? TODO: dragn'drop quirky. TODO: add progressbar to totals (?) TODO: COMPAREMODE 1.12 beta1 ====================== ADDED: some GUI touch-ups: make buttons smaller, and bars leaner. all in all, the thing should look better. ADDED: FreeBSD compatability issues - patchs by Heiner, thanks man! ADDED: move to next-gen view (at last) FIXED: popup-menu poping out of place. FIXED: Panel & PanelFunc permission clean up. FIXED: krBack() clean up. FIXED: moved all the logic from ListPanel to ListPanelFunc FIXED: integrated the openUrl() API. FIXED: minor bug in mountman FIXED: bug in arc_vfs, concerning full-paths in tars (thanks Heiner) FIXED: right align size column REMOVED: Tree & Quickview panels. 1.11 KDE 3 ====================== ADDED: updated Swedish translation, thanks to Anders Linden. ADDED: new Spanish translation, thanks to Rafa Munoz. ADDED: new Polish translation, thanks to Lukasz Janyst. FIXED: Changed the internal viewer default from Hex to Text. FIXED: Crash when Krusader is called with open viewer/internal editor. FIXED: Keyboard shortcuts not saved in Konfigurator. 1.10 - KDE 3 ====================== ADDED: new and improved viewer. ADDED: Krename support ! (more info at: http://krename.sf.net ) ADDED: you can now use the command line to "cd" into konqi-supported urls. ( try: cd audiocd:/?dev=/dev/cdrom ) ADDED: you can try to execute files in remote filesystem. ADDED: new command detection function instead of using 'which' FIXED: rewritten the panel sorting function, it should be better and faster now. FIXED: back to KRDirWatch, since KDirWatch crashed us on systems with FAM enabled. FIXED: removed the "panel start path is invalid" error message. if the start path is invalid try to find the closest path (the previous solution was '/'); FIXED: don't watch read-only/not-readable directories - this should improve performance and avoid a loooong wait time on super-mounted cdroms. FIXED: multiple selctions modes are no-more. default mode is Konqueror. the multi-mode become unstable after the kde3 porting and we had to disable it. FIXED: memory leak when starting konfigurator. 1.0.2 - KDE 3 ====================== ADDED: new icon. ADDED: sftp & scp support. ADDED: multi-protocol and history to the new connection dialog. FIXED: normal_vfs now uses the KDE dir watch, in other words: better directory refresh. FIXED: new 'admin' folder. 1.0.1 - KDE 3 ====================== ADDED: Krusader now compiles on KDE 3 (tested with RC3). ADDED: New ftp/smb vfs due to KDE 3 API changes. 1.0.1 ====================== ADDED: When compare-mode is active, pressing the 'Select Files' icon (or the equivelent keyboard short-cut), will open the usual dialog with 4 new options in the predefined selections. This allows automatic selection of files according to their compare-mode status - newer, older, etc. ADDED: Terminal emulator now "follows mouse" - konqueror style. ADDED: French translation. ADDED: A new icon for Krusader. new we've got krusader.png and krusader2.png! FIXED: errors compiling on kde 2.1 - convertSizeFromKB FIXED: compatability issue with installing to debian FIXED: compatability issue with Solaris FIXED: keyboard settings are not saved. FIXED: a small bug causing 'rrr' to show instead of 'rwx'. 1/1/02 - 1.00 =====================