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"));