-
Notifications
You must be signed in to change notification settings - Fork 0
/
previewselectdialog.cpp
171 lines (141 loc) · 6.39 KB
/
previewselectdialog.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
#include "previewselectdialog.h"
#include "ui_previewselectdialog.h"
#include <QDir>
#include <QMessageBox>
#include <QPushButton>
#include <QScrollBar>
#include <QShowEvent>
#include <QStandardItemModel>
#include <QtSql/QSqlRecord>
#include "common.h"
#include "previewlistdelegate.h"
// TODO get rid of this include, move Column enum to separate file silverqx
#include "torrentsqltablemodel.h"
#include "utils/fs.h"
#include "utils/misc.h"
PreviewSelectDialog::PreviewSelectDialog(
QWidget *const parent, const QSqlRecord &torrent,
const QSharedPointer<const QVector<QSqlRecord>> &torrentFiles
)
: QDialog(parent)
, m_torrent(torrent)
, m_torrentFiles(torrentFiles)
, m_ui(std::make_unique<Ui::PreviewSelectDialog>())
{
m_ui->setupUi(this);
m_ui->infoLabel->setText(
QStringLiteral("The following files from torrent <strong>%1</strong> "
"support previewing, please select one of them:")
.arg(m_torrent.value("name").toString()));
m_ui->buttonBox->button(QDialogButtonBox::Ok)->setText(QStringLiteral("&Preview"));
// Events
connect(m_ui->buttonBox, &QDialogButtonBox::accepted,
this, &PreviewSelectDialog::previewButtonClicked);
connect(m_ui->previewList, &QAbstractItemView::doubleClicked,
this, &PreviewSelectDialog::previewButtonClicked);
// Create and apply delegate
m_listDelegate = new PreviewListDelegate(this); // NOLINT(cppcoreguidelines-owning-memory)
m_ui->previewList->setItemDelegate(m_listDelegate);
// Preview list model
m_previewListModel = new QStandardItemModel(0, NB_COLUMNS, this); // NOLINT(cppcoreguidelines-owning-memory)
m_previewListModel->setHeaderData(TR_NAME, Qt::Horizontal, QStringLiteral("Name"));
m_previewListModel->setHeaderData(TR_SIZE, Qt::Horizontal, QStringLiteral("Size"));
m_previewListModel->setHeaderData(TR_PROGRESS, Qt::Horizontal, QStringLiteral("Progress"));
// Preview list
m_ui->previewList->setModel(m_previewListModel);
m_ui->previewList->hideColumn(TR_FILE_INDEX);
m_ui->previewList->setAlternatingRowColors(true);
populatePreviewListModel();
// Setup initial sorting
m_previewListModel->sort(TR_NAME);
m_ui->previewList->header()->setSortIndicator(0, Qt::AscendingOrder);
// Header alignment
m_ui->previewList->header()->setDefaultAlignment(Qt::AlignCenter);
// TODO set height on the base of num rows, set min. and max. height silverqx
// Initial focus
m_ui->previewList->setFocus();
// Preselect first line
m_ui->previewList->selectionModel()->select(
m_previewListModel->index(0, TR_NAME),
QItemSelectionModel::Select | QItemSelectionModel::Rows);
}
void PreviewSelectDialog::previewButtonClicked()
{
// Only one file is allowed to select
const auto selectedIndexes = m_ui->previewList->selectionModel()->selectedRows(TR_NAME);
if (selectedIndexes.isEmpty())
return;
const auto selectedIndex = selectedIndexes.first();
if (!selectedIndex.isValid())
return;
// Get file path to preview
const auto filePath = getTorrentFileFilePathAbs(
m_previewListModel->data(selectedIndex).toString());
if (!QFile::exists(filePath)) {
reject();
QMessageBox::critical(this, QStringLiteral("Preview impossible"),
QStringLiteral("Sorry, we can't preview this file:<br>"
"<strong>%1</strong>")
.arg(Utils::Fs::toNativePath(filePath)));
return;
}
emit readyToPreviewFile(filePath);
accept();
}
void PreviewSelectDialog::showEvent(QShowEvent *const event)
{
// Event originated from system
if (event->spontaneous()) {
QDialog::showEvent(event);
return;
}
// Call only once during intial show
if (m_showEventInitialized)
return;
// Move this as top as possible to prevent race condition
m_showEventInitialized = true;
/* Pixel perfectly sized previewList header.
Set Name column width to all remaining area.
Has to be called after the show() because the previewList's width is needed. */
auto *const previewListHeader = m_ui->previewList->header();
previewListHeader->resizeSections(QHeaderView::ResizeToContents);
// Compute name column width
auto nameColWidth = m_ui->previewList->width();
const auto *const vScrollBar = m_ui->previewList->verticalScrollBar();
if (vScrollBar->isVisible())
nameColWidth -= vScrollBar->width();
nameColWidth -= previewListHeader->sectionSize(TR_SIZE) +
previewListHeader->sectionSize(TR_PROGRESS) +
2; // Borders
previewListHeader->resizeSection(TR_NAME, nameColWidth);
m_ui->previewList->header()->setStretchLastSection(true);
}
void PreviewSelectDialog::populatePreviewListModel() const
{
for (const auto &torrentFile : *m_torrentFiles) {
auto filePath = torrentFile.value("filepath").toString();
// Remove qBittorrent extension if needed
if (filePath.endsWith(::QB_EXT))
filePath.chop(4);
// Insert a new row to the model
const auto rowIndex = m_previewListModel->rowCount();
m_previewListModel->insertRow(rowIndex);
// Setup row data
m_previewListModel->setData(m_previewListModel->index(rowIndex, TR_NAME),
filePath);
m_previewListModel->setData(m_previewListModel->index(rowIndex, TR_NAME),
getTorrentFileFilePathAbs(filePath),
Qt::ToolTipRole);
m_previewListModel->setData(m_previewListModel->index(rowIndex, TR_SIZE),
torrentFile.value("size").toULongLong());
m_previewListModel->setData(m_previewListModel->index(rowIndex, TR_PROGRESS),
torrentFile.value("progress").toUInt());
m_previewListModel->setData(m_previewListModel->index(rowIndex, TR_FILE_INDEX),
torrentFile.value("id").toULongLong());
}
}
QString PreviewSelectDialog::getTorrentFileFilePathAbs(const QString &relativePath) const
{
const QDir saveDir(m_torrent.value(TorrentSqlTableModel::TR_SAVE_PATH).toString());
return Utils::Fs::expandPathAbs(saveDir.absoluteFilePath(relativePath));
}