[network/ktorrent] /: Modernize model columns with enum class

Jack Hill <[email protected]>
Newsgroups gmane.comp.kde.cvs
Message-ID <[email protected]>
Git commit c216e54aee4f344a1dd138d21614222a294cd89a by Jack Hill.
Committed on 05/08/2026 at 21:23.
Pushed by jackh into branch 'master'.

Modernize model columns with enum class

M  +21   -19   ktorrent/dialogs/speedlimitsmodel.cpp
M  +10   -0    ktorrent/dialogs/speedlimitsmodel.h
M  +3    -1    ktorrent/dialogs/spinboxdelegate.cpp
M  +12   -11   ktorrent/tools/magnetmodel.cpp
M  +8    -0    ktorrent/tools/magnetmodel.h
M  +17   -16   ktorrent/tools/queuemanagermodel.cpp
M  +10   -0    ktorrent/tools/queuemanagermodel.h
M  +1    -1    ktorrent/view/view.cpp
M  +1    -1    ktorrent/view/viewdelegate.cpp
M  +129  -128  ktorrent/view/viewmodel.cpp
M  +7    -6    ktorrent/view/viewmodel.h
M  +13   -12   libktcore/torrent/torrentfilelistmodel.cpp
M  +8    -0    libktcore/torrent/torrentfilelistmodel.h
M  +13   -12   libktcore/torrent/torrentfiletreemodel.cpp
M  +7    -0    libktcore/torrent/torrentfiletreemodel.h
M  +31   -28   plugins/infowidget/chunkdownloadmodel.cpp
M  +13   -4    plugins/infowidget/chunkdownloadmodel.h
M  +32   -24   plugins/infowidget/iwfilelistmodel.cpp
M  +8    -0    plugins/infowidget/iwfilelistmodel.h
M  +32   -26   plugins/infowidget/iwfiletreemodel.cpp
M  +8    -0    plugins/infowidget/iwfiletreemodel.h
M  +81   -78   plugins/infowidget/peerviewmodel.cpp
M  +24   -3    plugins/infowidget/peerviewmodel.h
M  +30   -27   plugins/infowidget/trackermodel.cpp
M  +13   -2    plugins/infowidget/trackermodel.h
M  +23   -18   plugins/infowidget/webseedsmodel.cpp
M  +9    -0    plugins/infowidget/webseedsmodel.h
M  +11   -10   plugins/logviewer/logflags.cpp
M  +7    -0    plugins/logviewer/logflags.h
M  +18   -17   plugins/mediaplayer/playlist.cpp
M  +10   -0    plugins/mediaplayer/playlist.h
M  +13   -11   plugins/shutdown/shutdowntorrentmodel.cpp
M  +7    -0    plugins/shutdown/shutdowntorrentmodel.h
M  +13   -12   plugins/syndication/feedwidgetmodel.cpp
M  +8    -0    plugins/syndication/feedwidgetmodel.h
M  +14   -11   plugins/upnp/routermodel.cpp
M  +7    -0    plugins/upnp/routermodel.h

https://invent.kde.org/network/ktorrent/-/commit/c216e54aee4f344a1dd138d21614222a294cd89a

diff --git a/ktorrent/dialogs/speedlimitsmodel.cpp b/ktorrent/dialogs/speedlimitsmodel.cpp
index 59f641cf7..b97697ebb 100644
--- a/ktorrent/dialogs/speedlimitsmodel.cpp
+++ b/ktorrent/dialogs/speedlimitsmodel.cpp
@@ -88,7 +88,7 @@ int SpeedLimitsModel::columnCount(const QModelIndex &parent) const
     if (parent.isValid()) {
         return 0;
     } else {
-        return 5;
+        return NUM_COLUMNS;
     }
 }
 
@@ -98,16 +98,16 @@ QVariant SpeedLimitsModel::headerData(int section, Qt::Orientation orientation,
         return QVariant();
     }
 
-    switch (section) {
-    case 0:
+    switch (Column{section}) {
+    case Column::TORRENT:
         return i18n("Torrent");
-    case 1:
+    case Column::DOWNLOAD_LIMIT:
         return i18n("Download Limit");
-    case 2:
+    case Column::UPLOAD_LIMIT:
         return i18n("Upload Limit");
-    case 3:
+    case Column::ASSURED_DOWNLOAD_SPEED:
         return i18n("Assured Download Speed");
-    case 4:
+    case Column::ASSURED_UPLOAD_SPEED:
         return i18n("Assured Upload Speed");
     default:
         return QVariant();
@@ -127,28 +127,28 @@ QVariant SpeedLimitsModel::data(const QModelIndex &index, int role) const
 
     const Limits &lim = limits[tc];
 
-    switch (index.column()) {
-    case 0:
+    switch (Column{index.column()}) {
+    case Column::TORRENT:
         return tc->getDisplayName();
-    case 1:
+    case Column::DOWNLOAD_LIMIT:
         if (role == Qt::EditRole || role == Qt::UserRole) {
             return lim.down / 1024;
         } else {
             return lim.down == 0 ? i18n("No limit") : BytesPerSecToString(lim.down);
         }
-    case 2:
+    case Column::UPLOAD_LIMIT:
         if (role == Qt::EditRole || role == Qt::UserRole) {
             return lim.up / 1024;
         } else {
             return lim.up == 0 ? i18n("No limit") : BytesPerSecToString(lim.up);
         }
-    case 3:
+    case Column::ASSURED_DOWNLOAD_SPEED:
         if (role == Qt::EditRole || role == Qt::UserRole) {
             return lim.assured_down / 1024;
         } else {
             return lim.assured_down == 0 ? i18n("No assured speed") : BytesPerSecToString(lim.assured_down);
         }
-    case 4:
+    case Column::ASSURED_UPLOAD_SPEED:
         if (role == Qt::EditRole || role == Qt::UserRole) {
             return lim.assured_up / 1024;
         } else {
@@ -173,19 +173,21 @@ bool SpeedLimitsModel::setData(const QModelIndex &index, const QVariant &value,
     bool ok = false;
     Limits &lim = limits[tc];
 
-    switch (index.column()) {
-    case 1:
+    switch (Column{index.column()}) {
+    case Column::DOWNLOAD_LIMIT:
         lim.down = value.toInt(&ok) * 1024;
         break;
-    case 2:
+    case Column::UPLOAD_LIMIT:
         lim.up = value.toInt(&ok) * 1024;
         break;
-    case 3:
+    case Column::ASSURED_DOWNLOAD_SPEED:
         lim.assured_down = value.toInt(&ok) * 1024;
         break;
-    case 4:
+    case Column::ASSURED_UPLOAD_SPEED:
         lim.assured_up = value.toInt(&ok) * 1024;
         break;
+    default:
+        break;
     }
 
     if (ok) {
@@ -205,7 +207,7 @@ Qt::ItemFlags SpeedLimitsModel::flags(const QModelIndex &index) const
         return Qt::ItemIsEnabled;
     }
 
-    if (index.column() > 0) {
+    if (Column{index.column()} > Column::TORRENT) {
         return QAbstractItemModel::flags(index) | Qt::ItemIsEditable;
     } else {
         return QAbstractItemModel::flags(index);
diff --git a/ktorrent/dialogs/speedlimitsmodel.h b/ktorrent/dialogs/speedlimitsmodel.h
index f03de2925..d4192c325 100644
--- a/ktorrent/dialogs/speedlimitsmodel.h
+++ b/ktorrent/dialogs/speedlimitsmodel.h
@@ -39,6 +39,16 @@ public:
 
     void apply();
 
+    enum class Column : int {
+        TORRENT,
+        DOWNLOAD_LIMIT,
+        UPLOAD_LIMIT,
+        ASSURED_DOWNLOAD_SPEED,
+        ASSURED_UPLOAD_SPEED,
+        _NUMBER_OF_COLUMNS,
+    };
+    static constexpr auto NUM_COLUMNS = static_cast<int>(Column::_NUMBER_OF_COLUMNS);
+
 Q_SIGNALS:
     void enableApply(bool on);
 
diff --git a/ktorrent/dialogs/spinboxdelegate.cpp b/ktorrent/dialogs/spinboxdelegate.cpp
index 392ddbe63..262e53c61 100644
--- a/ktorrent/dialogs/spinboxdelegate.cpp
+++ b/ktorrent/dialogs/spinboxdelegate.cpp
@@ -11,6 +11,8 @@
 
 #include <KLocalizedString>
 
+#include "speedlimitsmodel.h"
+
 namespace kt
 {
 SpinBoxDelegate::SpinBoxDelegate(QObject *parent)
@@ -26,7 +28,7 @@ QWidget *SpinBoxDelegate::createEditor(QWidget *parent, const QStyleOptionViewIt
 {
     QSpinBox *editor = new QSpinBox(parent);
     editor->setSuffix(i18n(" KiB/s"));
-    if (index.column() < 3) {
+    if (SpeedLimitsModel::Column{index.column()} < SpeedLimitsModel::Column::ASSURED_DOWNLOAD_SPEED) {
         editor->setSpecialValueText(i18n("No limit"));
     } else {
         editor->setSpecialValueText(i18n("No assured speed"));
diff --git a/ktorrent/tools/magnetmodel.cpp b/ktorrent/tools/magnetmodel.cpp
index 44d815620..53a0d5223 100644
--- a/ktorrent/tools/magnetmodel.cpp
+++ b/ktorrent/tools/magnetmodel.cpp
@@ -70,24 +70,25 @@ QVariant MagnetModel::data(const QModelIndex &index, int role) const
         return QVariant();
     }
 
+    const Column column{index.column()};
     const MagnetDownloader *md = mman->getMagnetDownloader(index.row());
     if (role == Qt::DisplayRole) {
-        switch (index.column()) {
-        case 0:
+        switch (column) {
+        case Column::MAGNET_LINK:
             return displayName(md);
-        case 1:
+        case Column::STATUS:
             return status(index.row());
-        case 2:
+        case Column::PEERS:
             return md->numPeers();
         default:
             return QVariant();
         }
     } else if (role == Qt::DecorationRole) {
-        if (index.column() == 0) {
+        if (column == Column::MAGNET_LINK) {
             return QIcon::fromTheme(QStringLiteral("kt-magnet"));
         }
     } else if (role == Qt::ToolTipRole) {
-        if (index.column() == 0) {
+        if (column == Column::MAGNET_LINK) {
             return md->magnetLink().toString();
         }
     }
@@ -102,12 +103,12 @@ QVariant MagnetModel::headerData(int section, Qt::Orientation orientation, int r
     }
 
     if (role == Qt::DisplayRole) {
-        switch (section) {
-        case 0:
+        switch (Column{section}) {
+        case Column::MAGNET_LINK:
             return i18n("Magnet Link");
-        case 1:
+        case Column::STATUS:
             return i18n("Status");
-        case 2:
+        case Column::PEERS:
             return i18n("Peers");
         default:
             return QVariant();
@@ -122,7 +123,7 @@ int MagnetModel::columnCount(const QModelIndex &parent) const
     if (parent.isValid()) {
         return 0;
     } else {
-        return 3;
+        return NUM_COLUMNS;
     }
 }
 
diff --git a/ktorrent/tools/magnetmodel.h b/ktorrent/tools/magnetmodel.h
index ce8b5e032..623985c94 100644
--- a/ktorrent/tools/magnetmodel.h
+++ b/ktorrent/tools/magnetmodel.h
@@ -53,6 +53,14 @@ private:
     QString status(int row) const;
 
 private:
+    enum class Column : int {
+        MAGNET_LINK,
+        STATUS,
+        PEERS,
+        _NUMBER_OF_COLUMNS,
+    };
+    static constexpr auto NUM_COLUMNS = static_cast<int>(Column::_NUMBER_OF_COLUMNS);
+
     int currentRows;
     QPointer<MagnetManager> mman;
 };
diff --git a/ktorrent/tools/queuemanagermodel.cpp b/ktorrent/tools/queuemanagermodel.cpp
index dfd1959e3..2ff1bc066 100644
--- a/ktorrent/tools/queuemanagermodel.cpp
+++ b/ktorrent/tools/queuemanagermodel.cpp
@@ -166,7 +166,7 @@ int QueueManagerModel::columnCount(const QModelIndex &parent) const
     if (parent.isValid()) {
         return 0;
     } else {
-        return 4;
+        return NUM_COLUMNS;
     }
 }
 
@@ -176,16 +176,16 @@ QVariant QueueManagerModel::headerData(int section, Qt::Orientation orientation,
         return QVariant();
     }
 
-    switch (section) {
-    case 0:
+    switch (Column{section}) {
+    case Column::ORDER:
         return i18n("Order");
-    case 1:
+    case Column::NAME:
         return i18n("Name");
-    case 2:
+    case Column::STATUS:
         return i18n("Status");
-    case 3:
+    case Column::TIME_STALLED:
         return i18n("Time Stalled");
-    case 4:
+    case Column::PRIORITY:
         return i18n("Priority");
     default:
         return QVariant();
@@ -198,9 +198,10 @@ QVariant QueueManagerModel::data(const QModelIndex &index, int role) const
         return QVariant();
     }
 
+    const Column column{index.column()};
     const bt::TorrentInterface *tc = queue.at(index.row()).tc;
     if (role == Qt::ForegroundRole) {
-        if (index.column() == 2) {
+        if (column == Column::STATUS) {
             if (tc->getStats().running) {
                 return QColor(40, 205, 40); // green
             } else if (tc->getStats().status == bt::QUEUED) {
@@ -211,12 +212,12 @@ QVariant QueueManagerModel::data(const QModelIndex &index, int role) const
         }
         return QVariant();
     } else if (role == Qt::DisplayRole) {
-        switch (index.column()) {
-        case 0:
+        switch (column) {
+        case Column::ORDER:
             return index.row() + 1;
-        case 1:
+        case Column::NAME:
             return tc->getDisplayName();
-        case 2:
+        case Column::STATUS:
             if (tc->getStats().running) {
                 return i18n("Running");
             } else if (tc->getStats().status == bt::QUEUED) {
@@ -225,7 +226,7 @@ QVariant QueueManagerModel::data(const QModelIndex &index, int role) const
                 return i18n("Not queued");
             }
             break;
-        case 3: {
+        case Column::TIME_STALLED: {
             if (!tc->getStats().running) {
                 return QVariant();
             }
@@ -237,14 +238,14 @@ QVariant QueueManagerModel::data(const QModelIndex &index, int role) const
                 return QVariant();
             }
         } break;
-        case 4:
+        case Column::PRIORITY:
             return tc->getPriority();
         default:
             return QVariant();
         }
-    } else if (role == Qt::ToolTipRole && index.column() == 0) {
+    } else if (role == Qt::ToolTipRole && column == Column::ORDER) {
         return i18n("Order of a torrent in the queue.\nUse drag and drop or the move up and down buttons on the right to change the order.");
-    } else if (role == Qt::DecorationRole && index.column() == 1) {
+    } else if (role == Qt::DecorationRole && column == Column::STATUS) {
         if (!tc->getStats().completed) {
             return QIcon::fromTheme(QStringLiteral("arrow-down"));
         } else {
diff --git a/ktorrent/tools/queuemanagermodel.h b/ktorrent/tools/queuemanagermodel.h
index 863d8b8aa..65597c400 100644
--- a/ktorrent/tools/queuemanagermodel.h
+++ b/ktorrent/tools/queuemanagermodel.h
@@ -114,6 +114,16 @@ private:
     void softReset();
 
 private:
+    enum class Column {
+        ORDER,
+        NAME,
+        STATUS,
+        TIME_STALLED,
+        PRIORITY,
+        _NUMBER_OF_COLUMNS,
+    };
+    static constexpr auto NUM_COLUMNS = static_cast<int>(Column::_NUMBER_OF_COLUMNS);
+
     QueueManager *qman;
     QList<Item> queue;
     mutable QList<int> dragged_items;
diff --git a/ktorrent/view/view.cpp b/ktorrent/view/view.cpp
index 477b0c2bc..1cbb9f13d 100644
--- a/ktorrent/view/view.cpp
+++ b/ktorrent/view/view.cpp
@@ -756,7 +756,7 @@ bool View::edit(const QModelIndex &index, EditTrigger trigger, QEvent *event)
 
 void View::onDoubleClicked(const QModelIndex &index)
 {
-    if (index.column() == 0) { // double clicking on column 0 will change the name of a torrent
+    if (ViewModel::Column{index.column()} == ViewModel::Column::NAME) { // double clicking the name will change the name of a torrent
         return;
     }
 
diff --git a/ktorrent/view/viewdelegate.cpp b/ktorrent/view/viewdelegate.cpp
index 867e44069..7da94bf67 100644
--- a/ktorrent/view/viewdelegate.cpp
+++ b/ktorrent/view/viewdelegate.cpp
@@ -350,7 +350,7 @@ void ViewDelegate::paintProgressBar(QPainter *painter, const QStyleOptionViewIte
 
 void ViewDelegate::normalPaint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
 {
-    if (index.column() == ViewModel::PERCENTAGE) {
+    if (ViewModel::Column{index.column()} == ViewModel::Column::PERCENTAGE) {
         paintProgressBar(painter, option, index);
     } else {
         QStyledItemDelegate::paint(painter, option, index);
diff --git a/ktorrent/view/viewmodel.cpp b/ktorrent/view/viewmodel.cpp
index fb2c0a068..78edc3ec3 100644
--- a/ktorrent/view/viewmodel.cpp
+++ b/ktorrent/view/viewmodel.cpp
@@ -65,95 +65,95 @@ ViewModel::Item::Item(bt::TorrentInterface *tc)
     last_activity = std::max(s.last_download_activity_time, s.last_upload_activity_time);
 }
 
-bool ViewModel::Item::update(int row, int sort_column, QModelIndexList &to_update, kt::ViewModel *model)
+bool ViewModel::Item::update(int row, Column sort_column, QModelIndexList &to_update, kt::ViewModel *model)
 {
     bool ret = false;
     const TorrentStats &s = tc->getStats();
 
-    const auto update_if_differs = [&](auto &target, const auto &source, int column) {
+    const auto update_if_differs = [&](auto &target, const auto &source, Column column) {
         if (target != source) {
-            to_update.append(model->index(row, column));
+            to_update.append(model->index(row, static_cast<int>(column)));
             target = source;
             ret |= (sort_column == column);
         }
     };
 
-    const auto update_if_differs_float = [&](auto &target, const auto &source, int column) {
+    const auto update_if_differs_float = [&](auto &target, const auto &source, Column column) {
         if (fabs(target - source) > 0.001) {
-            to_update.append(model->index(row, column));
+            to_update.append(model->index(row, static_cast<int>(column)));
             target = source;
             ret |= (sort_column == column);
         }
     };
 
-    update_if_differs(status, s.status, NAME);
-    update_if_differs(bytes_downloaded, s.bytes_downloaded, BYTES_DOWNLOADED);
-    update_if_differs(session_bytes_downloaded, s.session_bytes_downloaded, SESSION_BYTES_DOWNLOADED);
-    update_if_differs(total_bytes_to_download, s.total_bytes_to_download, TOTAL_BYTES_TO_DOWNLOAD);
-    update_if_differs(bytes_uploaded, s.bytes_uploaded, BYTES_UPLOADED);
-    update_if_differs(session_bytes_uploaded, s.session_bytes_uploaded, SESSION_BYTES_UPLOADED);
-    update_if_differs(bytes_left, s.bytes_left, BYTES_LEFT);
-    update_if_differs(download_rate, s.download_rate, DOWNLOAD_RATE);
-    update_if_differs(upload_rate, s.upload_rate, UPLOAD_RATE);
-    update_if_differs(eta, tc->getETA(), ETA);
-    update_if_differs(seeders_connected_to, s.seeders_connected_to, SEEDERS);
-    update_if_differs(seeders_total, s.seeders_total, SEEDERS);
-    update_if_differs(leechers_connected_to, s.leechers_connected_to, LEECHERS);
-    update_if_differs(leechers_total, s.leechers_total, LEECHERS);
+    update_if_differs(status, s.status, Column::NAME);
+    update_if_differs(bytes_downloaded, s.bytes_downloaded, Column::BYTES_DOWNLOADED);
+    update_if_differs(session_bytes_downloaded, s.session_bytes_downloaded, Column::SESSION_BYTES_DOWNLOADED);
+    update_if_differs(total_bytes_to_download, s.total_bytes_to_download, Column::TOTAL_BYTES_TO_DOWNLOAD);
+    update_if_differs(bytes_uploaded, s.bytes_uploaded, Column::BYTES_UPLOADED);
+    update_if_differs(session_bytes_uploaded, s.session_bytes_uploaded, Column::SESSION_BYTES_UPLOADED);
+    update_if_differs(bytes_left, s.bytes_left, Column::BYTES_LEFT);
+    update_if_differs(download_rate, s.download_rate, Column::DOWNLOAD_RATE);
+    update_if_differs(upload_rate, s.upload_rate, Column::UPLOAD_RATE);
+    update_if_differs(eta, tc->getETA(), Column::ETA);
+    update_if_differs(seeders_connected_to, s.seeders_connected_to, Column::SEEDERS);
+    update_if_differs(seeders_total, s.seeders_total, Column::SEEDERS);
+    update_if_differs(leechers_connected_to, s.leechers_connected_to, Column::LEECHERS);
+    update_if_differs(leechers_total, s.leechers_total, Column::LEECHERS);
 
     auto la = std::max(s.last_download_activity_time, s.last_upload_activity_time);
     if (last_activity < la) {
         last_activity = la;
-        to_update.append(model->index(row, LAST_ACTIVITY));
-        ret |= (sort_column == LAST_ACTIVITY);
+        to_update.append(model->index(row, static_cast<int>(Column::LAST_ACTIVITY)));
+        ret |= (sort_column == Column::LAST_ACTIVITY);
     }
 
-    update_if_differs_float(percentage, Percentage(s), PERCENTAGE);
-    update_if_differs_float(share_ratio, s.shareRatio(), SHARE_RATIO);
+    update_if_differs_float(percentage, Percentage(s), Column::PERCENTAGE);
+    update_if_differs_float(share_ratio, s.shareRatio(), Column::SHARE_RATIO);
 
-    update_if_differs(runtime_dl, tc->getRunningTimeDL(), DOWNLOAD_TIME);
+    update_if_differs(runtime_dl, tc->getRunningTimeDL(), Column::DOWNLOAD_TIME);
     // clang-format off
     const auto rul = (tc->getRunningTimeUL() >= tc->getRunningTimeDL()
                       ? tc->getRunningTimeUL() - tc->getRunningTimeDL()
                       : 0);
     // clang-format on
-    update_if_differs(runtime_ul, rul, SEED_TIME);
+    update_if_differs(runtime_ul, rul, Column::SEED_TIME);
 
     return ret;
 }
 
-QVariant ViewModel::Item::data(int col) const
+QVariant ViewModel::Item::data(Column col) const
 {
     static QLocale locale;
     const TorrentStats &s = tc->getStats();
     switch (col) {
-    case NAME:
+    case Column::NAME:
         return tc->getDisplayName();
-    case BYTES_DOWNLOADED:
+    case Column::BYTES_DOWNLOADED:
         return BytesToString(bytes_downloaded);
-    case SESSION_BYTES_DOWNLOADED:
+    case Column::SESSION_BYTES_DOWNLOADED:
         return BytesToString(session_bytes_downloaded);
-    case TOTAL_BYTES_TO_DOWNLOAD:
+    case Column::TOTAL_BYTES_TO_DOWNLOAD:
         return BytesToString(total_bytes_to_download);
-    case BYTES_UPLOADED:
+    case Column::BYTES_UPLOADED:
         return BytesToString(bytes_uploaded);
-    case SESSION_BYTES_UPLOADED:
+    case Column::SESSION_BYTES_UPLOADED:
         return BytesToString(session_bytes_uploaded);
-    case BYTES_LEFT:
+    case Column::BYTES_LEFT:
         return bytes_left > 0 ? BytesToString(bytes_left) : QVariant();
-    case DOWNLOAD_RATE:
+    case Column::DOWNLOAD_RATE:
         if (download_rate >= 103 && s.bytes_left_to_download > 0) { // lowest "visible" speed, all below will be 0,0 Kb/s
             return BytesPerSecToString(download_rate);
         } else {
             return QVariant();
         }
-    case UPLOAD_RATE:
+    case Column::UPLOAD_RATE:
         if (upload_rate >= 103) { // lowest "visible" speed, all below will be 0,0 Kb/s
             return BytesPerSecToString(upload_rate);
         } else {
             return QVariant();
         }
-    case ETA:
+    case Column::ETA:
         if (eta == bt::TimeEstimator::NEVER) {
             return QString(QChar(0x221E)); // infinity
         } else if (eta != bt::TimeEstimator::ALREADY_FINISHED) {
@@ -161,24 +161,24 @@ QVariant ViewModel::Item::data(int col) const
         } else {
             return QVariant();
         }
-    case SEEDERS:
+    case Column::SEEDERS:
         return QString(QString::number(seeders_connected_to) + QLatin1String(" (") + QString::number(seeders_total) + QLatin1Char(')'));
-    case LEECHERS:
+    case Column::LEECHERS:
         return QString(QString::number(leechers_connected_to) + QLatin1String(" (") + QString::number(leechers_total) + QLatin1Char(')'));
     // xgettext: no-c-format
-    case PERCENTAGE:
+    case Column::PERCENTAGE:
         return percentage;
-    case SHARE_RATIO:
+    case Column::SHARE_RATIO:
         return locale.toString(share_ratio, 'f', 2);
-    case DOWNLOAD_TIME:
+    case Column::DOWNLOAD_TIME:
         return DurationToString(runtime_dl);
-    case SEED_TIME:
+    case Column::SEED_TIME:
         return DurationToString(runtime_ul);
-    case DOWNLOAD_LOCATION:
+    case Column::DOWNLOAD_LOCATION:
         return tc->getStats().output_path;
-    case TIME_ADDED:
+    case Column::TIME_ADDED:
         return locale.toString(time_added, QLocale::ShortFormat);
-    case LAST_ACTIVITY: {
+    case Column::LAST_ACTIVITY: {
         KFormat kf;
         auto msSinceLastActivity = QDateTime::currentMSecsSinceEpoch() - last_activity;
         auto durationFormat = KFormat::AbbreviatedDuration | KFormat::HideSeconds;
@@ -189,54 +189,54 @@ QVariant ViewModel::Item::data(int col) const
     }
 }
 
-bool ViewModel::Item::lessThan(int col, const Item *other) const
+bool ViewModel::Item::lessThan(Column col, const Item *other) const
 {
     switch (col) {
-    case NAME:
+    case Column::NAME:
         return QString::localeAwareCompare(tc->getDisplayName(), other->tc->getDisplayName()) < 0;
-    case BYTES_DOWNLOADED:
+    case Column::BYTES_DOWNLOADED:
         return bytes_downloaded < other->bytes_downloaded;
-    case SESSION_BYTES_DOWNLOADED:
+    case Column::SESSION_BYTES_DOWNLOADED:
         return session_bytes_downloaded < other->session_bytes_downloaded;
-    case TOTAL_BYTES_TO_DOWNLOAD:
+    case Column::TOTAL_BYTES_TO_DOWNLOAD:
         return total_bytes_to_download < other->total_bytes_to_download;
-    case BYTES_UPLOADED:
+    case Column::BYTES_UPLOADED:
         return bytes_uploaded < other->bytes_uploaded;
-    case SESSION_BYTES_UPLOADED:
+    case Column::SESSION_BYTES_UPLOADED:
         return session_bytes_uploaded < other->session_bytes_uploaded;
-    case BYTES_LEFT:
+    case Column::BYTES_LEFT:
         return bytes_left < other->bytes_left;
-    case DOWNLOAD_RATE:
+    case Column::DOWNLOAD_RATE:
         return (download_rate < 102 ? 0 : download_rate) < (other->download_rate < 102 ? 0 : other->download_rate);
-    case UPLOAD_RATE:
+    case Column::UPLOAD_RATE:
         return (upload_rate < 102 ? 0 : upload_rate) < (other->upload_rate < 102 ? 0 : other->upload_rate);
-    case ETA:
+    case Column::ETA:
         return eta < other->eta;
-    case SEEDERS:
+    case Column::SEEDERS:
         if (seeders_connected_to == other->seeders_connected_to) {
             return seeders_total < other->seeders_total;
         } else {
             return seeders_connected_to < other->seeders_connected_to;
         }
-    case LEECHERS:
+    case Column::LEECHERS:
         if (leechers_connected_to == other->leechers_connected_to) {
             return leechers_total < other->leechers_total;
         } else {
             return leechers_connected_to < other->leechers_connected_to;
         }
-    case PERCENTAGE:
+    case Column::PERCENTAGE:
         return percentage < other->percentage;
-    case SHARE_RATIO:
+    case Column::SHARE_RATIO:
         return share_ratio < other->share_ratio;
-    case DOWNLOAD_TIME:
+    case Column::DOWNLOAD_TIME:
         return runtime_dl < other->runtime_dl;
-    case SEED_TIME:
+    case Column::SEED_TIME:
         return runtime_ul < other->runtime_ul;
-    case DOWNLOAD_LOCATION:
+    case Column::DOWNLOAD_LOCATION:
         return tc->getStats().output_path < other->tc->getStats().output_path;
-    case TIME_ADDED:
+    case Column::TIME_ADDED:
         return time_added < other->time_added;
-    case LAST_ACTIVITY:
+    case Column::LAST_ACTIVITY:
         // last_activity the timestamp for 1 minute is bigger than the timestamp for 1 hour
         // but when sorting descending 1 hour should come before 1 minute
         return last_activity > other->last_activity;
@@ -245,9 +245,9 @@ bool ViewModel::Item::lessThan(int col, const Item *other) const
     }
 }
 
-QVariant ViewModel::Item::color(int col) const
+QVariant ViewModel::Item::color(Column col) const
 {
-    if (col == NAME) {
+    if (col == Column::NAME) {
         switch (status) {
         case bt::SEEDING:
         case bt::SUPERSEEDING:
@@ -284,7 +284,7 @@ QVariant ViewModel::Item::color(int col) const
             return QVariant();
         }
 
-    } else if (col == SHARE_RATIO) {
+    } else if (col == Column::SHARE_RATIO) {
         return share_ratio >= Settings::greenRatio() ? Settings::goodShareRatioColor() : Settings::lowShareRatioColor();
     } else {
         return QVariant();
@@ -346,7 +346,7 @@ ViewModel::ViewModel(Core *core, View *parent)
     connect(core, &Core::aboutToQuit, this, &ViewModel::onExit); // model must be in core's thread to be notified in time
     connect(core, &Core::torrentAdded, this, &ViewModel::addTorrent);
     connect(core, &Core::torrentRemoved, this, &ViewModel::removeTorrent);
-    sort_column = 0;
+    sort_column = Column::NAME;
     sort_order = Qt::AscendingOrder;
     group = nullptr;
     num_visible = 0;
@@ -447,7 +447,7 @@ bool ViewModel::update(ViewDelegate *delegate, bool force_resort)
 
     if (resort) {
         update_list.clear();
-        sort(sort_column, sort_order);
+        sort(static_cast<int>(sort_column), sort_order);
         return true;
     }
 
@@ -473,7 +473,7 @@ int ViewModel::columnCount(const QModelIndex &parent) const
     if (parent.isValid()) {
         return 0;
     } else {
-        return _NUMBER_OF_COLUMNS;
+        return NUM_COLUMNS;
     }
 }
 
@@ -484,87 +484,87 @@ QVariant ViewModel::headerData(int section, Qt::Orientation orientation, int rol
     }
 
     if (role == Qt::DisplayRole) {
-        switch (section) {
-        case NAME:
+        switch (Column{section}) {
+        case Column::NAME:
             return i18n("Name");
-        case BYTES_DOWNLOADED:
+        case Column::BYTES_DOWNLOADED:
             return i18n("Downloaded");
-        case SESSION_BYTES_DOWNLOADED:
+        case Column::SESSION_BYTES_DOWNLOADED:
             return i18nc("Bytes downloaded this session", "Session Downloaded");
-        case TOTAL_BYTES_TO_DOWNLOAD:
+        case Column::TOTAL_BYTES_TO_DOWNLOAD:
             return i18n("Size");
-        case BYTES_UPLOADED:
+        case Column::BYTES_UPLOADED:
             return i18n("Uploaded");
-        case SESSION_BYTES_UPLOADED:
+        case Column::SESSION_BYTES_UPLOADED:
             return i18nc("Bytes uploaded this session", "Session Uploaded");
-        case BYTES_LEFT:
+        case Column::BYTES_LEFT:
             return i18nc("Bytes left to downloaded", "Left");
-        case DOWNLOAD_RATE:
+        case Column::DOWNLOAD_RATE:
             return i18n("Down Speed");
-        case UPLOAD_RATE:
+        case Column::UPLOAD_RATE:
             return i18n("Up Speed");
-        case ETA:
+        case Column::ETA:
             return i18n("Time Left");
-        case SEEDERS:
+        case Column::SEEDERS:
             return i18n("Seeders");
-        case LEECHERS:
+        case Column::LEECHERS:
             return i18n("Leechers");
-        case PERCENTAGE:
+        case Column::PERCENTAGE:
             // xgettext: no-c-format
             return i18n("% Complete");
-        case SHARE_RATIO:
+        case Column::SHARE_RATIO:
             return i18n("Share Ratio");
-        case DOWNLOAD_TIME:
+        case Column::DOWNLOAD_TIME:
             return i18n("Time Downloaded");
-        case SEED_TIME:
+        case Column::SEED_TIME:
             return i18n("Time Seeded");
-        case DOWNLOAD_LOCATION:
+        case Column::DOWNLOAD_LOCATION:
             return i18n("Location");
-        case TIME_ADDED:
+        case Column::TIME_ADDED:
             return i18n("Added");
-        case LAST_ACTIVITY:
+        case Column::LAST_ACTIVITY:
             return i18n("Last Activity");
         default:
             return QVariant();
         }
     } else if (role == Qt::ToolTipRole) {
-        switch (section) {
-        case BYTES_DOWNLOADED:
+        switch (Column{section}) {
+        case Column::BYTES_DOWNLOADED:
             return i18n("How much data we have downloaded of the torrent");
-        case SESSION_BYTES_DOWNLOADED:
+        case Column::SESSION_BYTES_DOWNLOADED:
             return i18n("How much data we have downloaded of the torrent this session");
-        case TOTAL_BYTES_TO_DOWNLOAD:
+        case Column::TOTAL_BYTES_TO_DOWNLOAD:
             return i18n("Total size of the torrent, excluded files are not included");
-        case BYTES_UPLOADED:
+        case Column::BYTES_UPLOADED:
             return i18n("How much data we have uploaded");
-        case SESSION_BYTES_UPLOADED:
+        case Column::SESSION_BYTES_UPLOADED:
             return i18n("How much data we have uploaded this session");
-        case BYTES_LEFT:
+        case Column::BYTES_LEFT:
             return i18n("How much data left to download");
-        case DOWNLOAD_RATE:
+        case Column::DOWNLOAD_RATE:
             return i18n("Current download speed");
-        case UPLOAD_RATE:
+        case Column::UPLOAD_RATE:
             return i18n("Current upload speed");
-        case ETA:
+        case Column::ETA:
             return i18n("How much time is left before the torrent is finished or before the maximum share ratio is reached, if that is enabled");
-        case SEEDERS:
+        case Column::SEEDERS:
             return i18n("How many seeders we are connected to (How many seeders there are according to the tracker)");
-        case LEECHERS:
+        case Column::LEECHERS:
             return i18n("How many leechers we are connected to (How many leechers there are according to the tracker)");
         // xgettext: no-c-format
-        case PERCENTAGE:
+        case Column::PERCENTAGE:
             return i18n("The percentage of data we have of the whole torrent, not including excluded files");
-        case SHARE_RATIO:
+        case Column::SHARE_RATIO:
             return i18n("Share ratio is the number of bytes uploaded divided by the number of bytes downloaded");
-        case DOWNLOAD_TIME:
+        case Column::DOWNLOAD_TIME:
             return i18n("How long we have been downloading the torrent");
-        case SEED_TIME:
+        case Column::SEED_TIME:
             return i18n("How long we have been seeding the torrent");
-        case DOWNLOAD_LOCATION:
+        case Column::DOWNLOAD_LOCATION:
             return i18n("The location of the torrent's data on disk");
-        case TIME_ADDED:
+        case Column::TIME_ADDED:
             return i18n("When this torrent was added");
-        case LAST_ACTIVITY:
+        case Column::LAST_ACTIVITY:
             return i18n("Time since last download or upload activity");
         default:
             return QVariant();
@@ -599,15 +599,16 @@ QVariant ViewModel::data(const QModelIndex &index, int role) const
         return QVariant();
     }
 
+    const Column column{index.column()};
     if (role == Qt::ForegroundRole) {
-        return item->color(index.column());
+        return item->color(column);
     } else if (role == Qt::DisplayRole) {
-        return item->data(index.column());
-    } else if (role == Qt::EditRole && index.column() == NAME) {
+        return item->data(column);
+    } else if (role == Qt::EditRole && column == Column::NAME) {
         return item->tc->getDisplayName();
-    } else if (role == Qt::DecorationRole && index.column() == NAME) {
+    } else if (role == Qt::DecorationRole && column == Column::NAME) {
         return item->statusIcon();
-    } else if (role == Qt::ToolTipRole && index.column() == NAME) {
+    } else if (role == Qt::ToolTipRole && column == Column::NAME) {
         bt::TorrentInterface *tc = item->tc;
         QString tooltip = tc->getDisplayName();
 
@@ -618,11 +619,11 @@ QVariant ViewModel::data(const QModelIndex &index, int role) const
 
         return tooltip;
     } else if (role == Qt::TextAlignmentRole) {
-        switch (index.column()) {
-        case NAME:
-        case PERCENTAGE:
-        case DOWNLOAD_LOCATION:
-        case TIME_ADDED:
+        switch (column) {
+        case Column::NAME:
+        case Column::PERCENTAGE:
+        case Column::DOWNLOAD_LOCATION:
+        case Column::TIME_ADDED:
             return static_cast<Qt::Alignment::Int>(Qt::AlignLeft | Qt::AlignVCenter);
         default:
             return static_cast<Qt::Alignment::Int>(Qt::AlignRight | Qt::AlignVCenter);
@@ -638,7 +639,7 @@ QVariant ViewModel::data(const QModelIndex &index, int role) const
 
 bool ViewModel::setData(const QModelIndex &index, const QVariant &value, int role)
 {
-    if (!index.isValid() || index.row() >= torrents.count() || role != Qt::EditRole || index.column() != NAME) {
+    if (!index.isValid() || index.row() >= torrents.count() || role != Qt::EditRole || Column{index.column()} != Column::NAME) {
         return false;
     }
 
@@ -651,8 +652,8 @@ bool ViewModel::setData(const QModelIndex &index, const QVariant &value, int rol
     bt::TorrentInterface *tc = item->tc;
     tc->setDisplayName(name);
     Q_EMIT dataChanged(index, index);
-    if (sort_column == NAME) {
-        sort(sort_column, sort_order);
+    if (sort_column == Column::NAME) {
+        sort(static_cast<int>(sort_column), sort_order);
     }
     return true;
 }
@@ -664,7 +665,7 @@ Qt::ItemFlags ViewModel::flags(const QModelIndex &index) const
     }
 
     Qt::ItemFlags flags = QAbstractTableModel::flags(index) | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled;
-    if (index.column() == NAME) {
+    if (Column{index.column()} == Column::NAME) {
         flags |= Qt::ItemIsEditable;
     }
 
@@ -801,7 +802,7 @@ void ViewModel::onExit()
 class ViewModelItemCmp
 {
 public:
-    ViewModelItemCmp(int col, Qt::SortOrder order)
+    ViewModelItemCmp(ViewModel::Column col, Qt::SortOrder order)
         : col(col)
         , order(order)
     {
@@ -820,16 +821,16 @@ public:
         }
     }
 
-    int col;
+    ViewModel::Column col;
     Qt::SortOrder order;
 };
 
 void ViewModel::sort(int col, Qt::SortOrder order)
 {
-    sort_column = col;
+    sort_column = Column{col};
     sort_order = order;
     Q_EMIT layoutAboutToBeChanged();
-    std::stable_sort(torrents.begin(), torrents.end(), ViewModelItemCmp(col, order));
+    std::stable_sort(torrents.begin(), torrents.end(), ViewModelItemCmp(sort_column, order));
     Q_EMIT layoutChanged();
     Q_EMIT sorted();
 }
diff --git a/ktorrent/view/viewmodel.h b/ktorrent/view/viewmodel.h
index 91a0498f4..9e8d3a72b 100644
--- a/ktorrent/view/viewmodel.h
+++ b/ktorrent/view/viewmodel.h
@@ -136,7 +136,7 @@ Q_SIGNALS:
     void sorted();
 
 public:
-    enum Column {
+    enum class Column : int {
         NAME = 0,
         BYTES_DOWNLOADED,
         SESSION_BYTES_DOWNLOADED,
@@ -158,6 +158,7 @@ public:
         LAST_ACTIVITY,
         _NUMBER_OF_COLUMNS,
     };
+    static constexpr auto NUM_COLUMNS = static_cast<int>(Column::_NUMBER_OF_COLUMNS);
 
     struct Item {
         bt::TorrentInterface *tc;
@@ -187,11 +188,11 @@ public:
 
         Item(bt::TorrentInterface *tc);
 
-        bool update(int row, int sort_column, QModelIndexList &to_update, ViewModel *model);
-        QVariant data(int col) const;
-        QVariant color(int col) const;
+        bool update(int row, Column sort_column, QModelIndexList &to_update, ViewModel *model);
+        QVariant data(Column col) const;
+        QVariant color(Column col) const;
         QVariant statusIcon() const;
-        bool lessThan(int col, const Item *other) const;
+        bool lessThan(Column col, const Item *other) const;
         bool visible(Group *group, const QString &filter_string) const;
     };
 
@@ -199,7 +200,7 @@ private:
     Core *core;
     View *view;
     QList<Item *> torrents;
-    int sort_column;
+    Column sort_column;
     Qt::SortOrder sort_order;
     Group *group;
     int num_visible;
diff --git a/libktcore/torrent/torrentfilelistmodel.cpp b/libktcore/torrent/torrentfilelistmodel.cpp
index 8749765a4..93842a135 100644
--- a/libktcore/torrent/torrentfilelistmodel.cpp
+++ b/libktcore/torrent/torrentfilelistmodel.cpp
@@ -49,7 +49,7 @@ int TorrentFileListModel::rowCount(const QModelIndex &parent) const
 int TorrentFileListModel::columnCount(const QModelIndex &parent) const
 {
     if (!parent.isValid()) {
-        return 2;
+        return NUM_COLUMNS;
     } else {
         return 0;
     }
@@ -61,10 +61,10 @@ QVariant TorrentFileListModel::headerData(int section, Qt::Orientation orientati
         return QVariant();
     }
 
-    switch (section) {
-    case 0:
+    switch (Column{section}) {
+    case Column::FILE:
         return i18n("File");
-    case 1:
+    case Column::SIZE:
         return i18n("Size");
     default:
         return QVariant();
@@ -84,16 +84,17 @@ QVariant TorrentFileListModel::data(const QModelIndex &index, int role) const
         return QVariant();
     }
 
+    const Column column{index.column()};
     const TorrentStats &s = tc->getStats();
     if (role == Qt::DisplayRole || role == Qt::EditRole) {
-        switch (index.column()) {
-        case 0:
+        switch (column) {
+        case Column::FILE:
             if (multi) {
                 return tc->getTorrentFile(r).getUserModifiedPath();
             } else {
                 return tc->getUserModifiedFileName();
             }
-        case 1:
+        case Column::SIZE:
             if (multi) {
                 return BytesToString(tc->getTorrentFile(r).getSize());
             } else {
@@ -103,14 +104,14 @@ QVariant TorrentFileListModel::data(const QModelIndex &index, int role) const
             return QVariant();
         }
     } else if (role == Qt::UserRole) { // sorting
-        switch (index.column()) {
-        case 0:
+        switch (column) {
+        case Column::FILE:
             if (multi) {
                 return tc->getTorrentFile(r).getUserModifiedPath();
             } else {
                 return tc->getUserModifiedFileName();
             }
-        case 1:
+        case Column::SIZE:
             if (multi) {
                 return tc->getTorrentFile(r).getSize();
             } else {
@@ -119,10 +120,10 @@ QVariant TorrentFileListModel::data(const QModelIndex &index, int role) const
         default:
             return QVariant();
         }
-    } else if (role == Qt::DecorationRole && index.column() == 0) {
+    } else if (role == Qt::DecorationRole && column == Column::FILE) {
         // if this is an empty folder then we are in the single file case
         return QIcon::fromTheme(QMimeDatabase().mimeTypeForFile(multi ? tc->getTorrentFile(r).getPath() : s.torrent_name).iconName());
-    } else if (role == Qt::CheckStateRole && index.column() == 0 && multi) {
+    } else if (role == Qt::CheckStateRole && column == Column::FILE && multi) {
         const TorrentFileInterface &file = tc->getTorrentFile(r);
         return file.doNotDownload() || file.getPriority() == ONLY_SEED_PRIORITY ? Qt::Unchecked : Qt::Checked;
     }
diff --git a/libktcore/torrent/torrentfilelistmodel.h b/libktcore/torrent/torrentfilelistmodel.h
index 443a64a18..4d3b371a0 100644
--- a/libktcore/torrent/torrentfilelistmodel.h
+++ b/libktcore/torrent/torrentfilelistmodel.h
@@ -40,6 +40,14 @@ public:
 
 private:
     void invertCheck(const QModelIndex &idx);
+
+protected:
+    enum class Column : int {
+        FILE,
+        SIZE,
+        _NUMBER_OF_COLUMNS,
+    };
+    static constexpr auto NUM_COLUMNS = static_cast<int>(Column::_NUMBER_OF_COLUMNS);
 };
 
 }
diff --git a/libktcore/torrent/torrentfiletreemodel.cpp b/libktcore/torrent/torrentfiletreemodel.cpp
index f560aebc5..9ac0031fe 100644
--- a/libktcore/torrent/torrentfiletreemodel.cpp
+++ b/libktcore/torrent/torrentfiletreemodel.cpp
@@ -368,7 +368,7 @@ int TorrentFileTreeModel::rowCount(const QModelIndex &parent) const
 
 int TorrentFileTreeModel::columnCount(const QModelIndex &) const
 {
-    return 2;
+    return NUM_COLUMNS;
 }
 
 QVariant TorrentFileTreeModel::headerData(int section, Qt::Orientation orientation, int role) const
@@ -377,10 +377,10 @@ QVariant TorrentFileTreeModel::headerData(int section, Qt::Orientation orientati
         return QVariant();
     }
 
-    switch (section) {
-    case 0:
+    switch (Column{section}) {
+    case Column::FILE:
         return i18n("File");
-    case 1:
+    case Column::SIZE:
         return i18n("Size");
     default:
         return QVariant();
@@ -398,11 +398,12 @@ QVariant TorrentFileTreeModel::data(const QModelIndex &index, int role) const
         return QVariant();
     }
 
+    const Column column{index.column()};
     if (role == Qt::DisplayRole || role == Qt::EditRole) {
-        switch (index.column()) {
-        case 0:
+        switch (column) {
+        case Column::FILE:
             return n->name;
-        case 1:
+        case Column::SIZE:
             if (tc->getStats().multi_file_torrent) {
                 return BytesToString(n->fileSize(tc));
             } else {
@@ -412,10 +413,10 @@ QVariant TorrentFileTreeModel::data(const QModelIndex &index, int role) const
             return QVariant();
         }
     } else if (role == Qt::UserRole) { // sorting
-        switch (index.column()) {
-        case 0:
+        switch (column) {
+        case Column::FILE:
             return n->name;
-        case 1:
+        case Column::SIZE:
             if (tc->getStats().multi_file_torrent) {
                 return n->fileSize(tc);
             } else {
@@ -424,7 +425,7 @@ QVariant TorrentFileTreeModel::data(const QModelIndex &index, int role) const
         default:
             return QVariant();
         }
-    } else if (role == Qt::DecorationRole && index.column() == 0) {
+    } else if (role == Qt::DecorationRole && column == Column::FILE) {
 #if 0
         if (!n->file && n->children.count() <= 0) {
             qWarning() << tc;
@@ -445,7 +446,7 @@ QVariant TorrentFileTreeModel::data(const QModelIndex &index, int role) const
         } else {
             return QIcon::fromTheme(QMimeDatabase().mimeTypeForFile(n->file->getPath()).iconName());
         }
-    } else if (role == Qt::CheckStateRole && index.column() == 0) {
+    } else if (role == Qt::CheckStateRole && column == Column::FILE) {
         if (tc->getStats().multi_file_torrent) {
             return n->checkState(tc);
         }
diff --git a/libktcore/torrent/torrentfiletreemodel.h b/libktcore/torrent/torrentfiletreemodel.h
index 50e5cdf9b..1cb9df076 100644
--- a/libktcore/torrent/torrentfiletreemodel.h
+++ b/libktcore/torrent/torrentfiletreemodel.h
@@ -106,6 +106,13 @@ private:
     void modifyPathOfFiles(Node *n, const QString &path);
 
 protected:
+    enum class Column : int {
+        FILE,
+        SIZE,
+        _NUMBER_OF_COLUMNS,
+    };
+    static constexpr auto NUM_COLUMNS = static_cast<int>(Column::_NUMBER_OF_COLUMNS);
+
     Node *root;
     bool emit_check_state_change;
 };
diff --git a/plugins/infowidget/chunkdownloadmodel.cpp b/plugins/infowidget/chunkdownloadmodel.cpp
index 107dfc951..62e017af8 100644
--- a/plugins/infowidget/chunkdownloadmodel.cpp
+++ b/plugins/infowidget/chunkdownloadmodel.cpp
@@ -33,35 +33,36 @@ bool ChunkDownloadModel::Item::changed() const
     return ret;
 }
 
-QVariant ChunkDownloadModel::Item::data(int col) const
+QVariant ChunkDownloadModel::Item::data(Column col) const
 {
     switch (col) {
-    case 0:
+    case Column::CHUNK:
         return stats.chunk_index;
-    case 1:
+    case Column::PROGRESS:
         return QStringLiteral("%1 / %2").arg(stats.pieces_downloaded).arg(stats.total_pieces);
-    case 2:
+    case Column::PEER:
         return stats.current_peer_id;
-    case 3:
+    case Column::DOWNLOAD_SPEED:
         return BytesPerSecToString(stats.download_speed);
-    case 4:
+    case Column::FILES:
         return files;
+    default:
+        return QVariant();
     }
-    return QVariant();
 }
 
-QVariant ChunkDownloadModel::Item::sortData(int col) const
+QVariant ChunkDownloadModel::Item::sortData(Column col) const
 {
     switch (col) {
-    case 0:
+    case Column::CHUNK:
         return stats.chunk_index;
-    case 1:
+    case Column::PROGRESS:
         return stats.pieces_downloaded;
-    case 2:
+    case Column::PEER:
         return stats.current_peer_id;
-    case 3:
+    case Column::DOWNLOAD_SPEED:
         return stats.download_speed;
-    case 4:
+    case Column::FILES:
         return files;
     default:
         return QVariant();
@@ -181,7 +182,7 @@ int ChunkDownloadModel::columnCount(const QModelIndex &parent) const
     if (parent.isValid()) {
         return 0;
     } else {
-        return 5;
+        return NUM_COLUMNS;
     }
 }
 
@@ -191,32 +192,33 @@ QVariant ChunkDownloadModel::headerData(int section, Qt::Orientation orientation
         return QVariant();
     }
 
+    const Column column{section};
     if (role == Qt::DisplayRole) {
-        switch (section) {
-        case 0:
+        switch (column) {
+        case Column::CHUNK:
             return i18n("Chunk");
-        case 1:
+        case Column::PROGRESS:
             return i18n("Progress");
-        case 2:
+        case Column::PEER:
             return i18n("Peer");
-        case 3:
+        case Column::DOWNLOAD_SPEED:
             return i18n("Down Speed");
-        case 4:
+        case Column::FILES:
             return i18n("Files");
         default:
             return QVariant();
         }
     } else if (role == Qt::ToolTipRole) {
-        switch (section) {
-        case 0:
+        switch (column) {
+        case Column::CHUNK:
             return i18n("Number of the chunk");
-        case 1:
+        case Column::PROGRESS:
             return i18n("Download progress of the chunk");
-        case 2:
+        case Column::PEER:
             return i18n("Which peer we are downloading it from");
-        case 3:
+        case Column::DOWNLOAD_SPEED:
             return i18n("Download speed of the chunk");
-        case 4:
+        case Column::FILES:
             return i18n("Which files the chunk is located in");
         default:
             return QVariant();
@@ -241,10 +243,11 @@ QVariant ChunkDownloadModel::data(const QModelIndex &index, int role) const
         return QVariant();
     }
 
+    const Column column{index.column()};
     if (role == Qt::DisplayRole) {
-        return items[index.row()]->data(index.column());
+        return items[index.row()]->data(column);
     } else if (role == Qt::UserRole) {
-        return items[index.row()]->sortData(index.column());
+        return items[index.row()]->sortData(column);
     }
 
     return QVariant();
diff --git a/plugins/infowidget/chunkdownloadmodel.h b/plugins/infowidget/chunkdownloadmodel.h
index 5e32361f7..e3f5bb7f5 100644
--- a/plugins/infowidget/chunkdownloadmodel.h
+++ b/plugins/infowidget/chunkdownloadmodel.h
@@ -51,7 +51,17 @@ public:
     bool insertRows(int row, int count, const QModelIndex &parent) override;
     QModelIndex index(int row, int column, const QModelIndex &parent = QModelIndex()) const override;
 
-public:
+private:
+    enum class Column : int {
+        CHUNK,
+        PROGRESS,
+        PEER,
+        DOWNLOAD_SPEED,
+        FILES,
+        _NUMBER_OF_COLUMNS,
+    };
+    static constexpr auto NUM_COLUMNS = static_cast<int>(Column::_NUMBER_OF_COLUMNS);
+
     struct Item {
         mutable bt::ChunkDownloadInterface::Stats stats;
         bt::ChunkDownloadInterface *cd;
@@ -60,11 +70,10 @@ public:
         Item(bt::ChunkDownloadInterface *cd, const QString &files);
 
         bool changed() const;
-        QVariant data(int col) const;
-        QVariant sortData(int col) const;
+        QVariant data(Column col) const;
+        QVariant sortData(Column col) const;
     };
 
-private:
     QList<Item *> items;
     bt::TorrentInterface::WPtr tc;
 };
diff --git a/plugins/infowidget/iwfilelistmodel.cpp b/plugins/infowidget/iwfilelistmodel.cpp
index c3706a38b..09d362b11 100644
--- a/plugins/infowidget/iwfilelistmodel.cpp
+++ b/plugins/infowidget/iwfilelistmodel.cpp
@@ -46,7 +46,7 @@ void IWFileListModel::changeTorrent(bt::TorrentInterface *tc)
 int IWFileListModel::columnCount(const QModelIndex &parent) const
 {
     if (!parent.isValid()) {
-        return 5;
+        return NUM_COLUMNS;
     } else {
         return 0;
     }
@@ -58,17 +58,17 @@ QVariant IWFileListModel::headerData(int section, Qt::Orientation orientation, i
         return QVariant();
     }
 
-    if (section < 2) {
+    if (section < TorrentFileListModel::NUM_COLUMNS) {
         return TorrentFileListModel::headerData(section, orientation, role);
     }
 
-    switch (section) {
-    case 2:
+    switch (Column{section}) {
+    case Column::PRIORITY:
         return i18n("Priority");
-    case 3:
+    case Column::PREVIEW:
         return i18nc("@title:column", "Preview");
     // xgettext: no-c-format
-    case 4:
+    case Column::PERCENT_COMPLETE:
         return i18nc("Percent of File Downloaded", "% Complete");
     default:
         return QVariant();
@@ -95,7 +95,7 @@ static QString PriorityString(const bt::TorrentFileInterface *file)
 
 QVariant IWFileListModel::data(const QModelIndex &index, int role) const
 {
-    if (index.column() < 2 && role != Qt::ForegroundRole) {
+    if (index.column() < TorrentFileListModel::NUM_COLUMNS && role != Qt::ForegroundRole) {
         return TorrentFileListModel::data(index, role);
     }
 
@@ -103,7 +103,7 @@ QVariant IWFileListModel::data(const QModelIndex &index, int role) const
         return QVariant();
     }
 
-    if (role == Qt::ForegroundRole && index.column() == 2 && tc->getStats().multi_file_torrent) {
+    if (role == Qt::ForegroundRole && Column{index.column()} == Column::PRIORITY && tc->getStats().multi_file_torrent) {
         const bt::TorrentFileInterface *file = &tc->getTorrentFile(index.row());
         switch (file->getPriority()) {
         case FIRST_PREVIEW_PRIORITY:
@@ -133,12 +133,14 @@ QVariant IWFileListModel::data(const QModelIndex &index, int role) const
 
 QVariant IWFileListModel::displayData(const QModelIndex &index) const
 {
+    const Column column{index.column()};
+
     if (tc->getStats().multi_file_torrent) {
         const bt::TorrentFileInterface *file = &tc->getTorrentFile(index.row());
-        switch (index.column()) {
-        case 2:
+        switch (column) {
+        case Column::PRIORITY:
             return PriorityString(file);
-        case 3:
+        case Column::PREVIEW:
             if (file->isMultimedia()) {
                 if (file->isPreviewAvailable()) {
                     return i18nc("Preview available", "Available");
@@ -148,7 +150,7 @@ QVariant IWFileListModel::displayData(const QModelIndex &index) const
             } else {
                 return i18nc("No preview available", "No");
             }
-        case 4: {
+        case Column::PERCENT_COMPLETE: {
             float percent = file->getDownloadPercentage();
             return ki18n("%1 %").subs(percent, 0, 'f', 2).toString();
         }
@@ -156,10 +158,10 @@ QVariant IWFileListModel::displayData(const QModelIndex &index) const
             return QVariant();
         }
     } else {
-        switch (index.column()) {
-        case 2:
+        switch (column) {
+        case Column::PRIORITY:
             return QVariant();
-        case 3:
+        case Column::PREVIEW:
             if (mmfile) {
                 if (tc->readyForPreview()) {
                     return i18nc("Preview available", "Available");
@@ -169,7 +171,7 @@ QVariant IWFileListModel::displayData(const QModelIndex &index) const
             } else {
                 return i18nc("No preview available", "No");
             }
-        case 4: {
+        case Column::PERCENT_COMPLETE: {
             double percent = bt::Percentage(tc->getStats());
             return ki18n("%1 %").subs(percent, 0, 'f', 2).toString();
         }
@@ -182,12 +184,14 @@ QVariant IWFileListModel::displayData(const QModelIndex &index) const
 
 QVariant IWFileListModel::sortData(const QModelIndex &index) const
 {
+    const Column column{index.column()};
+
     if (tc->getStats().multi_file_torrent) {
         const bt::TorrentFileInterface *file = &tc->getTorrentFile(index.row());
-        switch (index.column()) {
-        case 2:
+        switch (column) {
+        case Column::PRIORITY:
             return (int)file->getPriority();
-        case 3:
+        case Column::PREVIEW:
             if (file->isMultimedia()) {
                 if (file->isPreviewAvailable()) {
                     return 3;
@@ -197,14 +201,16 @@ QVariant IWFileListModel::sortData(const QModelIndex &index) const
             } else {
                 return 1;
             }
-        case 4:
+        case Column::PERCENT_COMPLETE:
             return file->getDownloadPercentage();
+        default:
+            break;
         }
     } else {
-        switch (index.column()) {
-        case 2:
+        switch (column) {
+        case Column::PRIORITY:
             return QVariant();
-        case 3:
+        case Column::PREVIEW:
             if (mmfile) {
                 if (tc->readyForPreview()) {
                     return 3;
@@ -214,8 +220,10 @@ QVariant IWFileListModel::sortData(const QModelIndex &index) const
             } else {
                 return 1;
             }
-        case 4:
+        case Column::PERCENT_COMPLETE:
             return bt::Percentage(tc->getStats());
+        default:
+            break;
         }
     }
     return QVariant();
diff --git a/plugins/infowidget/iwfilelistmodel.h b/plugins/infowidget/iwfilelistmodel.h
index 69df69d61..02dad4992 100644
--- a/plugins/infowidget/iwfilelistmodel.h
+++ b/plugins/infowidget/iwfilelistmodel.h
@@ -39,6 +39,14 @@ private:
     QVariant sortData(const QModelIndex &index) const;
 
 private:
+    enum class Column : int {
+        PRIORITY = TorrentFileListModel::NUM_COLUMNS,
+        PREVIEW,
+        PERCENT_COMPLETE,
+        _NUMBER_OF_COLUMNS,
+    };
+    static constexpr auto NUM_COLUMNS = static_cast<int>(Column::_NUMBER_OF_COLUMNS);
+
     bool preview;
     bool mmfile;
     double percentage;
diff --git a/plugins/infowidget/iwfiletreemodel.cpp b/plugins/infowidget/iwfiletreemodel.cpp
index 65baf90b4..a29dc4114 100644
--- a/plugins/infowidget/iwfiletreemodel.cpp
+++ b/plugins/infowidget/iwfiletreemodel.cpp
@@ -56,7 +56,7 @@ void IWFileTreeModel::changeTorrent(bt::TorrentInterface *tc)
 
 int IWFileTreeModel::columnCount(const QModelIndex & /*parent*/) const
 {
-    return 5;
+    return NUM_COLUMNS;
 }
 
 QVariant IWFileTreeModel::headerData(int section, Qt::Orientation orientation, int role) const
@@ -65,17 +65,17 @@ QVariant IWFileTreeModel::headerData(int section, Qt::Orientation orientation, i
         return QVariant();
     }
 
-    if (section < 2) {
+    if (section < TorrentFileTreeModel::NUM_COLUMNS) {
         return TorrentFileTreeModel::headerData(section, orientation, role);
     }
 
-    switch (section) {
-    case 2:
+    switch (Column{section}) {
+    case Column::PRIORITY:
         return i18n("Priority");
-    case 3:
+    case Column::PREVIEW:
         return i18nc("@title:column", "Preview");
     // xgettext: no-c-format
-    case 4:
+    case Column::PERCENT_COMPLETE:
         return i18nc("Percent of File Downloaded", "% Complete");
     default:
         return QVariant();
@@ -103,7 +103,7 @@ static QString PriorityString(const bt::TorrentFileInterface *file)
 QVariant IWFileTreeModel::data(const QModelIndex &index, int role) const
 {
     Node *n = nullptr;
-    if (index.column() < 2 && role != Qt::ForegroundRole) {
+    if (index.column() < TorrentFileTreeModel::NUM_COLUMNS && role != Qt::ForegroundRole) {
         return TorrentFileTreeModel::data(index, role);
     }
 
@@ -111,7 +111,7 @@ QVariant IWFileTreeModel::data(const QModelIndex &index, int role) const
         return QVariant();
     }
 
-    if (role == Qt::ForegroundRole && index.column() == 2 && tc->getStats().multi_file_torrent && n->file) {
+    if (role == Qt::ForegroundRole && Column{index.column()} == Column::PRIORITY && tc->getStats().multi_file_torrent && n->file) {
         const bt::TorrentFileInterface *file = n->file;
         switch (file->getPriority()) {
         case FIRST_PREVIEW_PRIORITY:
@@ -157,12 +157,13 @@ bool IWFileTreeModel::setData(const QModelIndex &index, const QVariant &value, i
 
 QVariant IWFileTreeModel::displayData(Node *n, const QModelIndex &index) const
 {
+    const Column column{index.column()};
     if (tc->getStats().multi_file_torrent && n->file) {
         const bt::TorrentFileInterface *file = n->file;
-        switch (index.column()) {
-        case 2:
+        switch (column) {
+        case Column::PRIORITY:
             return PriorityString(file);
-        case 3:
+        case Column::PREVIEW:
             if (file->isMultimedia()) {
                 if (file->isPreviewAvailable()) {
                     return i18nc("preview available", "Available");
@@ -172,7 +173,7 @@ QVariant IWFileTreeModel::displayData(Node *n, const QModelIndex &index) const
             } else {
                 return i18nc("No preview available", "No");
             }
-        case 4:
+        case Column::PERCENT_COMPLETE:
             if (file->getPriority() == ONLY_SEED_PRIORITY || file->getPriority() == EXCLUDED) {
                 return QVariant();
             } else {
@@ -182,10 +183,10 @@ QVariant IWFileTreeModel::displayData(Node *n, const QModelIndex &index) const
             return QVariant();
         }
     } else if (!tc->getStats().multi_file_torrent) {
-        switch (index.column()) {
-        case 2:
+        switch (column) {
+        case Column::PRIORITY:
             return QVariant();
-        case 3:
+        case Column::PREVIEW:
             if (mmfile) {
                 if (tc->readyForPreview()) {
                     return i18nc("Preview available", "Available");
@@ -195,12 +196,12 @@ QVariant IWFileTreeModel::displayData(Node *n, const QModelIndex &index) const
             } else {
                 return i18nc("No preview available", "No");
             }
-        case 4:
+        case Column::PERCENT_COMPLETE:
             return ki18n("%1 %").subs(bt::Percentage(tc->getStats()), 0, 'f', 2).toString();
         default:
             return QVariant();
         }
-    } else if (tc->getStats().multi_file_torrent && index.column() == 4) {
+    } else if (tc->getStats().multi_file_torrent && column == Column::PERCENT_COMPLETE) {
         return ki18n("%1 %").subs(n->percentage, 0, 'f', 2).toString();
     }
 
@@ -209,12 +210,13 @@ QVariant IWFileTreeModel::displayData(Node *n, const QModelIndex &index) const
 
 QVariant IWFileTreeModel::sortData(Node *n, const QModelIndex &index) const
 {
+    const Column column{index.column()};
     if (tc->getStats().multi_file_torrent && n->file) {
         const bt::TorrentFileInterface *file = n->file;
-        switch (index.column()) {
-        case 2:
+        switch (column) {
+        case Column::PRIORITY:
             return (int)file->getPriority();
-        case 3:
+        case Column::PREVIEW:
             if (file->isMultimedia()) {
                 if (file->isPreviewAvailable()) {
                     return 3;
@@ -224,14 +226,16 @@ QVariant IWFileTreeModel::sortData(Node *n, const QModelIndex &index) const
             } else {
                 return 1;
             }
-        case 4:
+        case Column::PERCENT_COMPLETE:
             return n->percentage;
+        default:
+            break;
         }
     } else if (!tc->getStats().multi_file_torrent) {
-        switch (index.column()) {
-        case 2:
+        switch (column) {
+        case Column::PRIORITY:
             return QVariant();
-        case 3:
+        case Column::PREVIEW:
             if (mmfile) {
                 if (tc->readyForPreview()) {
                     return 3;
@@ -241,10 +245,12 @@ QVariant IWFileTreeModel::sortData(Node *n, const QModelIndex &index) const
             } else {
                 return 1;
             }
-        case 4:
+        case Column::PERCENT_COMPLETE:
             return bt::Percentage(tc->getStats());
+        default:
+            break;
         }
-    } else if (tc->getStats().multi_file_torrent && index.column() == 4) {
+    } else if (tc->getStats().multi_file_torrent && column == Column::PERCENT_COMPLETE) {
         return n->percentage;
     }
 
diff --git a/plugins/infowidget/iwfiletreemodel.h b/plugins/infowidget/iwfiletreemodel.h
index 8eaa89007..a7cdc0d22 100644
--- a/plugins/infowidget/iwfiletreemodel.h
+++ b/plugins/infowidget/iwfiletreemodel.h
@@ -42,6 +42,14 @@ private:
     void setPriority(Node *n, bt::Priority newpriority, bool selected_node);
 
 private:
+    enum class Column : int {
+        PRIORITY = TorrentFileTreeModel::NUM_COLUMNS,
+        PREVIEW,
+        PERCENT_COMPLETE,
+        _NUMBER_OF_COLUMNS,
+    };
+    static constexpr auto NUM_COLUMNS = static_cast<int>(Column::_NUMBER_OF_COLUMNS);
+
     bool preview;
     bool mmfile;
     double percentage;
diff --git a/plugins/infowidget/peerviewmodel.cpp b/plugins/infowidget/peerviewmodel.cpp
index 0c73c9c68..19de88ecf 100644
--- a/plugins/infowidget/peerviewmodel.cpp
+++ b/plugins/infowidget/peerviewmodel.cpp
@@ -73,52 +73,52 @@ bool PeerViewModel::Item::changed() const
     return ret;
 }
 
-QVariant PeerViewModel::Item::data(int col) const
+QVariant PeerViewModel::Item::data(Column col) const
 {
     switch (col) {
-    case 0:
+    case Column::ADDRESS:
         if (stats.transport_protocol == bt::UTP) {
             return QString(stats.address() + i18n(" (µTP)"));
         } else {
             return stats.address();
         }
-    case 1:
+    case Column::COUNTRY:
         return country;
-    case 2:
+    case Column::CLIENT:
         return stats.client;
-    case 3:
+    case Column::DOWNLOAD_SPEED:
         if (stats.download_rate >= 103) {
             return BytesPerSecToString(stats.download_rate);
         } else {
             return QVariant();
         }
-    case 4:
+    case Column::UPLOAD_SPEED:
         if (stats.upload_rate >= 103) {
             return BytesPerSecToString(stats.upload_rate);
         } else {
             return QVariant();
         }
-    case 5:
+    case Column::CHOKED:
         return stats.choked ? i18nc("Choked", "Yes") : i18nc("Not choked", "No");
-    case 6:
+    case Column::SNUBBED:
         return stats.snubbed ? i18nc("Snubbed", "Yes") : i18nc("Not snubbed", "No");
-    case 7:
+    case Column::AVAILABILITY:
         return i18nc("File percentage stat", "%1%", (int)stats.perc_of_file);
-    case 8:
+    case Column::DHT:
         return QVariant();
-    case 9:
+    case Column::SCORE:
         return QLocale().toString(stats.aca_score, 'f', 2);
-    case 10:
+    case Column::UPLOAD_SLOT:
         return QVariant();
-    case 11:
+    case Column::REQUESTS:
         return QString(QString::number(stats.num_down_requests) + QLatin1String(" / ") + QString::number(stats.num_up_requests));
-    case 12:
+    case Column::DOWNLOADED:
         return BytesToString(stats.bytes_downloaded);
-    case 13:
+    case Column::UPLOADED:
         return BytesToString(stats.bytes_uploaded);
-    case 14:
+    case Column::INTERESTED:
         return stats.interested ? i18nc("Interested", "Yes") : i18nc("Not Interested", "No");
-    case 15:
+    case Column::INTERESTING:
         return stats.am_interested ? i18nc("Interesting", "Yes") : i18nc("Not Interesting", "No");
     default:
         return QVariant();
@@ -126,62 +126,63 @@ QVariant PeerViewModel::Item::data(int col) const
     return QVariant();
 }
 
-QVariant PeerViewModel::Item::sortData(int col) const
+QVariant PeerViewModel::Item::sortData(Column col) const
 {
     switch (col) {
-    case 0:
+    case Column::ADDRESS:
         return stats.address();
-    case 1:
+    case Column::COUNTRY:
         return country;
-    case 2:
+    case Column::CLIENT:
         return stats.client;
-    case 3:
+    case Column::DOWNLOAD_SPEED:
         return stats.download_rate;
-    case 4:
+    case Column::UPLOAD_SPEED:
         return stats.upload_rate;
-    case 5:
+    case Column::CHOKED:
         return stats.choked;
-    case 6:
+    case Column::SNUBBED:
         return stats.snubbed;
-    case 7:
+    case Column::AVAILABILITY:
         return stats.perc_of_file;
-    case 8:
+    case Column::DHT:
         return stats.dht_support;
-    case 9:
+    case Column::SCORE:
         return stats.aca_score;
-    case 10:
+    case Column::UPLOAD_SLOT:
         return stats.has_upload_slot;
-    case 11:
+    case Column::REQUESTS:
         return stats.num_down_requests + stats.num_up_requests;
-    case 12:
+    case Column::DOWNLOADED:
         return stats.bytes_downloaded;
-    case 13:
+    case Column::UPLOADED:
         return stats.bytes_uploaded;
-    case 14:
+    case Column::INTERESTED:
         return stats.interested;
-    case 15:
+    case Column::INTERESTING:
         return stats.am_interested;
     default:
         return QVariant();
     }
 }
 
-QVariant PeerViewModel::Item::decoration(int col) const
+QVariant PeerViewModel::Item::decoration(Column col) const
 {
     switch (col) {
-    case 0:
+    case Column::ADDRESS:
         if (stats.encrypted) {
             return QIcon::fromTheme(QStringLiteral("kt-encrypted"));
         }
         break;
-    case 1:
+    case Column::COUNTRY:
         return flag;
-    case 8:
+    case Column::DHT:
         return stats.dht_support ? yes : no;
-    case 10:
+    case Column::UPLOAD_SLOT:
         return stats.has_upload_slot ? yes : QIcon();
+    default:
+        break;
     }
-
     return QVariant();
 }
 
@@ -281,7 +282,7 @@ int PeerViewModel::columnCount(const QModelIndex &parent) const
     if (parent.isValid()) {
         return 0;
     } else {
-        return 16;
+        return NUM_COLUMNS;
     }
 }
 
@@ -291,76 +292,77 @@ QVariant PeerViewModel::headerData(int section, Qt::Orientation orientation, int
         return QVariant();
     }
 
+    const Column column{section};
     if (role == Qt::DisplayRole) {
-        switch (section) {
-        case 0:
+        switch (column) {
+        case Column::ADDRESS:
             return i18n("Address");
-        case 1:
+        case Column::COUNTRY:
             return i18n("Country");
-        case 2:
+        case Column::CLIENT:
             return i18n("Client");
-        case 3:
+        case Column::DOWNLOAD_SPEED:
             return i18n("Down Speed");
-        case 4:
+        case Column::UPLOAD_SPEED:
             return i18n("Up Speed");
-        case 5:
+        case Column::CHOKED:
             return i18n("Choked");
-        case 6:
+        case Column::SNUBBED:
             return i18n("Snubbed");
-        case 7:
+        case Column::AVAILABILITY:
             return i18n("Availability");
-        case 8:
+        case Column::DHT:
             return i18n("DHT");
-        case 9:
+        case Column::SCORE:
             return i18n("Score");
-        case 10:
+        case Column::UPLOAD_SLOT:
             return i18n("Upload Slot");
-        case 11:
+        case Column::REQUESTS:
             return i18n("Requests");
-        case 12:
+        case Column::DOWNLOADED:
             return i18n("Downloaded");
-        case 13:
+        case Column::UPLOADED:
             return i18n("Uploaded");
-        case 14:
+        case Column::INTERESTED:
             return i18n("Interested");
-        case 15:
+        case Column::INTERESTING:
             return i18n("Interesting");
         default:
             return QVariant();
         }
     } else if (role == Qt::ToolTipRole) {
-        switch (section) {
-        case 0:
+        switch (column) {
+        case Column::ADDRESS:
             return i18n("IP address of the peer");
-        case 1:
+        case Column::COUNTRY:
             return i18n("Country the peer is in");
-        case 2:
+        case Column::CLIENT:
             return i18n("Which client the peer is using");
-        case 3:
+        case Column::DOWNLOAD_SPEED:
             return i18n("Download speed");
-        case 4:
+        case Column::UPLOAD_SPEED:
             return i18n("Upload speed");
-        case 5:
+        case Column::CHOKED:
             return i18n("Whether or not the peer has choked us - when we are choked the peer will not send us any data");
-        case 6:
+        case Column::SNUBBED:
             return i18n("Snubbed means the peer has not sent us any data in the last 2 minutes");
-        case 7:
+        case Column::AVAILABILITY:
             return i18n("How much data the peer has of the torrent");
-        case 8:
+        case Column::DHT:
             return i18n("Whether or not the peer has DHT enabled");
-        case 9:
+        case Column::SCORE:
             return i18n("The score of the peer, KTorrent uses this to determine who to upload to");
-        case 10:
+        case Column::UPLOAD_SLOT:
             return i18n("Only peers which have an upload slot will get data from us");
-        case 11:
+        case Column::REQUESTS:
             return i18n("The number of download and upload requests");
-        case 12:
+        case Column::DOWNLOADED:
             return i18n("How much data we have downloaded from this peer");
-        case 13:
+        case Column::UPLOADED:
             return i18n("How much data we have uploaded to this peer");
-        case 14:
+        case Column::INTERESTED:
             return i18n("Whether the peer is interested in downloading data from us");
-        case 15:
+        case Column::INTERESTING:
             return i18n("Whether we are interested in downloading from this peer");
         default:
             return QVariant();
@@ -376,13 +378,14 @@ QVariant PeerViewModel::data(const QModelIndex &index, int role) const
         return QVariant();
     }
 
+    const Column column{index.column()};
     Item *item = items[index.row()];
     if (role == Qt::DisplayRole) {
-        return item->data(index.column());
+        return item->data(column);
     } else if (role == Qt::UserRole) {
-        return item->sortData(index.column());
+        return item->sortData(column);
     } else if (role == Qt::DecorationRole) {
-        return item->decoration(index.column());
+        return item->decoration(column);
     }
 
     return QVariant();
diff --git a/plugins/infowidget/peerviewmodel.h b/plugins/infowidget/peerviewmodel.h
index 48bd08360..359cd86b1 100644
--- a/plugins/infowidget/peerviewmodel.h
+++ b/plugins/infowidget/peerviewmodel.h
@@ -55,6 +55,27 @@ public:
     bt::PeerInterface *indexToPeer(const QModelIndex &idx);
 
 public:
+    enum class Column : int {
+        ADDRESS,
+        COUNTRY,
+        CLIENT,
+        DOWNLOAD_SPEED,
+        UPLOAD_SPEED,
+        CHOKED,
+        SNUBBED,
+        AVAILABILITY,
+        DHT,
+        SCORE,
+        UPLOAD_SLOT,
+        REQUESTS,
+        DOWNLOADED,
+        UPLOADED,
+        INTERESTED,
+        INTERESTING,
+        _NUMBER_OF_COLUMNS,
+    };
+    static constexpr auto NUM_COLUMNS = static_cast<int>(Column::_NUMBER_OF_COLUMNS);
+
     struct Item {
         bt::PeerInterface *peer;
         mutable bt::PeerInterface::Stats stats;
@@ -69,9 +90,9 @@ public:
         );
 
         bool changed() const;
-        QVariant data(int col) const;
-        QVariant decoration(int col) const;
-        QVariant sortData(int col) const;
+        QVariant data(Column col) const;
+        QVariant decoration(Column col) const;
+        QVariant sortData(Column col) const;
     };
 
 private:
diff --git a/plugins/infowidget/trackermodel.cpp b/plugins/infowidget/trackermodel.cpp
index 71f29997e..13e136ec4 100644
--- a/plugins/infowidget/trackermodel.cpp
+++ b/plugins/infowidget/trackermodel.cpp
@@ -73,7 +73,7 @@ int TrackerModel::columnCount(const QModelIndex &parent) const
     if (parent.isValid()) {
         return 0;
     } else {
-        return 6;
+        return NUM_COLUMNS;
     }
 }
 
@@ -90,13 +90,14 @@ QVariant TrackerModel::data(const QModelIndex &index, int role) const
 
     bt::TrackerInterface *trk = item->trk;
 
-    if (role == Qt::CheckStateRole && index.column() == 0) {
+    const Column column{index.column()};
+    if (role == Qt::CheckStateRole && column == Column::URL) {
         return trk->isEnabled() ? Qt::Checked : Qt::Unchecked;
     } else if (role == Qt::DisplayRole) {
-        return item->displayData(index.column());
+        return item->displayData(column);
     } else if (role == Qt::UserRole) {
-        return item->sortData(index.column());
-    } else if (role == Qt::ForegroundRole && index.column() == 1 && trk->trackerStatus() == bt::TRACKER_ERROR) {
+        return item->sortData(column);
+    } else if (role == Qt::ForegroundRole && column == Column::STATUS && trk->trackerStatus() == bt::TRACKER_ERROR) {
         return QColor(Qt::red);
     }
 
@@ -124,19 +125,21 @@ QVariant TrackerModel::headerData(int section, Qt::Orientation orientation, int
     }
 
     if (role == Qt::DisplayRole) {
-        switch (section) {
-        case 0:
+        switch (Column{section}) {
+        case Column::URL:
             return i18n("URL");
-        case 1:
+        case Column::STATUS:
             return i18n("Status");
-        case 2:
+        case Column::SEEDERS:
             return i18n("Seeders");
-        case 3:
+        case Column::LEECHERS:
             return i18n("Leechers");
-        case 4:
+        case Column::TIMES_DOWNLOADED:
             return i18n("Times Downloaded");
-        case 5:
+        case Column::NEXT_UPDATE:
             return i18n("Next Update");
+        default:
+            break;
         }
     }
     return QVariant();
@@ -182,7 +185,7 @@ bool TrackerModel::removeRows(int row, int count, const QModelIndex &parent)
 
 Qt::ItemFlags TrackerModel::flags(const QModelIndex &index) const
 {
-    if (!tc || !index.isValid() || index.row() >= trackers.count() || index.row() < 0 || index.column() != 0) {
+    if (!tc || !index.isValid() || index.row() >= trackers.count() || index.row() < 0 || Column{index.column()} != Column::URL) {
         return QAbstractItemModel::flags(index);
     } else {
         return QAbstractItemModel::flags(index) | Qt::ItemIsUserCheckable;
@@ -259,20 +262,20 @@ bool TrackerModel::Item::update()
     return ret;
 }
 
-QVariant TrackerModel::Item::displayData(int column) const
+QVariant TrackerModel::Item::displayData(Column column) const
 {
     switch (column) {
-    case 0:
+    case Column::URL:
         return trk->trackerURL().toString();
-    case 1:
+    case Column::STATUS:
         return trk->trackerStatusString();
-    case 2:
+    case Column::SEEDERS:
         return seeders >= 0 ? seeders : QVariant();
-    case 3:
+    case Column::LEECHERS:
         return leechers >= 0 ? leechers : QVariant();
-    case 4:
+    case Column::TIMES_DOWNLOADED:
         return times_downloaded >= 0 ? times_downloaded : QVariant();
-    case 5: {
+    case Column::NEXT_UPDATE: {
         int secs = time_to_next_update;
         if (secs) {
             return QTime(0, 0, 0, 0).addSecs(secs).toString(QStringLiteral("mm:ss"));
@@ -285,20 +288,20 @@ QVariant TrackerModel::Item::displayData(int column) const
     }
 }
 
-QVariant TrackerModel::Item::sortData(int column) const
+QVariant TrackerModel::Item::sortData(Column column) const
 {
     switch (column) {
-    case 0:
+    case Column::URL:
         return trk->trackerURL().toString();
-    case 1:
+    case Column::STATUS:
         return status;
-    case 2:
+    case Column::SEEDERS:
         return seeders;
-    case 3:
+    case Column::LEECHERS:
         return leechers;
-    case 4:
+    case Column::TIMES_DOWNLOADED:
         return times_downloaded;
-    case 5:
+    case Column::NEXT_UPDATE:
         return time_to_next_update;
     default:
         return QVariant();
diff --git a/plugins/infowidget/trackermodel.h b/plugins/infowidget/trackermodel.h
index 38c82de8e..f309ecef8 100644
--- a/plugins/infowidget/trackermodel.h
+++ b/plugins/infowidget/trackermodel.h
@@ -53,6 +53,17 @@ public:
     void addTrackers(QList<bt::TrackerInterface *> &tracker_list);
 
 private:
+    enum class Column : int {
+        URL,
+        STATUS,
+        SEEDERS,
+        LEECHERS,
+        TIMES_DOWNLOADED,
+        NEXT_UPDATE,
+        _NUMBER_OF_COLUMNS,
+    };
+    static constexpr auto NUM_COLUMNS = static_cast<int>(Column::_NUMBER_OF_COLUMNS);
+
     struct Item {
         bt::TrackerInterface *trk;
         bt::TrackerStatus status;
@@ -63,8 +74,8 @@ private:
 
         Item(bt::TrackerInterface *tracker);
         bool update();
-        QVariant displayData(int column) const;
-        QVariant sortData(int column) const;
+        QVariant displayData(Column column) const;
+        QVariant sortData(Column column) const;
     };
 
     bt::TorrentInterface *tc;
diff --git a/plugins/infowidget/webseedsmodel.cpp b/plugins/infowidget/webseedsmodel.cpp
index daa3a0707..1c9e004fc 100644
--- a/plugins/infowidget/webseedsmodel.cpp
+++ b/plugins/infowidget/webseedsmodel.cpp
@@ -93,7 +93,7 @@ int WebSeedsModel::columnCount(const QModelIndex &parent) const
     if (parent.isValid()) {
         return 0;
     } else {
-        return 4;
+        return NUM_COLUMNS;
     }
 }
 
@@ -103,14 +103,14 @@ QVariant WebSeedsModel::headerData(int section, Qt::Orientation orientation, int
         return QVariant();
     }
 
-    switch (section) {
-    case 0:
+    switch (Column{section}) {
+    case Column::URL:
         return i18n("URL");
-    case 1:
+    case Column::SPEED:
         return i18n("Speed");
-    case 2:
+    case Column::DOWNLOADED:
         return i18n("Downloaded");
-    case 3:
+    case Column::STATUS:
         return i18n("Status");
     default:
         return QVariant();
@@ -127,32 +127,37 @@ QVariant WebSeedsModel::data(const QModelIndex &index, int role) const
         return QVariant();
     }
 
+    const Column column{index.column()};
     if (role == Qt::DisplayRole) {
         const bt::WebSeedInterface *ws = curr_tc.data()->getWebSeed(index.row());
-        switch (index.column()) {
-        case 0:
+        switch (column) {
+        case Column::URL:
             return ws->getUrl().toDisplayString();
-        case 1:
+        case Column::SPEED:
             return bt::BytesPerSecToString(ws->getDownloadRate());
-        case 2:
+        case Column::DOWNLOADED:
             return bt::BytesToString(ws->getTotalDownloaded());
-        case 3:
+        case Column::STATUS:
             return ws->getStatus();
+        default:
+            break;
         }
-    } else if (role == Qt::CheckStateRole && index.column() == 0) {
+    } else if (role == Qt::CheckStateRole && column == Column::URL) {
         const bt::WebSeedInterface *ws = curr_tc.data()->getWebSeed(index.row());
         return ws->isEnabled() ? Qt::Checked : Qt::Unchecked;
     } else if (role == Qt::UserRole) {
         const bt::WebSeedInterface *ws = curr_tc.data()->getWebSeed(index.row());
-        switch (index.column()) {
-        case 0:
+        switch (column) {
+        case Column::URL:
             return ws->getUrl().toDisplayString();
-        case 1:
+        case Column::SPEED:
             return ws->getDownloadRate();
-        case 2:
+        case Column::DOWNLOADED:
             return ws->getTotalDownloaded();
-        case 3:
+        case Column::STATUS:
             return ws->getStatus();
+        default:
+            break;
         }
     }
     return QVariant();
@@ -161,7 +166,7 @@ QVariant WebSeedsModel::data(const QModelIndex &index, int role) const
 Qt::ItemFlags WebSeedsModel::flags(const QModelIndex &index) const
 {
     Qt::ItemFlags flags = QAbstractTableModel::flags(index);
-    if (index.column() == 0) {
+    if (Column{index.column()} == Column::URL) {
         flags |= Qt::ItemIsUserCheckable;
     }
 
diff --git a/plugins/infowidget/webseedsmodel.h b/plugins/infowidget/webseedsmodel.h
index d2af8038a..f76156963 100644
--- a/plugins/infowidget/webseedsmodel.h
+++ b/plugins/infowidget/webseedsmodel.h
@@ -45,6 +45,15 @@ public:
     bool setData(const QModelIndex &index, const QVariant &value, int role) override;
 
 private:
+    enum class Column : int {
+        URL,
+        SPEED,
+        DOWNLOADED,
+        STATUS,
+        _NUMBER_OF_COLUMNS,
+    };
+    static constexpr auto NUM_COLUMNS = static_cast<int>(Column::_NUMBER_OF_COLUMNS);
+
     struct Item {
         QString status;
         bt::Uint64 downloaded;
diff --git a/plugins/logviewer/logflags.cpp b/plugins/logviewer/logflags.cpp
index 3f860fd1f..00e34863e 100644
--- a/plugins/logviewer/logflags.cpp
+++ b/plugins/logviewer/logflags.cpp
@@ -94,7 +94,7 @@ int LogFlags::rowCount(const QModelIndex &parent) const
 int LogFlags::columnCount(const QModelIndex &parent) const
 {
     if (!parent.isValid()) {
-        return 2;
+        return NUM_COLUMNS;
     } else {
         return 0;
     }
@@ -106,10 +106,10 @@ QVariant LogFlags::headerData(int section, Qt::Orientation orientation, int role
         return QVariant();
     }
 
-    switch (section) {
-    case 0:
+    switch (Column{section}) {
+    case Column::CATEGORY:
         return i18n("System");
-    case 1:
+    case Column::LEVEL:
         return i18n("Log Level");
     default:
         return QVariant();
@@ -122,17 +122,18 @@ QVariant LogFlags::data(const QModelIndex &index, int role) const
         return QVariant();
     }
 
+    const Column column{index.column()};
     if (role == Qt::DisplayRole) {
         const LogFlag &f = log_flags.at(index.row());
-        switch (index.column()) {
-        case 0:
+        switch (column) {
+        case Column::CATEGORY:
             return f.name;
-        case 1:
+        case Column::LEVEL:
             return flagToString(f.flag);
         default:
             return QVariant();
         }
-    } else if (role == Qt::EditRole && index.column() == 1) {
+    } else if (role == Qt::EditRole && column == Column::LEVEL) {
         const LogFlag &f = log_flags.at(index.row());
         return f.flag;
     }
@@ -142,7 +143,7 @@ QVariant LogFlags::data(const QModelIndex &index, int role) const
 
 bool LogFlags::setData(const QModelIndex &index, const QVariant &value, int role)
 {
-    if (!index.isValid() || role != Qt::EditRole || index.column() != 1) {
+    if (!index.isValid() || role != Qt::EditRole || Column{index.column()} != Column::LEVEL) {
         return false;
     }
 
@@ -168,7 +169,7 @@ Qt::ItemFlags LogFlags::flags(const QModelIndex &index) const
         return Qt::ItemIsEnabled;
     }
 
-    if (index.column() == 1) {
+    if (Column{index.column()} == Column::LEVEL) {
         return QAbstractItemModel::flags(index) | Qt::ItemIsEditable;
     } else {
         return QAbstractItemModel::flags(index);
diff --git a/plugins/logviewer/logflags.h b/plugins/logviewer/logflags.h
index 88b48fe5f..54b2369da 100644
--- a/plugins/logviewer/logflags.h
+++ b/plugins/logviewer/logflags.h
@@ -54,6 +54,13 @@ private:
     QString flagToString(bt::Uint32 flag) const;
 
 private:
+    enum class Column : int {
+        CATEGORY,
+        LEVEL,
+        _NUMBER_OF_COLUMNS,
+    };
+    static constexpr auto NUM_COLUMNS = static_cast<int>(Column::_NUMBER_OF_COLUMNS);
+
     struct LogFlag {
         QString name;
         bt::Uint32 id;
diff --git a/plugins/mediaplayer/playlist.cpp b/plugins/mediaplayer/playlist.cpp
index a5f6d636e..1035ba496 100644
--- a/plugins/mediaplayer/playlist.cpp
+++ b/plugins/mediaplayer/playlist.cpp
@@ -85,16 +85,16 @@ QVariant PlayList::headerData(int section, Qt::Orientation orientation, int role
         return QVariant();
     }
 
-    switch (section) {
-    case 0:
+    switch (Column{section}) {
+    case Column::TITLE:
         return i18n("Title");
-    case 1:
+    case Column::ARTIST:
         return i18n("Artist");
-    case 2:
+    case Column::ALBUM:
         return i18n("Album");
-    case 3:
+    case Column::LENGTH:
         return i18n("Length");
-    case 4:
+    case Column::YEAR:
         return i18n("Year");
     default:
         return QVariant();
@@ -116,8 +116,9 @@ QVariant PlayList::data(const QModelIndex &index, int role) const
         ref = item.second;
     }
 
+    const Column column{index.column()};
     if (!ref || ref->isNull()) {
-        if (index.column() == 0) {
+        if (column == Column::TITLE) {
             return QFileInfo(file.path()).fileName();
         } else {
             return QVariant();
@@ -126,7 +127,7 @@ QVariant PlayList::data(const QModelIndex &index, int role) const
 
     TagLib::Tag *tag = ref->tag();
     if (!tag) {
-        if (index.column() == 0) {
+        if (column == Column::TITLE) {
             return QFileInfo(file.path()).fileName();
         } else {
             return QVariant();
@@ -134,16 +135,16 @@ QVariant PlayList::data(const QModelIndex &index, int role) const
     }
 
     if (role == Qt::DisplayRole || role == Qt::UserRole) {
-        switch (index.column()) {
-        case 0: {
+        switch (column) {
+        case Column::TITLE: {
             QString title = TStringToQString(tag->title());
             return title.isEmpty() ? QFileInfo(file.path()).fileName() : title;
         }
-        case 1:
+        case Column::ARTIST:
             return TStringToQString(tag->artist());
-        case 2:
+        case Column::ALBUM:
             return TStringToQString(tag->album());
-        case 3:
+        case Column::LENGTH:
             if (role == Qt::UserRole) {
                 return ref->audioProperties()->lengthInSeconds();
             } else {
@@ -151,14 +152,14 @@ QVariant PlayList::data(const QModelIndex &index, int role) const
                 t = t.addSecs(ref->audioProperties()->lengthInSeconds());
                 return t.toString(QStringLiteral("m:ss"));
             }
-        case 4:
+        case Column::YEAR:
             return tag->year() == 0 ? QVariant() : tag->year();
         default:
             return QVariant();
         }
     }
 
-    if (role == Qt::DecorationRole && index.column() == 0) {
+    if (role == Qt::DecorationRole && column == Column::TITLE) {
         if (file == player->getCurrentSource()) {
             return QIcon::fromTheme(QStringLiteral("arrow-right"));
         }
@@ -172,7 +173,7 @@ int PlayList::columnCount(const QModelIndex &parent) const
     if (parent.isValid()) {
         return 0;
     } else {
-        return 5;
+        return NUM_COLUMNS;
     }
 }
 
@@ -225,7 +226,7 @@ QMimeData *PlayList::mimeData(const QModelIndexList &indexes) const
     QMimeData *data = new QMimeData();
     QList<QUrl> urls;
     for (const QModelIndex &index : indexes) {
-        if (index.isValid() && index.column() == 0) {
+        if (index.isValid() && Column{index.column()} == Column::TITLE) {
             urls << QUrl::fromLocalFile(files.at(index.row()).first.path());
             dragged_rows.append(index.row());
         }
diff --git a/plugins/mediaplayer/playlist.h b/plugins/mediaplayer/playlist.h
index 73314c6de..b414bc1e4 100644
--- a/plugins/mediaplayer/playlist.h
+++ b/plugins/mediaplayer/playlist.h
@@ -56,6 +56,16 @@ Q_SIGNALS:
     void itemsDropped();
 
 private:
+    enum class Column : int {
+        TITLE,
+        ARTIST,
+        ALBUM,
+        LENGTH,
+        YEAR,
+        _NUMBER_OF_COLUMNS,
+    };
+    static constexpr auto NUM_COLUMNS = static_cast<int>(Column::_NUMBER_OF_COLUMNS);
+
     typedef QPair<MediaFileRef, TagLib::FileRef *> PlayListItem;
     mutable QList<PlayListItem> files;
     mutable QList<int> dragged_rows;
diff --git a/plugins/shutdown/shutdowntorrentmodel.cpp b/plugins/shutdown/shutdowntorrentmodel.cpp
index df1a47717..d0d6cb2cf 100644
--- a/plugins/shutdown/shutdowntorrentmodel.cpp
+++ b/plugins/shutdown/shutdowntorrentmodel.cpp
@@ -60,18 +60,19 @@ QVariant ShutdownTorrentModel::data(const QModelIndex &index, int role) const
         return QVariant();
     }
 
+    const Column column{index.column()};
     if (role == Qt::CheckStateRole) {
-        if (index.column() != 0) {
+        if (column != Column::EVENT) {
             return QVariant();
         }
 
         return conds.at(index.row()).checked ? Qt::Checked : Qt::Unchecked;
     } else if (role == Qt::DisplayRole) {
         const TriggerItem &cond = conds.at(index.row());
-        switch (index.column()) {
-        case 0:
+        switch (column) {
+        case Column::EVENT:
             return cond.tc->getDisplayName();
-        case 1:
+        case Column::TORRENT:
             if (cond.trigger == DOWNLOADING_COMPLETED) {
                 return i18n("Downloading finishes");
             } else {
@@ -81,7 +82,7 @@ QVariant ShutdownTorrentModel::data(const QModelIndex &index, int role) const
             return QVariant();
         }
     } else if (role == Qt::EditRole) {
-        if (index.column() == 1) {
+        if (column == Column::TORRENT) {
             return conds.at(index.row()).trigger;
         }
     }
@@ -91,7 +92,7 @@ QVariant ShutdownTorrentModel::data(const QModelIndex &index, int role) const
 
 int ShutdownTorrentModel::columnCount(const QModelIndex &parent) const
 {
-    return parent.isValid() ? 0 : 2;
+    return parent.isValid() ? 0 : NUM_COLUMNS;
 }
 
 int ShutdownTorrentModel::rowCount(const QModelIndex &parent) const
@@ -132,10 +133,10 @@ QVariant ShutdownTorrentModel::headerData(int section, Qt::Orientation orientati
         return QVariant();
     }
 
-    switch (section) {
-    case 0:
+    switch (Column{section}) {
+    case Column::TORRENT:
         return i18n("Torrent");
-    case 1:
+    case Column::EVENT:
         return i18n("Event");
     default:
         return QVariant();
@@ -167,12 +168,13 @@ Qt::ItemFlags ShutdownTorrentModel::flags(const QModelIndex &index) const
         return {};
     }
 
+    const Column column{index.column()};
     Qt::ItemFlags flags = Qt::ItemIsSelectable | Qt::ItemIsEnabled;
-    if (index.column() == 0) {
+    if (column == Column::EVENT) {
         flags |= Qt::ItemIsUserCheckable;
     }
 
-    if (index.column() == 1) {
+    if (column == Column::TORRENT) {
         flags |= Qt::ItemIsEditable;
     }
 
diff --git a/plugins/shutdown/shutdowntorrentmodel.h b/plugins/shutdown/shutdowntorrentmodel.h
index 3188ffed5..0e8247b83 100644
--- a/plugins/shutdown/shutdowntorrentmodel.h
+++ b/plugins/shutdown/shutdowntorrentmodel.h
@@ -66,6 +66,13 @@ private Q_SLOTS:
     void torrentRemoved(bt::TorrentInterface *tc);
 
 private:
+    enum class Column : int {
+        TORRENT,
+        EVENT,
+        _NUMBER_OF_COLUMNS,
+    };
+    static constexpr auto NUM_COLUMNS = static_cast<int>(Column::_NUMBER_OF_COLUMNS);
+
     struct TriggerItem {
         bt::TorrentInterface *tc;
         bool checked;
diff --git a/plugins/syndication/feedwidgetmodel.cpp b/plugins/syndication/feedwidgetmodel.cpp
index 57dd6bf63..dc38e8520 100644
--- a/plugins/syndication/feedwidgetmodel.cpp
+++ b/plugins/syndication/feedwidgetmodel.cpp
@@ -63,7 +63,7 @@ int FeedWidgetModel::rowCount(const QModelIndex &parent) const
 int FeedWidgetModel::columnCount(const QModelIndex &parent) const
 {
     if (!parent.isValid()) {
-        return 3;
+        return NUM_COLUMNS;
     } else {
         return 0;
     }
@@ -71,16 +71,16 @@ int FeedWidgetModel::columnCount(const QModelIndex &parent) const
 
 QVariant FeedWidgetModel::headerData(int section, Qt::Orientation orientation, int role) const
 {
-    if (role != Qt::DisplayRole || section < 0 || section >= 3 || orientation != Qt::Horizontal) {
+    if (role != Qt::DisplayRole || section < 0 || section >= NUM_COLUMNS || orientation != Qt::Horizontal) {
         return QVariant();
     }
 
-    switch (section) {
-    case 0:
+    switch (Column{section}) {
+    case Column::TITLE:
         return i18n("Title");
-    case 1:
+    case Column::DATE_PUBLISHED:
         return i18n("Date Published");
-    case 2:
+    case Column::TORRENT:
         return i18n("Torrent");
     default:
         return QVariant();
@@ -97,21 +97,22 @@ QVariant FeedWidgetModel::data(const QModelIndex &index, int role) const
         return QVariant();
     }
 
+    const Column column{index.column()};
     Syndication::ItemPtr item = items.at(index.row());
     if (role == Qt::DisplayRole) {
-        switch (index.column()) {
-        case 0:
+        switch (column) {
+        case Column::TITLE:
             return item->title();
-        case 1:
+        case Column::DATE_PUBLISHED:
             return QLocale().toString(QDateTime::fromSecsSinceEpoch(item->datePublished()), QLocale::ShortFormat);
-        case 2:
+        case Column::TORRENT:
             return TorrentUrlFromItem(item);
         default:
             return QVariant();
         }
-    } else if (role == Qt::DecorationRole && index.column() == 0 && feed->downloaded(item)) {
+    } else if (role == Qt::DecorationRole && column == Column::TITLE && feed->downloaded(item)) {
         return QIcon::fromTheme(QStringLiteral("go-down"));
-    } else if (role == Qt::DecorationRole && index.column() == 0 && feed->failed(item)) {
+    } else if (role == Qt::DecorationRole && column == Column::TITLE && feed->failed(item)) {
         return QIcon::fromTheme(QStringLiteral("data-error"));
     }
 
diff --git a/plugins/syndication/feedwidgetmodel.h b/plugins/syndication/feedwidgetmodel.h
index 9bb300527..ef2fff034 100644
--- a/plugins/syndication/feedwidgetmodel.h
+++ b/plugins/syndication/feedwidgetmodel.h
@@ -44,6 +44,14 @@ public:
     void updated();
 
 private:
+    enum class Column : int {
+        TITLE,
+        DATE_PUBLISHED,
+        TORRENT,
+        _NUMBER_OF_COLUMNS,
+    };
+    static constexpr auto NUM_COLUMNS = static_cast<int>(Column::_NUMBER_OF_COLUMNS);
+
     Feed *feed;
     QList<Syndication::ItemPtr> items;
 };
diff --git a/plugins/upnp/routermodel.cpp b/plugins/upnp/routermodel.cpp
index abb7ea51f..54cf0b923 100644
--- a/plugins/upnp/routermodel.cpp
+++ b/plugins/upnp/routermodel.cpp
@@ -43,7 +43,7 @@ int RouterModel::rowCount(const QModelIndex &parent) const
 int RouterModel::columnCount(const QModelIndex &parent) const
 {
     if (!parent.isValid()) {
-        return 2;
+        return NUM_COLUMNS;
     } else {
         return 0;
     }
@@ -55,10 +55,10 @@ QVariant RouterModel::headerData(int section, Qt::Orientation orientation, int r
         return QVariant();
     }
 
-    switch (section) {
-    case 0:
+    switch (Column{section}) {
+    case Column::DEVICE:
         return i18n("Device");
-    case 1:
+    case Column::PORTS_FORWARDED:
         return i18n("Ports Forwarded");
     default:
         return QVariant();
@@ -80,26 +80,29 @@ QVariant RouterModel::data(const QModelIndex &index, int role) const
         return QVariant();
     }
 
+    const Column column{index.column()};
     const bt::UPnPRouter *r = routers.at(index.row());
     if (role == Qt::DisplayRole) {
-        switch (index.column()) {
-        case 0:
+        switch (column) {
+        case Column::DEVICE:
             return r->getDescription().friendlyName;
-        case 1:
+        case Column::PORTS_FORWARDED:
             if (!r->getError().isEmpty()) {
                 return r->getError();
             } else {
                 return ports(r);
             }
+        default:
+            break;
         }
     } else if (role == Qt::DecorationRole) {
-        if (index.column() == 0) {
+        if (column == Column::DEVICE) {
             return QIcon::fromTheme(QStringLiteral("modem"));
-        } else if (index.column() == 1 && !r->getError().isEmpty()) {
+        } else if (column == Column::PORTS_FORWARDED && !r->getError().isEmpty()) {
             return QIcon::fromTheme(QStringLiteral("dialog-error"));
         }
     } else if (role == Qt::ToolTipRole) {
-        if (index.column() == 0) {
+        if (column == Column::DEVICE) {
             const bt::UPnPDeviceDescription &d = r->getDescription();
             return i18n(
                 "Model Name: <b>%1</b><br/>"
@@ -108,7 +111,7 @@ QVariant RouterModel::data(const QModelIndex &index, int role) const
                 d.modelName,
                 d.manufacturer,
                 d.modelDescription);
-        } else if (index.column() == 1 && !r->getError().isEmpty()) {
+        } else if (column == Column::PORTS_FORWARDED && !r->getError().isEmpty()) {
             return r->getError();
         }
     }
diff --git a/plugins/upnp/routermodel.h b/plugins/upnp/routermodel.h
index f55776616..4a4799354 100644
--- a/plugins/upnp/routermodel.h
+++ b/plugins/upnp/routermodel.h
@@ -57,6 +57,13 @@ private:
     QString ports(const bt::UPnPRouter *r) const;
 
 private:
+    enum class Column : int {
+        DEVICE,
+        PORTS_FORWARDED,
+        _NUMBER_OF_COLUMNS,
+    };
+    static constexpr auto NUM_COLUMNS = static_cast<int>(Column::_NUMBER_OF_COLUMNS);
+
     QList<bt::UPnPRouter *> routers;
 };
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.