diff options
Diffstat (limited to 'kftpgrabber/src/widgets/queueview/queueview.cpp')
-rw-r--r-- | kftpgrabber/src/widgets/queueview/queueview.cpp | 888 |
1 files changed, 888 insertions, 0 deletions
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" |