📄 panelfunc.cpp
字号:
/*************************************************************************** panelfunc.cpp -------------------copyright : (C) 2000 by Shie Erlich & Rafi Yanaie-mail : krusader@users.sourceforge.netweb 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> // Qt Includes#include <qdir.h>#include <qtextstream.h>#include <qeventloop.h>#include <qclipboard.h> // KDE Includes#include <klocale.h>#include <kprocess.h>#include <kpropertiesdialog.h>#include <kopenwith.h>#include <kmessagebox.h>#include <kcursor.h>#include <kstandarddirs.h>#include <ktempfile.h>#include <kurl.h>#include <krun.h>#include <kinputdialog.h>#include <kdebug.h>#include <kio/netaccess.h>#include <kstandarddirs.h>#include <ktempdir.h> #include <kurlrequester.h>#include <kprocio.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, SIGNAL( timeout() ), this, SLOT( doOpenUrl() ) );}void ListPanelFunc::openUrl( const QString& url, const QString& 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( QDir::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, 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.start( 100, true ); /* 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.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(), 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::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 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.... 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 qApp->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 ; QString file = files() ->vfs_getFile( vf->vfile_getName() ).path( -1 ); 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.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 ; } 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( -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() { 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() { QString save = getcwd( 0, 0 ); chdir( panel->realPath().local8Bit() ); KProcess proc; krConfig->setGroup( "General" ); QString 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( KProcess::DontCare ) ) KMessageBox::sorry( krApp, i18n( "<qt>Can't open <b>%1</b></qt>" ).arg(term) ); chdir( save.local8Bit() );}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." ) );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -