You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
kftpgrabber/kftpgrabber/src/kftpsession.h

617 lines
17 KiB

/*
* 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.
*/
#ifndef KFTPSESSION_H
#define KFTPSESSION_H
#include <ntqobject.h>
#include <ntqguardedptr.h>
#include <ntqdom.h>
#include <ntqlistview.h>
#include "kftpqueue.h"
#include "logview.h"
#include "kftptabwidget.h"
#include "engine/thread.h"
namespace KFTPWidgets {
namespace Browser {
class Actions;
class View;
}
}
namespace KFTPBookmarks {
class Site;
}
namespace KFTPSession {
class Session;
enum Side {
LeftSide,
RightSide,
IgnoreSide
};
#define oppositeSide(x) (x == KFTPSession::LeftSide ? KFTPSession::RightSide : KFTPSession::LeftSide)
/**
* The Connection class represents a session's connection to a ftp server. There
* can be many connections in the same session (to the same server), thus providing
* support for multiple threads at once.
*
* Individual transfers must acquire connections before they can use them. When a
* connection is acquired it cannot be used by another transfer or another remote
* operation.
*
* @author Jernej Kos
*/
class Connection : public TQObject
{
Q_OBJECT
public:
/**
* Class constructor.
*
* @param session The parent session
* @param primary Set to true if this is session's primary connection
*/
Connection(Session *session, bool primary = false);
/**
* Class destructor.
*/
~Connection();
/**
* Returns the client thread for this connection.
*
* @return A KFTPClientThr object representing a client.
*/
KFTPEngine::Thread *getClient() const { return m_client; }
/**
* Returns the URL this connection is connected to.
*
* @return A KURL this connection is connected to.
*/
KURL getUrl() { return m_client->socket()->getCurrentUrl(); }
/**
* Returns the current transfer if this connection is locked by one. If
* it isn't locked NULL will be returned.
*/
KFTPQueue::Transfer *getTransfer() const { return m_curTransfer; }
/**
* Lock this connection for a specific transfer. While the connection is
* locked no other transfer may use it. The connection will be automaticly
* unlocked when the transfer completes.
*
* @param transfer The transfer which is locking this connection.
*/
void acquire(KFTPQueue::Transfer *transfer);
/**
* Clear existing connection lock. Only the transfer who locked the connection
* should do this!
*/
void remove();
/**
* Abort any actions going via this connection. It will call abort on the
* underlying client and emit the aborting signal.
*/
void abort();
/**
* Connect to the previously connected URL. If this connection is already
* established this method does nothing.
*/
void reconnect();
/**
* Is the current connection locked by some transfer ?
*
* @return Returns true if the current connection is locked, false otherwise.
*/
bool isBusy() const { return m_busy; }
/**
* Is the current connection actually connected to a server ?
*
* @return Returns true if a connection to a server is established.
*/
bool isConnected();
/**
* Is the current connection the primary session connection ?
*
* @return Returns true if the current connection is primary, false otherwise
*/
bool isPrimary() const { return m_primary; }
/**
* Scans a directory - usually called from KFTPSession for remote scans.
*
* @param parent The transfer that requested the scan
*/
void scanDirectory(KFTPQueue::Transfer *parent);
private:
void addScannedDirectory(KFTPEngine::DirectoryTree *tree, KFTPQueue::Transfer *parent);
private:
bool m_primary;
bool m_busy;
bool m_aborting;
bool m_scanning;
TQGuardedPtr<KFTPQueue::Transfer> m_curTransfer;
KFTPEngine::Thread *m_client;
private slots:
void slotTransferCompleted();
void slotEngineEvent(KFTPEngine::Event *event);
signals:
/**
* This signal gets emitted when the connection is acquired for exclusive
* use by a transfer.
*/
void connectionAcquired();
/**
* This signal gets emitted when connection is returned to the pool and is
* no longer locked.
*/
void connectionRemoved();
/**
* This signal gets emitted when the connection is lost.
*
* @param connection This connection instance
*/
void connectionLost(KFTPSession::Connection *connection);
/**
* This signal gets emitted when connection with the remote server is
* established.
*/
void connectionEstablished();
/**
* This signal gets emitted when this connection is in the process of
* aborting any currently running operations.
*/
void aborting();
};
/**
* A Session instance connects all the relevant elements together. Via the
* manager this abstraction allows many independent sessions inside one
* applications.
*
* Each session can either be local or remote. A remote session can have
* multiple connections open (each connection is represented by a Connection
* instance).
*
* @author Jernej Kos
*/
class Session : public TQObject
{
Q_OBJECT
friend class KFTPWidgets::Browser::Actions;
friend class Manager;
friend class Connection;
public:
/**
* Class constructor.
*
* @param side The side the session should be located on
*/
Session(Side side);
/**
* Class destructor.
*/
~Session();
/**
* Has the session registration procedure already been completed ?
*
* @return True if the registration procedure has been completed, false otherwise
*/
bool isRegistred() const { return m_registred; }
/**
* Is this a remote session ?
*
* @return Returns true if this is a remote session.
*/
bool isRemote() const { return m_remote; }
/**
* Is this session currently active (=visible to the user) ?
*
* @return Returns true if this session is currently active.
*/
bool isActive() const { return m_active; }
/**
* Is this session currently connected to a server ? This actually checks if
* the primary connection is connected to a server.
*
* @return Returns true if this session is connected to a server.
*/
bool isConnected();
/**
* Get the site in bookmarks this session is asociated with or NULL if there
* is no such site.
*
* @return Returns the asociated bookmarks site.
*/
KFTPBookmarks::Site *getSite() const { return m_site; }
/**
* Get the session's client thread. This actually returns the client thread
* of the primary session's connection.
*
* @return A KFTPEngine::Thread object representing a client.
*/
KFTPEngine::Thread *getClient();
/**
* Get this session's log widget.
*
* @return Returns the session's log widget.
*/
KFTPWidgets::LogView *getLog() const { return m_log; }
/**
* Get this session's file view.
*
* @return Returns the session's file view.
*/
KFTPWidgets::Browser::View *getFileView() const { return m_fileView; }
/**
* Get the side on which this session is located.
*
* @return Returns the session's side.
*/
Side getSide() const { return m_side; }
/**
* Set bookmark site asociation.
*
* @param site A valid site to which this session is asociated.
*/
void setSite(KFTPBookmarks::Site *site) { m_site = site; }
/**
* Are there any free connections (or if some new can be created) to lock ?
*
* @return Returns true if there is a connection that can be locked.
*/
bool isFreeConnection();
/**
* Assigns a free connection if there is one. A connection can be created if
* the limit hasn't yet been reached. If there are no free connections this
* method returns NULL.
*
* @return A free Connection or NULL if there is none.
*/
Connection *assignConnection();
/**
* Disconnects all connections for this session.
*/
void disconnectAllConnections();
/**
* Get the list of current connections for this session.
*
* @return A list of current connections.
*/
TQPtrList<Connection> *getConnectionList() { return &m_connections; }
/**
* Reconnect to a new URL. The current connections will be droped and reconnected
* to the new URL.
*
* @param url The URL to connect to.
*/
void reconnect(const KURL &url);
/**
* Abort this session. This will actually call abort on all connections for
* this session.
*/
void abort();
/**
* Initiate a directory scan, adding all new files and directories under the
* transfer specified as parent. This method will change the current transfer's
* status to Locked and will return imediately. The actual scan will take
* place in a separate thread.
*
* @param parent The transfer which requested the scan
* @param connection An optional connection to use
*/
void scanDirectory(KFTPQueue::Transfer *parent, Connection *connection = 0);
private:
Side m_side;
bool m_remote;
bool m_active;
bool m_aborting;
bool m_registred;
// Session description
KFTPBookmarks::Site *m_site;
KFTPWidgets::LogView *m_log;
KFTPWidgets::Browser::View *m_fileView;
KURL m_lastUrl;
KURL m_reconnectUrl;
// Connection list
TQPtrList<Connection> m_connections;
int getMaxThreadCount();
private slots:
void slotClientEngineEvent(KFTPEngine::Event *event);
void slotStartReconnect();
signals:
void dirScanDone();
void aborting();
void freeConnectionAvailable();
};
typedef TQPtrList<Session> SessionList;
/**
* The Manager class provides access to sessions, their registration and deletion.
*
* @author Jernej Kos
*/
class Manager : public TQObject
{
Q_OBJECT
public:
/**
* Get a global manager instance.
*/
static Manager *self();
/**
* Class constructor.
*
* @param parent Parent object
* @param stat A widget that contains log tabs
* @param left A widget that contains sessions on the left side
* @param right A widget that contains sessions on the right side
*/
Manager(TQObject *parent, TQTabWidget *stat, KFTPTabWidget *left, KFTPTabWidget *right);
/**
* Spawn a new local (=unconnected) session. This method may reuse an old local session.
*
* @param side The side on which the session should be created.
* @param forceNew Should a new session be created if a similar session already exists.
* @return Allways returns a valid session.
*/
Session *spawnLocalSession(Side side, bool forceNew = false);
/**
* Spawn a new remote session. This method may reuse an old remote session. It may also
* spawn a new local session if the URL appears local.
*
* @param side The side on which the session should be created.
* @param remoteUrl URL to which the session should connect upon creation.
* @param site The bookmarked site the session is connecting to.
* @param mustUnlock Must the returned session be unlocked ?
* @return Allways returns a valid session.
*/
Session *spawnRemoteSession(Side side, const KURL &remoteUrl, KFTPBookmarks::Site *site = 0, bool mustUnlock = false);
/**
* Register a new session with the session manager. Every session calls this method in
* its constructor to init the session - this method shouldn't be called otherwise.
*
* @param session A new session.
*/
void registerSession(Session *session);
/**
* Destroy the session. All connections and transfers related to this session are
* aborted and disconnected first.
*
* @param session The session that is going to be destroyed.
*/
void unregisterSession(Session *session);
/**
* Disconnects all sessions and their connections.
*/
void disconnectAllSessions();
/**
* Find a session related to a client thread.
*
* @param client The client thread related to a session.
* @return Returns a valid session if one is found, NULL otherwise.
*/
Session *find(KFTPEngine::Thread *client);
/**
* Find a session related to a file view widget.
*
* @param fileView The file view widget related to a session.
* @return Returns a valid session if one is found, NULL otherwise.
*/
Session *find(KFTPWidgets::Browser::View *fileView);
/**
* Find a session related to a log widget.
*
* @param log The log widget related to a session.
* @return Returns a valid session if one is found, NULL otherwise.
*/
Session *find(KFTPWidgets::LogView *log);
/**
* Find a session by the url it is connected to.
*
* @param url The URL a session is connected to.
* @param mustUnlock Must the session be unlocked ?
* @return Returns a valid session if one is found, NULL otherwise.
*/
Session *find(const KURL &url, bool mustUnlock = false);
/**
* Finds a session by its state (remote/local).
*
* @param local Must a session be local ?
* @return Returns a valid session if one is found, NULL otherwise.
*/
Session *find(bool local);
/**
* Finds a session that was last connected to a specific URL that is placed
* on a specific side.
*
* @param url The URL to which the session was connected to.
* @param side The side where the session must be.
* @return Returns a valid session if one is found, NULL otherwise.
*/
Session *findLast(const KURL &url, Side side);
/**
* Get the list of all sessions in existance.
*
* @return The session list.
*/
SessionList *getSessionList() { return &m_sessionList; }
/**
* Emits the update signal.
*/
void doEmitUpdate();
/**
* Returns the tab widget that holds the log widgets.
*
* @return Returns a TQTabWidget that holds the log widgets.
*/
TQTabWidget *getStatTabs() const { return m_statTabs; }
/**
* Returns the tab widget that holds the sessions on a specific side.
*
* @param side The side of the tab widget.
* @return Returns a KFTPTabWidget that holds the sessions.
*/
KFTPTabWidget *getTabs(Side side);
/**
* Make a session active (=visible to the user).
*
* @param session Session to be made active.
*/
void setActive(Session *session);
/**
* Get the active session on a specific side.
*
* @param side The side where the session is active.
* @return Returns a valid session.
*/
Session *getActive(Side side);
/**
* Get the currently active view.
*
* @return The active view instance
*/
KFTPWidgets::Browser::View *getActiveView();
/**
* Get the currently active session.
*/
Session *getActiveSession();
protected:
static Manager *m_self;
/**
* Event filter handler.
*/
bool eventFilter(TQObject *object, TQEvent *event);
/**
* Change the currently active session to the browser view inheriting
* the passed object.
*
* @param object The object that has browser view as some parent
*/
void switchFocusToObject(const TQObject *object);
private:
SessionList m_sessionList;
// These variables should be assigned right after construction
TQTabWidget *m_statTabs;
KFTPTabWidget *m_leftTabs;
KFTPTabWidget *m_rightTabs;
// Currently active sessions
Session *m_active;
Session *m_leftActive;
Session *m_rightActive;
private slots:
void slotActiveChanged(TQWidget *page);
void slotSwitchFocus();
public slots:
void slotSessionCloseRequest(TQWidget *page);
signals:
void update();
};
}
#endif