diff options
Diffstat (limited to 'kftpgrabber/src/widgets/queueview')
-rw-r--r-- | kftpgrabber/src/widgets/queueview/Makefile.am | 13 | ||||
-rw-r--r-- | kftpgrabber/src/widgets/queueview/queueeditor.cpp | 323 | ||||
-rw-r--r-- | kftpgrabber/src/widgets/queueview/queueeditor.h | 82 | ||||
-rw-r--r-- | kftpgrabber/src/widgets/queueview/queueview.cpp | 888 | ||||
-rw-r--r-- | kftpgrabber/src/widgets/queueview/queueview.h | 296 | ||||
-rw-r--r-- | kftpgrabber/src/widgets/queueview/threadview.cpp | 202 | ||||
-rw-r--r-- | kftpgrabber/src/widgets/queueview/threadview.h | 93 |
7 files changed, 1897 insertions, 0 deletions
diff --git a/kftpgrabber/src/widgets/queueview/Makefile.am b/kftpgrabber/src/widgets/queueview/Makefile.am new file mode 100644 index 0000000..5ba11d9 --- /dev/null +++ b/kftpgrabber/src/widgets/queueview/Makefile.am @@ -0,0 +1,13 @@ +INCLUDES = -I$(srcdir)/../.. \ + -I$(srcdir)/../../engine \ + -I$(srcdir)/../../misc \ + -I$(srcdir)/../../ui -I../../ui\ + -I$(srcdir)/.. \ + -I$(srcdir)/../browser \ + $(all_includes) + +METASOURCES = AUTO +noinst_LIBRARIES = libqueueviewwidget.a +libqueueviewwidget_a_SOURCES = queueeditor.cpp queueview.cpp threadview.cpp + +noinst_HEADERS = queueeditor.h queueview.h threadview.h diff --git a/kftpgrabber/src/widgets/queueview/queueeditor.cpp b/kftpgrabber/src/widgets/queueview/queueeditor.cpp new file mode 100644 index 0000000..c565165 --- /dev/null +++ b/kftpgrabber/src/widgets/queueview/queueeditor.cpp @@ -0,0 +1,323 @@ +/* + * 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 "queueeditor.h" +#include "kftpserverlineedit.h" +#include "kftpbookmarks.h" +#include "kftpqueueeditorlayout.h" + +#include <klineedit.h> +#include <kpassdlg.h> +#include <kcombobox.h> +#include <klocale.h> + +#include <qspinbox.h> +#include <qlabel.h> +#include <qlayout.h> +#include <qtabwidget.h> + +#define REMOTE_PROTOCOL m_transfer->getSourceUrl().isLocalFile() ? m_transfer->getDestUrl().protocol() : m_transfer->getSourceUrl().protocol() + +namespace KFTPWidgets { + +QueueEditor::QueueEditor(QWidget *parent, const char *name) +: KDialogBase(parent, name, true, "Edit queue", KDialogBase::Ok | KDialogBase::Cancel, + KDialogBase::Ok, true) +{ + m_layout = new KFTPQueueEditorLayout(this); + setMainWidget(m_layout); + + connect(m_layout->srcPath, SIGNAL(textChanged(const QString&)), this, SLOT(slotTextChanged())); + connect(m_layout->dstPath, SIGNAL(textChanged(const QString&)), this, SLOT(slotTextChanged())); + + connect(m_layout->srcHost, SIGNAL(textChanged(const QString&)), this, SLOT(slotTextChanged())); + connect(m_layout->srcUser, SIGNAL(textChanged(const QString&)), this, SLOT(slotTextChanged())); + connect(m_layout->srcPass, SIGNAL(textChanged(const QString&)), this, SLOT(slotTextChanged())); + + connect(m_layout->dstHost, SIGNAL(textChanged(const QString&)), this, SLOT(slotTextChanged())); + connect(m_layout->dstUser, SIGNAL(textChanged(const QString&)), this, SLOT(slotTextChanged())); + connect(m_layout->dstPass, SIGNAL(textChanged(const QString&)), this, SLOT(slotTextChanged())); + + connect(m_layout->srcName, SIGNAL(siteChanged(KFTPBookmarks::Site*)), this, SLOT(slotSourceSiteChanged(KFTPBookmarks::Site*))); + connect(m_layout->dstName, SIGNAL(siteChanged(KFTPBookmarks::Site*)), this, SLOT(slotDestSiteChanged(KFTPBookmarks::Site*))); + + connect(m_layout->transferType, SIGNAL(activated(int)), this, SLOT(slotTransferModeChanged(int))); + + setMaximumHeight(250); + setInitialSize(QSize(500, 250)); + + enableButtonOK(false); +} + +void QueueEditor::resetTabs() +{ + m_layout->serverTab->setTabEnabled(m_layout->tab, false); + m_layout->serverTab->setTabEnabled(m_layout->tab_2, false); +} + +void QueueEditor::resetServerData() +{ + // Source + m_layout->srcName->clear(); + m_layout->srcHost->setText(""); + m_layout->srcPort->setValue(21); + m_layout->srcUser->setText(""); + m_layout->srcPass->erase(); + + // Destination + m_layout->dstName->clear(); + m_layout->dstHost->setText(""); + m_layout->dstPort->setValue(21); + m_layout->dstUser->setText(""); + m_layout->dstPass->erase(); +} + +void QueueEditor::slotTransferModeChanged(int index) +{ + if (m_lastTransferType == index) + return; + else + m_lastTransferType = (KFTPQueue::TransferType) index; + + resetTabs(); + resetServerData(); + + switch (index) { + case 0: { + // Download - source: remote dest: local + m_layout->serverTab->setTabEnabled(m_layout->tab, true); + m_layout->serverTab->showPage(m_layout->tab); + break; + } + case 1: { + // Upload - source: local dest: remote + m_layout->serverTab->setTabEnabled(m_layout->tab_2, true); + m_layout->serverTab->showPage(m_layout->tab_2); + break; + } + case 2: { + // FXP - source: remote dest: remote + m_layout->serverTab->setTabEnabled(m_layout->tab, true); + m_layout->serverTab->setTabEnabled(m_layout->tab_2, true); + m_layout->serverTab->showPage(m_layout->tab); + break; + } + } + + slotTextChanged(); +} + +bool QueueEditor::sourceIsValid() +{ + if (m_lastTransferType == 1) return true; + + if (m_layout->srcHost->text().stripWhiteSpace().isEmpty() || m_layout->srcUser->text().stripWhiteSpace().isEmpty()) + return false; + else + return true; +} + +bool QueueEditor::destIsValid() +{ + if (m_lastTransferType == 0) return true; + + if (m_layout->dstHost->text().stripWhiteSpace().isEmpty() || m_layout->dstUser->text().stripWhiteSpace().isEmpty()) + return false; + else + return true; +} + +void QueueEditor::slotTextChanged() +{ + if (m_layout->srcPath->text().stripWhiteSpace().isEmpty() || m_layout->dstPath->text().stripWhiteSpace().isEmpty() || + m_layout->srcPath->text().left(1) != "/" || m_layout->dstPath->text().left(1) != "/" || + !sourceIsValid() || !destIsValid() ) + enableButtonOK(false); + else + enableButtonOK(true); +} + +void QueueEditor::setData(KFTPQueue::Transfer *transfer) +{ + KURL sUrl, dUrl; + + m_layout->srcPath->setText(transfer->getSourceUrl().path()); + m_layout->dstPath->setText(transfer->getDestUrl().path()); + + // Source + sUrl = transfer->getSourceUrl(); + + if (!sUrl.isLocalFile()) { + m_layout->srcName->setCurrentSite(KFTPBookmarks::Manager::self()->findSite(sUrl)); + m_layout->srcHost->setText(sUrl.host()); + m_layout->srcPort->setValue(sUrl.port()); + m_layout->srcUser->setText(sUrl.user()); + + m_layout->srcPass->erase(); + m_layout->srcPass->insert(sUrl.pass()); + } else { + m_layout->serverTab->setTabEnabled(m_layout->tab, false); + } + + // Destination + dUrl = transfer->getDestUrl(); + + if (!dUrl.isLocalFile()) { + m_layout->dstName->setCurrentSite(KFTPBookmarks::Manager::self()->findSite(dUrl)); + m_layout->dstHost->setText(dUrl.host()); + m_layout->dstPort->setValue(dUrl.port()); + m_layout->dstUser->setText(dUrl.user()); + + m_layout->dstPass->erase(); + m_layout->dstPass->insert(dUrl.pass()); + } else { + m_layout->serverTab->setTabEnabled(m_layout->tab_2, false); + } + + // Transfer type + m_lastTransferType = transfer->getTransferType(); + m_layout->transferType->setCurrentItem(m_lastTransferType); + + m_transfer = transfer; +} + +void QueueEditor::saveData() +{ + KURL sUrl, dUrl; + + if (m_lastTransferType != 1) { + sUrl.setProtocol(REMOTE_PROTOCOL); + sUrl.setHost(m_layout->srcHost->text()); + sUrl.setPort(m_layout->srcPort->value()); + sUrl.setUser(m_layout->srcUser->text()); + sUrl.setPass(m_layout->srcPass->password()); + + if (m_transfer->getSourceUrl().pass().isEmpty() && sUrl.pass().isEmpty()) + sUrl.setPass(QString::null); + } else { + sUrl.setProtocol("file"); + } + + sUrl.setPath(m_layout->srcPath->text()); + + if (m_lastTransferType != 0) { + dUrl.setProtocol(REMOTE_PROTOCOL); + dUrl.setHost(m_layout->dstHost->text()); + dUrl.setPort(m_layout->dstPort->value()); + dUrl.setUser(m_layout->dstUser->text()); + dUrl.setPass(m_layout->dstPass->password()); + + if (m_transfer->getDestUrl().pass().isEmpty() && dUrl.pass().isEmpty()) + dUrl.setPass(QString::null); + } else { + dUrl.setProtocol("file"); + } + + dUrl.setPath(m_layout->dstPath->text()); + + m_transfer->setSourceUrl(sUrl); + m_transfer->setDestUrl(dUrl); + m_transfer->setTransferType(m_lastTransferType); + + // If the transfer is a directory, we have to update all child transfers + // as well. + if (m_transfer->isDir()) + recursiveSaveData(static_cast<KFTPQueue::TransferDir*>(m_transfer), sUrl, dUrl); +} + +void QueueEditor::recursiveSaveData(KFTPQueue::TransferDir *parent, const KURL &srcUrl, const KURL &dstUrl) +{ + KFTPQueue::QueueObject *o; + QPtrList<KFTPQueue::QueueObject> children = parent->getChildrenList(); + + KURL sUrl, dUrl; + + for (o = children.first(); o; o = children.next()) { + KFTPQueue::Transfer *i = static_cast<KFTPQueue::Transfer*>(o); + + // Modify the urls + sUrl = srcUrl; + dUrl = dstUrl; + + sUrl.addPath(i->getSourceUrl().fileName()); + dUrl.addPath(i->getDestUrl().fileName()); + + // Set the urls + i->setSourceUrl(sUrl); + i->setDestUrl(dUrl); + i->setTransferType(m_lastTransferType); + i->emitUpdate(); + + if (i->isDir()) + recursiveSaveData(static_cast<KFTPQueue::TransferDir*>(i), sUrl, dUrl); + } +} + +void QueueEditor::slotSourceSiteChanged(KFTPBookmarks::Site *site) +{ + if (site) { + m_layout->srcHost->setText(site->getProperty("host")); + m_layout->srcPort->setValue(site->getIntProperty("port")); + m_layout->srcUser->setText(site->getProperty("username")); + m_layout->srcPass->erase(); + m_layout->srcPass->insert(site->getProperty("password")); + } else { + m_layout->srcHost->clear(); + m_layout->srcPort->setValue(21); + m_layout->srcUser->clear(); + m_layout->srcPass->erase(); + } +} + +void QueueEditor::slotDestSiteChanged(KFTPBookmarks::Site *site) +{ + if (site) { + m_layout->dstHost->setText(site->getProperty("host")); + m_layout->dstPort->setValue(site->getIntProperty("port")); + m_layout->dstUser->setText(site->getProperty("username")); + m_layout->dstPass->erase(); + m_layout->dstPass->insert(site->getProperty("password")); + } else { + m_layout->dstHost->clear(); + m_layout->dstPort->setValue(21); + m_layout->dstUser->clear(); + m_layout->dstPass->erase(); + } +} + +} + +#include "queueeditor.moc" + diff --git a/kftpgrabber/src/widgets/queueview/queueeditor.h b/kftpgrabber/src/widgets/queueview/queueeditor.h new file mode 100644 index 0000000..09027d6 --- /dev/null +++ b/kftpgrabber/src/widgets/queueview/queueeditor.h @@ -0,0 +1,82 @@ +/* + * 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 KFTPQUEUEEDITOR_H +#define KFTPQUEUEEDITOR_H + +#include "kftpqueue.h" +#include "kftpbookmarks.h" + +#include <kdialogbase.h> +#include <qdom.h> + +class KFTPQueueEditorLayout; + +namespace KFTPWidgets { + +/** +@author Jernej Kos +*/ +class QueueEditor : public KDialogBase +{ +Q_OBJECT +public: + QueueEditor(QWidget *parent = 0, const char *name = 0); + + void setData(KFTPQueue::Transfer *transfer); + void saveData(); +private: + KFTPQueueEditorLayout *m_layout; + KFTPQueue::Transfer *m_transfer; + KFTPQueue::TransferType m_lastTransferType; + + void resetTabs(); + void resetServerData(); + + bool sourceIsValid(); + bool destIsValid(); + + void recursiveSaveData(KFTPQueue::TransferDir *parent, const KURL &srcUrl, const KURL &dstUrl); +private slots: + void slotTextChanged(); + void slotTransferModeChanged(int index); + + void slotSourceSiteChanged(KFTPBookmarks::Site *site); + void slotDestSiteChanged(KFTPBookmarks::Site *site); +}; + +} + +#endif diff --git a/kftpgrabber/src/widgets/queueview/queueview.cpp b/kftpgrabber/src/widgets/queueview/queueview.cpp new file mode 100644 index 0000000..4fc8e5f --- /dev/null +++ b/kftpgrabber/src/widgets/queueview/queueview.cpp @@ -0,0 +1,888 @@ +/* + * 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> + * Copyright (C) 2005 Markus Brueffer <markus@brueffer.de> + * + * 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 "misc.h" + +#include "listview.h" +#include "queueview.h" +#include "kftpqueue.h" +#include "kftpapi.h" +#include "queueeditor.h" +#include "widgets/searchdialog.h" +#include "misc/config.h" + +#include <kapplication.h> +#include <kfiledialog.h> +#include <kiconloader.h> +#include <kio/job.h> +#include <klocale.h> +#include <kmessagebox.h> +#include <kmimetype.h> +#include <kpopupmenu.h> +#include <klistviewsearchline.h> +#include <kdebug.h> + +#include <qspinbox.h> +#include <qtooltip.h> + +using namespace KFTPGrabberBase; +using namespace KFTPCore; + +namespace KFTPWidgets { + +QueueViewItem::QueueViewItem(QueueView *view, KFTPQueue::QueueObject *object, QListView *parent) + : QListViewItem(parent), + m_lastChild(0), + m_queueObject(object), + m_queueView(view), + m_queueId(object->getId()) +{ + init(); +} + +QueueViewItem::QueueViewItem(QueueView *view, KFTPQueue::QueueObject *object, QListViewItem *parent) + : QListViewItem(parent, static_cast<QueueViewItem*>(parent)->lastChild()), + m_lastChild(0), + m_queueObject(object), + m_queueView(view), + m_queueId(object->getId()) +{ + init(); +} + +QueueViewItem::~QueueViewItem() +{ + m_queueView->m_queuedItems.remove(m_queueId); +} + +void QueueViewItem::insertItem(QListViewItem *newChild) +{ + QListViewItem::insertItem(newChild); + m_lastChild = newChild; +} + +void QueueViewItem::takeItem(QListViewItem *item) +{ + if (item == m_lastChild) { + QListViewItem *above = item->itemAbove(); + + if (above->parent() == m_lastChild->parent()) + m_lastChild = above; + else + m_lastChild = 0; + } + + QListViewItem::takeItem(item); +} + +void QueueViewItem::moveUp() +{ + QListViewItem *above = itemAbove(); + + if (above && above->parent() == QListViewItem::parent()) { + QListViewItem *previous = above->itemAbove(); + + if (previous && previous->parent() == QListViewItem::parent()) { + QueueViewItem *parent = static_cast<QueueViewItem*>(QListViewItem::parent()); + moveItem(previous); + + if (parent && this == parent->lastChild()) + parent->m_lastChild = above; + } else { + moveToTop(); + } + } +} + +void QueueViewItem::moveDown() +{ + QueueViewItem *parent = static_cast<QueueViewItem*>(QListViewItem::parent()); + QueueViewItem *next = static_cast<QueueViewItem*>(nextSibling()); + + if (next) { + moveItem(next); + + if (parent && parent->lastChild() == next) + parent->m_lastChild = this; + } +} + +void QueueViewItem::moveToTop() +{ + QueueViewItem *parent = static_cast<QueueViewItem*>(QListViewItem::parent()); + + // Just reinsert the item + if (parent) { + if (this == parent->lastChild()) + parent->m_lastChild = itemAbove(); + + parent->QListViewItem::takeItem(this); + parent->QListViewItem::insertItem(this); + } else { + ListView *view = m_queueView->m_queue; + view->QListView::takeItem(this); + view->QListView::insertItem(this); + } +} + +void QueueViewItem::moveToBottom() +{ + QueueViewItem *parent = static_cast<QueueViewItem*>(QListViewItem::parent()); + + // Just reinsert the item + if (parent) { + QListViewItem *last = parent->lastChild(); + + parent->takeItem(this); + parent->insertItem(this); + moveItem(last); + } else { + ListView *view = m_queueView->m_queue; + view->takeItem(this); + view->insertItem(this); + } +} + +void QueueViewItem::paintCell(QPainter *p, const QColorGroup &cg, int column, int width, int alignment) +{ + QColorGroup _cg(cg); + QColor c = _cg.text(); + + QColor n_color; + + if (m_queueObject && m_queueObject->isTransfer()) { + switch (m_queueObject->getStatus()) { + case KFTPQueue::Transfer::Running: n_color.setRgb(255, 0, 0); break; + case KFTPQueue::Transfer::Connecting: n_color.setRgb(0, 0, 255); break; + case KFTPQueue::Transfer::Waiting: n_color.setRgb(0, 0, 255); break; + case KFTPQueue::Transfer::Locked: n_color.setRgb(0, 150, 0); break; + default: break; + } + } + + if (n_color.isValid()) + _cg.setColor(QColorGroup::Text, n_color); + + QListViewItem::paintCell(p, _cg, column, width, alignment); + _cg.setColor(QColorGroup::Text, c); +} + +void QueueViewItem::init() +{ + if (m_queueObject->isTransfer()) { + KFTPQueue::Transfer *transfer = static_cast<KFTPQueue::Transfer*>(getObject()); + + setText(0, transfer->getSourceUrl().fileName()); + setText(1, KIO::convertSize(transfer->getActualSize())); + setText(2, transfer->getSourceUrl().pathOrURL()); + setText(3, transfer->getDestUrl().pathOrURL()); + + // Icon + QString iconText; + if (transfer->isDir()) { + iconText = "folder"; + } else { + KMimeType::Ptr theType = KMimeType::findByURL("/" + transfer->getSourceUrl().path(), 0, false, true); + iconText = theType->icon(QString::null, false); + } + + setPixmap(0, loadSmallPixmap(iconText)); + } else if (m_queueObject->getType() == KFTPQueue::QueueObject::Site) { + KFTPQueue::Site *site = static_cast<KFTPQueue::Site*>(getObject()); + + setText(0, QString("%1:%2").arg(site->getUrl().host()).arg(site->getUrl().port())); + setText(1, KIO::convertSize(site->getActualSize())); + + // Set the pixmap + setPixmap(0, loadSmallPixmap("server")); + } +} + +void QueueViewItem::refresh() +{ + if (!m_queueObject) + return; + + if (m_queueObject->isTransfer()) { + KFTPQueue::Transfer *transfer = static_cast<KFTPQueue::Transfer*>(getObject()); + + // Speed + bool noSpeed = transfer->getStatus() == KFTPQueue::Transfer::Waiting || transfer->getStatus() == KFTPQueue::Transfer::Connecting; + QString speed; + if ((!transfer->isDir() || !isOpen()) && transfer->isRunning() && !noSpeed) { + speed.sprintf( "%lld B/s", (transfer->getSpeed()) ); + + if (transfer->getSpeed() > 1024) + speed.sprintf( "%lld KB/s", (transfer->getSpeed() / 1024) ); + + if (transfer->getSpeed() > 1024*1024) + speed.sprintf("%lld MB/s", (transfer->getSpeed() / 1024) / 1024); + + if (transfer->getSpeed() == 0 && transfer->getTransferType() != KFTPQueue::FXP) + speed = i18n("stalled"); + + if (transfer->getSpeed() == 0 && transfer->getTransferType() == KFTPQueue::FXP) + speed = i18n("running"); + } + + // ETA + QString eta; + + if (transfer->isRunning() && transfer->getSpeed() > 0) { + eta = KIO::convertSeconds(KIO::calculateRemainingSeconds(transfer->getSize(), + transfer->getCompleted(), + transfer->getSpeed())); + } else { + eta = QString::null; + } + + // Set the columns + setText(0, transfer->getSourceUrl().fileName()); + setText(1, KIO::convertSize(transfer->getActualSize())); + setText(2, transfer->getSourceUrl().pathOrURL()); + setText(3, transfer->getDestUrl().pathOrURL()); + setText(5, speed); + setText(6, eta); + + // Don't show the file:// for local src/dest + if (transfer->getSourceUrl().isLocalFile()) { + setText(2, transfer->getSourceUrl().path()); + } else if (transfer->getDestUrl().isLocalFile()) { + setText(3, transfer->getDestUrl().path()); + } + + // Progress + int progress; + int r_progress; + + if (transfer->getSize() == 0) + progress = 0; + else + progress = transfer->getCompleted()*100/transfer->getSize(); + + if (transfer->getResumed() == 0) + r_progress = 0; + else + r_progress = transfer->getResumed()*100/transfer->getSize(); + + if (transfer->getStatus() == KFTPQueue::Transfer::Waiting) { + // Transfer is waiting for a free connection + setText(4, i18n("Waiting for connection...")); + setPixmap(4, NULL); + } else if (transfer->getStatus() == KFTPQueue::Transfer::Connecting) { + // Transfer is not yet connected, + setText(4, i18n("Connecting...")); + setPixmap(4, NULL); + } else if (progress > 0) { + setPixmap(4, createProgressPixmap(progress, r_progress)); + + QString progressText; + progressText.sprintf("%d %%", progress); + setText(4, progressText); + } else { + setPixmap(4, NULL); + setText(4, QString::null); + } + + // Icon + QString iconText; + if (transfer->isDir()) { + iconText = "folder"; + } else { + KMimeType::Ptr theType = KMimeType::findByURL("/" + transfer->getSourceUrl().path(), 0, false, true); + iconText = theType->icon(QString::null, false); + } + + setPixmap(0, loadSmallPixmap(iconText)); + } else if (m_queueObject->getType() == KFTPQueue::QueueObject::Site) { + KFTPQueue::Site *site = static_cast<KFTPQueue::Site*>(getObject()); + + // Speed + QString speed; + speed.sprintf( "%lld B/s", (site->getSpeed()) ); + + if (site->getSpeed() > 1024) + speed.sprintf( "%lld KB/s", (site->getSpeed() / 1024) ); + + if (site->getSpeed() > 1024*1024) + speed.sprintf("%lld MB/s", (site->getSpeed() / 1024) / 1024); + + if (site->getSpeed() == 0) + speed = QString::null; + + // ETA + QString eta; + + if (site->isRunning() && site->getSpeed() > 0) { + eta = KIO::convertSeconds(KIO::calculateRemainingSeconds(site->getSize(), + site->getCompleted(), + site->getSpeed())); + } else { + eta = ""; + } + + // Progress + if (site->isRunning()) { + int progress = 0; + + if (site->getSize() > 0) + progress = site->getCompleted()*100/site->getSize(); + + setPixmap(4, createProgressPixmap(progress, 0)); + + QString progressText; + progressText.sprintf("%d %%", progress); + setText(4, progressText); + } else { + setPixmap(4, NULL); + setText(4, QString::null); + } + + // Set the columns + setText(0, QString("%1:%2").arg(site->getUrl().host()).arg(site->getUrl().port())); + setText(1, KIO::convertSize(site->getActualSize())); + setText(5, speed); + setText(6, eta); + + // Set the pixmap + setPixmap(0, loadSmallPixmap("server")); + } +} + +QueueListView::QueueListView(QWidget *parent) + : ListView(parent) +{ +} + +void QueueListView::insertItem(QListViewItem *item) +{ + QListViewItem *last = lastChild(); + QListView::insertItem(item); + + if (last) + item->moveItem(last); +} + +QueueView::QueueView(QWidget *parent, const char *name) + : QWidget(parent, name) +{ + QVBoxLayout *layout = new QVBoxLayout(this); + + m_toolBar = new KToolBar(this, "queueToolBar"); + m_toolBar->setIconSize(16); + layout->addWidget(m_toolBar); + + m_searchToolBar = new KToolBar(this, "searchToolBar"); + m_searchToolBar->setEnableContextMenu(false); + m_searchToolBar->setMovingEnabled(false); + m_searchToolBar->setFullSize(true); + + // Create the erase button + m_searchToolBar->insertButton(QApplication::reverseLayout() ? "clear_left" :"locationbar_erase", 0, SIGNAL(clicked()), this, SLOT(slotSearchEraseClicked()), true); + + // Create the labels + QLabel *searchLabel = new QLabel(i18n("Filter: "), m_searchToolBar); + m_searchToolBar->insertWidget(1, 35, searchLabel); + + // Create the list view + m_queue = new QueueListView(this); + + // Create the search field + m_searchField = new KListViewSearchLine(m_searchToolBar, m_queue); + + // Do some more stuff + m_searchToolBar->setItemAutoSized(1, true); + m_searchToolBar->setStretchableWidget(m_searchField); + m_searchToolBar->updateRects(true); + m_searchToolBar->hide(); + + layout->addWidget(m_searchToolBar); + + // Create the columns + m_queue->addColumn(i18n("Name"), 150); + m_queue->addColumn(i18n("Size"), 75); + m_queue->addColumn(i18n("Source"), 250); + m_queue->addColumn(i18n("Destination"), 250); + m_queue->addColumn(i18n("Progress"), 140); + m_queue->addColumn(i18n("Speed"), 70); + m_queue->addColumn(i18n("ETA"), 80); + + // Text when there is nothing queued + m_queue->setEmptyListText(i18n("You do not have any files in the queue.")); + + // Multi-select + m_queue->setSelectionModeExt(KListView::FileManager); + m_queue->setAllColumnsShowFocus(true); + m_queue->setRootIsDecorated(true); + m_queue->QListView::setSorting(-1); + m_queue->QListView::setSortColumn(-1); + + layout->addWidget(m_queue); + + // The signals + connect(m_queue, SIGNAL(contextMenu(KListView*, QListViewItem*, const QPoint&)), this, + SLOT(contextMenuRequested(KListView*, QListViewItem*, const QPoint&))); + connect(m_queue, SIGNAL(selectionChanged()), this, SLOT(updateActions())); + + // Let us be up-to-date + connect(KFTPQueue::Manager::self(), SIGNAL(transferRemoved(long)), this, SLOT(slotObjectRemoved(long))); + connect(KFTPQueue::Manager::self(), SIGNAL(siteRemoved(long)), this, SLOT(slotObjectRemoved(long))); + connect(KFTPQueue::Manager::self(), SIGNAL(newTransfer(KFTPQueue::Transfer*)), this, SLOT(slotTransferAdded(KFTPQueue::Transfer*))); + connect(KFTPQueue::Manager::self(), SIGNAL(newSite(KFTPQueue::Site*)), this, SLOT(slotSiteAdded(KFTPQueue::Site*))); + connect(KFTPQueue::Manager::self(), SIGNAL(queueUpdate()), this, SLOT(updateActions())); + + // Load the listview layout + loadLayout(); + + // Create the context menu actions + initActions(); + initToolBar(); + updateActions(); + + setMinimumHeight(150); +} + +void QueueView::saveLayout() +{ + m_queue->saveLayout(kapp->config(), "queueViewLayout"); +} + +void QueueView::loadLayout() +{ + m_queue->restoreLayout(kapp->config(), "queueViewLayout"); +} + +void QueueView::initToolBar() +{ + // Plug all actions + m_loadAction->plug(m_toolBar); + m_saveAction->plug(m_toolBar); + m_toolBar->insertSeparator(); + m_startAction->plug(m_toolBar); + m_pauseAction->plug(m_toolBar); + m_stopAction->plug(m_toolBar); + m_toolBar->insertSeparator(); + m_addAction->plug(m_toolBar); + m_removeAction->plug(m_toolBar); + m_searchAction->plug(m_toolBar); + m_toolBar->insertSeparator(); + m_filterAction->plug(m_toolBar); + + // Create speed control widgets + m_toolBar->insertSeparator(); + + QSpinBox *downloadSpeed = new QSpinBox(0, 10240, 1, m_toolBar); + QToolTip::add(downloadSpeed, i18n("Limit download transfer speed")); + m_toolBar->insertWidget(1, 35, new QLabel(i18n("Down: "), m_toolBar)); + m_toolBar->insertWidget(2, 35, downloadSpeed); + downloadSpeed->setValue(Config::downloadSpeedLimit()); + connect(downloadSpeed, SIGNAL(valueChanged(int)), this, SLOT(slotDownloadLimitChanged(int))); + + m_toolBar->insertSeparator(); + + QSpinBox *uploadSpeed = new QSpinBox(0, 10240, 1, m_toolBar); + QToolTip::add(uploadSpeed, i18n("Limit upload transfer speed")); + m_toolBar->insertWidget(3, 35, new QLabel(i18n("Up: "), m_toolBar)); + m_toolBar->insertWidget(4, 35, uploadSpeed); + uploadSpeed->setValue(Config::uploadSpeedLimit()); + connect(uploadSpeed, SIGNAL(valueChanged(int)), this, SLOT(slotUploadLimitChanged(int))); + + // Create thread count control widget + m_toolBar->insertSeparator(); + + QSpinBox *threadCount = new QSpinBox(1, 10, 1, m_toolBar); + QToolTip::add(threadCount, i18n("Per-session transfer thread count")); + m_toolBar->insertWidget(5, 35, new QLabel(i18n("Threads: "), m_toolBar)); + m_toolBar->insertWidget(6, 35, threadCount); + threadCount->setValue(Config::threadCount()); + connect(threadCount, SIGNAL(valueChanged(int)), this, SLOT(slotThreadCountChanged(int))); +} + +void QueueView::slotDownloadLimitChanged(int value) +{ + Config::setDownloadSpeedLimit(value); + Config::self()->emitChange(); +} + +void QueueView::slotUploadLimitChanged(int value) +{ + Config::setUploadSpeedLimit(value); + Config::self()->emitChange(); +} + +void QueueView::slotThreadCountChanged(int value) +{ + Config::setThreadCount(value); + Config::self()->emitChange(); +} + +void QueueView::initActions() +{ + m_actionCollection = new KActionCollection(this, this); + + // Create all the actions + m_launchAction = new KAction(i18n("&Start Transfer"), "launch", KShortcut(), this, SLOT(slotLaunch()), m_actionCollection, "launch"); + m_abortAction = new KAction(i18n("&Abort Transfer"), KShortcut(), this, SLOT(slotAbort()), m_actionCollection, "abort"); + m_removeAction = new KAction(i18n("&Remove"), "editdelete", KShortcut(Qt::Key_Delete), this, SLOT(slotRemove()), m_actionCollection, "remove"); + m_removeAllAction = new KAction(i18n("Remove &All"), KShortcut(), this, SLOT(slotRemoveAll()), m_actionCollection, "removeAll"); + m_moveUpAction = new KAction(i18n("Move &Up"), "up", KShortcut(), this, SLOT(slotMoveUp()), m_actionCollection, "moveUp"); + m_moveDownAction = new KAction(i18n("Move &Down"), "down", KShortcut("del"), this, SLOT(slotMoveDown()), m_actionCollection, "moveDown"); + m_moveTopAction = new KAction(i18n("Move To &Top"), "top", KShortcut(), this, SLOT(slotMoveTop()), m_actionCollection, "moveTop"); + m_moveBottomAction = new KAction(i18n("Move To &Bottom"), "bottom", KShortcut(), this, SLOT(slotMoveBottom()), m_actionCollection, "moveBottom"); + m_editAction = new KAction(i18n("&Change Transfer Info"), KShortcut(), this, SLOT(slotEdit()), m_actionCollection, "changeTransfer"); + + // Create the toolbar actions + m_loadAction = new KAction(i18n("&Load Queue From File"), "fileopen", KShortcut(), this, SLOT(slotLoad()), m_actionCollection, "load"); + m_saveAction = new KAction(i18n("&Save Queue to File"), "filesaveas", KShortcut(), this, SLOT(slotSave()), m_actionCollection, "save"); + m_startAction = new KAction(i18n("S&tart"), "player_play", KShortcut(), this, SLOT(slotStart()), m_actionCollection, "start"); + m_pauseAction = new KAction(i18n("&Pause"), "player_pause", KShortcut(), this, SLOT(slotPause()), m_actionCollection, "pause"); + m_stopAction = new KAction(i18n("St&op"), "player_stop", KShortcut(), this, SLOT(slotStop()), m_actionCollection, "stop"); + m_addAction = new KAction(i18n("&Add Transfer..."), "filenew", KShortcut(), this, SLOT(slotAdd()), m_actionCollection, "add"); + m_searchAction = new KAction(i18n("&Search && Replace..."), "find", KShortcut(), this, SLOT(slotSearch()), m_actionCollection, "search"); + m_filterAction = new KToggleAction(i18n("Show &Filter"), "filter", KShortcut(), this, SLOT(slotFilter()), m_actionCollection, "filter"); + + m_saveAction->setEnabled( false ); + m_startAction->setEnabled(false); + m_pauseAction->setEnabled(false); + m_stopAction->setEnabled(false); + m_addAction->setEnabled(false); + m_removeAction->setEnabled(false); + m_searchAction->setEnabled(false); + m_filterAction->setEnabled(true); +} + +void QueueView::updateActions() +{ + m_startAction->setEnabled(!KFTPQueue::Manager::self()->isProcessing() && KFTPQueue::Manager::self()->topLevelObject()->hasChildren() && !KFTPQueue::Manager::self()->getNumRunning()); + m_stopAction->setEnabled(KFTPQueue::Manager::self()->isProcessing()); + m_removeAllAction->setEnabled(!KFTPQueue::Manager::self()->isProcessing()); + + QPtrList<QListViewItem> selection = m_queue->selectedItems(); + QueueViewItem *firstItem = static_cast<QueueViewItem*>(selection.first()); + + m_removeAction->setEnabled((bool) firstItem); + + if (!firstItem || !firstItem->getObject()) + return; + + bool locked = firstItem->getObject()->isLocked(); + bool parentRunning = false; + + if (firstItem->getObject()->hasParentObject()) + parentRunning = firstItem->getObject()->parentObject()->isRunning(); + + m_launchAction->setEnabled(!firstItem->getObject()->isRunning() && !KFTPQueue::Manager::self()->isProcessing() && !locked); + m_abortAction->setEnabled(firstItem->getObject()->isRunning() && !KFTPQueue::Manager::self()->isProcessing()); + m_removeAction->setEnabled(!firstItem->getObject()->isRunning() && !KFTPQueue::Manager::self()->isProcessing() && !locked); + m_editAction->setEnabled(!firstItem->getObject()->isRunning() && firstItem->getObject()->parentObject()->getType() == KFTPQueue::QueueObject::Site && !locked); + + // Only allow moving of multi selections if they have the same parent + bool allowMove = true; + for (QListViewItem *i = selection.first(); i; i = selection.next()) { + if (i->parent() != static_cast<QListViewItem*>(firstItem)->parent()) { + allowMove = false; + break; + } + } + + m_moveUpAction->setEnabled(allowMove && KFTPQueue::Manager::self()->canBeMovedUp(firstItem->getObject()) && !locked); + m_moveDownAction->setEnabled(allowMove && KFTPQueue::Manager::self()->canBeMovedDown(static_cast<QueueViewItem*>(selection.last())->getObject()) && !locked); + + m_moveTopAction->setEnabled(allowMove && KFTPQueue::Manager::self()->canBeMovedUp(firstItem->getObject()) && !locked); + m_moveBottomAction->setEnabled(allowMove && KFTPQueue::Manager::self()->canBeMovedDown(static_cast<QueueViewItem*>(selection.last())->getObject()) && !locked); +} + +void QueueView::slotSiteAdded(KFTPQueue::Site *site) +{ + // The site should be inserted top-level + m_queuedItems.insert(site->getId(), new QueueViewItem(this, site, m_queue)); + connect(site, SIGNAL(objectUpdated()), this, SLOT(slotObjectUpdated())); +} + +void QueueView::slotTransferAdded(KFTPQueue::Transfer *transfer) +{ + // This transfer should be inserted under some other transfer + QueueViewItem *parent = m_queuedItems.find(transfer->parentObject()->getId()); + + if (parent) { + m_queuedItems.insert(transfer->getId(), new QueueViewItem(this, transfer, parent)); + connect(transfer, SIGNAL(objectUpdated()), this, SLOT(slotObjectUpdated())); + } + + // Update actions + m_saveAction->setEnabled(true); + m_removeAllAction->setEnabled(true); + m_searchAction->setEnabled(true); +} + +void QueueView::slotObjectRemoved(long id) +{ + // Delete the transfer + QueueViewItem *item = m_queuedItems.find(id); + + if (item) + delete item; + + // Update actions + bool empty = (m_queue->childCount() == 0); + + m_saveAction->setEnabled(!empty); + if (empty) m_removeAction->setEnabled(false); + m_removeAllAction->setEnabled(!empty); + m_searchAction->setEnabled(!empty); +} + +void QueueView::slotObjectUpdated() +{ + KFTPQueue::QueueObject *object = (KFTPQueue::QueueObject*) QObject::sender(); + + if (object) { + QueueViewItem *item = m_queuedItems.find(object->getId()); + + if (item) + item->refresh(); + } +} + +void QueueView::contextMenuRequested(KListView*, QListViewItem* item, const QPoint& p) +{ + if (!item) + return; + + QueueViewItem *firstItem = static_cast<QueueViewItem*>(m_queue->selectedItems().first()); + KPopupMenu *contextMenu = new KPopupMenu(m_queue); + + // Populate context menu + if (firstItem->getObject()->isTransfer()) { + contextMenu->insertTitle(item->text(0) + ((m_queue->selectedItems().count() > 1) ? "..." : "" )); + m_launchAction->plug(contextMenu); + m_abortAction->plug(contextMenu); + contextMenu->insertSeparator(); + m_removeAction->plug(contextMenu); + m_removeAllAction->plug(contextMenu); + contextMenu->insertSeparator(); + m_moveTopAction->plug(contextMenu); + m_moveUpAction->plug(contextMenu); + m_moveDownAction->plug(contextMenu); + m_moveBottomAction->plug(contextMenu); + contextMenu->insertSeparator(); + m_editAction->plug(contextMenu); + } else if (firstItem->getObject()->getType() == KFTPQueue::QueueObject::Site) { + contextMenu->insertTitle(i18n("Site")); + m_launchAction->plug(contextMenu); + m_abortAction->plug(contextMenu); + contextMenu->insertSeparator(); + m_moveUpAction->plug(contextMenu); + m_moveDownAction->plug(contextMenu); + } + + // Update the actions + updateActions(); + + // Show the context menu + contextMenu->exec(p); +} + +void QueueView::slotLaunch() +{ + // Reset a possible preconfigured default action + KFTPQueue::Manager::self()->setDefaultFileExistsAction(); + + static_cast<QueueViewItem*>(m_queue->selectedItems().first())->getObject()->execute(); +} + +void QueueView::slotAbort() +{ + static_cast<QueueViewItem*>(m_queue->selectedItems().first())->getObject()->abort(); +} + +void QueueView::slotRemove() +{ + if (KMessageBox::questionYesNo(this, i18n("Are you sure you want to remove queued file(s)?")) == KMessageBox::Yes) { + KFTPQueue::Manager::self()->setEmitUpdate(false); + + QPtrList<QListViewItem> selection = m_queue->selectedItems(); + for (QListViewItem *item = selection.first(); item; item = selection.next()) { + if (item && static_cast<QueueViewItem*>(item)->getObject()) + KFTPQueue::Manager::self()->removeTransfer(static_cast<KFTPQueue::Transfer*>(static_cast<QueueViewItem*>(item)->getObject())); + } + + KFTPQueue::Manager::self()->setEmitUpdate(true); + KFTPQueue::Manager::self()->doEmitUpdate(); + } +} + +void QueueView::slotRemoveAll() +{ + if (KMessageBox::questionYesNo(this, i18n("Are you sure you want to remove ALL queued files?")) == KMessageBox::Yes) { + KFTPQueue::Manager::self()->clearQueue(); + } +} + +void QueueView::slotMoveUp() +{ + QPtrList<QListViewItem> selection = m_queue->selectedItems(); + + for (QListViewItem *item = selection.first(); item; item = selection.next()) { + QueueViewItem *queueItem = static_cast<QueueViewItem*>(item); + + // Move the transfer + KFTPQueue::Manager::self()->moveTransferUp(queueItem->getObject()); + queueItem->moveUp(); + } +} + +void QueueView::slotMoveDown() +{ + QPtrList<QListViewItem> selection = m_queue->selectedItems(); + + for (QListViewItem *item = selection.last(); item; item = selection.prev()) { + QueueViewItem *queueItem = static_cast<QueueViewItem*>(item); + + // Move the transfer + KFTPQueue::Manager::self()->moveTransferDown(queueItem->getObject()); + queueItem->moveDown(); + } +} + +void QueueView::slotMoveTop() +{ + QPtrList<QListViewItem> selection = m_queue->selectedItems(); + + for (QListViewItem *item = selection.last(); item; item = selection.prev()) { + QueueViewItem *queueItem = static_cast<QueueViewItem*>(item); + + // Move the transfer + KFTPQueue::Manager::self()->moveTransferTop(queueItem->getObject()); + queueItem->moveToTop(); + } +} + +void QueueView::slotMoveBottom() +{ + QPtrList<QListViewItem> selection = m_queue->selectedItems(); + + for (QListViewItem *item = selection.first(); item; item = selection.next()) { + QueueViewItem *queueItem = static_cast<QueueViewItem*>(item); + + // Move the transfer + KFTPQueue::Manager::self()->moveTransferBottom(queueItem->getObject()); + queueItem->moveToBottom(); + } +} + +void QueueView::slotEdit() +{ + QueueEditor *editor = new QueueEditor(this); + + QueueViewItem* item = static_cast<QueueViewItem*>(m_queue->selectedItems().first()); + editor->setData(static_cast<KFTPQueue::Transfer*>(item->getObject())); + + // Show the queue editor + if (editor->exec() == QDialog::Accepted) { + editor->saveData(); + + KFTPQueue::Manager::self()->revalidateTransfer(static_cast<KFTPQueue::Transfer*>(item->getObject())); + KFTPQueue::Manager::self()->doEmitUpdate(); + item->refresh(); + } +} + +void QueueView::slotSearch() +{ + SearchDialog *dialog = new SearchDialog(); + + dialog->exec(); + delete dialog; +} + +void QueueView::slotLoad() +{ + if (m_queue->childCount() && KMessageBox::warningContinueCancel(0L, i18n("Loading a new queue will overwrite the existing one; are you sure you want to continue?"), i18n("Load Queue")) == KMessageBox::Cancel) + return; + + QString loadPath = KFileDialog::getOpenFileName(); + + if (!loadPath.isEmpty()) { + KFTPQueue::Manager::self()->getConverter()->importQueue(loadPath); + } +} + +void QueueView::slotSave() +{ + QString savePath = KFileDialog::getSaveFileName(); + + if (!savePath.isEmpty()) { + KFTPQueue::Manager::self()->getConverter()->exportQueue(savePath); + } +} + +void QueueView::slotStart() +{ + // Begin queue processing + KFTPQueue::Manager::self()->start(); +} + +void QueueView::slotPause() +{ +} + +void QueueView::slotStop() +{ + // Abort queue processing + KFTPQueue::Manager::self()->abort(); +} + +void QueueView::slotAdd() +{ +} + +void QueueView::slotSearchEraseClicked() +{ + m_searchField->clear(); +} + +void QueueView::slotFilter() +{ + if (m_filterAction->isChecked()) + m_searchToolBar->show(); + else + m_searchToolBar->hide(); +} + +} + +#include "queueview.moc" diff --git a/kftpgrabber/src/widgets/queueview/queueview.h b/kftpgrabber/src/widgets/queueview/queueview.h new file mode 100644 index 0000000..d93e14f --- /dev/null +++ b/kftpgrabber/src/widgets/queueview/queueview.h @@ -0,0 +1,296 @@ +/* + * 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> + * Copyright (C) 2005 Markus Brueffer <markus@brueffer.de> + * + * 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 KFTPQUEUEVIEW_H +#define KFTPQUEUEVIEW_H + +#include <qguardedptr.h> +#include <qintdict.h> +#include <qlayout.h> +#include <qlabel.h> + +#include <kaction.h> +#include <klistview.h> + +#include "kftpqueue.h" + +class KToolBar; +class KListViewSearchLine; + +namespace KFTPWidgets { + +class ListView; +class QueueView; + +/** + * A visual representation of a queued object. + */ +class QueueViewItem : public QListViewItem +{ +public: + /** + * Class constructor. + * + * @param view Queue view widget + * @param object Queue object + * @param parent Parent list view + */ + QueueViewItem(QueueView *view, KFTPQueue::QueueObject *object, QListView *parent); + + /** + * Class constructor. + * + * @param view Queue view widget + * @param object Queue object + * @param parent Parent item + */ + QueueViewItem(QueueView *view, KFTPQueue::QueueObject *object, QListViewItem *parent); + + /** + * Class destructor. + */ + ~QueueViewItem(); + + /** + * Refresh the visual representation with data from the actual queue object. + */ + void refresh(); + + /** + * Associate a queue object with this item. + * + * @param object A valid object pointer + */ + void setObject(KFTPQueue::QueueObject *object) { m_queueObject = object; } + + /** + * Returns the currently associated queue object. + */ + KFTPQueue::QueueObject *getObject() const { return m_queueObject; } + + /** + * Returns the last child item. + */ + QListViewItem *lastChild() const { return m_lastChild; } + + /** + * Moves this item one position up. + */ + void moveUp(); + + /** + * Moves this item one position down. + */ + void moveDown(); + + /** + * Moves this item to parent's top. + */ + void moveToTop(); + + /** + * Moves this item to parent's bottom. + */ + void moveToBottom(); + + /** + * @overload + * Reimplemented from QListViewItem. + */ + void insertItem(QListViewItem *newChild); + + /** + * @overload + * Reimplemented from QListViewItem. + */ + void takeItem(QListViewItem *item); + + /** + * @overload + * Reimplemented from QListViewItem for text colors. + */ + void paintCell(QPainter *p, const QColorGroup &cg, int column, int width, int alignment); + + /** + * @overload + * Reimplemented from QListViewItem. + */ + void sortChildItems(int, bool) {} +protected: + /** + * Init the item. + */ + void init(); +private: + QListViewItem *m_lastChild; + + KFTPQueue::QueueObject *m_queueObject; + QueueView *m_queueView; + long m_queueId; +}; + +/** + * The list view widget. + * + * @author Jernej Kos + */ +class QueueListView : public ListView { +public: + /** + * Class constructor. + * + * @param parent Parent widget + */ + QueueListView(QWidget *parent); + + /** + * @overload + * Reimplemented from QListView. + */ + void insertItem(QListViewItem *item); + + /** + * @overload + * Reimplemented from QListView. + */ + void setSorting(int, bool = true) { QListView::setSorting(-1); } +}; + +/** + * A widget for displaying and manipulating the current queue. + * + * @author Jernej Kos + */ +class QueueView : public QWidget +{ +friend class QueueViewItem; +Q_OBJECT +public: + /** + * Class constructor. + */ + QueueView(QWidget *parent, const char *name); + + /** + * Load queue list layout from the configuration file. + */ + void loadLayout(); + + /** + * Save queue list layout to the configuration file. + */ + void saveLayout(); +public slots: + void updateActions(); +protected: + /** + * Initialize actions. + */ + void initActions(); + + /** + * Initialize toolbar widgets. + */ + void initToolBar(); +private: + KActionCollection *m_actionCollection; + + // Actions + KAction *m_launchAction; + KAction *m_abortAction; + KAction *m_removeAction; + KAction *m_removeAllAction; + KAction *m_moveUpAction; + KAction *m_moveDownAction; + KAction *m_moveTopAction; + KAction *m_moveBottomAction; + KAction *m_editAction; + + // Toolbar Actions + KAction *m_loadAction; + KAction *m_saveAction; + KAction *m_startAction; + KAction *m_pauseAction; + KAction *m_stopAction; + KAction *m_addAction; + KAction *m_searchAction; + KToggleAction *m_filterAction; + + KListViewSearchLine *m_searchField; + + KToolBar *m_toolBar; + KToolBar *m_searchToolBar; + QueueListView *m_queue; + + QIntDict<QueueViewItem> m_queuedItems; +private slots: + void slotObjectRemoved(long); + void slotObjectUpdated(); + void slotTransferAdded(KFTPQueue::Transfer*); + void slotSiteAdded(KFTPQueue::Site*); + + void contextMenuRequested(KListView*, QListViewItem*, const QPoint&); + + void slotSearchEraseClicked(); + + // Slots for actions + void slotLaunch(); + void slotAbort(); + void slotRemove(); + void slotRemoveAll(); + void slotMoveUp(); + void slotMoveDown(); + void slotMoveTop(); + void slotMoveBottom(); + void slotEdit(); + + void slotLoad(); + void slotSave(); + void slotStart(); + void slotPause(); + void slotStop(); + void slotAdd(); + void slotSearch(); + void slotFilter(); + + void slotDownloadLimitChanged(int value); + void slotUploadLimitChanged(int value); + void slotThreadCountChanged(int value); +}; + +} + +#endif diff --git a/kftpgrabber/src/widgets/queueview/threadview.cpp b/kftpgrabber/src/widgets/queueview/threadview.cpp new file mode 100644 index 0000000..fd1c663 --- /dev/null +++ b/kftpgrabber/src/widgets/queueview/threadview.cpp @@ -0,0 +1,202 @@ +/* + * This file is part of the KFTPGrabber project + * + * Copyright (C) 2003-2005 by the KFTPGrabber developers + * Copyright (C) 2003-2005 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 "threadview.h" +#include "kftpapi.h" + +#include "listview.h" + +#include <qlayout.h> +#include <klocale.h> + +namespace KFTPWidgets { + +ThreadViewItem::ThreadViewItem(KFTPSession::Session *session, QListView *parent) + : QObject(parent), + QListViewItem(parent), + m_connection(0), + m_session(session) +{ + refresh(); +} + +ThreadViewItem::ThreadViewItem(KFTPSession::Connection *conn, QListViewItem *parent, int id) + : QObject(), + QListViewItem(parent), + m_id(id), + m_connection(conn), + m_session(0) +{ + connect(conn, SIGNAL(connectionRemoved()), this, SLOT(slotUpdateItemRequested())); + connect(conn, SIGNAL(connectionLost(KFTPSession::Connection*)), this, SLOT(slotUpdateItemRequested())); + connect(conn, SIGNAL(connectionEstablished()), this, SLOT(slotUpdateItemRequested())); + + // Connect the transfer signals if the transfer is already present + KFTPQueue::Transfer *transfer = m_connection->getTransfer(); + if (transfer) { + connect(transfer, SIGNAL(objectUpdated()), this, SLOT(slotUpdateItemRequested())); + } else { + connect(conn, SIGNAL(connectionAcquired()), this, SLOT(slotConnectionAcquired())); + } + + refresh(); +} + +void ThreadViewItem::slotConnectionAcquired() +{ + if (!m_connection->getTransfer()) + return; + + connect(m_connection->getTransfer(), SIGNAL(objectUpdated()), this, SLOT(slotUpdateItemRequested())); + refresh(); +} + +void ThreadViewItem::refresh() +{ + if (m_session) { + // Set the columns + setText(0, i18n("Site session [%1]").arg(m_session->getClient()->socket()->getCurrentUrl().host())); + setPixmap(0, loadSmallPixmap("ftp")); + } else if (m_connection) { + setText(0, i18n("Thread %1").arg(m_id)); + setPixmap(0, loadSmallPixmap("server")); + setText(1, m_connection->isConnected() ? i18n("idle") : i18n("disconnected")); + setText(2, ""); + + KFTPQueue::Transfer *transfer = m_connection->getTransfer(); + if (transfer && transfer->isRunning()) { + QString speed; + filesize_t rawSpeed = transfer->getSpeed(); + + speed.sprintf( "%lld KB/s", (rawSpeed / 1024) ); + + if (rawSpeed > 1024*1024) + speed.sprintf("%lld MB/s", (rawSpeed / 1024) / 1024); + else if (rawSpeed == 0) + speed = ""; + + if (transfer->getStatus() == KFTPQueue::Transfer::Connecting) { + setText(1, i18n("connecting")); + } else { + setText(1, i18n("transferring")); + } + + if (transfer->getTransferType() == KFTPQueue::FXP && rawSpeed == 0) { + KFTPSession::Connection *c = static_cast<KFTPQueue::TransferFile*>(transfer)->getOppositeConnection(m_connection); + + setText(2, i18n("FXP - [%1]").arg(c->getUrl().host())); + } else { + setText(2, speed); + } + } + } +} + +void ThreadViewItem::paintCell(QPainter *p, const QColorGroup &cg, int column, int width, int alignment) +{ + QListViewItem::paintCell(p, cg, column, width, alignment); +} + +void ThreadViewItem::slotUpdateItemRequested() +{ + refresh(); +} + +KActionCollection *ThreadView::actionCollection() +{ + return KFTPAPI::getInstance()->mainWindow()->actionCollection(); +} + +ThreadView::ThreadView(QWidget *parent, const char *name) + : QWidget(parent, name) +{ + QVBoxLayout *layout = new QVBoxLayout(this); + + // Create the list view + m_threads = new KFTPWidgets::ListView(this); + + // Create the columns + m_threads->addColumn(i18n("Name"), 400); + m_threads->addColumn(i18n("Status"), 120); + m_threads->addColumn(i18n("Speed"), 70); + + // Text when there are no threads + m_threads->setEmptyListText(i18n("There are no threads currently running.")); + + // Multi-select + m_threads->setSelectionModeExt(KListView::FileManager); + m_threads->setAllColumnsShowFocus(true); + m_threads->setRootIsDecorated(true); + + layout->addWidget(m_threads); + + connect(KFTPSession::Manager::self(), SIGNAL(update()), this, SLOT(slotUpdateSessions())); +} + +ThreadView::~ThreadView() +{ +} + +void ThreadView::slotUpdateSessions() +{ + KFTPSession::SessionList *list = KFTPSession::Manager::self()->getSessionList(); + KFTPSession::Session *i; + + m_threads->clear(); + + for (i = list->first(); i; i = list->next()) { + if (i->isRemote()) { + ThreadViewItem *site = new ThreadViewItem(i, m_threads); + + QPtrList<KFTPSession::Connection> *c_list = i->getConnectionList(); + + if (c_list->count() > 0) { + KFTPSession::Connection *conn; + int id = 0; + + for (conn = c_list->first(); conn; conn = c_list->next()) { + new ThreadViewItem(conn, site, ++id); + } + + site->setOpen(true); + } + } + } +} + +} + +#include "threadview.moc" + diff --git a/kftpgrabber/src/widgets/queueview/threadview.h b/kftpgrabber/src/widgets/queueview/threadview.h new file mode 100644 index 0000000..5c37e6c --- /dev/null +++ b/kftpgrabber/src/widgets/queueview/threadview.h @@ -0,0 +1,93 @@ +/* + * This file is part of the KFTPGrabber project + * + * Copyright (C) 2003-2005 by the KFTPGrabber developers + * Copyright (C) 2003-2005 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 KFTPTHREADVIEW_H +#define KFTPTHREADVIEW_H + +#include <qguardedptr.h> + +#include <kaction.h> +#include <klistview.h> + +#include "kftpsession.h" + +class KToolBar; + +namespace KFTPWidgets { + +class ListView; + +class ThreadViewItem : public QObject, public QListViewItem +{ +Q_OBJECT +public: + ThreadViewItem(KFTPSession::Session *session, QListView *parent); + ThreadViewItem(KFTPSession::Connection *conn, QListViewItem *parent, int id); + + void refresh(); + virtual void paintCell(QPainter *p, const QColorGroup &cg, int column, int width, int alignment); +private: + int m_id; + + QGuardedPtr<KFTPSession::Connection> m_connection; + QGuardedPtr<KFTPSession::Session> m_session; +private slots: + void slotConnectionAcquired(); + void slotUpdateItemRequested(); +}; + +/** + * This widget shows all the currently used threads in KFTPGrabber transfers. + * + * @author Jernej Kos + */ +class ThreadView : public QWidget +{ +Q_OBJECT +public: + ThreadView(QWidget *parent = 0, const char *name = 0); + ~ThreadView(); + + KActionCollection *actionCollection(); + +private slots: + void slotUpdateSessions(); +private: + KFTPWidgets::ListView *m_threads; +}; + +} + +#endif |