From f88a0e7bce90883a7c801a524707f30f36f38044 Mon Sep 17 00:00:00 2001 From: lappelhans Date: Sat, 15 Dec 2007 15:59:46 +0000 Subject: [PATCH] Make filepriorities working... git-svn-id: svn://anonsvn.kde.org/home/kde/trunk/KDE/kdenetwork@748811 283d02a7-25f6-0310-bc7c-ecb5cbfe19da --- kget/transfer-plugins/bittorrent/CMakeLists.txt | 3 + .../bittorrent/btadvanceddetailswidget.cpp | 14 +- .../bittorrent/btadvanceddetailswidget.ui | 6 +- .../transfer-plugins/bittorrent/btfiletreeview.cpp | 158 +++++++++++++ kget/transfer-plugins/bittorrent/btfiletreeview.h | 62 +++++ .../bittorrent/iwfiletreemodel.cpp | 252 +++++++++++++++++++++ kget/transfer-plugins/bittorrent/iwfiletreemodel.h | 63 ++++++ .../bittorrent/torrentfilemodel.cpp | 52 +++++ .../{torrentfiletreemodel.h => torrentfilemodel.h} | 107 ++++----- .../bittorrent/torrentfiletreemodel.cpp | 110 +++++++-- .../bittorrent/torrentfiletreemodel.h | 72 ++---- 11 files changed, 756 insertions(+), 143 deletions(-) create mode 100644 kget/transfer-plugins/bittorrent/btfiletreeview.cpp create mode 100644 kget/transfer-plugins/bittorrent/btfiletreeview.h create mode 100644 kget/transfer-plugins/bittorrent/iwfiletreemodel.cpp create mode 100644 kget/transfer-plugins/bittorrent/iwfiletreemodel.h create mode 100644 kget/transfer-plugins/bittorrent/torrentfilemodel.cpp copy kget/transfer-plugins/bittorrent/{torrentfiletreemodel.h => torrentfilemodel.h} (53%) diff --git a/kget/transfer-plugins/bittorrent/CMakeLists.txt b/kget/transfer-plugins/bittorrent/CMakeLists.txt index 8ce64aed6..87aba7c94 100644 --- a/kget/transfer-plugins/bittorrent/CMakeLists.txt +++ b/kget/transfer-plugins/bittorrent/CMakeLists.txt @@ -21,10 +21,13 @@ set(kget_bittorrentfactory_PART_SRCS btdownload.cpp btspeedlimits.cpp peerview.cpp + iwfiletreemodel.cpp torrentfiletreemodel.cpp + torrentfilemodel.cpp chunkdownloadviewitem.cpp flagdb.cpp GeoIP.c + btfiletreeview.cpp ) kde4_add_ui_files(kget_bittorrentfactory_PART_SRCS btdetailswidgetfrm.ui btsettingswidget.ui btadvanceddetailswidget.ui btspeedlimits.ui) diff --git a/kget/transfer-plugins/bittorrent/btadvanceddetailswidget.cpp b/kget/transfer-plugins/bittorrent/btadvanceddetailswidget.cpp index 1dc2cddec..7719e382d 100644 --- a/kget/transfer-plugins/bittorrent/btadvanceddetailswidget.cpp +++ b/kget/transfer-plugins/bittorrent/btadvanceddetailswidget.cpp @@ -14,7 +14,7 @@ #include #include "bttransferhandler.h" -#include "torrentfiletreemodel.h" +#include "btfiletreeview.h" #include "bittorrentsettings.h" #include @@ -49,6 +49,9 @@ void BTAdvancedDetailsWidget::init() setWindowTitle(i18n("Advanced-Details for %1", m_transfer->source().fileName())); const KUrl::List trackers = tc->getTrackersList()->getTrackerURLs(); + BTFileTreeView *fileTreeView = new BTFileTreeView(tc, tabWidget->widget(0)); + tabWidget->widget(0)->layout()->addWidget(fileTreeView); + if (trackers.empty()) { trackerList->addItem(tc->getTrackersList()->getTrackerURL().prettyUrl()); @@ -60,9 +63,6 @@ void BTAdvancedDetailsWidget::init() } updateTracker(); - kt::TorrentFileTreeModel *fileTree = new kt::TorrentFileTreeModel(tc,kt::TorrentFileTreeModel::DeselectMode(1),this); - fileTreeView->setModel(fileTree); - const bt::TorrentStats & s = tc->getStats(); totalChunksLabel->setText(QString::number(s.total_chunks)); sizeChunkLabel->setText(KGlobal::locale()->formatByteSize(s.chunk_size)); @@ -75,13 +75,13 @@ void BTAdvancedDetailsWidget::init() int j = 0; foreach(int i, fileColumnWidths) { - fileTreeView->setColumnWidth(j, i); + //fileTreeView->setColumnWidth(j, i); j++; } } else { - fileTreeView->setColumnWidth(0 , 250); + //fileTreeView->setColumnWidth(0 , 250); } QList peersColumnWidths = BittorrentSettings::peersColumnWidths(); @@ -263,7 +263,7 @@ void BTAdvancedDetailsWidget::hideEvent(QHideEvent * event) QList fileColumnWidths; for (int i = 0; i<1; i++) { - fileColumnWidths.append(fileTreeView->columnWidth(i)); + //fileColumnWidths.append(fileTreeView->columnWidth(i)); } BittorrentSettings::setFileColumnWidths(fileColumnWidths); diff --git a/kget/transfer-plugins/bittorrent/btadvanceddetailswidget.ui b/kget/transfer-plugins/bittorrent/btadvanceddetailswidget.ui index 542887d8a..cd98b7565 100644 --- a/kget/transfer-plugins/bittorrent/btadvanceddetailswidget.ui +++ b/kget/transfer-plugins/bittorrent/btadvanceddetailswidget.ui @@ -19,11 +19,7 @@ Files - - - - - + diff --git a/kget/transfer-plugins/bittorrent/btfiletreeview.cpp b/kget/transfer-plugins/bittorrent/btfiletreeview.cpp new file mode 100644 index 000000000..e07f2d7e4 --- /dev/null +++ b/kget/transfer-plugins/bittorrent/btfiletreeview.cpp @@ -0,0 +1,158 @@ +/* This file is part of the KDE project + + Copyright (C) 2007 Lukas Appelhans + + 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. +*/ +#include "btfiletreeview.h" + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +using namespace bt; + +BTFileTreeView::BTFileTreeView(bt::TorrentInterface *tc, QWidget * parent) + : QTreeView(parent), + m_tc(tc) +{ + fileTreeModel = new kt::IWFileTreeModel(tc, this); + setModel(fileTreeModel); + + contextMenu = new KMenu(this); + open_action = contextMenu->addAction(KIcon("document-open"),i18n("Open"),this,SLOT(open())); + contextMenu->addSeparator(); + download_first_action = contextMenu->addAction(i18n("Download first"),this,SLOT(downloadFirst())); + download_normal_action = contextMenu->addAction(i18n("Download normally"),this,SLOT(downloadNormal())); + download_last_action = contextMenu->addAction(i18n("Download last"),this,SLOT(downloadLast())); + contextMenu->addSeparator(); + dnd_action = contextMenu->addAction(i18n("Do Not Download"),this,SLOT(doNotDownload())); + delete_action = contextMenu->addAction(i18n("Delete File(s)"),this,SLOT(deleteFiles())); + + //connect(this, SIGNAL(customContextMenuRequested(const QPoint & )), this, SLOT(showContextMenu(const QPoint& ))); +} + +void BTFileTreeView::contextMenuEvent(QContextMenuEvent * e) +{ + kDebug(5001); + const TorrentStats & s = m_tc->getStats(); + + QModelIndexList sel = selectionModel()->selectedRows(); + if (sel.count() == 0) + return; + + if (sel.count() > 1) + { + download_first_action->setEnabled(true); + download_normal_action->setEnabled(true); + download_last_action->setEnabled(true); + open_action->setEnabled(false); + dnd_action->setEnabled(true); + delete_action->setEnabled(true); + contextMenu->popup(QCursor::pos()); + return; + } + + QModelIndex item = sel.front(); + bt::TorrentFileInterface* file = fileTreeModel->indexToFile(item); + + download_first_action->setEnabled(false); + download_last_action->setEnabled(false); + download_normal_action->setEnabled(false); + dnd_action->setEnabled(false); + delete_action->setEnabled(false); + + if (!s.multi_file_torrent) + { + open_action->setEnabled(true); + preview_path = m_tc->getStats().output_path; + } + else if (file) + { + if (!file->isNull()) + { + open_action->setEnabled(true); + preview_path = file->getPathOnDisk(); + + download_first_action->setEnabled(file->getPriority() != FIRST_PRIORITY); + download_normal_action->setEnabled(file->getPriority() != NORMAL_PRIORITY); + download_last_action->setEnabled(file->getPriority() != LAST_PRIORITY); + dnd_action->setEnabled(file->getPriority() != ONLY_SEED_PRIORITY); + delete_action->setEnabled(file->getPriority() != EXCLUDED); + } + else + { + open_action->setEnabled(false); + } + } + else + { + download_first_action->setEnabled(true); + download_normal_action->setEnabled(true); + download_last_action->setEnabled(true); + dnd_action->setEnabled(true); + delete_action->setEnabled(true); + open_action->setEnabled(true); + preview_path = m_tc->getDataDir() + fileTreeModel->dirPath(item); + } + + contextMenu->popup(QCursor::pos()); +} + +void BTFileTreeView::open() +{ + new KRun(KUrl(preview_path), 0, false, true); +} + +void BTFileTreeView::changePriority(bt::Priority newpriority) +{ + fileTreeModel->changePriority(selectionModel()->selectedRows(2),newpriority); +} + +void BTFileTreeView::downloadFirst() +{ + changePriority(FIRST_PRIORITY); +} + +void BTFileTreeView::downloadLast() +{ + changePriority(LAST_PRIORITY); +} + +void BTFileTreeView::downloadNormal() +{ + changePriority(NORMAL_PRIORITY); +} + +void BTFileTreeView::doNotDownload() +{ + changePriority(ONLY_SEED_PRIORITY); +} + +void BTFileTreeView::deleteFiles() +{ + QModelIndexList sel = selectionModel()->selectedRows(); + Uint32 n = sel.count(); + if (n == 1) // single item can be a directory + { + if (!fileTreeModel->indexToFile(sel.front())) + n++; + } + + QString msg = n > 1 ? i18n("You will lose all data in this file, are you sure you want to do this ?") : + i18n("You will lose all data in these files, are you sure you want to do this ?"); + + if (KMessageBox::warningYesNo(0,msg) == KMessageBox::Yes) + changePriority(EXCLUDED); +} \ No newline at end of file diff --git a/kget/transfer-plugins/bittorrent/btfiletreeview.h b/kget/transfer-plugins/bittorrent/btfiletreeview.h new file mode 100644 index 000000000..63bc2f93c --- /dev/null +++ b/kget/transfer-plugins/bittorrent/btfiletreeview.h @@ -0,0 +1,62 @@ +/* This file is part of the KDE project + + Copyright (C) 2007 Lukas Appelhans + + 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. +*/ + +#ifndef BTFILETREEVIEW_H +#define BTFILETREEVIEW_H + +#include "iwfiletreemodel.h" + +#include + +#include + + +class KMenu; + +namespace bt +{ + class TorrentInterface; + class TorrentControl; +} + +class BTFileTreeView : public QTreeView +{ + Q_OBJECT + public: + BTFileTreeView(bt::TorrentInterface *tc, QWidget * parent); + + private slots: + void contextMenuEvent(QContextMenuEvent * e); + void open(); + void downloadFirst(); + void downloadLast(); + void downloadNormal(); + void doNotDownload(); + void deleteFiles(); + + private: + void changePriority(bt::Priority newpriority); + + kt::IWFileTreeModel *fileTreeModel; + bt::TorrentInterface *m_tc; + + KMenu *contextMenu; + + QAction* open_action; + QAction* download_first_action; + QAction* download_normal_action; + QAction* download_last_action; + QAction* dnd_action; + QAction* delete_action; + + QString preview_path; +}; + +#endif diff --git a/kget/transfer-plugins/bittorrent/iwfiletreemodel.cpp b/kget/transfer-plugins/bittorrent/iwfiletreemodel.cpp new file mode 100644 index 000000000..eb6b9fe3d --- /dev/null +++ b/kget/transfer-plugins/bittorrent/iwfiletreemodel.cpp @@ -0,0 +1,252 @@ +/*************************************************************************** + * Copyright (C) 2007 by Joris Guisson and Ivan Vasic * + * joris.guisson@gmail.com * + * ivasic@gmail.com * + * * + * 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 WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 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 Street, Fifth Floor, Boston, MA 02110-1301, USA. * + ***************************************************************************/ +#include +#include +#include +#include +#include +#include +#include "iwfiletreemodel.h" + +using namespace bt; + +namespace kt +{ + + IWFileTreeModel::IWFileTreeModel(bt::TorrentInterface* tc,QObject* parent) + : TorrentFileTreeModel(tc,KEEP_FILES,parent) + { + mmfile = IsMultimediaFile(tc->getStats().output_path); + preview = false; + percentage = 0; + for (Uint32 i = 0;i < tc->getNumFiles();i++) + { + bt::TorrentFileInterface & file = tc->getTorrentFile(i); + connect(&file,SIGNAL(downloadPercentageChanged( float )),this,SLOT(onPercentageUpdated( float ))); + connect(&file,SIGNAL(previewAvailable( bool )),this,SLOT(onPreviewAvailable( bool ))); + } + } + + + IWFileTreeModel::~IWFileTreeModel() + { + } + + int IWFileTreeModel::columnCount(const QModelIndex & /*parent*/) const + { + return 5; + } + + QVariant IWFileTreeModel::headerData(int section, Qt::Orientation orientation,int role) const + { + if (role != Qt::DisplayRole || orientation != Qt::Horizontal) + return QVariant(); + + if (section < 2) + return TorrentFileTreeModel::headerData(section,orientation,role); + + switch (section) + { + case 2: return i18n("Priority"); + case 3: return i18n("Preview"); + case 4: return i18n("% Complete"); + default: return QVariant(); + } + } + + static QString PriorityString(const bt::TorrentFileInterface* file) + { + switch(file->getPriority()) + { + case FIRST_PRIORITY: return i18n("First"); + case LAST_PRIORITY: return i18n("Last"); + case ONLY_SEED_PRIORITY: + case EXCLUDED: + case PREVIEW_PRIORITY: + return QString::null; + default:return i18n("Normal"); + } + } + + QVariant IWFileTreeModel::data(const QModelIndex & index, int role) const + { + Node* n = 0; + if (index.column() < 2) + return TorrentFileTreeModel::data(index,role); + + if (!index.isValid() || !(n = (Node*)index.internalPointer())) + return QVariant(); + + if (role != Qt::DisplayRole) + return QVariant(); + + if (tc->getStats().multi_file_torrent && n->file) + { + const bt::TorrentFileInterface* file = n->file; + switch (index.column()) + { + case 2: return PriorityString(file); + case 3: + if (file->isMultimedia()) + { + if (tc->readyForPreview(file->getFirstChunk(), file->getFirstChunk()+1) ) + return i18n("Available"); + else + return i18n("Pending"); + } + else + return i18n("No"); + case 4: + { + float percent = file->getDownloadPercentage(); + KLocale* loc = KGlobal::locale(); + return i18n("%1 %",loc->formatNumber(percent,2)); + } + default: return QVariant(); + } + } + else if (!tc->getStats().multi_file_torrent) + { + switch (index.column()) + { + case 2: return QVariant(); + case 3: + if (mmfile) + { + if (tc->readyForPreview(0,1)) + return i18n("Available"); + else + return i18n("Pending"); + } + else + return i18n("No"); + case 4: + { + double percent = bt::Percentage(tc->getStats()); + KLocale* loc = KGlobal::locale(); + return i18n("%1 %",loc->formatNumber(percent,2)); + } + default: return QVariant(); + } + } + + return QVariant(); + } + + + + bool IWFileTreeModel::setData(const QModelIndex & index, const QVariant & value, int role) + { + if (role == Qt::CheckStateRole) + return TorrentFileTreeModel::setData(index,value,role); + + if (!index.isValid() || role != Qt::UserRole) + return false; + + Node* n = static_cast(index.internalPointer()); + if (!n) + return false; + + if (!n->file) + { + for (Uint32 i = 0;i < n->children.count();i++) + { + // recurse down the tree + setData(index.child(i,0),value,role); + } + } + else + { + bt::TorrentFileInterface* file = n->file; + Priority prio = (bt::Priority)value.toInt(); + Priority old = file->getPriority(); + + if (prio != old) + { + file->setPriority(prio); + dataChanged(createIndex(index.row(),0),createIndex(index.row(),4)); + QModelIndex parent = index.parent(); + if (parent.isValid()) + dataChanged(parent,parent); // parent needs to be updated to + } + } + + return true; + } + + + + void IWFileTreeModel::onPercentageUpdated(float /*p*/) + { + bt::TorrentFileInterface* file = (bt::TorrentFileInterface*)sender(); + update(index(0,0,QModelIndex()),file,4); + } + + void IWFileTreeModel::onPreviewAvailable(bool /*av*/) + { + bt::TorrentFileInterface* file = (bt::TorrentFileInterface*)sender(); + update(index(0,0,QModelIndex()),file,3); + } + + void IWFileTreeModel::update(const QModelIndex & idx,bt::TorrentFileInterface* file,int col) + { + Node* n = (Node*)idx.internalPointer(); + if (n->file && n->file == file) + { + QModelIndex i = createIndex(idx.row(),col,n); + emit dataChanged(i,i); + } + else + { + for (Uint32 i = 0;i < n->children.count();i++) + { + // recurse down the tree + update(idx.child(i,0),file,col); + } + } + } + + void IWFileTreeModel::update() + { + if (!tc->getStats().multi_file_torrent) + { + bool changed = false; + bool np = mmfile && tc->readyForPreview(0,1); + if (preview != np) + { + preview = np; + changed = true; + } + + double perc = bt::Percentage(tc->getStats()); + if (fabs(perc - percentage) > 0.01) + { + percentage = perc; + changed = true; + } + + if (changed) + dataChanged(createIndex(0,0),createIndex(0,4)); + } + } +} + +#include "iwfiletreemodel.moc" diff --git a/kget/transfer-plugins/bittorrent/iwfiletreemodel.h b/kget/transfer-plugins/bittorrent/iwfiletreemodel.h new file mode 100644 index 000000000..43bddd9c2 --- /dev/null +++ b/kget/transfer-plugins/bittorrent/iwfiletreemodel.h @@ -0,0 +1,63 @@ +/*************************************************************************** + * Copyright (C) 2007 by Joris Guisson and Ivan Vasic * + * joris.guisson@gmail.com * + * ivasic@gmail.com * + * * + * 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 WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 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 Street, Fifth Floor, Boston, MA 02110-1301, USA. * + ***************************************************************************/ +#ifndef KTIWFILETREEMODEL_H +#define KTIWFILETREEMODEL_H + +#include + +namespace kt +{ + + /** + * + * @author Joris Guisson + * + * Expands the standard TorrentFileTreeModel to show more information. + */ + class IWFileTreeModel : public TorrentFileTreeModel + { + Q_OBJECT + public: + IWFileTreeModel(bt::TorrentInterface* tc,QObject* parent); + virtual ~IWFileTreeModel(); + + virtual int columnCount(const QModelIndex & parent) const; + virtual QVariant headerData(int section, Qt::Orientation orientation,int role) const; + virtual QVariant data(const QModelIndex & index, int role) const; + virtual bool setData(const QModelIndex & index, const QVariant & value, int role); + virtual void update(); + + private slots: + void onPercentageUpdated(float p); + void onPreviewAvailable(bool av); + + private: + void update(const QModelIndex & index,bt::TorrentFileInterface* file,int col); + + private: + bool preview; + bool mmfile; + double percentage; + }; + +} + +#endif diff --git a/kget/transfer-plugins/bittorrent/torrentfilemodel.cpp b/kget/transfer-plugins/bittorrent/torrentfilemodel.cpp new file mode 100644 index 000000000..8f6111ab7 --- /dev/null +++ b/kget/transfer-plugins/bittorrent/torrentfilemodel.cpp @@ -0,0 +1,52 @@ +/*************************************************************************** + * Copyright (C) 2007 by Joris Guisson and Ivan Vasic * + * joris.guisson@gmail.com * + * ivasic@gmail.com * + * * + * 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 WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 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 Street, Fifth Floor, Boston, MA 02110-1301, USA. * + ***************************************************************************/ +#include +#include +#include "torrentfilemodel.h" + +namespace kt +{ + TorrentFileModel::TorrentFileModel(bt::TorrentInterface* tc,DeselectMode mode,QObject* parent) + : QAbstractItemModel(parent),tc(tc),mode(mode) + {} + + TorrentFileModel::~TorrentFileModel() + {} + + QByteArray TorrentFileModel::saveExpandedState(QTreeView* ) + { + return QByteArray(); + } + + void TorrentFileModel::loadExpandedState(QTreeView* ,const QByteArray &) + {} + + void TorrentFileModel::missingFilesMarkedDND() + { + reset(); + } + + void TorrentFileModel::update() + {} + +} + +#include "torrentfilemodel.moc" diff --git a/kget/transfer-plugins/bittorrent/torrentfiletreemodel.h b/kget/transfer-plugins/bittorrent/torrentfilemodel.h similarity index 53% copy from kget/transfer-plugins/bittorrent/torrentfiletreemodel.h copy to kget/transfer-plugins/bittorrent/torrentfilemodel.h index 505933c03..c322cc615 100644 --- a/kget/transfer-plugins/bittorrent/torrentfiletreemodel.h +++ b/kget/transfer-plugins/bittorrent/torrentfilemodel.h @@ -18,9 +18,10 @@ * Free Software Foundation, Inc., * * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. * ***************************************************************************/ -#ifndef KTTORRENTFILETREEMODEL_H -#define KTTORRENTFILETREEMODEL_H +#ifndef KTTORRENTFILEMODEL_HH +#define KTTORRENTFILEMODEL_HH +#include #include #include @@ -34,12 +35,7 @@ namespace bt namespace kt { - - /** - * Model for displaying file trees of a torrent - * @author Joris Guisson - */ - class TorrentFileTreeModel : public QAbstractItemModel + class TorrentFileModel : public QAbstractItemModel { Q_OBJECT public: @@ -47,92 +43,85 @@ namespace kt { KEEP_FILES,DELETE_FILES }; - - TorrentFileTreeModel(bt::TorrentInterface* tc,DeselectMode mode,QObject* parent); - virtual ~TorrentFileTreeModel(); - - virtual int rowCount(const QModelIndex & parent) const; - virtual int columnCount(const QModelIndex & parent) const; - virtual QVariant headerData(int section, Qt::Orientation orientation,int role) const; - virtual QVariant data(const QModelIndex & index, int role) const; - virtual QModelIndex parent(const QModelIndex & index) const; - virtual QModelIndex index(int row,int column,const QModelIndex & parent) const; - virtual Qt::ItemFlags flags(const QModelIndex & index) const; - virtual bool setData(const QModelIndex & index, const QVariant & value, int role); + TorrentFileModel(bt::TorrentInterface* tc,DeselectMode mode,QObject* parent); + virtual ~TorrentFileModel(); + /** * Check all the files in the torrent. */ - void checkAll(); + virtual void checkAll() = 0; /** * Uncheck all files in the torrent. */ - void uncheckAll(); + virtual void uncheckAll() = 0; /** * Invert the check of each file of the torrent */ - void invertCheck(); + virtual void invertCheck() = 0; /** * Calculate the number of bytes to download * @return Bytes to download */ - bt::Uint64 bytesToDownload(); + virtual bt::Uint64 bytesToDownload() = 0; /** * Save which items are expanded. * @param tv The QTreeView + * @return The expanded state encoded in a byte array */ - void saveExpandedState(QTreeView* tv); + virtual QByteArray saveExpandedState(QTreeView* tv); /** - * Retore the expaned state of the tree.in a QTreeView + * Retore the expanded state of the tree.in a QTreeView * @param tv The QTreeView + * @param state The encoded expanded state */ - void loadExpandedState(QTreeView* tv); - - signals: + virtual void loadExpandedState(QTreeView* tv,const QByteArray & state); + + /** + * Convert a model index to a file. + * @param idx The model index + * @return The file index or 0 for a directory + **/ + virtual bt::TorrentFileInterface* indexToFile(const QModelIndex & idx) = 0; + + /** + * Get the path of a directory (root directory not included) + * @param idx The model index + * @return The path + */ + virtual QString dirPath(const QModelIndex & idx) = 0; + + /** + * Change the priority of a bunch of items. + * @param indexes The list of items + * @param newpriority The new priority + */ + virtual void changePriority(const QModelIndexList & indexes,bt::Priority newpriority) = 0; + + /** + * Missing files have been marked DND, update the preview and selection information. + */ + virtual void missingFilesMarkedDND(); + + /** + * Update gui if necessary + */ + virtual void update(); + signals: /** * Emitted whenever one or more items changes check state */ void checkStateChanged(); - - private: - void constructTree(); - void invertCheck(const QModelIndex & idx); protected: - struct Node - { - Node* parent; - bt::TorrentFileInterface* file; // file (0 if this is a directory) - QString name; // name or directory - QList children; // child dirs - bt::Uint64 size; - bool expanded; - - Node(Node* parent,bt::TorrentFileInterface* file,const QString & name); - Node(Node* parent,const QString & name); - ~Node(); - - void insert(const QString & path,bt::TorrentFileInterface* file); - int row(); - bt::Uint64 fileSize(const bt::TorrentInterface* tc); - bt::Uint64 bytesToDownload(const bt::TorrentInterface* tc); - Qt::CheckState checkState(const bt::TorrentInterface* tc) const; - - void saveExpandedState(const QModelIndex & index,QTreeView* tv); - void loadExpandedState(const QModelIndex & index,QTreeView* tv); - }; - bt::TorrentInterface* tc; - Node* root; DeselectMode mode; - bool emit_check_state_change; }; - } #endif diff --git a/kget/transfer-plugins/bittorrent/torrentfiletreemodel.cpp b/kget/transfer-plugins/bittorrent/torrentfiletreemodel.cpp index 5693f0ae8..104e921ca 100644 --- a/kget/transfer-plugins/bittorrent/torrentfiletreemodel.cpp +++ b/kget/transfer-plugins/bittorrent/torrentfiletreemodel.cpp @@ -22,9 +22,13 @@ #include #include #include +#include +#include +#include #include #include #include +#include #include "torrentfiletreemodel.h" using namespace bt; @@ -33,11 +37,11 @@ namespace kt { TorrentFileTreeModel::Node::Node(Node* parent,bt::TorrentFileInterface* file,const QString & name) - : parent(parent),file(file),name(name),size(0),expanded(true) + : parent(parent),file(file),name(name),size(0) {} TorrentFileTreeModel::Node::Node(Node* parent,const QString & name) - : parent(parent),file(0),name(name),size(0),expanded(true) + : parent(parent),file(0),name(name),size(0) { } @@ -145,40 +149,56 @@ namespace kt } } - void TorrentFileTreeModel::Node::saveExpandedState(const QModelIndex & index,QTreeView* tv) + void TorrentFileTreeModel::Node::saveExpandedState(const QModelIndex & index,QTreeView* tv,BEncoder* enc) { if (file) return; - expanded = tv->isExpanded(index); + enc->write("expanded"); + enc->write((Uint32)(tv->isExpanded(index) ? 1 : 0)); int idx = 0; foreach (Node* n,children) { if (!n->file) - n->saveExpandedState(index.child(idx,0),tv); + { + enc->write(n->name); + enc->beginDict(); + n->saveExpandedState(index.child(idx,0),tv,enc); + enc->end(); + } idx++; } } - void TorrentFileTreeModel::Node::loadExpandedState(const QModelIndex & index,QTreeView* tv) + void TorrentFileTreeModel::Node::loadExpandedState(const QModelIndex & index,QTreeView* tv,BNode* n) { if (file) return; - tv->setExpanded(index,expanded); + BDictNode* dict = dynamic_cast(n); + if (!dict) + return; + + BValueNode* v = dict->getValue("expanded"); + if (v) + tv->setExpanded(index,v->data().toInt() == 1); int idx = 0; foreach (Node* n,children) { if (!n->file) - n->loadExpandedState(index.child(idx,0),tv); + { + BDictNode* d = dict->getDict(n->name); + if (d) + n->loadExpandedState(index.child(idx,0),tv,d); + } idx++; } } TorrentFileTreeModel::TorrentFileTreeModel(bt::TorrentInterface* tc,DeselectMode mode,QObject* parent) - : QAbstractItemModel(parent),tc(tc),root(0),mode(mode),emit_check_state_change(true) + : TorrentFileModel(tc,mode,parent),root(0),emit_check_state_change(true) { if (tc->getStats().multi_file_torrent) constructTree(); @@ -431,17 +451,77 @@ namespace kt return tc->getStats().total_bytes; } - void TorrentFileTreeModel::saveExpandedState(QTreeView* tv) + QByteArray TorrentFileTreeModel::saveExpandedState(QTreeView* tv) { - if (tc->getStats().multi_file_torrent) - root->saveExpandedState(index(0,0,QModelIndex()),tv); + if (!tc->getStats().multi_file_torrent) + return QByteArray(); + + QByteArray data; + BEncoder enc(new BEncoderBufferOutput(data)); + enc.beginDict(); + root->saveExpandedState(index(0,0,QModelIndex()),tv,&enc); + enc.end(); + return data; } - void TorrentFileTreeModel::loadExpandedState(QTreeView* tv) + void TorrentFileTreeModel::loadExpandedState(QTreeView* tv,const QByteArray & state) { - if (tc->getStats().multi_file_torrent) - root->loadExpandedState(index(0,0,QModelIndex()),tv); + if (!tc->getStats().multi_file_torrent) + return; + + BDecoder dec(state,false,0); + BNode* n = dec.decode(); + if (n && n->getType() == BNode::DICT) + { + n->printDebugInfo(); + root->loadExpandedState(index(0,0,QModelIndex()),tv,n); + } + delete n; + } + + bt::TorrentFileInterface* TorrentFileTreeModel::indexToFile(const QModelIndex & idx) + { + if (!idx.isValid()) + return 0; + + Node* n = (Node*)idx.internalPointer(); + if (!n) + return 0; + + return n->file; + } + + QString TorrentFileTreeModel::dirPath(const QModelIndex & idx) + { + if (!idx.isValid()) + return QString::null; + + Node* n = (Node*)idx.internalPointer(); + if (!n || n == root) + return QString::null; + + QString ret = n->name; + do + { + n = n->parent; + if (n && n->parent) + ret = n->name + bt::DirSeparator() + ret; + }while (n); + + return ret; + } + + void TorrentFileTreeModel::changePriority(const QModelIndexList & indexes,bt::Priority newpriority) + { + foreach (QModelIndex idx,indexes) + { + Node* n = (Node*)idx.internalPointer(); + if (!n) + continue; + + setData(idx,newpriority,Qt::UserRole); + } } } diff --git a/kget/transfer-plugins/bittorrent/torrentfiletreemodel.h b/kget/transfer-plugins/bittorrent/torrentfiletreemodel.h index 505933c03..d41843fbe 100644 --- a/kget/transfer-plugins/bittorrent/torrentfiletreemodel.h +++ b/kget/transfer-plugins/bittorrent/torrentfiletreemodel.h @@ -21,15 +21,12 @@ #ifndef KTTORRENTFILETREEMODEL_H #define KTTORRENTFILETREEMODEL_H -#include -#include - -class QTreeView; +#include "torrentfilemodel.h" namespace bt { - class TorrentInterface; - class TorrentFileInterface; + class BEncoder; + class BNode; } namespace kt @@ -39,15 +36,10 @@ namespace kt * Model for displaying file trees of a torrent * @author Joris Guisson */ - class TorrentFileTreeModel : public QAbstractItemModel + class TorrentFileTreeModel : public TorrentFileModel { Q_OBJECT public: - enum DeselectMode - { - KEEP_FILES,DELETE_FILES - }; - TorrentFileTreeModel(bt::TorrentInterface* tc,DeselectMode mode,QObject* parent); virtual ~TorrentFileTreeModel(); @@ -59,46 +51,15 @@ namespace kt virtual QModelIndex index(int row,int column,const QModelIndex & parent) const; virtual Qt::ItemFlags flags(const QModelIndex & index) const; virtual bool setData(const QModelIndex & index, const QVariant & value, int role); - - /** - * Check all the files in the torrent. - */ - void checkAll(); - - /** - * Uncheck all files in the torrent. - */ - void uncheckAll(); - - /** - * Invert the check of each file of the torrent - */ - void invertCheck(); - - /** - * Calculate the number of bytes to download - * @return Bytes to download - */ - bt::Uint64 bytesToDownload(); - - /** - * Save which items are expanded. - * @param tv The QTreeView - */ - void saveExpandedState(QTreeView* tv); - - /** - * Retore the expaned state of the tree.in a QTreeView - * @param tv The QTreeView - */ - void loadExpandedState(QTreeView* tv); - - signals: - /** - * Emitted whenever one or more items changes check state - */ - void checkStateChanged(); - + virtual void checkAll(); + virtual void uncheckAll(); + virtual void invertCheck(); + virtual bt::Uint64 bytesToDownload(); + virtual QByteArray saveExpandedState(QTreeView* tv); + virtual void loadExpandedState(QTreeView* tv,const QByteArray & state); + virtual bt::TorrentFileInterface* indexToFile(const QModelIndex & idx); + virtual QString dirPath(const QModelIndex & idx); + virtual void changePriority(const QModelIndexList & indexes,bt::Priority newpriority); private: void constructTree(); void invertCheck(const QModelIndex & idx); @@ -111,7 +72,6 @@ namespace kt QString name; // name or directory QList children; // child dirs bt::Uint64 size; - bool expanded; Node(Node* parent,bt::TorrentFileInterface* file,const QString & name); Node(Node* parent,const QString & name); @@ -123,13 +83,11 @@ namespace kt bt::Uint64 bytesToDownload(const bt::TorrentInterface* tc); Qt::CheckState checkState(const bt::TorrentInterface* tc) const; - void saveExpandedState(const QModelIndex & index,QTreeView* tv); - void loadExpandedState(const QModelIndex & index,QTreeView* tv); + void saveExpandedState(const QModelIndex & index,QTreeView* tv,bt::BEncoder* enc); + void loadExpandedState(const QModelIndex & index,QTreeView* tv,bt::BNode* node); }; - bt::TorrentInterface* tc; Node* root; - DeselectMode mode; bool emit_check_state_change; }; -- 2.11.4.GIT