summaryrefslogtreecommitdiffstats
path: root/src/app/Panel/panelfunc.cpp
diff options
context:
space:
mode:
authorMichele Calgaro <michele.calgaro@yahoo.it>2025-08-28 22:44:34 +0900
committerMichele Calgaro <michele.calgaro@yahoo.it>2025-08-31 23:30:34 +0900
commitf9abd9d505434c9244c03eac708e29a0ca042f6b (patch)
tree30a197ab4c413849188bc131ff859212e636c821 /src/app/Panel/panelfunc.cpp
parent14d42d284de233f9937becf3fc9ee0dabede3b21 (diff)
downloadkrusader-r14.1.x.tar.gz
krusader-r14.1.x.zip
Restructure source foldersr14.1.x
Signed-off-by: Michele Calgaro <michele.calgaro@yahoo.it> (cherry picked from commit 086012dcad8a976a0dabbb7cbc20c9cb612cdfa9)
Diffstat (limited to 'src/app/Panel/panelfunc.cpp')
-rw-r--r--src/app/Panel/panelfunc.cpp1202
1 files changed, 1202 insertions, 0 deletions
diff --git a/src/app/Panel/panelfunc.cpp b/src/app/Panel/panelfunc.cpp
new file mode 100644
index 0000000..7d1fa68
--- /dev/null
+++ b/src/app/Panel/panelfunc.cpp
@@ -0,0 +1,1202 @@
+/***************************************************************************
+ 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 <unistd.h>
+// TQt Includes
+#include <tqdir.h>
+#include <tqtextstream.h>
+#include <tqeventloop.h>
+#include <tqclipboard.h>
+// TDE Includes
+#include <tdelocale.h>
+#include <kprocess.h>
+#include <kpropertiesdialog.h>
+#include <kopenwith.h>
+#include <tdemessagebox.h>
+#include <kcursor.h>
+#include <kstandarddirs.h>
+#include <tdetempfile.h>
+#include <kurl.h>
+#include <krun.h>
+#include <kinputdialog.h>
+#include <kdebug.h>
+#include <tdeio/netaccess.h>
+#include <kstandarddirs.h>
+#include <ktempdir.h>
+#include <kurlrequester.h>
+#include <kdesktopfile.h>
+// Krusader Includes
+#include "panelfunc.h"
+#include "krcalcspacedialog.h"
+#include "krdetailedview.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 "krdrag.h"
+#include <kurldrag.h>
+
+//////////////////////////////////////////////////////////
+////// ---------- List Panel ------------- ////////
+//////////////////////////////////////////////////////////
+
+ListPanelFunc::ListPanelFunc( ListPanel *parent ) :
+panel( parent ), inRefresh( false ), vfsP( 0 ) {
+ urlStack.push( "file:/" );
+ connect( &delayTimer, TQ_SIGNAL( timeout() ), this, TQ_SLOT( doOpenUrl() ) );
+}
+
+void ListPanelFunc::openUrl( const TQString& url, const TQString& nameToMakeCurrent ) {
+ openUrl( vfs::fromPathOrURL(
+ // KURLRequester is buggy: it should return a string containing "/home/shie/downloads"
+ // but it returns "~/downloads" which is parsed incorrectly by vfs::fromPathOrURL.
+ // 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() ) {
+ if ( url.url() == "~" ) {
+ return openUrl( TQDir::homeDirPath() );
+ } else if ( !url.url().startsWith( "/" ) ) {
+ // possible relative URL - translate to full URL
+ url = files() ->vfs_getOrigin();
+ url.addPath( urlIn.url() );
+ //kdDebug()<< urlIn.url() << "," << url.url() <<endl;
+ } else {
+ panel->slotStartUpdate(); // refresh the panel
+ return ;
+ }
+ }
+
+ // if we are not refreshing to current URL
+ bool is_equal_url = files() ->vfs_getOrigin().equals( url, true );
+
+ if ( !is_equal_url ) {
+ // change the cursor to busy
+ panel->setCursor( KCursor::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.top().equals( url ) )
+ urlStack.push( url );
+ // count home many urls is in the stack, so later on, we'll know if the refresh was a success
+ uint stackSize = urlStack.size();
+ bool refreshFailed = true; // assume the worst
+ while ( true ) {
+ KURL u = urlStack.pop();
+ //u.adjustPath(-1); // 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, TQ_SIGNAL( deleteAllowed() ), vfsP, TQ_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.start( 100, true ); /* if vfs is busy try refreshing later */
+ return;
+ }
+ }
+ connect( files(), TQ_SIGNAL(startJob(TDEIO::Job* )),
+ panel, TQ_SLOT(slotJobStarted(TDEIO::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.size() + 1)
+ refreshFailed = false;
+
+ // update the urls stack
+ if ( !files() ->vfs_getOrigin().equals( urlStack.top() ) ) {
+ urlStack.push( files() ->vfs_getOrigin() );
+ }
+ // disconnect older signals
+ disconnect( files(), TQ_SIGNAL( addedVfile( vfile* ) ), 0, 0 );
+ disconnect( files(), TQ_SIGNAL( updatedVfile( vfile* ) ), 0, 0 );
+ disconnect( files(), TQ_SIGNAL( deletedVfile( const TQString& ) ), 0, 0 );
+ disconnect( files(), TQ_SIGNAL( cleared() ), 0, 0 );
+ // connect to the vfs's dirwatch signals
+ connect( files(), TQ_SIGNAL( addedVfile( vfile* ) ),
+ panel, TQ_SLOT( slotItemAdded( vfile* ) ) );
+ connect( files(), TQ_SIGNAL( updatedVfile( vfile* ) ),
+ panel, TQ_SLOT( slotItemUpdated( vfile* ) ) );
+ connect( files(), TQ_SIGNAL( deletedVfile( const TQString& ) ),
+ panel, TQ_SLOT( slotItemDeleted( const TQString& ) ) );
+ connect( files(), TQ_SIGNAL( cleared() ),
+ panel, TQ_SLOT( slotCleared() ) );
+
+ // on local file system change the working directory
+ if ( files() ->vfs_getType() == vfs::NORMAL )
+ chdir( files() ->vfs_getOrigin().path().local8Bit() );
+
+ // 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();
+ }
+}
+
+void ListPanelFunc::openUrl( const KURL& url, const TQString& 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....
+ KURL otherDir = OTHER_PANEL->virtualPath();
+ 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 ( ACTIVE_PANEL->virtualPath().equals( otherDir ) ) {
+ // deactivating the sync-browse if syncbrowse not possible
+ panel->syncBrowseButton->setOn( false );
+ }
+ inSync = false;
+ }
+ }
+ this->nameToMakeCurrent = nameToMakeCurrent;
+ delayURL = url; /* this function is useful for FTP url-s and bookmarks */
+ delayTimer.start( 0, true ); /* to avoid tqApp->processEvents() deadlock situaltion */
+}
+
+void ListPanelFunc::refresh() {
+ openUrl(panel->virtualPath()); // re-read the files
+}
+
+void ListPanelFunc::doOpenUrl() {
+ immediateOpenUrl( delayURL );
+}
+
+void ListPanelFunc::goBack() {
+ if ( urlStack.isEmpty() )
+ return ;
+
+ if ( urlStack.top().equals( files() ->vfs_getOrigin() ) )
+ urlStack.pop();
+ openUrl( urlStack.top(), files() ->vfs_getOrigin().fileName() );
+
+ if ( urlStack.isEmpty() )
+ krBack->setEnabled( false );
+}
+
+void ListPanelFunc::redirectLink() {
+ if ( files() ->vfs_getType() != 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 ;
+
+ TQString file = files() ->vfs_getFile( vf->vfile_getName() ).path( -1 );
+ TQString 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;
+ TQString 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.local8Bit() ) == -1 ) {
+ KMessageBox::sorry( krApp, i18n( "Can't remove old link: " ) + file );
+ return ;
+ }
+ // try to create a new symlink
+ if ( symlink( newLink.local8Bit(), file.local8Bit() ) == -1 ) {
+ KMessageBox:: /* --=={ Patch by Heiner <h.eichmann@gmx.de> }==-- */sorry( krApp, i18n( "Failed to create a new link: " ) + file );
+ return ;
+ }
+}
+
+void ListPanelFunc::krlink( bool sym ) {
+ if ( files() ->vfs_getType() != vfs::NORMAL ) {
+ KMessageBox::sorry( krApp, i18n( "You can create links only on local file systems" ) );
+ return ;
+ }
+
+ TQString name = panel->getCurrentName();
+
+ // ask the new link name..
+ bool ok = false;
+ TQString 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( -1 );
+
+ if ( sym ) {
+ if ( symlink( name.local8Bit(), linkName.local8Bit() ) == -1 )
+ KMessageBox::sorry( krApp, i18n( "Failed to create a new symlink: " ) + linkName +
+ i18n( " To: " ) + name );
+ } else {
+ if ( link( name.local8Bit(), linkName.local8Bit() ) == -1 )
+ KMessageBox::sorry( krApp, i18n( "Failed to create a new link: " ) + linkName +
+ i18n( " To: " ) + name );
+ }
+}
+
+void ListPanelFunc::view() {
+ TQString 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() {
+ TQString save = getcwd( 0, 0 );
+ chdir( panel->realPath().local8Bit() );
+
+ TDEProcess proc;
+ krConfig->setGroup( "General" );
+ TQString term = krConfig->readEntry( "Terminal", _Terminal );
+ proc << KrServices::separateArgs( term );
+
+ 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 );
+ }
+
+ if ( !proc.start( TDEProcess::DontCare ) )
+ KMessageBox::sorry( krApp, i18n( "<qt>Can't open <b>%1</b></qt>" ).arg(term) );
+
+ chdir( save.local8Bit() );
+}
+
+void ListPanelFunc::editFile() {
+ TQString 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() {
+ PreserveMode pmode = PM_DEFAULT;
+
+ TQStringList fileNames;
+ panel->getSelectedNames( &fileNames );
+ if ( fileNames.isEmpty() )
+ return ; // safety
+
+ KURL dest = panel->otherPanel->virtualPath();
+ KURL virtualBaseURL;
+
+ TQString destProtocol = dest.protocol();
+ if ( destProtocol == "krarc" || destProtocol == "tar" || destProtocol == "zip" ) {
+ KMessageBox::sorry( krApp, i18n( "Moving into archive is disabled" ) );
+ return ;
+ }
+
+ krConfig->setGroup( "Advanced" );
+ if ( krConfig->readBoolEntry( "Confirm Move", _ConfirmMove ) ) {
+ bool preserveAttrs = krConfig->readBoolEntry( "PreserveAttributes", _PreserveAttributes );
+ TQString s;
+
+ if( fileNames.count() == 1 )
+ s = i18n("Move %1 to:").arg(fileNames.first());
+ else
+ s = i18n("Move %n file to:", "Move %n files to:", fileNames.count());
+
+ // ask the user for the copy dest
+ virtualBaseURL = getVirtualBaseURL();
+ dest = KChooseDir::getDir(s, dest, panel->virtualPath(), 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( !virtualBaseURL.isEmpty() ) {
+ // keep the directory structure for virtual paths
+ VirtualCopyJob *vjob = new VirtualCopyJob( &fileNames, files(), dest, virtualBaseURL, pmode, TDEIO::CopyJob::Move, false, true );
+ connect( vjob, TQ_SIGNAL( result( TDEIO::Job* ) ), this, TQ_SLOT( refresh() ) );
+ if ( dest.equals( panel->otherPanel->virtualPath(), true ) )
+ connect( vjob, TQ_SIGNAL( result( TDEIO::Job* ) ), panel->otherPanel->func, TQ_SLOT( refresh() ) );
+ }
+ // if we are not moving to the other panel :
+ else if ( !dest.equals( panel->otherPanel->virtualPath(), true ) ) {
+ // you can rename only *one* file not a batch,
+ // so a batch dest must alwayes be a directory
+ if ( fileNames.count() > 1 ) dest.adjustPath(1);
+ TDEIO::Job* job = PreservingCopyJob::createCopyJob( pmode, *fileUrls, dest, TDEIO::CopyJob::Move, false, true );
+ job->setAutoErrorHandlingEnabled( true );
+ // refresh our panel when done
+ connect( job, TQ_SIGNAL( result( TDEIO::Job* ) ), this, TQ_SLOT( refresh() ) );
+ // and if needed the other panel as well
+ if ( dest.equals( panel->otherPanel->virtualPath(), true ) )
+ connect( job, TQ_SIGNAL( result( TDEIO::Job* ) ), panel->otherPanel->func, TQ_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, TDEIO::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 TQString &oldname, const TQString &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;
+ TQString dirName =
+ KInputDialog::getText( i18n( "New directory" ), i18n( "Directory's name:" ), "", &ok, krApp );
+
+ // if the user canceled - quit
+ if ( !ok || dirName.isEmpty() )
+ return ;
+
+ TQStringList dirTree = TQStringList::split( "/", dirName );
+
+ for ( TQStringList::Iterator it = dirTree.begin(); it != dirTree.end(); ++it ) {
+ // 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::VIRT || otherFunc()->files()->vfs_getType() == vfs::VIRT )
+ return KURL();
+
+ TQStringList 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( unsigned 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, true ) )
+ return KURL();
+ if( base.isParentOf( (*fileUrls)[ i ] ) )
+ break;
+ }while( true );
+ }
+ return base;
+}
+
+void ListPanelFunc::copyFiles() {
+ PreserveMode pmode = PM_DEFAULT;
+
+ TQStringList fileNames;
+ panel->getSelectedNames( &fileNames );
+ if ( fileNames.isEmpty() )
+ return ; // safety
+
+ KURL dest = panel->otherPanel->virtualPath();
+ KURL virtualBaseURL;
+
+ // confirm copy
+ krConfig->setGroup( "Advanced" );
+ if ( krConfig->readBoolEntry( "Confirm Copy", _ConfirmCopy ) ) {
+ bool preserveAttrs = krConfig->readBoolEntry( "PreserveAttributes", _PreserveAttributes );
+ TQString s;
+
+ if( fileNames.count() == 1 )
+ s = i18n("Copy %1 to:").arg(fileNames.first());
+ else
+ s = i18n("Copy %n file to:", "Copy %n files to:", fileNames.count());
+
+ // ask the user for the copy dest
+ virtualBaseURL = getVirtualBaseURL();
+ dest = KChooseDir::getDir(s, dest, panel->virtualPath(), 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( !virtualBaseURL.isEmpty() ) {
+ // keep the directory structure for virtual paths
+ VirtualCopyJob *vjob = new VirtualCopyJob( &fileNames, files(), dest, virtualBaseURL, pmode, TDEIO::CopyJob::Copy, false, true );
+ connect( vjob, TQ_SIGNAL( result( TDEIO::Job* ) ), this, TQ_SLOT( refresh() ) );
+ if ( dest.equals( panel->otherPanel->virtualPath(), true ) )
+ connect( vjob, TQ_SIGNAL( result( TDEIO::Job* ) ), panel->otherPanel->func, TQ_SLOT( refresh() ) );
+ }
+ // if we are not copying to the other panel :
+ else if ( !dest.equals( panel->otherPanel->virtualPath(), true ) ) {
+ // you can rename only *one* file not a batch,
+ // so a batch dest must alwayes be a directory
+ if ( fileNames.count() > 1 ) dest.adjustPath(1);
+ TDEIO::Job* job = PreservingCopyJob::createCopyJob( pmode, *fileUrls, dest, TDEIO::CopyJob::Copy, false, true );
+ job->setAutoErrorHandlingEnabled( true );
+ if ( dest.equals( panel->virtualPath(), true ) ||
+ dest.upURL().equals( panel->virtualPath(), true ) )
+ // refresh our panel when done
+ connect( job, TQ_SIGNAL( result( TDEIO::Job* ) ), this, TQ_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, TDEIO::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
+ TQStringList fileNames;
+ panel->getSelectedNames( &fileNames );
+ if ( fileNames.isEmpty() )
+ return ;
+
+ krConfig->setGroup( "General" );
+ bool trash = krConfig->readBoolEntry( "Move To Trash", _MoveToTrash );
+ // now ask the user if he want to delete:
+ krConfig->setGroup( "Advanced" );
+ if ( krConfig->readBoolEntry( "Confirm Delete", _ConfirmDelete ) ) {
+ TQString s, b;
+
+ if ( !reallyDelete && trash && files() ->vfs_getType() == vfs::NORMAL ) {
+ s = i18n( "Do you really want to move this item to the trash?", "Do you really want to move these %n items to the trash?", fileNames.count() );
+ b = i18n( "&Trash" );
+ } else if( files() ->vfs_getType() == vfs::VIRT && files()->vfs_getOrigin().equals( KURL("virt:/"), true ) ) {
+ s = i18n( "Do you really want to delete this virtual item (physical files stay untouched)?", "Do you really want to delete these virtual items (physical files stay untouched)?", fileNames.count() );
+ b = i18n( "&Delete" );
+ } else if( files() ->vfs_getType() == vfs::VIRT ) {
+ s = i18n( "<qt>Do you really want to delete this item <b>physically</b> (not just removing it from the virtual items)?</qt>", "<qt>Do you really want to delete these %n items <b>physically</b> (not just removing them from the virtual items)?</qt>", fileNames.count() );
+ b = i18n( "&Delete" );
+ } else {
+ s = i18n( "Do you really want to delete this item?", "Do you really want to delete these %n 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" ), b ) != KMessageBox::Continue )
+ return ;
+ }
+ //we want to warn the user about non empty dir
+ // and files he don't have permission to delete
+ krConfig->setGroup( "Advanced" );
+ bool emptyDirVerify = krConfig->readBoolEntry( "Confirm Unempty Dir", _ConfirmUnemptyDir );
+ emptyDirVerify = ( ( emptyDirVerify ) && ( files() ->vfs_getType() == vfs::NORMAL ) );
+
+ TQDir dir;
+ for ( TQStringList::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(TQDir::All | TQDir::System | TQDir::Hidden ).count() > 2 ) {
+ switch ( KMessageBox::warningYesNoCancel( krApp,
+ i18n( "<qt><p>Directory <b>%1</b> is not empty!</p><p>Skip this one or Delete All?</p></qt>" ).arg(*name),
+ TQString(), i18n( "&Skip" ), i18n( "&Delete All" ) ) ) {
+ case KMessageBox::Cancel :
+ return ;
+ case KMessageBox::No :
+ emptyDirVerify = false;
+ break;
+ case KMessageBox::Yes :
+ name = fileNames.remove( 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
+ krConfig->setGroup("General");
+ krConfig->writeEntry( "Move To Trash", false );
+ }
+ files() ->vfs_delFiles( &fileNames );
+ if (reallyDelete) {
+ krConfig->setGroup("General");
+ krConfig->writeEntry( "Move To Trash", trash);
+ }
+}
+
+// this is done when you double click on a file
+void ListPanelFunc::execute( TQString& name ) {
+ if ( name == ".." ) {
+ dirUp();
+ return ;
+ }
+ vfile *vf = files() ->vfs_search( name );
+ if ( vf == 0 )
+ return ;
+
+ KURL origin = files() ->vfs_getOrigin();
+
+ TQString protocol = origin.isLocalFile() ? KrServices::registerdProtocol( vf->vfile_getMime() ) : "";
+ if ( protocol == "tar" || protocol == "krarc" ) {
+ bool encrypted;
+ TQString 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( TQString() );
+ 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() {
+ TQStringList fileNames;
+ panel->getSelectedNames( &fileNames );
+ if ( fileNames.isEmpty() )
+ return ; // safety
+
+ if ( fileNames.count() == 0 )
+ return ; // nothing to pack
+
+ // choose the default name
+ TQString 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(), -1 ), fileNames.count(), fileNames.first() );
+ if ( PackGUI::type == TQString() )
+ return ; // the user canceled
+
+ // check for partial URLs
+ if( !PackGUI::destination.contains(":/") && !PackGUI::destination.startsWith("/") ){
+ PackGUI::destination = panel->virtualPath().prettyURL()+"/"+PackGUI::destination;
+ }
+
+ TQString destDir = PackGUI::destination;
+ if( !destDir.endsWith( "/" ) )
+ destDir += "/";
+
+ bool packToOtherPanel = ( destDir == panel->otherPanel->virtualPath().prettyURL(1) );
+
+ // on remote URL-s first pack into a temp file then copy to its right place
+ KURL destURL = vfs::fromPathOrURL( destDir + PackGUI::filename + "." + PackGUI::type );
+ KTempFile *tempDestFile = 0;
+ TQString 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 KTempFile( TQString(), "." + PackGUI::type );
+ tempDestFile->setAutoDelete( true );
+ arcFile = tempDestFile->name();
+ TQFile::remove
+ ( arcFile );
+ }
+
+ if ( TQFileInfo( arcFile ).exists() ) {
+ TQString msg = i18n( "<qt><p>The archive <b>%1.%2</b> already exists. Do you want to overwrite it?</p><p>All data in the previous archive will be lost!</p></qt>").arg(PackGUI::filename).arg(PackGUI::type);
+ if( PackGUI::type == "zip" ) {
+ msg = i18n( "<qt><p>The archive <b>%1.%2</b> already exists. Do you want to overwrite it?</p><p>Zip will replace identically named entries in the zip archive or add entries for new names.</p></qt>").arg(PackGUI::filename).arg(PackGUI::type);
+ }
+ if ( KMessageBox::warningContinueCancel( krApp,msg,TQString(),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 );
+
+ TDEIO::filesize_t totalSize = 0;
+ unsigned long totalDirs = 0, totalFiles = 0;
+ if( !calcSpace( fileNames, totalSize, totalFiles, totalDirs ) )
+ return;
+
+ // download remote URL-s if necessary
+ TQString arcDir;
+ KTempDir *tempDir = 0;
+
+ if ( files() ->vfs_getOrigin().isLocalFile() )
+ arcDir = files() ->vfs_workingDir();
+ else {
+ tempDir = new KTempDir();
+ tempDir->setAutoDelete( true );
+ arcDir = tempDir->name();
+ KURL::List *urlList = files() ->vfs_getFiles( &fileNames );
+ TDEIO::NetAccess::dircopy( *urlList, vfs::fromPathOrURL( arcDir ), 0 );
+ delete urlList;
+ }
+
+ // pack the files
+ // we must chdir() first because we supply *names* not URL's
+ TQString save = getcwd( 0, 0 );
+ chdir( arcDir.local8Bit() );
+ KRarcHandler::pack( fileNames, PackGUI::type, arcFile, totalFiles + totalDirs, PackGUI::extraProps );
+ chdir( save.local8Bit() );
+
+ // delete the temporary directory if created
+ if ( tempDir )
+ delete tempDir;
+
+ // copy from the temp file to it's right place
+ if ( tempDestFile ) {
+ TDEIO::NetAccess::file_move( vfs::fromPathOrURL( arcFile ), destURL );
+ delete tempDestFile;
+ }
+
+ if ( packToOtherPanel )
+ panel->otherPanel->func->refresh();
+}
+
+void ListPanelFunc::testArchive() {
+ TQString arcName = panel->getCurrentName();
+ if ( arcName.isNull() )
+ return ;
+ if ( arcName == ".." )
+ return ; // safety
+
+ KURL arcURL = files() ->vfs_getFile( arcName );
+ TQString url = TQString();
+
+ // download the file if it's on a remote filesystem
+ if ( !arcURL.isLocalFile() ) {
+ url = locateLocal( "tmp", TQString( arcName ) );
+ if ( !TDEIO::NetAccess::download( arcURL, url, 0 ) ) {
+ KMessageBox::sorry( krApp, i18n( "Krusader is unable to download: " ) + arcURL.fileName() );
+ return ;
+ }
+ } else
+ url = arcURL.path( -1 );
+
+ TQString mime = files() ->vfs_search( arcName ) ->vfile_getMime();
+ bool encrypted = false;
+ TQString type = KRarcHandler::getType( encrypted, url, mime );
+
+ // check we that archive is supported
+ if ( !KRarcHandler::arcSupported( type ) ) {
+ KMessageBox::sorry( krApp, i18n( "%1, unknown archive type." ).arg( arcName ) );
+ return ;
+ }
+
+ TQString password = encrypted ? KRarcHandler::getPassword( url ) : TQString();
+
+ // test the archive
+ if ( KRarcHandler::test( url, type, password ) )
+ KMessageBox::information( krApp, i18n( "%1, test passed." ).arg( arcName ) );
+ else
+ KMessageBox::error( krApp, i18n( "%1, test failed!" ).arg( arcName ) );
+
+ // remove the downloaded file if necessary
+ if ( url != arcURL.path( -1 ) )
+ TQFile( url ).remove();
+}
+
+void ListPanelFunc::unpack() {
+ TQStringList fileNames;
+ panel->getSelectedNames( &fileNames );
+ if ( fileNames.isEmpty() )
+ return ; // safety
+
+ TQString s;
+ if(fileNames.count() == 1)
+ s = i18n("Unpack %1 to:").arg(fileNames[0]);
+ else
+ s = i18n("Unpack %n file to:", "Unpack %n 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(), true ) );
+
+ for ( unsigned int i = 0; i < fileNames.count(); ++i ) {
+ TQString 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 );
+ TQString url = TQString();
+ if ( !arcURL.isLocalFile() ) {
+ url = locateLocal( "tmp", TQString( arcName ) );
+ if ( !TDEIO::NetAccess::download( arcURL, url, 0 ) ) {
+ KMessageBox::sorry( krApp, i18n( "Krusader is unable to download: " ) + arcURL.fileName() );
+ continue;
+ }
+ } else
+ url = arcURL.path( -1 );
+
+ // for local destionation, check whether it exists or not
+ if ( dest.isLocalFile() ) {
+ TQDir destdir = TQDir(dest.path(1));
+ if (!destdir.exists()) {
+ // Destination folder does not exists
+ int res = KMessageBox::warningContinueCancel( NULL,
+ i18n("The destination folder does not exist.\nDo you want to create it?"),
+ i18n("Create folder"));
+ if ( res != KMessageBox::Continue ) {
+ return;
+ }
+ // Create destination folder. If failed, return
+ if (!destdir.mkdir(destdir.absPath())) {
+ KMessageBox::error(NULL, i18n("Unable to create the destionation folder. Aborting operation."), i18n("Error!"));
+ }
+ }
+ }
+
+ // if the destination is in remote directory use temporary one instead
+ dest.adjustPath(1);
+ KURL originalDestURL;
+ KTempDir *tempDir = 0;
+
+ if ( !dest.isLocalFile() ) {
+ originalDestURL = dest;
+ tempDir = new KTempDir();
+ tempDir->setAutoDelete( true );
+ dest = tempDir->name();
+ }
+
+ // determining the type
+ TQString mime = files() ->vfs_search( arcName ) ->vfile_getMime();
+ bool encrypted = false;
+ TQString type = KRarcHandler::getType( encrypted, url, mime );
+
+ // check we that archive is supported
+ if ( !KRarcHandler::arcSupported( type ) ) {
+ KMessageBox::sorry( krApp, i18n( "%1, unknown archive type" ).arg( arcName ) );
+ continue;
+ }
+
+ TQString password = encrypted ? KRarcHandler::getPassword( url ) : TQString();
+
+ // unpack the files
+ KRarcHandler::unpack( url, type, password, dest.path( -1 ) );
+
+ // remove the downloaded file if necessary
+ if ( url != arcURL.path( -1 ) )
+ TQFile( url ).remove();
+
+ // copy files to the destination directory at remote files
+ if ( tempDir ) {
+ TQStringList nameList = TQDir( dest.path( -1 ) ).entryList();
+ KURL::List urlList;
+ for ( unsigned int i = 0; i != nameList.count(); i++ )
+ if ( nameList[ i ] != "." && nameList[ i ] != ".." )
+ urlList.append( vfs::fromPathOrURL( dest.path( 1 ) + nameList[ i ] ) );
+ if ( urlList.count() > 0 )
+ TDEIO::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, TQStringList& 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() {
+ TQStringList args;
+ bool folders;
+ checksum_wrapper(panel, args, folders);
+ CreateChecksumDlg dlg(args, folders, panel->realPath());
+}
+
+void ListPanelFunc::matchChecksum() {
+ TQStringList args;
+ bool folders;
+ checksum_wrapper(panel, args, folders);
+ TQValueList<vfile*> checksumFiles = files()->vfs_search(
+ KRQuery(MatchChecksumDlg::checksumTypesFilter)
+ );
+ MatchChecksumDlg dlg(args, folders, panel->realPath(),
+ (checksumFiles.size()==1 ? checksumFiles[0]->vfile_getUrl().prettyURL() : TQString()));
+}
+
+void ListPanelFunc::calcSpace() {
+ TQStringList 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 ( TQStringList::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 TQStringList & items, TDEIO::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::FTP ) {
+ krFTPDiss->setEnabled( false );
+ panel->view->setNameToMakeCurrent( TQString() );
+ 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() {
+ TQStringList names;
+ panel->getSelectedNames( &names );
+ if ( names.isEmpty() )
+ return ; // no names...
+ KFileItemList fi;
+ fi.setAutoDelete( true );
+
+ for ( unsigned 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.append( new KFileItem( vf->vfile_getEntry(), url ) );
+ }
+
+ if ( fi.isEmpty() )
+ return ;
+
+ // Show the properties dialog
+ KPropertiesDialog *dlg = new KPropertiesDialog( fi );
+ connect( dlg, TQ_SIGNAL( applied() ), SLOTS, TQ_SLOT( refresh() ) );
+}
+
+void ListPanelFunc::refreshActions() {
+ vfs::VFS_TYPE vfsType = files() ->vfs_getType();
+
+ // set up actions
+ krMultiRename->setEnabled( vfsType == vfs::NORMAL ); // batch rename
+ //krProperties ->setEnabled( vfsType == vfs::NORMAL || vfsType == vfs::FTP ); // file properties
+ krFTPDiss ->setEnabled( vfsType == vfs::FTP ); // disconnect an FTP session
+ krCreateCS->setEnabled( vfsType == vfs::NORMAL );
+ /*
+ 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
+ krBack->setEnabled(func->canGoBack()); // go back
+ krRoot->setEnabled(true); // go all the way up
+ krExecFiles->setEnabled(true); // show only executables
+ */
+}
+
+ListPanelFunc::~ListPanelFunc() {
+ if( !vfsP ) {
+ if( vfsP->vfs_canDelete() )
+ delete vfsP;
+ else {
+ connect( vfsP, TQ_SIGNAL( deleteAllowed() ), vfsP, TQ_SLOT( deleteLater() ) );
+ vfsP->vfs_requestDelete();
+ }
+ }
+ vfsP = 0;
+}
+
+vfs* ListPanelFunc::files() {
+ if ( !vfsP )
+ vfsP = KrVfsHandler::getVfs( "/", panel, 0 );
+ return vfsP;
+}
+
+
+void ListPanelFunc::copyToClipboard( bool move ) {
+ if( files()->vfs_getOrigin().equals( KURL("virt:/"), true ) ) {
+ 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;
+ }
+
+ TQStringList fileNames;
+
+ panel->getSelectedNames( &fileNames );
+ if ( fileNames.isEmpty() )
+ return ; // safety
+
+ KURL::List* fileUrls = files() ->vfs_getFiles( &fileNames );
+ if ( fileUrls ) {
+ KRDrag * urlData = KRDrag::newDrag( *fileUrls, move, krApp->mainView, "krusader" );
+ TQApplication::clipboard() ->setData( urlData );
+
+ if( move && files()->vfs_getType() == vfs::VIRT )
+ ( static_cast<virt_vfs*>( files() ) )->vfs_removeFiles( &fileNames );
+
+ delete fileUrls;
+ }
+}
+
+void ListPanelFunc::pasteFromClipboard() {
+ TQClipboard * cb = TQApplication::clipboard();
+ TQMimeSource * data = cb->data();
+ KURL::List urls;
+ if ( KURLDrag::canDecode( data ) ) {
+ KURLDrag::decode( data, urls );
+ bool cutSelection = KRDrag::decodeIsCutSelection( data );
+
+ KURL destUrl = panel->virtualPath();
+
+ files()->vfs_addFiles( &urls, cutSelection ? TDEIO::CopyJob::Move : TDEIO::CopyJob::Copy, otherFunc()->files(),
+ "", PM_DEFAULT );
+ }
+}
+
+#include "panelfunc.moc"