1 /*
2  * Bittorrent Client using Qt and libtorrent.
3  * Copyright (C) 2021  Vladimir Golovnev <glassez@yandex.ru>
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License
7  * as published by the Free Software Foundation; either version 2
8  * of the License, or (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
18  *
19  * In addition, as a special exception, the copyright holders give permission to
20  * link this program with the OpenSSL project's "OpenSSL" library (or with
21  * modified versions of it that use the same license as the "OpenSSL" library),
22  * and distribute the linked executables. You must obey the GNU General Public
23  * License in all respects for all of the code used other than "OpenSSL".  If you
24  * modify file(s), you may extend this exception to your version of the file(s),
25  * but you are not obligated to do so. If you do not wish to do so, delete this
26  * exception statement from your version.
27  */
28 
29 #include "watchedfolderoptionsdialog.h"
30 
31 #include <QDir>
32 #include <QPushButton>
33 
34 #include "base/bittorrent/session.h"
35 #include "base/global.h"
36 #include "base/settingsstorage.h"
37 #include "base/utils/fs.h"
38 #include "base/utils/string.h"
39 #include "ui_watchedfolderoptionsdialog.h"
40 #include "utils.h"
41 
42 #define SETTINGS_KEY(name) "WatchedFolderOptionsDialog/" name
43 
WatchedFolderOptionsDialog(const TorrentFilesWatcher::WatchedFolderOptions & watchedFolderOptions,QWidget * parent)44 WatchedFolderOptionsDialog::WatchedFolderOptionsDialog(
45         const TorrentFilesWatcher::WatchedFolderOptions &watchedFolderOptions, QWidget *parent)
46     : QDialog {parent}
47     , m_ui {new Ui::WatchedFolderOptionsDialog}
48     , m_savePath {watchedFolderOptions.addTorrentParams.savePath}
49     , m_storeDialogSize {SETTINGS_KEY("DialogSize")}
50 {
51     m_ui->setupUi(this);
52 
53     m_ui->savePath->setMode(FileSystemPathEdit::Mode::DirectorySave);
54     m_ui->savePath->setDialogCaption(tr("Choose save path"));
55 
56     connect(m_ui->comboTTM, qOverload<int>(&QComboBox::currentIndexChanged), this, &WatchedFolderOptionsDialog::onTMMChanged);
57     connect(m_ui->categoryComboBox, qOverload<int>(&QComboBox::currentIndexChanged), this, &WatchedFolderOptionsDialog::onCategoryChanged);
58 
59     m_ui->checkBoxRecursive->setChecked(watchedFolderOptions.recursive);
60     populateSavePathComboBox();
61 
62     const auto *session = BitTorrent::Session::instance();
63     const BitTorrent::AddTorrentParams &torrentParams = watchedFolderOptions.addTorrentParams;
64     m_ui->startTorrentCheckBox->setChecked(!torrentParams.addPaused.value_or(session->isAddTorrentPaused()));
65     m_ui->comboTTM->setCurrentIndex(torrentParams.useAutoTMM.value_or(!session->isAutoTMMDisabledByDefault()));
66     m_ui->contentLayoutComboBox->setCurrentIndex(
67         static_cast<int>(torrentParams.contentLayout.value_or(session->torrentContentLayout())));
68 
69     // Load categories
70     QStringList categories = session->categories().keys();
71     std::sort(categories.begin(), categories.end(), Utils::String::naturalLessThan<Qt::CaseInsensitive>);
72 
73     if (!torrentParams.category.isEmpty())
74         m_ui->categoryComboBox->addItem(torrentParams.category);
75     m_ui->categoryComboBox->addItem("");
76 
77     for (const QString &category : asConst(categories))
78     {
79         if (category != torrentParams.category)
80             m_ui->categoryComboBox->addItem(category);
81     }
82 
83     loadState();
84 
85     m_ui->buttonBox->button(QDialogButtonBox::Ok)->setFocus();
86 }
87 
~WatchedFolderOptionsDialog()88 WatchedFolderOptionsDialog::~WatchedFolderOptionsDialog()
89 {
90     saveState();
91     delete m_ui;
92 }
93 
watchedFolderOptions() const94 TorrentFilesWatcher::WatchedFolderOptions WatchedFolderOptionsDialog::watchedFolderOptions() const
95 {
96     TorrentFilesWatcher::WatchedFolderOptions watchedFolderOptions;
97     watchedFolderOptions.recursive = m_ui->checkBoxRecursive->isChecked();
98 
99     BitTorrent::AddTorrentParams &params = watchedFolderOptions.addTorrentParams;
100     params.useAutoTMM = (m_ui->comboTTM->currentIndex() == 1);
101     if (!*params.useAutoTMM)
102         params.savePath = m_ui->savePath->selectedPath();
103     params.category = m_ui->categoryComboBox->currentText();;
104     params.addPaused = !m_ui->startTorrentCheckBox->isChecked();
105     params.contentLayout = static_cast<BitTorrent::TorrentContentLayout>(m_ui->contentLayoutComboBox->currentIndex());
106 
107     return watchedFolderOptions;
108 }
109 
loadState()110 void WatchedFolderOptionsDialog::loadState()
111 {
112     Utils::Gui::resize(this, m_storeDialogSize);
113 }
114 
saveState()115 void WatchedFolderOptionsDialog::saveState()
116 {
117     m_storeDialogSize = size();
118 }
119 
onCategoryChanged(const int index)120 void WatchedFolderOptionsDialog::onCategoryChanged(const int index)
121 {
122     Q_UNUSED(index);
123 
124     const QString category = m_ui->categoryComboBox->currentText();
125     if (m_ui->comboTTM->currentIndex() == 1)
126     {
127         const QString savePath = BitTorrent::Session::instance()->categorySavePath(category);
128         m_ui->savePath->setSelectedPath(Utils::Fs::toNativePath(savePath));
129     }
130 }
131 
populateSavePathComboBox()132 void WatchedFolderOptionsDialog::populateSavePathComboBox()
133 {
134     const QString defSavePath {BitTorrent::Session::instance()->defaultSavePath()};
135     m_ui->savePath->setSelectedPath(!m_savePath.isEmpty() ? m_savePath : defSavePath);
136 }
137 
onTMMChanged(const int index)138 void WatchedFolderOptionsDialog::onTMMChanged(const int index)
139 {
140     if (index != 1)
141     { // 0 is Manual mode and 1 is Automatic mode. Handle all non 1 values as manual mode.
142         populateSavePathComboBox();
143         m_ui->groupBoxSavePath->setEnabled(true);
144         m_ui->savePath->blockSignals(false);
145     }
146     else
147     {
148         m_ui->groupBoxSavePath->setEnabled(false);
149         m_ui->savePath->blockSignals(true);
150         m_savePath = m_ui->savePath->selectedPath();
151         const QString savePath = BitTorrent::Session::instance()->categorySavePath(m_ui->categoryComboBox->currentText());
152         m_ui->savePath->setSelectedPath(savePath);
153     }
154 }
155