27 #include "util/display.h"
31 #include <QHeaderView>
32 #include <QPushButton>
34 #include <QMouseEvent>
38 QRect pauseRect(
const QStyleOptionViewItem& option)
40 float controlSize = option.rect.height() * 0.8f;
41 float rectWidth = option.rect.width();
42 float buttonHorizontalArea = rectWidth / 2;
46 int buttonXPos = std::round(option.rect.x() + buttonHorizontalArea / 2 - controlSize / 2);
47 int buttonYPos = std::round(option.rect.y() + option.rect.height() * 0.1f);
48 return QRect(buttonXPos, buttonYPos, controlSize, controlSize);
51 QRect stopRect(
const QStyleOptionViewItem& option)
53 float controlSize = option.rect.height() * 0.8;
54 float rectWidth = option.rect.width();
55 float buttonHorizontalArea = rectWidth / 2;
59 int buttonXPos = std::round(option.rect.x() + buttonHorizontalArea + buttonHorizontalArea / 2 - controlSize / 2);
60 int buttonYPos = std::round(option.rect.y() + option.rect.height() * 0.1f);
61 return QRect(buttonXPos, buttonYPos, controlSize, controlSize);
64 QString fileStatusString(
ToxFile file)
69 return QObject::tr(
"Initializing");
71 return QObject::tr(
"Transmitting");
73 return QObject::tr(
"Finished");
75 return QObject::tr(
"Broken");
77 return QObject::tr(
"Canceled");
79 if (
file.pauseStatus.localPaused()) {
80 return QObject::tr(
"Paused");
82 return QObject::tr(
"Remote paused");
86 qWarning(
"Corrupt file status %d",
file.status);
103 qWarning(
"Invalid file status: %d", status);
107 bool shouldProcessFileKind(uint8_t inKind)
109 auto kind =
static_cast<TOX_FILE_KIND
>(inKind);
113 case TOX_FILE_KIND_DATA:
return true;
116 case TOX_FILE_KIND_AVATAR:
return false;
119 qWarning(
"Unexpected file kind %d", kind);
129 return static_cast<Column>(in);
132 qWarning(
"Invalid file transfer list column %d", in);
140 return QObject::tr(
"File Name");
142 return QObject::tr(
"Contact");
144 return QObject::tr(
"Progress");
146 return QObject::tr(
"Size");
148 return QObject::tr(
"Speed");
150 return QObject::tr(
"Status");
152 return QObject::tr(
"Control");
162 qWarning(
"Unexpected editor action %d", in);
170 : QAbstractTableModel(parent)
175 if (role != Qt::DisplayRole) {
179 if (orientation != Qt::Orientation::Horizontal) {
189 if (!shouldProcessFileKind(
file.fileKind)) {
197 if (
files.size() >= std::numeric_limits<int>::max()) {
200 qWarning(
"Too many file transfers rendered, ignoring");
204 auto insertedIdx =
files.size();
206 emit rowsAboutToBeInserted(QModelIndex(), insertedIdx, insertedIdx, {});
211 emit rowsInserted(QModelIndex(), insertedIdx, insertedIdx, {});
213 rowIdx = idxIt.value();
215 if (fileTransferFailed(
file.status)) {
216 emit rowsAboutToBeRemoved(QModelIndex(), rowIdx, rowIdx, {});
219 if (it.value() > rowIdx) {
226 emit rowsRemoved(QModelIndex(), rowIdx, rowIdx, {});
229 emit dataChanged(index(rowIdx, 0), index(rowIdx,
columnCount()));
247 const auto row = index.row();
248 if (row < 0 ||
static_cast<size_t>(row) >
files.size()) {
249 qWarning(
"Invalid file transfer row %d (files: %lu)", row,
files.size());
253 if (role == Qt::UserRole) {
254 return files[row].filePath;
257 if (role != Qt::DisplayRole) {
266 return files[row].fileName;
271 qWarning(
"Invalid friend for file transfer");
275 return f->getDisplayedName();
278 return files[row].progress.getProgress() * 100.0;
280 return getHumanReadableSize(
files[row].
progress.getFileSize());
282 return getHumanReadableSize(
files[row].
progress.getSpeed()) +
"/s";
284 return fileStatusString(
files[row]);
286 return files[row].pauseStatus.localPaused();
302 if (!value.canConvert<
int>()) {
303 qWarning(
"Unexpected model data");
325 : QStyledItemDelegate(parent)
328 void Delegate::paint(QPainter* painter,
const QStyleOptionViewItem& option,
const QModelIndex& index)
const
335 int progress = index.data().toInt();
337 QStyleOptionProgressBar progressBarOption;
338 progressBarOption.rect = option.rect;
339 progressBarOption.minimum = 0;
340 progressBarOption.maximum = 100;
341 progressBarOption.progress =
progress;
342 progressBarOption.text = QString::number(
progress) +
"%";
343 progressBarOption.textVisible =
true;
345 QApplication::style()->drawControl(QStyle::CE_ProgressBar,
346 &progressBarOption, painter);
351 const auto data = index.data();
352 if (!data.canConvert<
bool>()) {
353 qWarning(
"Unexpected control type, not rendering controls");
356 const auto localPaused = data.toBool();
357 QPixmap pausePixmap = localPaused
360 QApplication::style()->drawItemPixmap(painter, pauseRect(option), Qt::AlignCenter, pausePixmap);
363 QApplication::style()->drawItemPixmap(painter, stopRect(option), Qt::AlignCenter, stopPixmap);
375 QStyledItemDelegate::paint(painter, option, index);
379 const QStyleOptionViewItem& option,
const QModelIndex& index)
383 if (event->type() == QEvent::MouseButtonPress) {
384 auto mouseEvent =
reinterpret_cast<QMouseEvent*
>(event);
385 const auto pos = mouseEvent->pos();
386 const auto posRect = pauseRect(option);
387 const auto stRect = stopRect(option);
389 if (posRect.contains(pos)) {
391 }
else if (stRect.contains(pos)) {
407 horizontalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents);
408 horizontalHeader()->setSectionResizeMode(0, QHeaderView::Stretch);
410 horizontalHeader()->setMinimumSectionSize(75);
411 horizontalHeader()->setStretchLastSection(
false);
412 verticalHeader()->hide();
414 setSelectionBehavior(QAbstractItemView::SelectRows);
415 setSelectionMode(QAbstractItemView::SingleSelection);
416 setItemDelegate(
new Delegate(
this));
426 head =
new QWidget();
476 if (
main.isVisible()) {
477 head->window()->windowHandle()->alert(0);
494 if (!shouldProcessFileKind(inFile.
fileKind)) {
505 qWarning(
"Unexpected file direction");
511 const auto& filePath =
sentModel->
data(index, Qt::UserRole).toString();
517 const auto& filePath =
recvdModel->
data(index, Qt::UserRole).toString();
523 headLabel.setText(tr(
"Transferred files",
"\"Headline\" of the window"));
524 main.setTabText(0, tr(
"Downloads"));
525 main.setTabText(1, tr(
"Uploads"));