File indexing completed on 2024-07-21 07:58:07

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