qBittorrent
previewselectdialog.cpp
Go to the documentation of this file.
1 /*
2  * Bittorrent Client using Qt and libtorrent.
3  * Copyright (C) 2011 Christophe Dumez <chris@qbittorrent.org>
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 "previewselectdialog.h"
30 
31 #include <QDir>
32 #include <QFile>
33 #include <QHeaderView>
34 #include <QMessageBox>
35 #include <QPushButton>
36 #include <QShowEvent>
37 #include <QStandardItemModel>
38 #include <QTableView>
39 
41 #include "base/preferences.h"
42 #include "base/utils/fs.h"
43 #include "base/utils/misc.h"
44 #include "previewlistdelegate.h"
45 #include "ui_previewselectdialog.h"
46 #include "utils.h"
47 
48 #define SETTINGS_KEY(name) "PreviewSelectDialog/" name
49 
51  : QDialog(parent)
52  , m_ui(new Ui::PreviewSelectDialog)
53  , m_torrent(torrent)
54  , m_storeDialogSize(SETTINGS_KEY("Size"))
55 #if (QT_VERSION >= QT_VERSION_CHECK(6, 0, 0))
56  , m_storeTreeHeaderState("GUI/Qt6/" SETTINGS_KEY("HeaderState"))
57 #else
58  , m_storeTreeHeaderState(SETTINGS_KEY("HeaderState"))
59 #endif
60 {
61  m_ui->setupUi(this);
62 
63  m_ui->label->setText(tr("The following files from torrent \"%1\" support previewing, please select one of them:")
64  .arg(m_torrent->name()));
65 
66  m_ui->buttonBox->button(QDialogButtonBox::Ok)->setText(tr("Preview"));
67  connect(m_ui->buttonBox, &QDialogButtonBox::accepted, this, &PreviewSelectDialog::previewButtonClicked);
68  connect(m_ui->buttonBox, &QDialogButtonBox::rejected, this, &QDialog::reject);
69  connect(m_ui->previewList, &QAbstractItemView::doubleClicked, this, &PreviewSelectDialog::previewButtonClicked);
70 
71  const Preferences *pref = Preferences::instance();
72  // Preview list
73  m_previewListModel = new QStandardItemModel(0, NB_COLUMNS, this);
74  m_previewListModel->setHeaderData(NAME, Qt::Horizontal, tr("Name"));
75  m_previewListModel->setHeaderData(SIZE, Qt::Horizontal, tr("Size"));
76  m_previewListModel->setHeaderData(PROGRESS, Qt::Horizontal, tr("Progress"));
77 
78  // This hack fixes reordering of first column with Qt5.
79  // https://github.com/qtproject/qtbase/commit/e0fc088c0c8bc61dbcaf5928b24986cd61a22777
80  QTableView unused;
81  unused.setVerticalHeader(m_ui->previewList->header());
82  m_ui->previewList->header()->setParent(m_ui->previewList);
83  unused.setVerticalHeader(new QHeaderView(Qt::Horizontal));
84 
85  m_ui->previewList->setModel(m_previewListModel);
86  m_ui->previewList->hideColumn(FILE_INDEX);
88  m_ui->previewList->setItemDelegate(m_listDelegate);
89  m_ui->previewList->setAlternatingRowColors(pref->useAlternatingRowColors());
90  // Fill list in
91  const QVector<qreal> fp = torrent->filesProgress();
92  for (int i = 0; i < torrent->filesCount(); ++i)
93  {
94  const QString fileName = Utils::Fs::fileName(torrent->filePath(i));
96  {
97  int row = m_previewListModel->rowCount();
98  m_previewListModel->insertRow(row);
99  m_previewListModel->setData(m_previewListModel->index(row, NAME), fileName);
100  m_previewListModel->setData(m_previewListModel->index(row, SIZE), torrent->fileSize(i));
101  m_previewListModel->setData(m_previewListModel->index(row, PROGRESS), fp[i]);
102  m_previewListModel->setData(m_previewListModel->index(row, FILE_INDEX), i);
103  }
104  }
105 
106  m_previewListModel->sort(NAME);
107  m_ui->previewList->header()->setSortIndicator(0, Qt::AscendingOrder);
108  m_ui->previewList->selectionModel()->select(m_previewListModel->index(0, NAME), QItemSelectionModel::Select | QItemSelectionModel::Rows);
109 
110  // Restore dialog state
111  loadWindowState();
112 }
113 
115 {
116  saveWindowState();
117 
118  delete m_ui;
119 }
120 
122 {
123  const QModelIndexList selectedIndexes = m_ui->previewList->selectionModel()->selectedRows(FILE_INDEX);
124  if (selectedIndexes.isEmpty()) return;
125 
126  // Flush data
128 
129  // Only one file should be selected
130  const int fileIndex = selectedIndexes.at(0).data().toInt();
131  const QString path = QDir(m_torrent->actualStorageLocation()).absoluteFilePath(m_torrent->actualFilePath(fileIndex));
132  // File
133  if (!QFile::exists(path))
134  {
135  const bool isSingleFile = (m_previewListModel->rowCount() == 1);
136  QWidget *parent = isSingleFile ? this->parentWidget() : this;
137  QMessageBox::critical(parent, tr("Preview impossible")
138  , tr("Sorry, we can't preview this file: \"%1\".").arg(Utils::Fs::toNativePath(path)));
139  if (isSingleFile)
140  reject();
141  return;
142  }
143 
144  emit readyToPreviewFile(path);
145  accept();
146 }
147 
149 {
150  // Persist dialog size
151  m_storeDialogSize = size();
152  // Persist TreeView Header state
153  m_storeTreeHeaderState = m_ui->previewList->header()->saveState();
154 }
155 
157 {
158  // Restore dialog size
160 
161  // Restore TreeView Header state
162  if (!m_storeTreeHeaderState.get().isEmpty())
163  {
164  m_headerStateInitialized = m_ui->previewList->header()->restoreState(m_storeTreeHeaderState);
165  }
166 }
167 
168 void PreviewSelectDialog::showEvent(QShowEvent *event)
169 {
170  // event originated from system
171  if (event->spontaneous())
172  {
173  QDialog::showEvent(event);
174  return;
175  }
176 
177  // Default size, have to be called after show(), because width is needed
178  // Set Name column width to 60% of TreeView
180  {
181  const int nameSize = (m_ui->previewList->size().width() * 0.6);
182  m_ui->previewList->header()->resizeSection(0, nameSize);
184  }
185 
186  // Only one file, no choice
187  if (m_previewListModel->rowCount() <= 1)
189 }
QBITTORRENT_HAS_EXECINFO_H if(NOT QBITTORRENT_HAS_EXECINFO_H) message(FATAL_ERROR "execinfo.h header file not found.\n" "Please either disable the STACKTRACE feature or use a libc that has this header file
virtual int filesCount() const =0
virtual qlonglong fileSize(int index) const =0
virtual QString filePath(int index) const =0
virtual void flushCache() const =0
virtual QVector< qreal > filesProgress() const =0
virtual QString actualStorageLocation() const =0
virtual QString actualFilePath(int index) const =0
virtual QString name() const =0
static Preferences * instance()
bool useAlternatingRowColors() const
SettingValue< QByteArray > m_storeTreeHeaderState
void readyToPreviewFile(QString) const
PreviewListDelegate * m_listDelegate
void showEvent(QShowEvent *event) override
QStandardItemModel * m_previewListModel
SettingValue< QSize > m_storeDialogSize
PreviewSelectDialog(QWidget *parent, const BitTorrent::Torrent *torrent)
Ui::PreviewSelectDialog * m_ui
const BitTorrent::Torrent * m_torrent
T get(const T &defaultValue={}) const
Definition: settingvalue.h:46
QString fileName(const QString &filePath)
Definition: fs.cpp:87
QString toNativePath(const QString &path)
Definition: fs.cpp:64
void resize(QWidget *widget, const QSize &newSize={})
Definition: utils.cpp:54
bool isPreviewable(const QString &filename)
Definition: misc.cpp:295
#define SETTINGS_KEY(name)