diff --git a/model/syncthingdevicemodel.cpp b/model/syncthingdevicemodel.cpp index 6b90249..9e7b21a 100644 --- a/model/syncthingdevicemodel.cpp +++ b/model/syncthingdevicemodel.cpp @@ -94,165 +94,172 @@ QVariant SyncthingDeviceModel::headerData(int section, Qt::Orientation orientati QVariant SyncthingDeviceModel::data(const QModelIndex &index, int role) const { - if (index.isValid()) { - if (index.parent().isValid()) { - // dir attributes - if (static_cast(index.parent().row()) < m_devs.size()) { - switch (role) { - case Qt::DisplayRole: - case Qt::EditRole: - if (index.column() == 0) { - // attribute names - switch (index.row()) { - case 0: - return tr("ID"); - case 1: - return tr("Addresses"); - case 2: - return tr("Last seen"); - case 3: - return tr("Compression"); - case 4: - return tr("Certificate"); - case 5: - return tr("Introducer"); - case 6: - return tr("Incoming traffic"); - case 7: - return tr("Outgoing traffic"); - case 8: - return tr("Version"); - } - break; - } - FALLTHROUGH; - case DeviceDetail: - if (index.column() == 1 || role == DeviceDetail) { - // attribute values - const SyncthingDev &dev = m_devs[static_cast(index.parent().row())]; - switch (index.row()) { - case 0: - return dev.id; - case 1: - return dev.addresses.join(QStringLiteral(", ")); - case 2: - return dev.lastSeen.isNull() ? tr("unknown or own device") - : QString::fromLatin1(dev.lastSeen.toString(DateTimeOutputFormat::DateAndTime, true).data()); - case 3: - return dev.compression; - case 4: - return dev.certName.isEmpty() ? tr("none") : dev.certName; - case 5: - return dev.introducer ? tr("yes") : tr("no"); - case 6: - return QString::fromStdString(dataSizeToString(dev.totalIncomingTraffic)); - case 7: - return QString::fromStdString(dataSizeToString(dev.totalOutgoingTraffic)); - case 8: - return dev.clientVersion; - } - } - break; - case Qt::ForegroundRole: - switch (index.column()) { - case 1: - const SyncthingDev &dev = m_devs[static_cast(index.parent().row())]; - switch (index.row()) { - case 2: - if (dev.lastSeen.isNull()) { - return Colors::gray(m_brightColors); - } - break; - case 4: - if (dev.certName.isEmpty()) { - return Colors::gray(m_brightColors); - } - break; - } - } - break; - case Qt::ToolTipRole: - switch (index.column()) { - case 1: - switch (index.row()) { - case 2: - const SyncthingDev &dev = m_devs[static_cast(index.parent().row())]; - if (!dev.lastSeen.isNull()) { - return agoString(dev.lastSeen); - } - break; - } - } - break; - default:; - } - } - } else if (static_cast(index.row()) < m_devs.size()) { - // dir IDs and status - const SyncthingDev &dev = m_devs[static_cast(index.row())]; - switch (role) { - case Qt::DisplayRole: - case Qt::EditRole: - switch (index.column()) { - case 0: - return dev.name.isEmpty() ? dev.id : dev.name; - case 1: - return devStatusString(dev); - } - case Qt::DecorationRole: - switch (index.column()) { - case 0: - if (dev.paused) { - return statusIcons().pause; - } else { - switch (dev.status) { - case SyncthingDevStatus::Unknown: - case SyncthingDevStatus::Disconnected: - return statusIcons().disconnected; - case SyncthingDevStatus::OwnDevice: - case SyncthingDevStatus::Idle: - return statusIcons().idling; - case SyncthingDevStatus::Synchronizing: - return statusIcons().sync; - case SyncthingDevStatus::OutOfSync: - case SyncthingDevStatus::Rejected: - return statusIcons().error; - } - } - break; - } - break; - case Qt::TextAlignmentRole: - switch (index.column()) { - case 0: - break; - case 1: - return static_cast(Qt::AlignRight | Qt::AlignVCenter); - } - break; - case Qt::ForegroundRole: - switch (index.column()) { - case 0: - break; - case 1: - return devStatusColor(dev); - } - break; - case DeviceStatus: - return static_cast(dev.status); - case DevicePaused: - return dev.paused; - case IsOwnDevice: - return dev.status == SyncthingDevStatus::OwnDevice; - case DeviceStatusString: - return devStatusString(dev); - case DeviceStatusColor: - return devStatusColor(dev); - case DeviceId: - return dev.id; - default:; - } + if (!index.isValid()) { + return QVariant(); + } + if (index.parent().isValid()) { + // dir attributes + if (static_cast(index.parent().row()) >= m_devs.size()) { + return QVariant(); } + switch (role) { + case Qt::DisplayRole: + case Qt::EditRole: + if (index.column() == 0) { + // attribute names + switch (index.row()) { + case 0: + return tr("ID"); + case 1: + return tr("Addresses"); + case 2: + return tr("Last seen"); + case 3: + return tr("Compression"); + case 4: + return tr("Certificate"); + case 5: + return tr("Introducer"); + case 6: + return tr("Incoming traffic"); + case 7: + return tr("Outgoing traffic"); + case 8: + return tr("Version"); + } + break; + } + FALLTHROUGH; + case DeviceDetail: + if (index.column() == 1 || role == DeviceDetail) { + // attribute values + const SyncthingDev &dev = m_devs[static_cast(index.parent().row())]; + switch (index.row()) { + case 0: + return dev.id; + case 1: + return dev.addresses.join(QStringLiteral(", ")); + case 2: + return dev.lastSeen.isNull() ? tr("unknown or own device") + : QString::fromLatin1(dev.lastSeen.toString(DateTimeOutputFormat::DateAndTime, true).data()); + case 3: + return dev.compression; + case 4: + return dev.certName.isEmpty() ? tr("none") : dev.certName; + case 5: + return dev.introducer ? tr("yes") : tr("no"); + case 6: + return QString::fromStdString(dataSizeToString(dev.totalIncomingTraffic)); + case 7: + return QString::fromStdString(dataSizeToString(dev.totalOutgoingTraffic)); + case 8: + return dev.clientVersion; + } + } + break; + case Qt::ForegroundRole: + switch (index.column()) { + case 1: + const SyncthingDev &dev = m_devs[static_cast(index.parent().row())]; + switch (index.row()) { + case 2: + if (dev.lastSeen.isNull()) { + return Colors::gray(m_brightColors); + } + break; + case 4: + if (dev.certName.isEmpty()) { + return Colors::gray(m_brightColors); + } + break; + } + } + break; + case Qt::ToolTipRole: + switch (index.column()) { + case 1: + switch (index.row()) { + case 2: + const SyncthingDev &dev = m_devs[static_cast(index.parent().row())]; + if (!dev.lastSeen.isNull()) { + return agoString(dev.lastSeen); + } + break; + } + } + break; + default:; + } + return QVariant(); + } + + if (static_cast(index.row()) >= m_devs.size()) { + return QVariant(); + } + + // dir IDs and status + const SyncthingDev &dev = m_devs[static_cast(index.row())]; + switch (role) { + case Qt::DisplayRole: + case Qt::EditRole: + switch (index.column()) { + case 0: + return dev.name.isEmpty() ? dev.id : dev.name; + case 1: + return devStatusString(dev); + } + case Qt::DecorationRole: + switch (index.column()) { + case 0: + if (dev.paused) { + return statusIcons().pause; + } else { + switch (dev.status) { + case SyncthingDevStatus::Unknown: + case SyncthingDevStatus::Disconnected: + return statusIcons().disconnected; + case SyncthingDevStatus::OwnDevice: + case SyncthingDevStatus::Idle: + return statusIcons().idling; + case SyncthingDevStatus::Synchronizing: + return statusIcons().sync; + case SyncthingDevStatus::OutOfSync: + case SyncthingDevStatus::Rejected: + return statusIcons().error; + } + } + break; + } + break; + case Qt::TextAlignmentRole: + switch (index.column()) { + case 0: + break; + case 1: + return static_cast(Qt::AlignRight | Qt::AlignVCenter); + } + break; + case Qt::ForegroundRole: + switch (index.column()) { + case 0: + break; + case 1: + return devStatusColor(dev); + } + break; + case DeviceStatus: + return static_cast(dev.status); + case DevicePaused: + return dev.paused; + case IsOwnDevice: + return dev.status == SyncthingDevStatus::OwnDevice; + case DeviceStatusString: + return devStatusString(dev); + case DeviceStatusColor: + return devStatusColor(dev); + case DeviceId: + return dev.id; + default:; } return QVariant(); } diff --git a/model/syncthingdirectorymodel.cpp b/model/syncthingdirectorymodel.cpp index aa3c729..9a513a3 100644 --- a/model/syncthingdirectorymodel.cpp +++ b/model/syncthingdirectorymodel.cpp @@ -98,226 +98,231 @@ QVariant SyncthingDirectoryModel::headerData(int section, Qt::Orientation orient QVariant SyncthingDirectoryModel::data(const QModelIndex &index, int role) const { - if (index.isValid()) { - if (index.parent().isValid()) { - // dir attributes - if (static_cast(index.parent().row()) < m_dirs.size()) { - const SyncthingDir &dir = m_dirs[static_cast(index.parent().row())]; - const auto row = dir.paused && index.row() > 1 ? index.row() + 2 : index.row(); - switch (role) { - case Qt::DisplayRole: - case Qt::EditRole: - if (index.column() == 0) { - // attribute names - switch (row) { - case 0: - return tr("ID"); - case 1: - return tr("Path"); - case 2: - return tr("Global status"); - case 3: - return tr("Local status"); - case 4: - return tr("Shared with"); - case 5: - return tr("Type"); - case 6: - return tr("Rescan interval"); - case 7: - return tr("Last scan"); - case 8: - return tr("Last file"); - case 9: - return tr("Errors"); - } - break; - } - FALLTHROUGH; - case DirectoryDetail: - if (index.column() == 1 || role == DirectoryDetail) { - // attribute values - switch (row) { - case 0: - return dir.id; - case 1: - return dir.path; - case 2: - return directoryStatusString(dir.globalStats); - case 3: - return directoryStatusString(dir.localStats); - case 4: - if (!dir.deviceNames.isEmpty()) { - return dir.deviceNames.join(QStringLiteral(", ")); - } else if (!dir.deviceIds.isEmpty()) { - return dir.deviceIds.join(QStringLiteral(", ")); - } else { - return tr("not shared"); - } - case 5: - return dir.dirTypeString(); - case 6: - return rescanIntervalString(dir.rescanInterval, dir.fileSystemWatcherEnabled); - case 7: - return dir.lastScanTime.isNull() - ? tr("unknown") - : QString::fromLatin1(dir.lastScanTime.toString(DateTimeOutputFormat::DateAndTime, true).data()); - case 8: - return dir.lastFileName.isEmpty() ? tr("unknown") : dir.lastFileName; - case 9: - if (dir.globalError.isEmpty() && !dir.pullErrorCount) { - return tr("none"); - } - if (!dir.pullErrorCount) { - return dir.globalError; - } - if (dir.globalError.isEmpty()) { - return tr("%1 item(s) out of sync", nullptr, trQuandity(dir.pullErrorCount)).arg(dir.pullErrorCount); - } - return tr("%1 and %2 item(s) out of sync", nullptr, trQuandity(dir.pullErrorCount)) - .arg(dir.globalError) - .arg(dir.pullErrorCount); - } - } - break; - case Qt::ForegroundRole: - switch (index.column()) { - case 1: - const SyncthingDir &dir = m_dirs[static_cast(index.parent().row())]; - switch (row) { - case 4: - if (dir.deviceIds.isEmpty()) { - return Colors::gray(m_brightColors); - } - break; - case 7: - if (dir.lastScanTime.isNull()) { - return Colors::gray(m_brightColors); - } - break; - case 8: - return dir.lastFileName.isEmpty() ? Colors::gray(m_brightColors) - : (dir.lastFileDeleted ? Colors::red(m_brightColors) : QVariant()); - case 9: - return dir.globalError.isEmpty() && !dir.pullErrorCount ? Colors::gray(m_brightColors) : Colors::red(m_brightColors); - } - } - break; - case Qt::ToolTipRole: - switch (index.column()) { - case 1: - const SyncthingDir &dir = m_dirs[static_cast(index.parent().row())]; - switch (row) { - case 3: - if (dir.deviceNames.isEmpty()) { - return dir.deviceIds.join(QChar('\n')); - } else { - return QString(dir.deviceNames.join(QStringLiteral(", ")) % QChar('\n') % QChar('(') % dir.deviceIds.join(QChar('\n')) - % QChar(')')); - } - case 7: - if (!dir.lastScanTime.isNull()) { - return agoString(dir.lastScanTime); - } - break; - case 8: - if (!dir.lastFileTime.isNull()) { - if (dir.lastFileDeleted) { - return tr("Deleted at %1") - .arg(QString::fromLatin1(dir.lastFileTime.toString(DateTimeOutputFormat::DateAndTime, true).data())); - } else { - return tr("Updated at %1") - .arg(QString::fromLatin1(dir.lastFileTime.toString(DateTimeOutputFormat::DateAndTime, true).data())); - } - } - break; - case 9: - if (!dir.itemErrors.empty()) { - QStringList errors; - errors.reserve(static_cast(dir.itemErrors.size())); - for (const auto &error : dir.itemErrors) { - errors << error.path; - } - return QVariant(QStringLiteral("") % tr("Failed items") % QStringLiteral("
  • ") - % errors.join(QStringLiteral("
  • ")) % QStringLiteral("
") % tr("Click for details")); - } - } - } - break; - default:; - } - } - } else if (static_cast(index.row()) < m_dirs.size()) { - // dir IDs and status - const SyncthingDir &dir = m_dirs[static_cast(index.row())]; - switch (role) { - case Qt::DisplayRole: - case Qt::EditRole: - switch (index.column()) { - case 0: - return dir.label.isEmpty() ? dir.id : dir.label; - case 1: - return dirStatusString(dir); - } - break; - case Qt::DecorationRole: - switch (index.column()) { - case 0: - if (dir.paused && dir.status != SyncthingDirStatus::OutOfSync) { - return statusIcons().pause; - } else if (dir.deviceIds.empty()) { - return statusIcons().disconnected; // "unshared" status - } else { - switch (dir.status) { - case SyncthingDirStatus::Unknown: - return statusIcons().disconnected; - case SyncthingDirStatus::Idle: - return statusIcons().idling; - case SyncthingDirStatus::Scanning: - return statusIcons().scanninig; - case SyncthingDirStatus::Synchronizing: - return statusIcons().sync; - case SyncthingDirStatus::OutOfSync: - return statusIcons().error; - } - } - break; - } - break; - case Qt::TextAlignmentRole: - switch (index.column()) { - case 0: - break; - case 1: - return static_cast(Qt::AlignRight | Qt::AlignVCenter); - } - break; - case Qt::ForegroundRole: - switch (index.column()) { - case 0: - break; - case 1: - return dirStatusColor(dir); - } - break; - case DirectoryStatus: - return static_cast(dir.status); - case DirectoryPaused: - return dir.paused; - case DirectoryStatusString: - return dirStatusString(dir); - case DirectoryStatusColor: - return dirStatusColor(dir); - case DirectoryId: - return dir.id; - case DirectoryPath: - return dir.path; - case DirectoryPullErrorCount: - return dir.pullErrorCount; - default:; - } - } + if (!index.isValid()) { + return QVariant(); } + if (index.parent().isValid()) { + // dir attributes + if (static_cast(index.parent().row()) >= m_dirs.size()) { + return QVariant(); + } + const SyncthingDir &dir = m_dirs[static_cast(index.parent().row())]; + const auto row = dir.paused && index.row() > 1 ? index.row() + 2 : index.row(); + switch (role) { + case Qt::DisplayRole: + case Qt::EditRole: + if (index.column() == 0) { + // attribute names + switch (row) { + case 0: + return tr("ID"); + case 1: + return tr("Path"); + case 2: + return tr("Global status"); + case 3: + return tr("Local status"); + case 4: + return tr("Shared with"); + case 5: + return tr("Type"); + case 6: + return tr("Rescan interval"); + case 7: + return tr("Last scan"); + case 8: + return tr("Last file"); + case 9: + return tr("Errors"); + } + break; + } + FALLTHROUGH; + case DirectoryDetail: + if (index.column() == 1 || role == DirectoryDetail) { + // attribute values + switch (row) { + case 0: + return dir.id; + case 1: + return dir.path; + case 2: + return directoryStatusString(dir.globalStats); + case 3: + return directoryStatusString(dir.localStats); + case 4: + if (!dir.deviceNames.isEmpty()) { + return dir.deviceNames.join(QStringLiteral(", ")); + } else if (!dir.deviceIds.isEmpty()) { + return dir.deviceIds.join(QStringLiteral(", ")); + } else { + return tr("not shared"); + } + case 5: + return dir.dirTypeString(); + case 6: + return rescanIntervalString(dir.rescanInterval, dir.fileSystemWatcherEnabled); + case 7: + return dir.lastScanTime.isNull() ? tr("unknown") + : QString::fromLatin1(dir.lastScanTime.toString(DateTimeOutputFormat::DateAndTime, true).data()); + case 8: + return dir.lastFileName.isEmpty() ? tr("unknown") : dir.lastFileName; + case 9: + if (dir.globalError.isEmpty() && !dir.pullErrorCount) { + return tr("none"); + } + if (!dir.pullErrorCount) { + return dir.globalError; + } + if (dir.globalError.isEmpty()) { + return tr("%1 item(s) out of sync", nullptr, trQuandity(dir.pullErrorCount)).arg(dir.pullErrorCount); + } + return tr("%1 and %2 item(s) out of sync", nullptr, trQuandity(dir.pullErrorCount)).arg(dir.globalError).arg(dir.pullErrorCount); + } + } + break; + case Qt::ForegroundRole: + switch (index.column()) { + case 1: + const SyncthingDir &dir = m_dirs[static_cast(index.parent().row())]; + switch (row) { + case 4: + if (dir.deviceIds.isEmpty()) { + return Colors::gray(m_brightColors); + } + break; + case 7: + if (dir.lastScanTime.isNull()) { + return Colors::gray(m_brightColors); + } + break; + case 8: + return dir.lastFileName.isEmpty() ? Colors::gray(m_brightColors) + : (dir.lastFileDeleted ? Colors::red(m_brightColors) : QVariant()); + case 9: + return dir.globalError.isEmpty() && !dir.pullErrorCount ? Colors::gray(m_brightColors) : Colors::red(m_brightColors); + } + } + break; + case Qt::ToolTipRole: + switch (index.column()) { + case 1: + const SyncthingDir &dir = m_dirs[static_cast(index.parent().row())]; + switch (row) { + case 3: + if (dir.deviceNames.isEmpty()) { + return dir.deviceIds.join(QChar('\n')); + } else { + return QString( + dir.deviceNames.join(QStringLiteral(", ")) % QChar('\n') % QChar('(') % dir.deviceIds.join(QChar('\n')) % QChar(')')); + } + case 7: + if (!dir.lastScanTime.isNull()) { + return agoString(dir.lastScanTime); + } + break; + case 8: + if (!dir.lastFileTime.isNull()) { + if (dir.lastFileDeleted) { + return tr("Deleted at %1") + .arg(QString::fromLatin1(dir.lastFileTime.toString(DateTimeOutputFormat::DateAndTime, true).data())); + } else { + return tr("Updated at %1") + .arg(QString::fromLatin1(dir.lastFileTime.toString(DateTimeOutputFormat::DateAndTime, true).data())); + } + } + break; + case 9: + if (!dir.itemErrors.empty()) { + QStringList errors; + errors.reserve(static_cast(dir.itemErrors.size())); + for (const auto &error : dir.itemErrors) { + errors << error.path; + } + return QVariant(QStringLiteral("") % tr("Failed items") % QStringLiteral("
  • ") + % errors.join(QStringLiteral("
  • ")) % QStringLiteral("
") % tr("Click for details")); + } + } + } + break; + default:; + } + return QVariant(); + } + + if (static_cast(index.row()) >= m_dirs.size()) { + return QVariant(); + } + + // dir IDs and status + const SyncthingDir &dir = m_dirs[static_cast(index.row())]; + switch (role) { + case Qt::DisplayRole: + case Qt::EditRole: + switch (index.column()) { + case 0: + return dir.label.isEmpty() ? dir.id : dir.label; + case 1: + return dirStatusString(dir); + } + break; + case Qt::DecorationRole: + switch (index.column()) { + case 0: + if (dir.paused && dir.status != SyncthingDirStatus::OutOfSync) { + return statusIcons().pause; + } else if (dir.deviceIds.empty()) { + return statusIcons().disconnected; // "unshared" status + } else { + switch (dir.status) { + case SyncthingDirStatus::Unknown: + return statusIcons().disconnected; + case SyncthingDirStatus::Idle: + return statusIcons().idling; + case SyncthingDirStatus::Scanning: + return statusIcons().scanninig; + case SyncthingDirStatus::Synchronizing: + return statusIcons().sync; + case SyncthingDirStatus::OutOfSync: + return statusIcons().error; + } + } + break; + } + break; + case Qt::TextAlignmentRole: + switch (index.column()) { + case 0: + break; + case 1: + return static_cast(Qt::AlignRight | Qt::AlignVCenter); + } + break; + case Qt::ForegroundRole: + switch (index.column()) { + case 0: + break; + case 1: + return dirStatusColor(dir); + } + break; + case DirectoryStatus: + return static_cast(dir.status); + case DirectoryPaused: + return dir.paused; + case DirectoryStatusString: + return dirStatusString(dir); + case DirectoryStatusColor: + return dirStatusColor(dir); + case DirectoryId: + return dir.id; + case DirectoryPath: + return dir.path; + case DirectoryPullErrorCount: + return dir.pullErrorCount; + default:; + } + return QVariant(); } diff --git a/model/syncthingdownloadmodel.cpp b/model/syncthingdownloadmodel.cpp index f54f455..4c73bdc 100644 --- a/model/syncthingdownloadmodel.cpp +++ b/model/syncthingdownloadmodel.cpp @@ -108,73 +108,81 @@ QVariant SyncthingDownloadModel::headerData(int section, Qt::Orientation orienta QVariant SyncthingDownloadModel::data(const QModelIndex &index, int role) const { - if (index.isValid()) { - if (index.parent().isValid()) { - // downloading items (of dir) - if (static_cast(index.parent().row()) < m_pendingDirs.size()) { - const SyncthingDir &dir = *m_pendingDirs[static_cast(index.parent().row())].syncthingDir; - if (static_cast(index.row()) < dir.downloadingItems.size()) { - const SyncthingItemDownloadProgress &progress = dir.downloadingItems[static_cast(index.row())]; - switch (role) { - case Qt::DisplayRole: - case Qt::EditRole: - switch (index.column()) { - case 0: // file names - return progress.relativePath; - case 1: // progress information - return progress.label; - } - break; - case Qt::ToolTipRole: - break; - case Qt::DecorationRole: - switch (index.column()) { - case 0: // file icon - return progress.fileInfo.exists() ? m_fileIconProvider.icon(progress.fileInfo) : m_unknownIcon; - default:; - } - break; - case ItemPercentage: - return progress.downloadPercentage; - case ItemProgressLabel: - return progress.label; - case ItemPath: - return dir.path + progress.relativePath; - default:; - } - } - } - } else if (static_cast(index.row()) < m_pendingDirs.size()) { - // dir IDs and overall dir progress - const SyncthingDir &dir = *m_pendingDirs[static_cast(index.row())].syncthingDir; + if (!index.isValid()) { + return QVariant(); + } + + if (index.parent().isValid()) { + // downloading items (of dir) + if (static_cast(index.parent().row()) >= m_pendingDirs.size()) { + return QVariant(); + } + const SyncthingDir &dir = *m_pendingDirs[static_cast(index.parent().row())].syncthingDir; + if (static_cast(index.row()) < dir.downloadingItems.size()) { + const SyncthingItemDownloadProgress &progress = dir.downloadingItems[static_cast(index.row())]; switch (role) { case Qt::DisplayRole: case Qt::EditRole: switch (index.column()) { - case 0: - return QVariant((dir.label.isEmpty() ? dir.id : dir.label) % QChar(' ') % QChar('(') - % QString::number(dir.downloadingItems.size()) % QChar(')')); - case 1: - return dir.downloadLabel; + case 0: // file names + return progress.relativePath; + case 1: // progress information + return progress.label; } break; - case Qt::TextAlignmentRole: + case Qt::ToolTipRole: + break; + case Qt::DecorationRole: switch (index.column()) { - case 0: - break; - case 1: - return static_cast(Qt::AlignRight | Qt::AlignVCenter); + case 0: // file icon + return progress.fileInfo.exists() ? m_fileIconProvider.icon(progress.fileInfo) : m_unknownIcon; + default:; } break; case ItemPercentage: - return dir.downloadPercentage; + return progress.downloadPercentage; case ItemProgressLabel: - return dir.downloadLabel; + return progress.label; case ItemPath: - return dir.path; + return dir.path + progress.relativePath; default:; } } + return QVariant(); + } + + if (static_cast(index.row()) >= m_pendingDirs.size()) { + return QVariant(); + } + + // dir IDs and overall dir progress + const SyncthingDir &dir = *m_pendingDirs[static_cast(index.row())].syncthingDir; + switch (role) { + case Qt::DisplayRole: + case Qt::EditRole: + switch (index.column()) { + case 0: + return QVariant( + (dir.label.isEmpty() ? dir.id : dir.label) % QChar(' ') % QChar('(') % QString::number(dir.downloadingItems.size()) % QChar(')')); + case 1: + return dir.downloadLabel; + } + break; + case Qt::TextAlignmentRole: + switch (index.column()) { + case 0: + break; + case 1: + return static_cast(Qt::AlignRight | Qt::AlignVCenter); + } + break; + case ItemPercentage: + return dir.downloadPercentage; + case ItemProgressLabel: + return dir.downloadLabel; + case ItemPath: + return dir.path; + default:; } return QVariant(); }