/* * This file is part of the KFTPGrabber project * * Copyright (C) 2003-2004 by the KFTPGrabber developers * Copyright (C) 2003-2004 Jernej Kos * * 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 KFTPQUEUE_H #define KFTPQUEUE_H #include #include #include #include #include #include #include #include #include #include "kftpqueueprocessor.h" #include "kftpqueueconverter.h" #include "kftpfileexistsactions.h" #include "misc.h" #include "engine/directorylisting.h" #include "engine/event.h" #include "directoryscanner.h" #include "kftptransfer.h" #include "kftptransferfile.h" #include "kftptransferdir.h" #include "site.h" using namespace KFTPGrabberBase; namespace KFTPSession { class Session; class Connection; } class KFTPQueueConverter; typedef TQPtrList KFTPQueueTransfers; namespace KFTPQueue { class FailedTransfer; /** * This class represents an opened remote file. The file is stored locally * while its being displayed to the user. * * @author Jernej Kos */ class OpenedFile { public: OpenedFile() {} /** * Creates a new OpenedFile object. * * @param transfer The transfer used to transfer the file */ OpenedFile(TransferFile *transfer); /** * Get file's source (remote). * * @return File's remote source URL */ KURL source() { return m_source; } /** * Get file's destination (local). * * @return File's local destination URL */ KURL destination() { return m_dest; } /** * Has the file changed since the transfer ? * * @return True if the file has been changed since being transfered */ bool hasChanged(); private: KURL m_source; KURL m_dest; TQString m_hash; }; /** * This class represents a request for "file already exists" dialog * display request. * * @author Jernej Kos */ class UserDialogRequest { public: /** * Class constructor. */ UserDialogRequest(TransferFile *transfer, filesize_t srcSize, time_t srcTime, filesize_t dstSize, time_t dstTime); /** * Sends a response to this request. * * @param event A valid file exists wakeup event */ void sendResponse(KFTPEngine::FileExistsWakeupEvent *event); /** * Returns the transfer that initiated the request. */ TransferFile *getTransfer() const { return m_transfer; } /** * Returns source file size. */ filesize_t sourceSize() const { return m_srcSize; } /** * Returns source file time. */ time_t sourceTime() const { return m_srcTime; } /** * Returns destination file size. */ filesize_t destinationSize() const { return m_dstSize; } /** * Returns destination file time. */ time_t destinationTime() const { return m_dstTime; } private: TransferFile *m_transfer; filesize_t m_srcSize; time_t m_srcTime; filesize_t m_dstSize; time_t m_dstTime; }; /** * This class is responsible for managing the complete queue hierarchy. All * queued items descend from QueueObject and are contained in a simple tree * model. Statistics and abort requests propagate from bottom to top and exec * requests go in the other direction. * * @author Jernej Kos */ class Manager : public TQObject { Q_OBJECT friend class KFTPSession::Session; friend class KFTPSession::Connection; friend class ::KFTPQueueConverter; friend class DirectoryScanner::ScannerThread; friend class KFTPQueue::FailedTransfer; public: /** * Returns the global manager instance. */ static Manager *self(); /** * Class destructor. */ ~Manager(); /** * Stop all queued transfers. */ void stopAllTransfers(); /** * Get the toplevel queue object. The direct children of this object are different * KFTPQueue::Site objects that represent separate sites. * * @return A QueueObject representing the toplevel object */ QueueObject *topLevelObject() const { return m_topLevel; } /** * Queues a new transfer by looking at the URL drag data. * * @param drag The drag data */ void insertTransfer(KURLDrag *drag); /** * Queues a new transfer. This method will create the site if one doesn't exist yet * for this transfer. The object will be reparented under the assigned site. * * @param transfer The transfer to be queued */ void insertTransfer(Transfer *transfer); /** * Remove a transfer from the queue. The faceDestruction method will be called on the * transfer object before removal. After calling this method, you shouldn't use the * object anymore! * * @param transfer The transfer to be removed from queue * @param abortSession If true any session that this transfer is using is aborted */ void removeTransfer(Transfer *transfer, bool abortSession = true); /** * This method removes all the transfers from the queue. */ void clearQueue(); /** * Check if the transfer is under the correct site and move it if not. * * @param transfer The transfer to check */ void revalidateTransfer(Transfer *transfer); /** * Finds a transfer by its id. * * @param id The transfer's id * @return The transfer object */ Transfer *findTransfer(long id); /** * Finds a site by its URL. * * @param url The site's URL * @param noCreate If set to true the site will not be created when not found * and NULL will be returned * @return The site object */ Site *findSite(KURL url, bool noCreate = false); /** * Remove a failed transfer from the list. * * @param transfer The failed transfer object to be removed */ void removeFailedTransfer(FailedTransfer *transfer); /** * Remove all failed transfers from the list. This method actually calls the * removeFailedTransfer for every failed transfer present. */ void clearFailedTransferList(); /** * Moves the specified transfer up in the queue. * * @param object The queue object to be moved */ void moveTransferUp(QueueObject *object); /** * Moves the specified transfer down in the queue. * * @param object The queue object to be moved */ void moveTransferDown(QueueObject *object); /** * Moves the specified transfer to the top of the queue (only within the * parent boundaries). * * @param object The queue object to be moved */ void moveTransferTop(QueueObject *object); /** * Moves the specified transfer to the bottom of the queue (only within the * parent boundaries). * * @param object The queue object to be moved */ void moveTransferBottom(QueueObject *object); /** * Can the transfer be moved up ? * * @param object The queue object to be moved * @return True if the transfer can be moved */ bool canBeMovedUp(QueueObject *object); /** * Can the transfer be moved down ? * * @param object The queue object to be moved * @return True if the transfer can be moved */ bool canBeMovedDown(QueueObject *object); /** * Returns the list of failed transfers. * * @return The TQPtrList of FailedTransfer objects */ TQPtrList *getFailedTransferList() { return &m_failedTransfers; } /** * Return the queue converter (exporter). * * @return the KFTPQueueConverter object */ KFTPQueueConverter *getConverter() const { return m_converter; } /** * Opens the file with the registred application for it's MIME type and waits * for the process to exit (then it will reupload the file if it has changed). * * @param transfer The transfer whose destination should be opened */ void openAfterTransfer(TransferFile *transfer); /** * Should the update() be emitted on changes ? * * @param value True if the value should be emitted, false otherwise */ void setEmitUpdate(bool value) { m_emitUpdate = value; } /** * Does a global queue update and removes all transfers that have the "delete me" * variable set. */ void doEmitUpdate(); /** * Get the current download speed. * * @return The current download speed */ filesize_t getDownloadSpeed() const { return m_curDownSpeed; } /** * Get the current upload speed. * * @return The current upload speed */ filesize_t getUploadSpeed() const { return m_curUpSpeed; } /** * Get the percentage of the queue's completion. * * @return The percentage of the queue's completion */ int getTransferPercentage(); /** * Get the number of currently running transfers. * * @param onlyDirs Should only directories be counted * @return The number of currently running transfers */ int getNumRunning(bool onlyDirs = false); /** * Get the number of currently running transfers under a specific * site. * * @param url The remote URL * @return The number of currently running transfers */ int getNumRunning(const KURL &remoteUrl); /** * Start the queue processing. */ void start(); /** * Abort the queue processing. */ void abort(); /** * Is the queue being processed ? * * @return True if the queue is being processed, false otherwise */ bool isProcessing() { return m_queueProc->isRunning(); } /** * Return the next available transfer id and reserve it. * * @return The next available transfer id */ long nextTransferId() { return m_lastTQID++; } /** * Set a default action to take when encountering an existing file situation. Note that * the action set here will override any preconfigured user actions unless set to the * value of FE_DISABLE_ACT. * * @param action The action to take */ void setDefaultFileExistsAction(FEAction action = FE_DISABLE_ACT) { m_defaultFeAction = action; } /** * Get the default action preset for situations where a file already exists. * * @return A valid FEAction */ FEAction getDefaultFileExistsAction() const { return m_defaultFeAction; } /** * Decides what to do with the existing file. It will return a valid wakeup event to * dispatch. It will first consider the pre-configured "on file exists" action matrix. * * @param transfer The transfer object * @param srcStat Source file information (if remote) * @param dstStat Destination file information (if remote) * @return A FileExistsWakeupEvent that will be sent to the engine */ KFTPEngine::FileExistsWakeupEvent *fileExistsAction(KFTPQueue::TransferFile *transfer, TQValueList stat); /** * Spawn a new transfer. * * @param sourceUrl Source URL * @param destinationUrl Destination URL * @param size Filesize * @param dir True if this transfer represents a directory * @param ignoreSkip Ignore skiplist for this transfer * @param insertToQueue Should the new transfer be queued * @param parent Optional parent object * @param noScan True if directory transfers shouldn't be scanned * @return A valid KFTPQueue::Transfer instance */ KFTPQueue::Transfer *spawnTransfer(KURL sourceUrl, KURL destinationUrl, filesize_t size, bool dir, bool ignoreSkip = false, bool insertToQueue = true, TQObject *parent = 0L, bool noScan = false); protected: /** * Global class instance. */ static Manager *m_self; /** * Class constructor. */ Manager(); /** * Appends a new user dialog request. * * @param request Request instance */ void appendUserDialogRequest(UserDialogRequest *request); /** * Processes the top user dialog request by opening the desired "file * already exists" dialog. */ void processUserDialogRequest(); private: QueueObject *m_topLevel; TQCache m_queueObjectCache; TQMap m_editProcessList; TQPtrList m_failedTransfers; KFTPQueueProcessor *m_queueProc; KFTPQueueConverter *m_converter; long m_lastTQID; bool m_emitUpdate; bool m_processingQueue; filesize_t m_curDownSpeed; filesize_t m_curUpSpeed; bool m_feDialogOpen; FEAction m_defaultFeAction; TQPtrList m_userDialogRequests; private slots: void slotQueueProcessingComplete(); void slotQueueProcessingAborted(); void slotEditProcessTerminated(TDEProcess *p); signals: void newSite(KFTPQueue::Site*); void newTransfer(KFTPQueue::Transfer*); void transferRemoved(long); void siteRemoved(long); void queueUpdate(); void failedTransferNew(KFTPQueue::FailedTransfer*); void failedTransferRemoved(long); }; } #endif