diff --git a/src/base/preferences.cpp b/src/base/preferences.cpp index 590039380..6a417922a 100644 --- a/src/base/preferences.cpp +++ b/src/base/preferences.cpp @@ -475,46 +475,15 @@ void Preferences::addTorrentsInPause(bool b) setValue("Preferences/Downloads/StartInPause", b); } -QStringList Preferences::getScanDirs() const +QVariantHash Preferences::getScanDirs() const { - QStringList originalList = value("Preferences/Downloads/ScanDirs").toStringList(); - if (originalList.isEmpty()) - return originalList; - - QStringList newList; - foreach (const QString& s, originalList) - newList << Utils::Fs::fromNativePath(s); - return newList; + return value("Preferences/Downloads/ScanDirsV2").toHash(); } // This must be called somewhere with data from the model -void Preferences::setScanDirs(const QStringList &dirs) -{ - QStringList newList; - if (!dirs.isEmpty()) - foreach (const QString& s, dirs) - newList << Utils::Fs::fromNativePath(s); - setValue("Preferences/Downloads/ScanDirs", newList); -} - -QList Preferences::getDownloadInScanDirs() const -{ - return Utils::Misc::boolListfromStringList(value("Preferences/Downloads/DownloadInScanDirs").toStringList()); -} - -void Preferences::setDownloadInScanDirs(const QList &list) -{ - setValue("Preferences/Downloads/DownloadInScanDirs", Utils::Misc::toStringList(list)); -} - -void Preferences::setScanDirsDownloadPaths(const QStringList &downloadpaths) -{ - setValue("Preferences/Downloads/ScanDirsDownloadPaths", downloadpaths); -} - -QStringList Preferences::getScanDirsDownloadPaths() const +void Preferences::setScanDirs(const QVariantHash &dirs) { - return value("Preferences/Downloads/ScanDirsDownloadPaths").toStringList(); + setValue("Preferences/Downloads/ScanDirsV2", dirs); } QString Preferences::getScanDirsLastPath() const diff --git a/src/base/preferences.h b/src/base/preferences.h index 4767a1d59..0a4fb41bd 100644 --- a/src/base/preferences.h +++ b/src/base/preferences.h @@ -176,13 +176,9 @@ public: void additionDialogFront(bool b); bool addTorrentsInPause() const; void addTorrentsInPause(bool b); - QStringList getScanDirs() const; - void setScanDirs(const QStringList &dirs); - QList getDownloadInScanDirs() const; - void setDownloadInScanDirs(const QList &list); + QVariantHash getScanDirs() const; + void setScanDirs(const QVariantHash &dirs); QString getScanDirsLastPath() const; - void setScanDirsDownloadPaths(const QStringList &downloadpaths); - QStringList getScanDirsDownloadPaths() const; void setScanDirsLastPath(const QString &path); bool isTorrentExportEnabled() const; QString getTorrentExportDir() const; diff --git a/src/base/scanfoldersmodel.cpp b/src/base/scanfoldersmodel.cpp index 7c544fd63..784077741 100644 --- a/src/base/scanfoldersmodel.cpp +++ b/src/base/scanfoldersmodel.cpp @@ -37,37 +37,25 @@ #include "utils/misc.h" #include "utils/fs.h" #include "preferences.h" +#include "logger.h" #include "filesystemwatcher.h" #include "bittorrent/session.h" #include "scanfoldersmodel.h" -namespace +struct ScanFoldersModel::PathData { - const int PathColumn = 0; - const int DownloadAtTorrentColumn = 1; - const int DownloadPath = 2; -} - -class ScanFoldersModel::PathData -{ -public: - PathData(const QString &path) - : path(path) - , downloadAtPath(false) - , downloadPath(path) - { - } - - PathData(const QString &path, bool downloadAtPath, const QString &downloadPath) - : path(path) - , downloadAtPath(downloadAtPath) + PathData(const QString &watchPath, const PathType &type, const QString &downloadPath) + : watchPath(watchPath) + , downloadType(type) , downloadPath(downloadPath) { + if (this->downloadPath.isEmpty() && downloadType == CUSTOM_LOCATION) + downloadType = DEFAULT_LOCATION; } - const QString path; //watching directory - bool downloadAtPath; //if TRUE save data to watching directory - QString downloadPath; //if 'downloadAtPath' FALSE use this path for save data + QString watchPath; + PathType downloadType; + QString downloadPath; // valid for CUSTOM_LOCATION }; ScanFoldersModel *ScanFoldersModel::m_instance = 0; @@ -96,7 +84,7 @@ ScanFoldersModel *ScanFoldersModel::instance() } ScanFoldersModel::ScanFoldersModel(QObject *parent) - : QAbstractTableModel(parent) + : QAbstractListModel(parent) , m_fsWatcher(0) { configure(); @@ -116,7 +104,7 @@ int ScanFoldersModel::rowCount(const QModelIndex &parent) const int ScanFoldersModel::columnCount(const QModelIndex &parent) const { Q_UNUSED(parent); - return 3; + return NB_COLUMNS; } QVariant ScanFoldersModel::data(const QModelIndex &index, int role) const @@ -128,17 +116,17 @@ QVariant ScanFoldersModel::data(const QModelIndex &index, int role) const QVariant value; switch (index.column()) { - case PathColumn: + case WATCH: if (role == Qt::DisplayRole) - value = Utils::Fs::toNativePath(pathData->path); + value = Utils::Fs::toNativePath(pathData->watchPath); break; - case DownloadAtTorrentColumn: - if (role == Qt::CheckStateRole) - value = pathData->downloadAtPath ? Qt::Checked : Qt::Unchecked; - break; - case DownloadPath: - if (role == Qt::DisplayRole || role == Qt::EditRole || role == Qt::ToolTipRole) - value = Utils::Fs::toNativePath(pathData->downloadPath); + case DOWNLOAD: + if (role == Qt::DisplayRole) { + value = pathData->downloadType; + } + else if ((role == Qt::UserRole) && (pathData->downloadType == CUSTOM_LOCATION)) { + value = pathData->downloadPath; + } break; } @@ -153,14 +141,11 @@ QVariant ScanFoldersModel::headerData(int section, Qt::Orientation orientation, QVariant title; switch (section) { - case PathColumn: + case WATCH: title = tr("Watched Folder"); break; - case DownloadAtTorrentColumn: - title = tr("Download here"); - break; - case DownloadPath: - title = tr("Download path"); + case DOWNLOAD: + title = tr("Save Files to"); break; } @@ -170,23 +155,16 @@ QVariant ScanFoldersModel::headerData(int section, Qt::Orientation orientation, Qt::ItemFlags ScanFoldersModel::flags(const QModelIndex &index) const { if (!index.isValid() || (index.row() >= rowCount())) - return QAbstractTableModel::flags(index); + return QAbstractListModel::flags(index); - const PathData *pathData = m_pathList.at(index.row()); Qt::ItemFlags flags; switch (index.column()) { - case PathColumn: - flags = QAbstractTableModel::flags(index); + case WATCH: + flags = QAbstractListModel::flags(index); break; - case DownloadAtTorrentColumn: - flags = QAbstractTableModel::flags(index) | Qt::ItemIsUserCheckable; - break; - case DownloadPath: - if (pathData->downloadAtPath == false) - flags = QAbstractTableModel::flags(index) | Qt::ItemIsEditable | Qt::ItemIsEnabled; - else - flags = QAbstractTableModel::flags(index) ^ Qt::ItemIsEnabled; //dont edit DownloadPath if checked 'downloadAtPath' + case DOWNLOAD: + flags = QAbstractListModel::flags(index) | Qt::ItemIsEditable; break; } @@ -195,42 +173,46 @@ Qt::ItemFlags ScanFoldersModel::flags(const QModelIndex &index) const bool ScanFoldersModel::setData(const QModelIndex &index, const QVariant &value, int role) { - if (!index.isValid() || (index.row() >= rowCount()) || (index.column() > DownloadPath)) + if (!index.isValid() || (index.row() >= rowCount()) || (index.column() >= columnCount()) + || (index.column() != DOWNLOAD)) return false; - bool success = true; + if (role == Qt::DisplayRole) { + PathType type = static_cast(value.toInt()); + if (type == CUSTOM_LOCATION) + return false; - switch (index.column()) { - case PathColumn: - success = false; - break; - case DownloadAtTorrentColumn: - if (role == Qt::CheckStateRole) { - Q_ASSERT(index.column() == DownloadAtTorrentColumn); - m_pathList[index.row()]->downloadAtPath = (value.toInt() == Qt::Checked); - emit dataChanged(index, index); - success = true; - } - break; - case DownloadPath: - Q_ASSERT(index.column() == DownloadPath); - m_pathList[index.row()]->downloadPath = value.toString(); + m_pathList[index.row()]->downloadType = type; + m_pathList[index.row()]->downloadPath.clear(); + emit dataChanged(index, index); + } + else if (role == Qt::UserRole) { + QString path = value.toString(); + if (path.isEmpty()) // means we didn't pass CUSTOM_LOCATION type + return false; + + m_pathList[index.row()]->downloadType = CUSTOM_LOCATION; + m_pathList[index.row()]->downloadPath = Utils::Fs::toNativePath(path); emit dataChanged(index, index); - success = true; - break; + } + else { + return false; } - return success; + return true; } -ScanFoldersModel::PathStatus ScanFoldersModel::addPath(const QString &path, bool downloadAtPath, const QString &downloadPath) +ScanFoldersModel::PathStatus ScanFoldersModel::addPath(const QString &watchPath, const PathType &downloadType, const QString &downloadPath) { - QDir dir(path); - if (!dir.exists()) return DoesNotExist; - if (!dir.isReadable()) return CannotRead; + QDir watchDir(watchPath); + if (!watchDir.exists()) return DoesNotExist; + if (!watchDir.isReadable()) return CannotRead; - const QString &canonicalPath = dir.canonicalPath(); - if (findPathData(canonicalPath) != -1) return AlreadyInList; + const QString &canonicalWatchPath = watchDir.canonicalPath(); + if (findPathData(canonicalWatchPath) != -1) return AlreadyInList; + + QDir downloadDir(downloadPath); + const QString &canonicalDownloadPath = downloadDir.canonicalPath(); if (!m_fsWatcher) { m_fsWatcher = new FileSystemWatcher(this); @@ -238,12 +220,11 @@ ScanFoldersModel::PathStatus ScanFoldersModel::addPath(const QString &path, bool } beginInsertRows(QModelIndex(), rowCount(), rowCount()); - QString downloadToPath = downloadPath.isEmpty() ? path : downloadPath; - m_pathList << new PathData(canonicalPath, downloadAtPath, downloadToPath); + m_pathList << new PathData(Utils::Fs::toNativePath(canonicalWatchPath), downloadType, Utils::Fs::toNativePath(canonicalDownloadPath)); endInsertRows(); // Start scanning - m_fsWatcher->addPath(canonicalPath); + m_fsWatcher->addPath(canonicalWatchPath); return Ok; } @@ -251,8 +232,8 @@ void ScanFoldersModel::removePath(int row) { Q_ASSERT((row >= 0) && (row < rowCount())); beginRemoveRows(QModelIndex(), row, row); - m_fsWatcher->removePath(m_pathList.at(row)->path); - m_pathList.removeAt(row); + m_fsWatcher->removePath(m_pathList.at(row)->watchPath); + delete m_pathList.takeAt(row); endRemoveRows(); } @@ -265,43 +246,37 @@ bool ScanFoldersModel::removePath(const QString &path) return true; } -ScanFoldersModel::PathStatus ScanFoldersModel::setDownloadAtPath(int row, bool downloadAtPath) +bool ScanFoldersModel::downloadInWatchFolder(const QString &filePath) const { - Q_ASSERT((row >= 0) && (row < rowCount())); - - bool &oldValue = m_pathList[row]->downloadAtPath; - if (oldValue != downloadAtPath) { - if (downloadAtPath) { - QTemporaryFile testFile(m_pathList[row]->path + "/tmpFile"); - if (!testFile.open()) return CannotWrite; - } - - oldValue = downloadAtPath; - const QModelIndex changedIndex = index(row, DownloadAtTorrentColumn); - emit dataChanged(changedIndex, changedIndex); - } - - return Ok; + const int row = findPathData(QFileInfo(filePath).dir().path()); + Q_ASSERT(row != -1); + PathData *data = m_pathList.at(row); + return (data->downloadType == DOWNLOAD_IN_WATCH_FOLDER); } -bool ScanFoldersModel::downloadInTorrentFolder(const QString &filePath) const +bool ScanFoldersModel::downloadInDefaultFolder(const QString &filePath) const { const int row = findPathData(QFileInfo(filePath).dir().path()); Q_ASSERT(row != -1); - return m_pathList.at(row)->downloadAtPath; + PathData *data = m_pathList.at(row); + return (data->downloadType == DEFAULT_LOCATION); } QString ScanFoldersModel::downloadPathTorrentFolder(const QString &filePath) const { const int row = findPathData(QFileInfo(filePath).dir().path()); Q_ASSERT(row != -1); - return m_pathList.at(row)->downloadPath; + PathData *data = m_pathList.at(row); + if (data->downloadType == CUSTOM_LOCATION) + return data->downloadPath; + + return QString(); } int ScanFoldersModel::findPathData(const QString &path) const { for (int i = 0; i < m_pathList.count(); ++i) - if (m_pathList.at(i)->path == Utils::Fs::fromNativePath(path)) + if (m_pathList.at(i)->watchPath == Utils::Fs::toNativePath(path)) return i; return -1; @@ -309,33 +284,27 @@ int ScanFoldersModel::findPathData(const QString &path) const void ScanFoldersModel::makePersistent() { - Preferences *const pref = Preferences::instance(); - QStringList paths; - QList downloadInFolderInfo; - QStringList downloadPaths; + QVariantHash dirs; + foreach (const PathData *pathData, m_pathList) { - paths << pathData->path; - downloadInFolderInfo << pathData->downloadAtPath; - downloadPaths << pathData->downloadPath; + if (pathData->downloadType == CUSTOM_LOCATION) + dirs.insert(Utils::Fs::fromNativePath(pathData->watchPath), Utils::Fs::fromNativePath(pathData->downloadPath)); + else + dirs.insert(Utils::Fs::fromNativePath(pathData->watchPath), pathData->downloadType); } - pref->setScanDirs(paths); - pref->setDownloadInScanDirs(downloadInFolderInfo); - pref->setScanDirsDownloadPaths(downloadPaths); + Preferences::instance()->setScanDirs(dirs); } void ScanFoldersModel::configure() { - Preferences *const pref = Preferences::instance(); - - int i = 0; - QStringList downloadPaths = pref->getScanDirsDownloadPaths(); - QList downloadInDirList = pref->getDownloadInScanDirs(); - foreach (const QString &dir, pref->getScanDirs()) { - bool downloadInDir = downloadInDirList.value(i, true); - QString downloadPath = downloadPaths.value(i); //empty string if out-of-bounds - addPath(dir, downloadInDir, downloadPath); - ++i; + QVariantHash dirs = Preferences::instance()->getScanDirs(); + + for (QVariantHash::const_iterator i = dirs.begin(), e = dirs.end(); i != e; ++i) { + if (i.value().type() == QVariant::Int) + addPath(i.key(), static_cast(i.value().toInt()), QString()); + else + addPath(i.key(), CUSTOM_LOCATION, i.value().toString()); } } @@ -343,10 +312,17 @@ void ScanFoldersModel::addTorrentsToSession(const QStringList &pathList) { foreach (const QString &file, pathList) { qDebug("File %s added", qPrintable(file)); + + BitTorrent::AddTorrentParams params; + if (downloadInWatchFolder(file)) + params.savePath = QFileInfo(file).dir().path(); + else if (!downloadInDefaultFolder(file)) + params.savePath = downloadPathTorrentFolder(file); + if (file.endsWith(".magnet")) { QFile f(file); if (f.open(QIODevice::ReadOnly)) { - BitTorrent::Session::instance()->addTorrent(QString::fromLocal8Bit(f.readAll())); + BitTorrent::Session::instance()->addTorrent(QString::fromLocal8Bit(f.readAll()), params); f.remove(); } else { @@ -354,12 +330,6 @@ void ScanFoldersModel::addTorrentsToSession(const QStringList &pathList) } } else { - BitTorrent::AddTorrentParams params; - if (downloadInTorrentFolder(file)) - params.savePath = QFileInfo(file).dir().path(); - else - params.savePath = downloadPathTorrentFolder(file); //if empty it will use the default savePath - BitTorrent::TorrentInfo torrentInfo = BitTorrent::TorrentInfo::loadFromFile(file); if (torrentInfo.isValid()) { BitTorrent::Session::instance()->addTorrent(torrentInfo, params); diff --git a/src/base/scanfoldersmodel.h b/src/base/scanfoldersmodel.h index ecbac4820..31959ca75 100644 --- a/src/base/scanfoldersmodel.h +++ b/src/base/scanfoldersmodel.h @@ -31,7 +31,7 @@ #ifndef SCANFOLDERSMODEL_H #define SCANFOLDERSMODEL_H -#include +#include #include QT_BEGIN_NAMESPACE @@ -40,7 +40,7 @@ QT_END_NAMESPACE class FileSystemWatcher; -class ScanFoldersModel : public QAbstractTableModel +class ScanFoldersModel : public QAbstractListModel { Q_OBJECT Q_DISABLE_COPY(ScanFoldersModel) @@ -55,6 +55,20 @@ public: AlreadyInList }; + enum Column + { + WATCH, + DOWNLOAD, + NB_COLUMNS + }; + + enum PathType + { + DOWNLOAD_IN_WATCH_FOLDER, + DEFAULT_LOCATION, + CUSTOM_LOCATION + }; + static bool initInstance(QObject *parent = 0); static void freeInstance(); static ScanFoldersModel *instance(); @@ -67,13 +81,10 @@ public: // TODO: removePaths(); singular version becomes private helper functions; // also: remove functions should take modelindexes - PathStatus addPath(const QString &path, bool downloadAtPath, const QString &downloadPath); + PathStatus addPath(const QString &watchPath, const PathType& downloadType, const QString &downloadPath); void removePath(int row); bool removePath(const QString &path); - PathStatus setDownloadAtPath(int row, bool downloadAtPath); - bool downloadInTorrentFolder(const QString &filePath) const; - QString downloadPathTorrentFolder(const QString &filePath) const; void makePersistent(); private slots: @@ -85,10 +96,15 @@ private: ~ScanFoldersModel(); virtual bool setData(const QModelIndex &index, const QVariant &value, int role = Qt::EditRole); - static ScanFoldersModel *m_instance; - class PathData; + bool downloadInWatchFolder(const QString &filePath) const; + bool downloadInDefaultFolder(const QString &filePath) const; + QString downloadPathTorrentFolder(const QString &filePath) const; int findPathData(const QString &path) const; +private: + static ScanFoldersModel *m_instance; + struct PathData; + QList m_pathList; FileSystemWatcher *m_fsWatcher; }; diff --git a/src/gui/gui.pri b/src/gui/gui.pri index d5c285fef..b586e7050 100644 --- a/src/gui/gui.pri +++ b/src/gui/gui.pri @@ -42,6 +42,7 @@ HEADERS += \ $$PWD/shutdownconfirm.h \ $$PWD/torrentmodel.h \ $$PWD/torrentcreatordlg.h \ + $$PWD/scanfoldersdelegate.h \ $$PWD/search/searchwidget.h \ $$PWD/search/searchtab.h \ $$PWD/search/pluginselectdlg.h \ @@ -79,6 +80,7 @@ SOURCES += \ $$PWD/shutdownconfirm.cpp \ $$PWD/torrentmodel.cpp \ $$PWD/torrentcreatordlg.cpp \ + $$PWD/scanfoldersdelegate.cpp \ $$PWD/search/searchwidget.cpp \ $$PWD/search/searchtab.cpp \ $$PWD/search/pluginselectdlg.cpp \ diff --git a/src/gui/options.ui b/src/gui/options.ui index 22a5ebea1..684033f21 100644 --- a/src/gui/options.ui +++ b/src/gui/options.ui @@ -714,7 +714,7 @@ - + 0 @@ -727,30 +727,24 @@ 150 + + QAbstractItemView::AllEditTriggers + QAbstractItemView::SingleSelection QAbstractItemView::SelectRows - - false + + Qt::ElideNone - - true + + false - + 80 - - false - - - true - - - false - diff --git a/src/gui/options_imp.cpp b/src/gui/options_imp.cpp index 6ef0283a3..d1fc939e7 100644 --- a/src/gui/options_imp.cpp +++ b/src/gui/options_imp.cpp @@ -41,15 +41,17 @@ #include #include -#include "options_imp.h" + #include "base/preferences.h" #include "base/utils/fs.h" -#include "advancedsettings.h" #include "base/scanfoldersmodel.h" #include "base/bittorrent/session.h" -#include "guiiconprovider.h" #include "base/net/dnsupdater.h" #include "base/unicodestrings.h" +#include "advancedsettings.h" +#include "guiiconprovider.h" +#include "scanfoldersdelegate.h" +#include "options_imp.h" #ifndef QT_NO_OPENSSL #include @@ -91,11 +93,12 @@ options_imp::options_imp(QWidget *parent) } #ifndef QBT_USES_QT5 - scanFoldersView->horizontalHeader()->setResizeMode(QHeaderView::ResizeToContents); + scanFoldersView->header()->setResizeMode(QHeaderView::ResizeToContents); #else - scanFoldersView->horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents); + scanFoldersView->header()->setSectionResizeMode(QHeaderView::ResizeToContents); #endif scanFoldersView->setModel(ScanFoldersModel::instance()); + scanFoldersView->setItemDelegate(new ScanFoldersDelegate(this, scanFoldersView)); connect(ScanFoldersModel::instance(), SIGNAL(dataChanged(QModelIndex, QModelIndex)), this, SLOT(enableApplyButton())); connect(scanFoldersView->selectionModel(), SIGNAL(selectionChanged(QItemSelection, QItemSelection)), this, SLOT(handleScanFolderViewSelectionChanged())); @@ -1200,7 +1203,7 @@ void options_imp::on_addScanFolderButton_clicked() const QString dir = QFileDialog::getExistingDirectory(this, tr("Add directory to scan"), Utils::Fs::toNativePath(Utils::Fs::folderName(pref->getScanDirsLastPath()))); if (!dir.isEmpty()) { - const ScanFoldersModel::PathStatus status = ScanFoldersModel::instance()->addPath(dir, true, ""); + const ScanFoldersModel::PathStatus status = ScanFoldersModel::instance()->addPath(dir, ScanFoldersModel::DOWNLOAD_IN_WATCH_FOLDER, QString()); QString error; switch (status) { case ScanFoldersModel::AlreadyInList: @@ -1215,7 +1218,8 @@ void options_imp::on_addScanFolderButton_clicked() default: pref->setScanDirsLastPath(dir); addedScanDirs << dir; - scanFoldersView->resizeColumnsToContents(); + for (int i = 0; i < ScanFoldersModel::instance()->columnCount(); ++i) + scanFoldersView->resizeColumnToContents(i); enableApplyButton(); } diff --git a/src/gui/scanfoldersdelegate.cpp b/src/gui/scanfoldersdelegate.cpp new file mode 100644 index 000000000..ca962b754 --- /dev/null +++ b/src/gui/scanfoldersdelegate.cpp @@ -0,0 +1,183 @@ +/* + * Bittorrent Client using Qt and libtorrent. + * Copyright (C) 2015 sledgehammer999 + * + * 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. + * + * In addition, as a special exception, the copyright holders give permission to + * link this program with the OpenSSL project's "OpenSSL" library (or with + * modified versions of it that use the same license as the "OpenSSL" library), + * and distribute the linked executables. 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), 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. + * + * Contact : hammered999@gmail.com + */ + +#include +#include +#include +#include +#include + +#include "base/scanfoldersmodel.h" +#include "base/preferences.h" +#include "scanfoldersdelegate.h" + + +ScanFoldersDelegate::ScanFoldersDelegate(QObject *parent, QTreeView *foldersView) + : QItemDelegate(parent) + , m_folderView(foldersView) +{ +} + +ScanFoldersDelegate::~ScanFoldersDelegate() {} + +void ScanFoldersDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const +{ + painter->save(); + + switch(index.column()) { + case ScanFoldersModel::WATCH: + QItemDelegate::paint(painter, option, index); + break; + + case ScanFoldersModel::DOWNLOAD: { + QStyleOptionViewItemV2 opt = QItemDelegate::setOptions(index, option); + QItemDelegate::drawBackground(painter, opt, index); + QString text; + + switch (index.data().toInt()) { + case ScanFoldersModel::DOWNLOAD_IN_WATCH_FOLDER: + text = tr("Watch Folder"); + break; + case ScanFoldersModel::DEFAULT_LOCATION: + text = tr("Default Folder"); + break; + case ScanFoldersModel::CUSTOM_LOCATION: + text = index.data(Qt::UserRole).toString(); + break; + } + QItemDelegate::drawDisplay(painter, opt, option.rect, text); + break; + } + + default: + break; + } + + painter->restore(); +} + +void ScanFoldersDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const +{ + QComboBox *combobox = static_cast(editor); + // Set combobox index + if (index.data().toInt() == ScanFoldersModel::CUSTOM_LOCATION) + combobox->setCurrentIndex(4); // '4' is the index of the item after the separator in the QComboBox menu + else + combobox->setCurrentIndex(index.data().toInt()); +} + +QWidget *ScanFoldersDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &, const QModelIndex &index) const +{ + if (index.column() != ScanFoldersModel::DOWNLOAD) return 0; + + QComboBox* editor = new QComboBox(parent); + editor->setFocusPolicy(Qt::StrongFocus); + editor->addItem(tr("Watch Folder")); + editor->addItem(tr("Default Folder")); + editor->addItem(tr("Browse...")); + if (index.data().toInt() == ScanFoldersModel::CUSTOM_LOCATION) { + editor->insertSeparator(3); + editor->addItem(index.data(Qt::UserRole).toString()); + } + + connect(editor, SIGNAL(currentIndexChanged(int)), this, SLOT(comboboxIndexChanged(int))); + return editor; +} + +void ScanFoldersDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const +{ + QComboBox *combobox = static_cast(editor); + int value = combobox->currentIndex(); + + switch(value) { + case ScanFoldersModel::DOWNLOAD_IN_WATCH_FOLDER: + case ScanFoldersModel::DEFAULT_LOCATION: + model->setData(index, value, Qt::DisplayRole); + break; + + case 4: // '4' is the index of the item after the separator in the QComboBox menu + model->setData(index, combobox->currentText(), Qt::UserRole); + break; + + default: + break; + } +} + +void ScanFoldersDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &) const +{ + qDebug("UpdateEditor Geometry called"); + editor->setGeometry(option.rect); +} + +void ScanFoldersDelegate::comboboxIndexChanged(int index) +{ + if (index < 2) + return; + + if (index == 2) { + QString path; + QString newPath; + QModelIndexList selIndex = m_folderView->selectionModel()->selectedRows(1); + + if (selIndex.isEmpty()) + return; + + ScanFoldersModel::PathType type = static_cast(selIndex.at(0).data().toInt()); + + if (type == ScanFoldersModel::CUSTOM_LOCATION) + path = selIndex.at(0).data(Qt::UserRole).toString(); + else + path = Preferences::instance()->getSavePath(); + + newPath = QFileDialog::getExistingDirectory(0, tr("Choose save path"), path); + QComboBox *combobox = static_cast(sender()); + disconnect(combobox, SIGNAL(currentIndexChanged(int)), this, SLOT(comboboxIndexChanged(int))); + + if (!newPath.isEmpty()) { + if (combobox->count() != 5) { + combobox->insertSeparator(3); + combobox->addItem(newPath); + } + else { + combobox->setItemText(4, newPath); + } + combobox->setCurrentIndex(4); + } + else { + if (type == ScanFoldersModel::CUSTOM_LOCATION) + combobox->setCurrentIndex(4); + else + combobox->setCurrentIndex(type); + } + + connect(combobox, SIGNAL(currentIndexChanged(int)), this, SLOT(comboboxIndexChanged(int))); + } +} diff --git a/src/gui/scanfoldersdelegate.h b/src/gui/scanfoldersdelegate.h new file mode 100644 index 000000000..9c22b0d17 --- /dev/null +++ b/src/gui/scanfoldersdelegate.h @@ -0,0 +1,65 @@ +/* + * Bittorrent Client using Qt and libtorrent. + * Copyright (C) 2015 sledgehammer999 + * + * 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. + * + * In addition, as a special exception, the copyright holders give permission to + * link this program with the OpenSSL project's "OpenSSL" library (or with + * modified versions of it that use the same license as the "OpenSSL" library), + * and distribute the linked executables. 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), 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. + * + * Contact : hammered999@gmail.com + */ + +#ifndef SCANFOLDERSDELEGATE_H +#define SCANFOLDERSDELEGATE_H + +#include + +class QPainter; +class QModelIndex; +class QStyleOptionViewItem; +class QAbstractItemModel; +class PropertiesWidget; +class QTreeView; + +class ScanFoldersDelegate : public QItemDelegate +{ + Q_OBJECT + +public: + ScanFoldersDelegate(QObject *parent, QTreeView *foldersView); + ~ScanFoldersDelegate(); + + void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const; + void setEditorData(QWidget *editor, const QModelIndex &index) const; + QWidget *createEditor(QWidget *parent, const QStyleOptionViewItem &, const QModelIndex &index) const; + +public slots: + void setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const; + void updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &) const; + void comboboxIndexChanged(int index); + +private: + QTreeView *m_folderView; +}; + +#endif // SCANFOLDERSDELEGATE_H + diff --git a/src/webui/prefjson.cpp b/src/webui/prefjson.cpp index 86517d326..54583f97a 100644 --- a/src/webui/prefjson.cpp +++ b/src/webui/prefjson.cpp @@ -58,7 +58,7 @@ QByteArray prefjson::getPreferences() data["temp_path"] = Utils::Fs::toNativePath(pref->getTempPath()); data["preallocate_all"] = pref->preAllocateAllFiles(); data["incomplete_files_ext"] = pref->useIncompleteFilesExtension(); - QVariantList scanDirs; + /*QVariantList scanDirs; foreach (const QString& s, pref->getScanDirs()) { scanDirs << Utils::Fs::toNativePath(s); } @@ -72,7 +72,7 @@ QByteArray prefjson::getPreferences() foreach (bool b, pref->getDownloadInScanDirs()) { var_list << b; } - data["download_in_scan_dirs"] = var_list; + data["download_in_scan_dirs"] = var_list;*/ data["export_dir"] = Utils::Fs::toNativePath(pref->getTorrentExportDir()); data["export_dir_fin"] = Utils::Fs::toNativePath(pref->getFinishedTorrentExportDir()); // Email notification upon download completion @@ -188,7 +188,7 @@ void prefjson::setPreferences(const QString& json) pref->preAllocateAllFiles(m["preallocate_all"].toBool()); if (m.contains("incomplete_files_ext")) pref->useIncompleteFilesExtension(m["incomplete_files_ext"].toBool()); - if (m.contains("scan_dirs") && m.contains("download_in_scan_dirs") && m.contains("scan_dirs_download_paths")) { + /*if (m.contains("scan_dirs") && m.contains("download_in_scan_dirs") && m.contains("scan_dirs_download_paths")) { QVariantList download_at_path_tmp = m["download_in_scan_dirs"].toList(); QList download_at_path; foreach (QVariant var, download_at_path_tmp) { @@ -217,7 +217,7 @@ void prefjson::setPreferences(const QString& json) ++i; } } - } + }*/ if (m.contains("export_dir")) pref->setTorrentExportDir(m["export_dir"].toString()); if (m.contains("export_dir_fin"))