From 9586f0e61cff695eba6659f5001b360a1c70c0b1 Mon Sep 17 00:00:00 2001 From: Christophe Dumez Date: Sat, 19 Dec 2009 18:55:04 +0000 Subject: [PATCH] - Use checkboxes for selective downloading instead of comboboxes --- Changelog | 1 + src/propertieswidget.cpp | 63 +--------------- src/propertieswidget.h | 8 --- src/proplistdelegate.h | 135 +---------------------------------- src/torrentadditiondlg.h | 53 -------------- src/torrentfilesmodel.h | 72 ++++++++++++------- src/ui/torrentadditiondlg.ui | 20 ------ 7 files changed, 52 insertions(+), 300 deletions(-) diff --git a/Changelog b/Changelog index 7387497ac..36d650b20 100644 --- a/Changelog +++ b/Changelog @@ -5,6 +5,7 @@ - FEATURE: Peer Exchange (PeX) can be disabled from preferences - FEATURE: Append !.qB extension to incomplete files option (libtorrent >= v0.15 only) - FEATURE: Torrent files/folders can be renamed + - COSMETIC: Use checkboxes to filter torrent content instead of comboboxes * Thu Dec 10 2009 - Christophe Dumez - v2.0.0 - FEATURE: Added program option to disable splash screen diff --git a/src/propertieswidget.cpp b/src/propertieswidget.cpp index 9be78f02b..4f4a8767f 100644 --- a/src/propertieswidget.cpp +++ b/src/propertieswidget.cpp @@ -78,21 +78,12 @@ PropertiesWidget::PropertiesWidget(QWidget *parent, GUI* main_window, TransferLi PropDelegate = new PropListDelegate(this); filesList->setItemDelegate(PropDelegate); - // QActions - actionIgnored = new QAction(tr("Ignored"), this); - actionNormal = new QAction(tr("Normal"), this); - actionMaximum = new QAction(tr("Maximum"), this); - actionHigh = new QAction(tr("High"), this); - // SIGNAL/SLOTS connect(filesList, SIGNAL(clicked(const QModelIndex&)), filesList, SLOT(edit(const QModelIndex&))); connect(collapseAllButton, SIGNAL(clicked()), filesList, SLOT(collapseAll())); connect(expandAllButton, SIGNAL(clicked()), filesList, SLOT(expandAll())); connect(filesList, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(displayFilesListMenu(const QPoint&))); - connect(actionIgnored, SIGNAL(triggered()), this, SLOT(ignoreSelection())); - connect(actionNormal, SIGNAL(triggered()), this, SLOT(normalSelection())); - connect(actionHigh, SIGNAL(triggered()), this, SLOT(highSelection())); - connect(actionMaximum, SIGNAL(triggered()), this, SLOT(maximumSelection())); + connect(PropListModel, SIGNAL(filteredFilesChanged()), this, SLOT(filteredFilesChanged())); connect(addWS_button, SIGNAL(clicked()), this, SLOT(askWebSeed())); connect(deleteWS_button, SIGNAL(clicked()), this, SLOT(deleteSelectedUrlSeeds())); connect(transferList, SIGNAL(currentTorrentChanged(QTorrentHandle&)), this, SLOT(loadTorrentInfos(QTorrentHandle &))); @@ -126,11 +117,6 @@ PropertiesWidget::~PropertiesWidget() { delete pieces_availability; delete PropListModel; delete PropDelegate; - // Delete QActions - delete actionIgnored; - delete actionNormal; - delete actionMaximum; - delete actionHigh; } @@ -482,12 +468,9 @@ void PropertiesWidget::displayFilesListMenu(const QPoint&){ if(selectedRows.size() == 1) { actRename = myFilesLlistMenu.addAction(QIcon(QString::fromUtf8(":/Icons/oxygen/edit_clear.png")), tr("Rename...")); myFilesLlistMenu.addSeparator(); + } else { + return; } - QMenu *prioritiesMenu = myFilesLlistMenu.addMenu(QIcon(":/Icons/oxygen/services.png"), tr("Set priority")); - prioritiesMenu->addAction(actionIgnored); - prioritiesMenu->addAction(actionNormal); - prioritiesMenu->addAction(actionHigh); - prioritiesMenu->addAction(actionMaximum); // Call menu QAction *act = myFilesLlistMenu.exec(QCursor::pos()); if(act) { @@ -592,46 +575,6 @@ void PropertiesWidget::renameSelectedFile() { } } - void PropertiesWidget::ignoreSelection(){ - QModelIndexList selectedIndexes = filesList->selectionModel()->selectedRows(PRIORITY); - foreach(const QModelIndex &index, selectedIndexes){ - if(PropListModel->data(index) != QVariant(IGNORED)){ - PropListModel->setData(index, QVariant(IGNORED)); - filteredFilesChanged(); - } - } - } - - void PropertiesWidget::normalSelection(){ - QModelIndexList selectedIndexes = filesList->selectionModel()->selectedRows(PRIORITY); - foreach(const QModelIndex &index, selectedIndexes){ - if(PropListModel->data(index) != QVariant(NORMAL)){ - PropListModel->setData(index, QVariant(NORMAL)); - filteredFilesChanged(); - } - } - } - - void PropertiesWidget::highSelection(){ - QModelIndexList selectedIndexes = filesList->selectionModel()->selectedRows(PRIORITY); - foreach(const QModelIndex &index, selectedIndexes){ - if(PropListModel->data(index) != QVariant(HIGH)){ - PropListModel->setData(index, QVariant(HIGH)); - filteredFilesChanged(); - } - } - } - - void PropertiesWidget::maximumSelection(){ - QModelIndexList selectedIndexes = filesList->selectionModel()->selectedRows(PRIORITY); - foreach(const QModelIndex &index, selectedIndexes){ - if(PropListModel->data(index) != QVariant(MAXIMUM)){ - PropListModel->setData(index, QVariant(MAXIMUM)); - filteredFilesChanged(); - } - } - } - void PropertiesWidget::askWebSeed(){ bool ok; // Ask user for a new url seed diff --git a/src/propertieswidget.h b/src/propertieswidget.h index 2c1434db4..f8e987953 100644 --- a/src/propertieswidget.h +++ b/src/propertieswidget.h @@ -66,10 +66,6 @@ private: PropListDelegate *PropDelegate; PeerListWidget *peersList; TrackerList *trackerList; - QAction *actionIgnored; - QAction *actionNormal; - QAction *actionMaximum; - QAction *actionHigh; QList slideSizes; DownloadedPiecesBar *downloaded_pieces; PieceAvailabilityBar *pieces_availability; @@ -86,10 +82,6 @@ protected slots: void on_peers_button_clicked(); void on_url_seeds_button_clicked(); void on_files_button_clicked(); - void ignoreSelection(); - void normalSelection(); - void highSelection(); - void maximumSelection(); void askWebSeed(); void deleteSelectedUrlSeeds(); void displayFilesListMenu(const QPoint& pos); diff --git a/src/proplistdelegate.h b/src/proplistdelegate.h index 02f057047..7dc038b2e 100644 --- a/src/proplistdelegate.h +++ b/src/proplistdelegate.h @@ -44,8 +44,7 @@ #include "propertieswidget.h" // Defines for properties list columns -enum PropColumn {NAME, SIZE, PROGRESS, PRIORITY}; -enum PropPriority {IGNORED=0, NORMAL=1, HIGH=2, MAXIMUM=7}; +enum PropColumn {NAME, SIZE, PROGRESS}; class PropListDelegate: public QItemDelegate { Q_OBJECT @@ -82,81 +81,11 @@ public: QApplication::style()->drawControl(QStyle::CE_ProgressBar, &newopt, painter); break; } - case PRIORITY:{ - QStyleOptionComboBox newopt; - newopt.rect = opt.rect; - switch(index.data().toInt()){ - case IGNORED: - newopt.currentText = tr("Ignored"); - break; - case NORMAL: - newopt.currentText = tr("Normal", "Normal (priority)"); - break; - case HIGH: - newopt.currentText = tr("High", "High (priority)"); - break; - case MAXIMUM: - newopt.currentText = tr("Maximum", "Maximum (priority)"); - break; - default: - qDebug("Unhandled priority, setting NORMAL"); - newopt.currentText = tr("Normal", "Normal (priority)"); - } - //newopt.state |= QStyle::State_Enabled; - //newopt.subControls = QStyle::SC_All; - //painter->translate(QPoint(opt.rect.x()*-1,opt.rect.y()*-1)); - //QApplication::style()->drawComplexControl(QStyle::CC_ComboBox, &newopt, painter); - //painter->translate(QPoint(opt.rect.x(),opt.rect.y())); - //QApplication::style()->drawControl(QStyle::CE_ComboBoxLabel, &newopt, painter); - QItemDelegate::drawBackground(painter, opt, index); - QItemDelegate::drawDisplay(painter, opt, option.rect, newopt.currentText); - break; - } default: QItemDelegate::paint(painter, option, index); } } - QWidget* createEditor(QWidget *parent, const QStyleOptionViewItem &/* option */, const QModelIndex & index) const { - qDebug("CreateEditor called"); - if(index.column() != PRIORITY) return 0; - if(properties) { - QTorrentHandle h = properties->getCurrentTorrent(); - if(!h.is_valid() || h.get_torrent_handle().is_seed() || !h.has_metadata()) return 0; - } - QComboBox* editor = new QComboBox(parent); - editor->setFocusPolicy(Qt::StrongFocus); - editor->addItem(tr("Ignored")); - editor->addItem(tr("Normal", "Normal (priority)")); - editor->addItem(tr("High", "High (priority)")); - editor->addItem(tr("Maximum", "Maximum (priority)")); - return editor; - } - - void setEditorData(QWidget *editor, const QModelIndex &index) const { - qDebug("setEditorData called"); - unsigned short val = index.model()->data(index, Qt::DisplayRole).toInt(); - QComboBox *combobox = static_cast(editor); - qDebug("Set Editor data: Prio is %d", val); - switch(val){ - case IGNORED: - combobox->setCurrentIndex(0); - break; - case NORMAL: - combobox->setCurrentIndex(1); - break; - case HIGH: - combobox->setCurrentIndex(2); - break; - case MAXIMUM: - combobox->setCurrentIndex(3); - break; - default: - qDebug("Unhandled priority, setting to NORMAL"); - combobox->setCurrentIndex(1); - } - } - QSize sizeHint(const QStyleOptionViewItem & option, const QModelIndex & index) const{ QVariant value = index.data(Qt::FontRole); QFont fnt = value.isValid() ? qvariant_cast(value) : option.font; @@ -167,66 +96,8 @@ public: return textRect.size(); } - public slots: - void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const { - QComboBox *combobox = static_cast(editor); - int value = combobox->currentIndex(); - qDebug("Setting combobox value in index: %d", value); - unsigned short old_val = index.model()->data(index, Qt::DisplayRole).toInt(); - switch(value){ - case 0: - if(old_val != IGNORED){ - model->setData(index, QVariant(IGNORED)); - emit filteredFilesChanged(); - } else { - // XXX: hack to force the model to send the itemChanged() signal - model->setData(index, QVariant(NORMAL)); - model->setData(index, QVariant(IGNORED)); - } - break; - case 1: - // if(old_val != NORMAL){ - // model->setData(index, QVariant(NORMAL)); - // if(filteredFilesChanged != 0) - // *filteredFilesChanged = true; - // } else { - model->setData(index, QVariant(HIGH)); - model->setData(index, QVariant(NORMAL)); - emit filteredFilesChanged(); - // } - break; - case 2: - if(old_val != HIGH){ - model->setData(index, QVariant(HIGH)); - emit filteredFilesChanged(); - } else { - model->setData(index, QVariant(NORMAL)); - model->setData(index, QVariant(HIGH)); - } - break; - case 3: - if(old_val != MAXIMUM){ - model->setData(index, QVariant(MAXIMUM)); - emit filteredFilesChanged(); - } else { - model->setData(index, QVariant(HIGH)); - model->setData(index, QVariant(MAXIMUM)); - } - break; - default: - if(old_val != NORMAL){ - model->setData(index, QVariant(NORMAL)); - emit filteredFilesChanged(); - } else { - model->setData(index, QVariant(HIGH)); - model->setData(index, QVariant(NORMAL)); - } - } - } - - void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &/* index */) const { - qDebug("UpdateEditor Geometry called"); - editor->setGeometry(option.rect); + QWidget* createEditor(QWidget *, const QStyleOptionViewItem &/* option */, const QModelIndex &) const { + return 0; } }; diff --git a/src/torrentadditiondlg.h b/src/torrentadditiondlg.h index 801d1d05a..68a137f2f 100644 --- a/src/torrentadditiondlg.h +++ b/src/torrentadditiondlg.h @@ -79,11 +79,6 @@ public: PropDelegate = new PropListDelegate(); torrentContentList->setItemDelegate(PropDelegate); connect(torrentContentList, SIGNAL(clicked(const QModelIndex&)), torrentContentList, SLOT(edit(const QModelIndex&))); - connect(torrentContentList, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(displayFilesListMenu(const QPoint&))); - connect(actionIgnored, SIGNAL(triggered()), this, SLOT(ignoreSelection())); - connect(actionNormal, SIGNAL(triggered()), this, SLOT(normalSelection())); - connect(actionHigh, SIGNAL(triggered()), this, SLOT(highSelection())); - connect(actionMaximum, SIGNAL(triggered()), this, SLOT(maximumSelection())); connect(collapseAllButton, SIGNAL(clicked()), torrentContentList, SLOT(collapseAll())); connect(expandAllButton, SIGNAL(clicked()), torrentContentList, SLOT(expandAll())); // Remember columns width @@ -259,54 +254,6 @@ public slots: return PropListModel->allFiltered(); } - void displayFilesListMenu(const QPoint&){ - QMenu myFilesLlistMenu(this); - // Enable/disable pause/start action given the DL state - myFilesLlistMenu.setTitle(tr("Priority")); - myFilesLlistMenu.addAction(actionIgnored); - myFilesLlistMenu.addAction(actionNormal); - myFilesLlistMenu.addAction(actionHigh); - myFilesLlistMenu.addAction(actionMaximum); - // Call menu - myFilesLlistMenu.exec(QCursor::pos()); - } - - void ignoreSelection(){ - QModelIndexList selectedIndexes = torrentContentList->selectionModel()->selectedIndexes(); - foreach(const QModelIndex &index, selectedIndexes){ - if(index.column() == PRIORITY){ - PropListModel->setData(index, QVariant(IGNORED)); - } - } - } - - void normalSelection(){ - QModelIndexList selectedIndexes = torrentContentList->selectionModel()->selectedIndexes(); - foreach(const QModelIndex &index, selectedIndexes){ - if(index.column() == PRIORITY){ - PropListModel->setData(index, QVariant(NORMAL)); - } - } - } - - void highSelection(){ - QModelIndexList selectedIndexes = torrentContentList->selectionModel()->selectedIndexes(); - foreach(const QModelIndex &index, selectedIndexes){ - if(index.column() == PRIORITY){ - PropListModel->setData(index, QVariant(HIGH)); - } - } - } - - void maximumSelection(){ - QModelIndexList selectedIndexes = torrentContentList->selectionModel()->selectedIndexes(); - foreach(const QModelIndex &index, selectedIndexes){ - if(index.column() == PRIORITY){ - PropListModel->setData(index, QVariant(MAXIMUM)); - } - } - } - void savePiecesPriorities(){ qDebug("Saving pieces priorities"); std::vector priorities = PropListModel->getFilesPriorities(t->num_files()); diff --git a/src/torrentfilesmodel.h b/src/torrentfilesmodel.h index d3aa69bc6..78f8fc45b 100644 --- a/src/torrentfilesmodel.h +++ b/src/torrentfilesmodel.h @@ -42,6 +42,8 @@ using namespace libtorrent; enum TreeItemType {TFILE, FOLDER, ROOT}; +#define IGNORED 0 +#define NORMAL 1 class TreeItem { private: @@ -208,12 +210,8 @@ public: itemData.replace(3, new_prio); // Update parent if(parentItem) { - if(new_prio == 0 || old_prio == 0) { - // Files got filtered or unfiltered - // Update parent size and progress - parentItem->updateSize(); - parentItem->updateProgress(); - } + parentItem->updateSize(); + parentItem->updateProgress(); parentItem->updatePriority(); } } @@ -310,7 +308,7 @@ public: TorrentFilesModel(QObject *parent=0): QAbstractItemModel(parent) { files_index = 0; QList rootData; - rootData << tr("Name") << tr("Size") << tr("Progress") << tr("Priority"); + rootData << tr("Name") << tr("Size") << tr("Progress"); rootItem = new TreeItem(rootData); } @@ -358,26 +356,37 @@ public: bool setData(const QModelIndex & index, const QVariant & value, int role = Qt::EditRole) { if(!index.isValid()) return false; - if (role != Qt::EditRole) return false; - TreeItem *item = static_cast(index.internalPointer()); - switch(index.column()) { - case 0: - item->setName(value.toString()); - break; - case 1: - item->setSize(value.toULongLong()); - break; - case 2: - item->setProgress(value.toDouble()); - break; - case 3: - item->setPriority(value.toInt()); - break; - default: - return false; + if (role == Qt::CheckStateRole) { + TreeItem *item = static_cast(index.internalPointer()); + if(item->getPriority() != value.toInt()) { + if(value.toInt() == Qt::Checked) + item->setPriority(1); + else + item->setPriority(0); + emit filteredFilesChanged(); + emit dataChanged(this->index(0,0), this->index(rowCount(), 0)); + } + return true; + } + if (role == Qt::EditRole) { + TreeItem *item = static_cast(index.internalPointer()); + switch(index.column()) { + case 0: + item->setName(value.toString()); + break; + case 1: + item->setSize(value.toULongLong()); + break; + case 2: + item->setProgress(value.toDouble()); + break; + default: + return false; + } + emit dataChanged(index, index); + return true; } - emit dataChanged(index, index); - return true; + return false; } TreeItemType getType(const QModelIndex &index) { @@ -400,6 +409,11 @@ public: else return QIcon(":/Icons/oxygen/file.png"); } + if(role == Qt::CheckStateRole) { + if(item->data(3).toInt() == 0) + return Qt::Unchecked; + return Qt::Checked; + } if (role != Qt::DisplayRole) return QVariant(); @@ -410,7 +424,7 @@ public: if (!index.isValid()) return 0; - return Qt::ItemIsEditable | Qt::ItemIsEnabled | Qt::ItemIsSelectable; + return Qt::ItemIsEditable | Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsUserCheckable; } QVariant headerData(int section, Qt::Orientation orientation, int role) const { @@ -526,6 +540,10 @@ public: } emit layoutChanged(); } + +public: +signals: + void filteredFilesChanged(); }; diff --git a/src/ui/torrentadditiondlg.ui b/src/ui/torrentadditiondlg.ui index 4c4872c09..acce1bb51 100644 --- a/src/ui/torrentadditiondlg.ui +++ b/src/ui/torrentadditiondlg.ui @@ -330,26 +330,6 @@ - - - Ignored - - - - - Normal - - - - - High - - - - - Maximum - -