/*
* This file is part of the KFTPGrabber project
*
* Copyright ( C ) 2003 - 2004 by the KFTPGrabber developers
* Copyright ( C ) 2003 - 2004 Jernej Kos < kostko @ jweb - network . net >
*
* This program is free software ; you can redistribute it and / or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation ; either version 2 of the
* License , or ( at your option ) any later version .
*
* This program is distributed in the hope that it will be useful , but
* is provided AS IS , WITHOUT ANY WARRANTY ; without even the implied
* warranty of MERCHANTABILITY , FITNESS FOR A PARTICULAR PURPOSE , and
* NON - INFRINGEMENT . See the GNU General Public License for more details .
*
* You should have received a copy of the GNU General Public License
* along with this program ; if not , write to the Free Software
* Foundation , Inc . , 51 Franklin Steet , Fifth Floor , Boston ,
* MA 02110 - 1301 , USA .
*
* In addition , as a special exception , the copyright holders give
* permission to link the code of portions of this program with the
* OpenSSL library under certain conditions as described in each
* individual source file , and distribute linked combinations
* including the two .
* You must obey the GNU General Public License in all respects
* for all of the code used other than OpenSSL . If you modify
* file ( s ) with this exception , you may extend this exception to your
* version of the file ( s ) , but you are not obligated to do so . If you
* do not wish to do so , delete this exception statement from your
* version . If you delete this exception statement from all source
* files in the program , then also delete it here .
*/
# include "kftpsession.h"
# include "kftpapi.h"
# include "browser/detailsview.h"
# include "browser/treeview.h"
# include "browser/view.h"
# include "kftpbookmarks.h"
# include "misc.h"
# include "widgets/systemtray.h"
# include "mainactions.h"
# include "misc/kftpconfig.h"
# include "misc/filter.h"
# include <tqdir.h>
# include <tqobjectlist.h>
# include <tdemessagebox.h>
# include <tdelocale.h>
# include <kdebug.h>
# include <kpassdlg.h>
# include <kstaticdeleter.h>
using namespace KFTPGrabberBase ;
using namespace KFTPEngine ;
using namespace KFTPCore : : Filter ;
namespace KFTPSession {
//////////////////////////////////////////////////////////////////
//////////////////////// Connection ///////////////////////
//////////////////////////////////////////////////////////////////
Connection : : Connection ( Session * session , bool primary )
: TQObject ( session ) ,
m_primary ( primary ) ,
m_busy ( false ) ,
m_aborting ( false ) ,
m_scanning ( false )
{
// Create the actual connection client
m_client = new KFTPEngine : : Thread ( ) ;
connect ( m_client - > eventHandler ( ) , TQ_SIGNAL ( engineEvent ( KFTPEngine : : Event * ) ) , this , TQ_SLOT ( slotEngineEvent ( KFTPEngine : : Event * ) ) ) ;
// If this is not a core session connection, connect
if ( ! primary ) {
// Connect to the server
KURL url = session - > getClient ( ) - > socket ( ) - > getCurrentUrl ( ) ;
KFTPBookmarks : : Manager : : self ( ) - > setupClient ( session - > getSite ( ) , m_client ) ;
m_client - > connect ( url ) ;
}
}
Connection : : ~ Connection ( )
{
delete m_client ;
}
bool Connection : : isConnected ( )
{
return ! static_cast < Session * > ( parent ( ) ) - > isRemote ( ) | | m_client - > socket ( ) - > isConnected ( ) ;
}
void Connection : : acquire ( KFTPQueue : : Transfer * transfer )
{
if ( m_busy | | ! static_cast < Session * > ( parent ( ) ) - > isRemote ( ) )
return ;
m_curTransfer = transfer ;
m_busy = true ;
connect ( transfer , TQ_SIGNAL ( transferComplete ( long ) ) , this , TQ_SLOT ( slotTransferCompleted ( ) ) ) ;
connect ( transfer , TQ_SIGNAL ( transferAbort ( long ) ) , this , TQ_SLOT ( slotTransferCompleted ( ) ) ) ;
emit connectionAcquired ( ) ;
}
void Connection : : remove ( )
{
// Disconnect all signals from the transfer
if ( m_curTransfer )
m_curTransfer - > TQObject : : disconnect ( this ) ;
m_curTransfer = 0L ;
m_busy = false ;
emit connectionRemoved ( ) ;
emit static_cast < Session * > ( parent ( ) ) - > freeConnectionAvailable ( ) ;
}
void Connection : : abort ( )
{
if ( m_aborting | | ! m_client - > socket ( ) - > isBusy ( ) )
return ;
// Emit the signal before aborting
emit aborting ( ) ;
// Abort transfer
m_aborting = true ;
m_client - > abort ( ) ;
m_aborting = false ;
}
void Connection : : scanDirectory ( KFTPQueue : : Transfer * parent )
{
// Lock the connection and the transfer
acquire ( parent ) ;
parent - > lock ( ) ;
m_scanning = true ;
if ( isConnected ( ) )
m_client - > scan ( parent - > getSourceUrl ( ) ) ;
}
void Connection : : addScannedDirectory ( KFTPEngine : : DirectoryTree * tree , KFTPQueue : : Transfer * parent )
{
// Directories
DirectoryTree : : DirIterator dirEnd = tree - > directories ( ) - > end ( ) ;
for ( DirectoryTree : : DirIterator i = tree - > directories ( ) - > begin ( ) ; i ! = dirEnd ; i + + ) {
KURL sourceUrlBase = parent - > getSourceUrl ( ) ;
KURL destUrlBase = parent - > getDestUrl ( ) ;
sourceUrlBase . addPath ( ( * i ) - > info ( ) . filename ( ) ) ;
destUrlBase . addPath ( ( * i ) - > info ( ) . filename ( ) ) ;
// Check if we should skip this entry
const ActionChain * actionChain = Filters : : self ( ) - > process ( sourceUrlBase , 0 , true ) ;
if ( actionChain & & actionChain - > getAction ( Action : : Skip ) )
continue ;
// Add directory transfer
KFTPQueue : : TransferDir * transfer = new KFTPQueue : : TransferDir ( parent ) ;
transfer - > setSourceUrl ( sourceUrlBase ) ;
transfer - > setDestUrl ( destUrlBase ) ;
transfer - > setTransferType ( parent - > getTransferType ( ) ) ;
transfer - > setId ( KFTPQueue : : Manager : : self ( ) - > nextTransferId ( ) ) ;
emit KFTPQueue : : Manager : : self ( ) - > newTransfer ( transfer ) ;
addScannedDirectory ( * i , transfer ) ;
if ( KFTPCore : : Config : : skipEmptyDirs ( ) & & ! transfer - > hasChildren ( ) )
KFTPQueue : : Manager : : self ( ) - > removeTransfer ( transfer , false ) ;
}
// Files
DirectoryTree : : FileIterator fileEnd = tree - > files ( ) - > end ( ) ;
for ( DirectoryTree : : FileIterator i = tree - > files ( ) - > begin ( ) ; i ! = fileEnd ; i + + ) {
KURL sourceUrlBase = parent - > getSourceUrl ( ) ;
KURL destUrlBase = parent - > getDestUrl ( ) ;
sourceUrlBase . addPath ( ( * i ) . filename ( ) ) ;
destUrlBase . addPath ( ( * i ) . filename ( ) ) ;
// Check if we should skip this entry
const ActionChain * actionChain = Filters : : self ( ) - > process ( sourceUrlBase , ( * i ) . size ( ) , false ) ;
if ( actionChain & & actionChain - > getAction ( Action : : Skip ) )
continue ;
// Add file transfer
KFTPQueue : : TransferFile * transfer = new KFTPQueue : : TransferFile ( parent ) ;
transfer - > addSize ( ( * i ) . size ( ) ) ;
transfer - > setSourceUrl ( sourceUrlBase ) ;
transfer - > setDestUrl ( destUrlBase ) ;
transfer - > setTransferType ( parent - > getTransferType ( ) ) ;
transfer - > setId ( KFTPQueue : : Manager : : self ( ) - > nextTransferId ( ) ) ;
emit KFTPQueue : : Manager : : self ( ) - > newTransfer ( transfer ) ;
}
}
void Connection : : slotEngineEvent ( KFTPEngine : : Event * event )
{
switch ( event - > type ( ) ) {
case Event : : EventDisconnect : {
emit connectionLost ( this ) ;
break ;
}
case Event : : EventConnect : {
emit connectionEstablished ( ) ;
if ( m_scanning ) {
// Connected successfully, let's scan
m_client - > scan ( m_curTransfer - > getSourceUrl ( ) ) ;
}
break ;
}
case Event : : EventError : {
ErrorCode error = event - > getParameter ( 0 ) . asErrorCode ( ) ;
if ( m_scanning & & ( error = = ConnectFailed | | error = = LoginFailed | | error = = OperationFailed ) ) {
// Scanning should be aborted, since there was an error
m_scanning = false ;
m_curTransfer - > unlock ( ) ;
remove ( ) ;
emit static_cast < Session * > ( parent ( ) ) - > dirScanDone ( ) ;
}
break ;
}
case Event : : EventScanComplete : {
if ( m_scanning ) {
// We have the listing
DirectoryTree * tree = static_cast < DirectoryTree * > ( event - > getParameter ( 0 ) . asData ( ) ) ;
addScannedDirectory ( tree , m_curTransfer ) ;
delete tree ;
m_scanning = false ;
m_curTransfer - > unlock ( ) ;
remove ( ) ;
emit static_cast < Session * > ( parent ( ) ) - > dirScanDone ( ) ;
}
break ;
}
default : break ;
}
}
void Connection : : slotTransferCompleted ( )
{
// Remove the lock
remove ( ) ;
}
void Connection : : reconnect ( )
{
if ( ! m_client - > socket ( ) - > isConnected ( ) ) {
KFTPBookmarks : : Manager : : self ( ) - > setupClient ( static_cast < Session * > ( parent ( ) ) - > getSite ( ) , m_client ) ;
m_client - > connect ( m_client - > socket ( ) - > getCurrentUrl ( ) ) ;
}
}
////////////////////////////////////////////////////////
//////////////////// Session ////////////////////
////////////////////////////////////////////////////////
Session : : Session ( Side side )
: TQObject ( ) ,
m_side ( side ) ,
m_remote ( false ) ,
m_aborting ( false ) ,
m_registred ( false ) ,
m_site ( 0 )
{
// Register this session
Manager : : self ( ) - > registerSession ( this ) ;
}
Session : : ~ Session ( )
{
}
KFTPEngine : : Thread * Session : : getClient ( )
{
// Return the first (core) connection's client
return m_connections . at ( 0 ) - > getClient ( ) ;
}
bool Session : : isConnected ( )
{
// If there are no connections, just check if the session is remote
if ( m_connections . count ( ) = = 0 )
return ! m_remote ;
return m_connections . at ( 0 ) - > isConnected ( ) ;
}
void Session : : slotClientEngineEvent ( KFTPEngine : : Event * event )
{
switch ( event - > type ( ) ) {
case Event : : EventConnect : {
// ***************************************************************************
// ****************************** EventConnect *******************************
// ***************************************************************************
m_remote = true ;
m_aborting = false ;
m_lastUrl = getClient ( ) - > socket ( ) - > getCurrentUrl ( ) ;
TQString siteName ;
if ( m_site )
siteName = m_site - > getAttribute ( " name " ) ;
else
siteName = m_lastUrl . host ( ) ;
Manager : : self ( ) - > getTabs ( m_side ) - > changeTab ( m_fileView , siteName ) ;
Manager : : self ( ) - > getStatTabs ( ) - > changeTab ( m_log , i18n ( " Log (%1) " ) . arg ( siteName ) ) ;
Manager : : self ( ) - > getStatTabs ( ) - > showPage ( m_log ) ;
Manager : : self ( ) - > doEmitUpdate ( ) ;
KURL homeUrl = getClient ( ) - > socket ( ) - > getCurrentUrl ( ) ;
if ( m_site & & ! m_site - > getProperty ( " defremotepath " ) . isEmpty ( ) )
homeUrl . setPath ( m_site - > getProperty ( " defremotepath " ) ) ;
else
homeUrl . setPath ( getClient ( ) - > socket ( ) - > getDefaultDirectory ( ) ) ;
m_fileView - > setHomeUrl ( homeUrl ) ;
m_fileView - > goHome ( ) ;
Session * opposite = Manager : : self ( ) - > getActive ( oppositeSide ( m_side ) ) ;
if ( m_site & & ! opposite - > isRemote ( ) ) {
TQString localPath = m_site - > getProperty ( " deflocalpath " ) ;
if ( ! localPath . isEmpty ( ) )
opposite - > getFileView ( ) - > openUrl ( KURL ( localPath ) ) ;
}
break ;
}
case Event : : EventDisconnect : {
// ***************************************************************************
// **************************** EventDisconnect ******************************
// ***************************************************************************
m_remote = false ;
m_aborting = false ;
Manager : : self ( ) - > getTabs ( m_side ) - > changeTab ( m_fileView , i18n ( " Local Session " ) ) ;
Manager : : self ( ) - > getStatTabs ( ) - > changeTab ( m_log , " [ " + i18n ( " Log " ) + " ] " ) ;
Manager : : self ( ) - > doEmitUpdate ( ) ;
m_fileView - > setHomeUrl ( KURL ( KFTPCore : : Config : : defLocalDir ( ) ) ) ;
m_fileView - > goHome ( ) ;
break ;
}
case Event : : EventCommand : m_log - > ftpLog ( 1 , event - > getParameter ( 0 ) . asString ( ) ) ; break ;
case Event : : EventMultiline : m_log - > ftpLog ( 2 , event - > getParameter ( 0 ) . asString ( ) ) ; break ;
case Event : : EventResponse : m_log - > ftpLog ( 0 , event - > getParameter ( 0 ) . asString ( ) ) ; break ;
case Event : : EventMessage : m_log - > ftpLog ( 3 , event - > getParameter ( 0 ) . asString ( ) ) ; break ;
case Event : : EventRetrySuccess : {
// ***************************************************************************
// ************************** EventRetrySuccess ******************************
// ***************************************************************************
if ( KFTPCore : : Config : : showRetrySuccessBalloon ( ) ) {
KFTPWidgets : : SystemTray : : self ( ) - > showBalloon ( i18n ( " Connection with %1 has been successfully established. " ) . arg ( getClient ( ) - > socket ( ) - > getCurrentUrl ( ) . host ( ) ) ) ;
}
break ;
}
case Event : : EventReloadNeeded : {
// We should only do refreshes if the queue is not being processed
if ( KFTPQueue : : Manager : : self ( ) - > getNumRunning ( ) = = 0 )
m_fileView - > reload ( ) ;
break ;
}
case Event : : EventPubkeyPassword : {
// A public-key authentication password was requested
TQString pass ;
int ret = KPasswordDialog : : getPassword ( pass , i18n ( " Please provide your private key decryption password. " ) ) ;
if ( ret = = KPasswordDialog : : Accepted ) {
PubkeyWakeupEvent * event = new PubkeyWakeupEvent ( ) ;
event - > password = pass ;
getClient ( ) - > wakeup ( event ) ;
} else {
getClient ( ) - > abort ( ) ;
}
break ;
}
default : break ;
}
}
void Session : : scanDirectory ( KFTPQueue : : Transfer * parent , Connection * connection )
{
// Go trough all files in path and add them as transfers that have parent as their parent
// transfer
KURL path = parent - > getSourceUrl ( ) ;
if ( path . isLocalFile ( ) ) {
connect ( new DirectoryScanner ( parent ) , TQ_SIGNAL ( completed ( ) ) , this , TQ_SIGNAL ( dirScanDone ( ) ) ) ;
} else if ( m_remote ) {
if ( ! connection ) {
if ( ! isFreeConnection ( ) ) {
emit dirScanDone ( ) ;
return ;
}
// Assign a new connection (it might be unconnected!)
connection = assignConnection ( ) ;
}
connection - > scanDirectory ( parent ) ;
}
}
void Session : : abort ( )
{
if ( m_aborting )
return ;
m_aborting = true ;
emit aborting ( ) ;
// Abort all connections
Connection * conn ;
for ( conn = m_connections . first ( ) ; conn ; conn = m_connections . next ( ) ) {
conn - > abort ( ) ;
}
m_aborting = false ;
}
void Session : : reconnect ( const KURL & url )
{
// Set the reconnect url
m_reconnectUrl = url ;
if ( m_remote & & getClient ( ) - > socket ( ) - > isConnected ( ) ) {
abort ( ) ;
connect ( getClient ( ) - > eventHandler ( ) , TQ_SIGNAL ( disconnected ( ) ) , this , TQ_SLOT ( slotStartReconnect ( ) ) ) ;
getClient ( ) - > disconnect ( ) ;
} else {
// The session is already disconnected, just call the slot
slotStartReconnect ( ) ;
}
}
void Session : : slotStartReconnect ( )
{
disconnect ( getClient ( ) - > eventHandler ( ) , TQ_SIGNAL ( disconnected ( ) ) , this , TQ_SLOT ( slotStartReconnect ( ) ) ) ;
// Reconnect only if this is a remote url
if ( ! m_reconnectUrl . isLocalFile ( ) ) {
KFTPBookmarks : : Manager : : self ( ) - > setupClient ( m_site , getClient ( ) ) ;
getClient ( ) - > connect ( m_reconnectUrl ) ;
}
// Invalidate the url
m_reconnectUrl = KURL ( ) ;
}
int Session : : getMaxThreadCount ( )
{
// First get the global thread count
int count = KFTPCore : : Config : : threadCount ( ) ;
if ( ! KFTPCore : : Config : : threadUsePrimary ( ) )
count + + ;
// Try to see if threads are disabled for this site
if ( count > 1 & & isRemote ( ) ) {
if ( m_site & & m_site - > getIntProperty ( " disableThreads " ) )
return 1 ;
}
return count ;
}
bool Session : : isFreeConnection ( )
{
unsigned int max = getMaxThreadCount ( ) ;
unsigned int free = 0 ;
if ( ( m_connections . count ( ) < max & & max > 1 ) | | ! isRemote ( ) )
return true ;
Connection * conn ;
for ( conn = m_connections . first ( ) ; conn ; conn = m_connections . next ( ) ) {
if ( ! conn - > isBusy ( ) & & ( ! conn - > isPrimary ( ) | | KFTPCore : : Config : : threadUsePrimary ( ) | | max = = 1 ) )
free + + ;
}
return free > 0 ;
}
Connection * Session : : assignConnection ( )
{
unsigned int max = getMaxThreadCount ( ) ;
if ( m_connections . count ( ) = = 0 ) {
// We need a new core connection
Connection * conn = new Connection ( this , true ) ;
m_connections . append ( conn ) ;
Manager : : self ( ) - > doEmitUpdate ( ) ;
return conn ;
} else {
// Find a free connection
Connection * conn ;
for ( conn = m_connections . first ( ) ; conn ; conn = m_connections . next ( ) ) {
if ( ! conn - > isBusy ( ) & & ( ! conn - > isPrimary ( ) | | KFTPCore : : Config : : threadUsePrimary ( ) | | max = = 1 ) )
return conn ;
}
// No free connection has been found, but we may be able to create
// another (if we are within limits)
if ( m_connections . count ( ) < max ) {
conn = new Connection ( this ) ;
m_connections . append ( conn ) ;
Manager : : self ( ) - > doEmitUpdate ( ) ;
return conn ;
}
}
return 0 ;
}
void Session : : disconnectAllConnections ( )
{
// Abort any possible transfers first
abort ( ) ;
// Now disconnect all connections
Connection * conn ;
for ( conn = m_connections . first ( ) ; conn ; conn = m_connections . next ( ) ) {
if ( conn - > getClient ( ) - > socket ( ) - > isConnected ( ) ) {
conn - > getClient ( ) - > disconnect ( ) ;
}
}
}
////////////////////////////////////////////////////////
/////////////////////// Manager ////////////////////////
////////////////////////////////////////////////////////
Manager * Manager : : m_self = 0 ;
Manager * Manager : : self ( )
{
return m_self ;
}
Manager : : Manager ( TQObject * parent , TQTabWidget * stat , KFTPTabWidget * left , KFTPTabWidget * right )
: TQObject ( parent ) ,
m_statTabs ( stat ) ,
m_leftTabs ( left ) ,
m_rightTabs ( right ) ,
m_active ( 0 ) ,
m_leftActive ( 0 ) ,
m_rightActive ( 0 )
{
Manager : : m_self = this ;
// Connect some signals
connect ( left , TQ_SIGNAL ( currentChanged ( TQWidget * ) ) , this , TQ_SLOT ( slotActiveChanged ( TQWidget * ) ) ) ;
connect ( right , TQ_SIGNAL ( currentChanged ( TQWidget * ) ) , this , TQ_SLOT ( slotActiveChanged ( TQWidget * ) ) ) ;
connect ( left , TQ_SIGNAL ( closeRequest ( TQWidget * ) ) , this , TQ_SLOT ( slotSessionCloseRequest ( TQWidget * ) ) ) ;
connect ( right , TQ_SIGNAL ( closeRequest ( TQWidget * ) ) , this , TQ_SLOT ( slotSessionCloseRequest ( TQWidget * ) ) ) ;
}
void Manager : : registerSession ( Session * session )
{
m_active = session ;
// Create some new stuff and assign it to the session
session - > assignConnection ( ) ;
session - > m_fileView = new KFTPWidgets : : Browser : : View ( 0L , " " , session - > getClient ( ) , session ) ;
session - > m_log = new KFTPWidgets : : LogView ( ) ;
// Install event filters
session - > getFileView ( ) - > getDetailsView ( ) - > installEventFilter ( this ) ;
session - > getFileView ( ) - > getTreeView ( ) - > installEventFilter ( this ) ;
session - > getFileView ( ) - > m_toolBarFirst - > installEventFilter ( this ) ;
session - > getFileView ( ) - > m_toolBarSecond - > installEventFilter ( this ) ;
connect ( session - > getFileView ( ) - > getDetailsView ( ) , TQ_SIGNAL ( clicked ( TQListViewItem * ) ) , this , TQ_SLOT ( slotSwitchFocus ( ) ) ) ;
connect ( session - > getFileView ( ) - > getTreeView ( ) , TQ_SIGNAL ( clicked ( TQListViewItem * ) ) , this , TQ_SLOT ( slotSwitchFocus ( ) ) ) ;
connect ( session - > getFileView ( ) - > m_toolBarFirst , TQ_SIGNAL ( clicked ( int ) ) , this , TQ_SLOT ( slotSwitchFocus ( ) ) ) ;
connect ( session - > getFileView ( ) - > m_toolBarSecond , TQ_SIGNAL ( clicked ( int ) ) , this , TQ_SLOT ( slotSwitchFocus ( ) ) ) ;
// Connect some signals
connect ( session - > getClient ( ) - > eventHandler ( ) , TQ_SIGNAL ( engineEvent ( KFTPEngine : : Event * ) ) , session , TQ_SLOT ( slotClientEngineEvent ( KFTPEngine : : Event * ) ) ) ;
// Assign GUI positions
m_statTabs - > addTab ( session - > m_log , " [ " + i18n ( " Log " ) + " ] " ) ;
getTabs ( session - > m_side ) - > addTab ( session - > m_fileView , KFTPGrabberBase : : loadSmallIcon ( " computer " ) , i18n ( " Session " ) ) ;
// Actually add the session
m_sessionList . append ( session ) ;
session - > m_registred = true ;
}
KFTPWidgets : : Browser : : View * Manager : : getActiveView ( )
{
if ( m_active )
return m_active - > getFileView ( ) ;
return 0 ;
}
Session * Manager : : getActiveSession ( )
{
return m_active ;
}
bool Manager : : eventFilter ( TQObject * object , TQEvent * event )
{
if ( event - > type ( ) = = TQEvent : : FocusIn | | event - > type ( ) = = TQEvent : : MouseButtonPress ) {
switchFocusToObject ( object ) ;
}
return false ;
}
void Manager : : slotSwitchFocus ( )
{
switchFocusToObject ( TQObject : : sender ( ) ) ;
}
void Manager : : switchFocusToObject ( const TQObject * object )
{
if ( ! object )
return ;
for ( ; ; ) {
if ( object - > isA ( " KFTPWidgets::Browser::View " ) )
break ;
if ( ! ( object = object - > parent ( ) ) )
break ;
}
if ( object ) {
// We have the proper object
Session * session = find ( static_cast < const KFTPWidgets : : Browser : : View * > ( object ) ) ;
if ( session & & session ! = m_active ) {
m_active = session ;
// Open the current session's log tab
if ( session - > isRemote ( ) )
m_statTabs - > showPage ( session - > getLog ( ) ) ;
}
}
}
void Manager : : unregisterSession ( Session * session )
{
// Destroy all objects related to the session and remove it
getTabs ( session - > m_side ) - > removePage ( session - > m_fileView ) ;
m_statTabs - > removePage ( session - > m_log ) ;
if ( session - > getClient ( ) - > socket ( ) - > isConnected ( ) ) {
session - > abort ( ) ;
session - > getClient ( ) - > disconnect ( ) ;
}
// Delete objects
session - > m_fileView - > deleteLater ( ) ;
session - > m_log - > deleteLater ( ) ;
// Actually remove the session
m_sessionList . remove ( session ) ;
delete session ;
// Emit update
emit update ( ) ;
}
void Manager : : doEmitUpdate ( )
{
emit update ( ) ;
}
void Manager : : disconnectAllSessions ( )
{
Session * i ;
for ( i = m_sessionList . first ( ) ; i ; i = m_sessionList . next ( ) )
i - > disconnectAllConnections ( ) ;
}
Session * Manager : : find ( KFTPEngine : : Thread * client )
{
Session * i ;
for ( i = m_sessionList . first ( ) ; i ; i = m_sessionList . next ( ) ) {
if ( i - > getClient ( ) = = client )
return i ;
}
return 0L ;
}
Session * Manager : : find ( KFTPWidgets : : Browser : : View * fileView )
{
Session * i ;
for ( i = m_sessionList . first ( ) ; i ; i = m_sessionList . next ( ) ) {
if ( i - > m_fileView = = fileView )
return i ;
}
return 0L ;
}
Session * Manager : : find ( KFTPWidgets : : LogView * log )
{
Session * i ;
for ( i = m_sessionList . first ( ) ; i ; i = m_sessionList . next ( ) ) {
if ( i - > m_log = = log )
return i ;
}
return 0L ;
}
Session * Manager : : find ( const KURL & url , bool mustUnlock )
{
if ( url . isLocalFile ( ) )
return find ( true ) ;
Session * i ;
for ( i = m_sessionList . first ( ) ; i ; i = m_sessionList . next ( ) ) {
KURL tmp = i - > getClient ( ) - > socket ( ) - > getCurrentUrl ( ) ;
tmp . setPath ( url . path ( ) ) ;
if ( tmp = = url & & i - > isRemote ( ) & & i - > isConnected ( ) & & ( ! mustUnlock | | i - > isFreeConnection ( ) ) )
return i ;
}
return 0L ;
}
Session * Manager : : find ( bool local )
{
Session * i ;
for ( i = m_sessionList . first ( ) ; i ; i = m_sessionList . next ( ) ) {
if ( i - > m_remote ! = local )
return i ;
}
return 0L ;
}
Session * Manager : : findLast ( const KURL & url , Side side )
{
if ( url . isLocalFile ( ) )
return find ( true ) ;
Session * i ;
for ( i = m_sessionList . first ( ) ; i ; i = m_sessionList . next ( ) ) {
KURL tmp = i - > m_lastUrl ;
tmp . setPath ( url . path ( ) ) ;
if ( tmp = = url & & ! i - > isRemote ( ) & & ( i - > getSide ( ) | | side = = IgnoreSide ) )
return i ;
}
return 0L ;
}
Session * Manager : : spawnLocalSession ( Side side , bool forceNew )
{
// Creates a new local session
Session * session = 0L ;
if ( forceNew | | ( session = find ( true ) ) = = 0L | | ( session - > m_side ! = side & & side ! = IgnoreSide ) ) {
side = side = = IgnoreSide ? LeftSide : side ;
session = new Session ( side ) ;
session - > m_remote = false ;
getTabs ( side ) - > changeTab ( session - > m_fileView , i18n ( " Local Session " ) ) ;
getStatTabs ( ) - > changeTab ( session - > m_log , " [ " + i18n ( " Log " ) + " ] " ) ;
}
setActive ( session ) ;
return session ;
}
Session * Manager : : spawnRemoteSession ( Side side , const KURL & remoteUrl , KFTPBookmarks : : Site * site , bool mustUnlock )
{
// Creates a new remote session and connects it to the correct server
Session * session ;
if ( remoteUrl . isLocalFile ( ) )
return spawnLocalSession ( side ) ;
if ( ( session = find ( remoteUrl , mustUnlock ) ) = = 0L | | ( session - > m_side ! = side & & side ! = IgnoreSide ) ) {
// Try to find the session that was last connected to this URL
if ( ( session = findLast ( remoteUrl , side ) ) = = 0L ) {
// Attempt to reuse a local session if one exists one the right side
session = getActive ( RightSide ) ;
if ( session - > isRemote ( ) ) {
side = side = = IgnoreSide ? RightSide : side ;
session = new Session ( side ) ;
}
}
// Try to find the site by url if it is not set
if ( ! site )
site = KFTPBookmarks : : Manager : : self ( ) - > findSite ( remoteUrl ) ;
// Set properties
session - > m_remote = true ;
session - > m_site = site ;
m_active = session ;
KFTPBookmarks : : Manager : : self ( ) - > setupClient ( site , session - > getClient ( ) ) ;
session - > getClient ( ) - > connect ( remoteUrl ) ;
}
return session ;
}
void Manager : : setActive ( Session * session )
{
// Make a session active on its own side ;)
Session * oldActive = getActive ( session - > m_side ) ;
oldActive ? oldActive - > m_active = false : 0 ;
session - > m_active = true ;
switch ( session - > m_side ) {
case LeftSide : m_leftActive = session ; break ;
case RightSide : m_rightActive = session ; break ;
case IgnoreSide : tqDebug ( " Invalid side specified! " ) ; return ;
}
// Refresh the GUI
getTabs ( session - > m_side ) - > showPage ( session - > m_fileView ) ;
}
Session * Manager : : getActive ( Side side )
{
switch ( side ) {
case LeftSide : return m_leftActive ;
case RightSide : return m_rightActive ;
case IgnoreSide : tqDebug ( " Invalid side specified! " ) ; break ;
}
return NULL ;
}
KFTPTabWidget * Manager : : getTabs ( Side side )
{
switch ( side ) {
case LeftSide : return m_leftTabs ;
case RightSide : return m_rightTabs ;
case IgnoreSide : tqDebug ( " Invalid side specified! " ) ; break ;
}
return NULL ;
}
void Manager : : slotActiveChanged ( TQWidget * page )
{
Session * session = find ( static_cast < KFTPWidgets : : Browser : : View * > ( page ) ) ;
setActive ( session ) ;
}
void Manager : : slotSessionCloseRequest ( TQWidget * page )
{
Session * session = find ( static_cast < KFTPWidgets : : Browser : : View * > ( page ) ) ;
if ( getTabs ( session - > m_side ) - > count ( ) = = 1 ) {
KMessageBox : : error ( 0L , i18n ( " At least one session must remain open on each side. " ) ) ;
return ;
}
if ( ( session - > m_remote & & session - > getClient ( ) - > socket ( ) - > isBusy ( ) ) | | ! session - > isFreeConnection ( ) ) {
KMessageBox : : error ( 0L , i18n ( " Please finish all transfers before closing the session. " ) ) ;
return ;
} else {
// Remove the session
if ( session - > getClient ( ) - > socket ( ) - > isConnected ( ) ) {
if ( KMessageBox : : questionYesNo ( 0L , i18n ( " This session is currently connected. Are you sure you wish to disconnect? " ) , i18n ( " Close Session " ) ) = = KMessageBox : : No )
return ;
}
unregisterSession ( session ) ;
}
}
}
# include "kftpsession.moc"