summaryrefslogtreecommitdiffstats
path: root/kftpgrabber/src/widgets/queueview/queueview.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'kftpgrabber/src/widgets/queueview/queueview.cpp')
-rw-r--r--kftpgrabber/src/widgets/queueview/queueview.cpp888
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"