File indexing completed on 2024-07-14 09:00:23

0001 /*
0002     SPDX-FileCopyrightText: 2011 Ilia Kats <ilia-kats@gmx.net>
0003 
0004     SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-only OR LicenseRef-KDE-Accepted-GPL
0005 */
0006 
0007 #include <QNetworkAddressEntry>
0008 #include <QStandardItem>
0009 #include <QStandardItemModel>
0010 
0011 #include <KAcceleratorManager>
0012 #include <KLocalizedString>
0013 
0014 #include "intdelegate.h"
0015 #include "ipv4delegate.h"
0016 #include "ipv4routeswidget.h"
0017 #include "ui_ipv4routes.h"
0018 
0019 class IpV4RoutesWidget::Private
0020 {
0021 public:
0022     Private()
0023         : model(0, 4)
0024     {
0025         auto headerItem = new QStandardItem(i18nc("Header text for IPv4 address", "Address"));
0026         model.setHorizontalHeaderItem(0, headerItem);
0027         headerItem = new QStandardItem(i18nc("Header text for IPv4 netmask", "Netmask"));
0028         model.setHorizontalHeaderItem(1, headerItem);
0029         headerItem = new QStandardItem(i18nc("Header text for IPv4 gateway", "Gateway"));
0030         model.setHorizontalHeaderItem(2, headerItem);
0031         headerItem = new QStandardItem(i18nc("Header text for IPv4 route metric", "Metric"));
0032         model.setHorizontalHeaderItem(3, headerItem);
0033     }
0034     Ui_RoutesIp4Config ui;
0035     QStandardItemModel model;
0036 };
0037 
0038 IpV4RoutesWidget::IpV4RoutesWidget(QWidget *parent)
0039     : QDialog(parent)
0040     , d(new IpV4RoutesWidget::Private())
0041 {
0042     d->ui.setupUi(this);
0043     d->ui.tableViewAddresses->setModel(&d->model);
0044     d->ui.tableViewAddresses->horizontalHeader()->setSectionResizeMode(QHeaderView::Interactive);
0045 
0046     auto ipDelegate = new IpV4Delegate(this);
0047     auto metricDelegate = new IntDelegate(this);
0048     d->ui.tableViewAddresses->setItemDelegateForColumn(0, ipDelegate);
0049     d->ui.tableViewAddresses->setItemDelegateForColumn(1, ipDelegate);
0050     d->ui.tableViewAddresses->setItemDelegateForColumn(2, ipDelegate);
0051     d->ui.tableViewAddresses->setItemDelegateForColumn(3, metricDelegate);
0052 
0053     connect(d->ui.pushButtonAdd, &QPushButton::clicked, this, &IpV4RoutesWidget::addRoute);
0054     connect(d->ui.pushButtonRemove, &QPushButton::clicked, this, &IpV4RoutesWidget::removeRoute);
0055 
0056     connect(d->ui.tableViewAddresses->selectionModel(), &QItemSelectionModel::selectionChanged, this, &IpV4RoutesWidget::selectionChanged);
0057 
0058     connect(&d->model, &QStandardItemModel::itemChanged, this, &IpV4RoutesWidget::tableViewItemChanged);
0059 
0060     connect(d->ui.buttonBox, &QDialogButtonBox::accepted, this, &IpV4RoutesWidget::accept);
0061     connect(d->ui.buttonBox, &QDialogButtonBox::rejected, this, &IpV4RoutesWidget::reject);
0062 
0063     KAcceleratorManager::manage(this);
0064 }
0065 
0066 IpV4RoutesWidget::~IpV4RoutesWidget()
0067 {
0068     delete d;
0069 }
0070 
0071 void IpV4RoutesWidget::setNeverDefault(bool checked)
0072 {
0073     d->ui.cbNeverDefault->setChecked(checked);
0074 }
0075 
0076 bool IpV4RoutesWidget::neverDefault() const
0077 {
0078     return d->ui.cbNeverDefault->isChecked();
0079 }
0080 
0081 void IpV4RoutesWidget::setIgnoreAutoRoutes(bool checked)
0082 {
0083     d->ui.cbIgnoreAutoRoutes->setChecked(checked);
0084 }
0085 
0086 void IpV4RoutesWidget::setIgnoreAutoRoutesCheckboxEnabled(bool enabled)
0087 {
0088     d->ui.cbIgnoreAutoRoutes->setEnabled(enabled);
0089 }
0090 
0091 bool IpV4RoutesWidget::ignoreautoroutes() const
0092 {
0093     return d->ui.cbIgnoreAutoRoutes->isChecked();
0094 }
0095 
0096 void IpV4RoutesWidget::setRoutes(const QList<NetworkManager::IpRoute> &list)
0097 {
0098     d->model.removeRows(0, d->model.rowCount());
0099     for (const NetworkManager::IpRoute &route : list) {
0100         const QList<QStandardItem *> item{
0101             new QStandardItem(route.ip().toString()),
0102             new QStandardItem(route.netmask().toString()),
0103             new QStandardItem(route.nextHop().toString()),
0104             new QStandardItem(QString::number(route.metric(), 10)),
0105         };
0106 
0107         d->model.appendRow(item);
0108     }
0109 }
0110 
0111 QList<NetworkManager::IpRoute> IpV4RoutesWidget::routes()
0112 {
0113     QList<NetworkManager::IpRoute> list;
0114 
0115     for (int i = 0, rowCount = d->model.rowCount(); i < rowCount; i++) {
0116         NetworkManager::IpRoute route;
0117         QStandardItem *item = d->model.item(i, 0);
0118         if (item) {
0119             route.setIp(QHostAddress(item->text()));
0120         }
0121         item = d->model.item(i, 1);
0122         if (item) {
0123             route.setNetmask(QHostAddress(item->text()));
0124         }
0125         item = d->model.item(i, 2);
0126         if (item) {
0127             route.setNextHop(QHostAddress(item->text()));
0128         }
0129         item = d->model.item(i, 3);
0130         if (item) {
0131             route.setMetric(item->text().toUInt());
0132         }
0133 
0134         list << route;
0135     }
0136     return list;
0137 }
0138 
0139 void IpV4RoutesWidget::addRoute()
0140 {
0141     QList<QStandardItem *> item{new QStandardItem, new QStandardItem, new QStandardItem};
0142     d->model.appendRow(item);
0143 
0144     const int rowCount = d->model.rowCount();
0145     if (rowCount > 0) {
0146         d->ui.tableViewAddresses->selectRow(rowCount - 1);
0147 
0148         QItemSelectionModel *selectionModel = d->ui.tableViewAddresses->selectionModel();
0149         QModelIndexList list = selectionModel->selectedIndexes();
0150         if (list.size()) {
0151             // QTableView is configured to select only rows.
0152             // So, list[0] - IP address.
0153             d->ui.tableViewAddresses->edit(list[0]);
0154         }
0155     }
0156 }
0157 
0158 void IpV4RoutesWidget::removeRoute()
0159 {
0160     QItemSelectionModel *selectionModel = d->ui.tableViewAddresses->selectionModel();
0161     if (selectionModel->hasSelection()) {
0162         QModelIndexList indexes = selectionModel->selectedIndexes();
0163         d->model.takeRow(indexes[0].row());
0164     }
0165     d->ui.pushButtonRemove->setEnabled(d->ui.tableViewAddresses->selectionModel()->hasSelection());
0166 }
0167 
0168 void IpV4RoutesWidget::selectionChanged(const QItemSelection &selected)
0169 {
0170     // qCDebug(PLASMA_NM_EDITOR_LOG) << "selectionChanged";
0171     d->ui.pushButtonRemove->setEnabled(!selected.isEmpty());
0172 }
0173 
0174 extern quint32 suggestNetmask(quint32 ip);
0175 
0176 void IpV4RoutesWidget::tableViewItemChanged(QStandardItem *item)
0177 {
0178     if (item->text().isEmpty()) {
0179         return;
0180     }
0181 
0182     const int column = item->column();
0183     if (column == 0) { // ip
0184         int row = item->row();
0185 
0186         QStandardItem *netmaskItem = d->model.item(row, column + 1); // netmask
0187         if (netmaskItem && netmaskItem->text().isEmpty()) {
0188             QHostAddress addr(item->text());
0189             const quint32 netmask = suggestNetmask(addr.toIPv4Address());
0190             if (netmask) {
0191                 QHostAddress v(netmask);
0192                 netmaskItem->setText(v.toString());
0193             }
0194         }
0195     }
0196 }
0197 
0198 #include "moc_ipv4routeswidget.cpp"