File indexing completed on 2025-02-16 08:18:43
0001 /* 0002 SPDX-FileCopyrightText: 2013 Lukas Tinkl <ltinkl@redhat.com> 0003 0004 SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL 0005 */ 0006 0007 #include "ipv4widget.h" 0008 #include "ipv4delegate.h" 0009 #include "ui_ipv4.h" 0010 0011 #include <QDesktopServices> 0012 #include <QDialog> 0013 #include <QDialogButtonBox> 0014 #include <QFormLayout> 0015 #include <QHostInfo> 0016 #include <QItemSelection> 0017 #include <QNetworkAddressEntry> 0018 #include <QSpinBox> 0019 #include <QStandardItemModel> 0020 #include <QUrl> 0021 0022 #include <KEditListWidget> 0023 #include <KLocalizedString> 0024 0025 quint32 suggestNetmask(quint32 ip) 0026 { 0027 /* 0028 A 0 0.0.0.0 <-->127.255.255.255 255.0.0.0 <--->/8 0029 B 10 128.0.0.0 <>191.255.255.255 255.255.0.0 <->/16 0030 C 110 192.0.0.0 <>223.255.255.255 255.255.255.0 >/24 0031 D 1110 224.0.0.0 <>239.255.255.255 not defined <->not defined 0032 E 1111 240.0.0.0 <>255.255.255.254 not defined <->not defined 0033 */ 0034 quint32 netmask = 0; 0035 0036 if (!(ip & 0x80000000)) { 0037 // test 0 leading bit 0038 netmask = 0xFF000000; 0039 } else if (!(ip & 0x40000000)) { 0040 // test 10 leading bits 0041 netmask = 0xFFFF0000; 0042 } else if (!(ip & 0x20000000)) { 0043 // test 110 leading bits 0044 netmask = 0xFFFFFF00; 0045 } 0046 0047 return netmask; 0048 } 0049 0050 class IPv4Widget::Private 0051 { 0052 public: 0053 Private() 0054 : model(0, 3) 0055 { 0056 auto headerItem = new QStandardItem(i18nc("Header text for IPv4 address", "Address")); 0057 model.setHorizontalHeaderItem(0, headerItem); 0058 headerItem = new QStandardItem(i18nc("Header text for IPv4 netmask", "Netmask")); 0059 model.setHorizontalHeaderItem(1, headerItem); 0060 headerItem = new QStandardItem(i18nc("Header text for IPv4 gateway", "Gateway")); 0061 model.setHorizontalHeaderItem(2, headerItem); 0062 } 0063 QStandardItemModel model; 0064 }; 0065 0066 IPv4Widget::IPv4Widget(const NetworkManager::Setting::Ptr &setting, QWidget *parent, Qt::WindowFlags f) 0067 : SettingWidget(setting, parent, f) 0068 , m_ui(new Ui::IPv4Widget) 0069 , d(new IPv4Widget::Private()) 0070 { 0071 m_ui->setupUi(this); 0072 0073 m_ui->tableViewAddresses->setModel(&d->model); 0074 m_ui->tableViewAddresses->horizontalHeader()->setSectionResizeMode(QHeaderView::Interactive); 0075 m_ui->tableViewAddresses->horizontalHeader()->setStretchLastSection(true); 0076 0077 auto ipDelegate = new IpV4Delegate(this); 0078 m_ui->tableViewAddresses->setItemDelegateForColumn(0, ipDelegate); 0079 m_ui->tableViewAddresses->setItemDelegateForColumn(1, ipDelegate); 0080 m_ui->tableViewAddresses->setItemDelegateForColumn(2, ipDelegate); 0081 0082 connect(m_ui->btnAdd, &QPushButton::clicked, this, &IPv4Widget::slotAddIPAddress); 0083 connect(m_ui->btnRemove, &QPushButton::clicked, this, &IPv4Widget::slotRemoveIPAddress); 0084 0085 connect(m_ui->dnsMorePushButton, &QPushButton::clicked, this, &IPv4Widget::slotDnsServers); 0086 connect(m_ui->dnsSearchMorePushButton, &QPushButton::clicked, this, &IPv4Widget::slotDnsDomains); 0087 0088 connect(m_ui->tableViewAddresses->selectionModel(), &QItemSelectionModel::selectionChanged, this, &IPv4Widget::selectionChanged); 0089 0090 connect(&d->model, &QStandardItemModel::itemChanged, this, &IPv4Widget::tableViewItemChanged); 0091 0092 if (setting) { 0093 loadConfig(setting); 0094 } 0095 0096 connect(m_ui->method, QOverload<int>::of(&KComboBox::currentIndexChanged), this, &IPv4Widget::slotModeComboChanged); 0097 slotModeComboChanged(m_ui->method->currentIndex()); 0098 0099 connect(m_ui->btnRoutes, &QPushButton::clicked, this, &IPv4Widget::slotRoutesDialog); 0100 connect(m_ui->btnAdvanced, &QPushButton::clicked, this, &IPv4Widget::slotAdvancedDialog); 0101 0102 // Connect for setting check 0103 watchChangedSetting(); 0104 0105 // Connect for validity check 0106 connect(m_ui->dns, &KLineEdit::textChanged, this, &IPv4Widget::slotWidgetChanged); 0107 connect(m_ui->method, QOverload<int>::of(&KComboBox::currentIndexChanged), this, &IPv4Widget::slotWidgetChanged); 0108 connect(&d->model, &QStandardItemModel::dataChanged, this, &IPv4Widget::slotWidgetChanged); 0109 connect(&d->model, &QStandardItemModel::rowsRemoved, this, &IPv4Widget::slotWidgetChanged); 0110 0111 KAcceleratorManager::manage(this); 0112 } 0113 0114 IPv4Widget::~IPv4Widget() 0115 { 0116 delete d; 0117 delete m_ui; 0118 } 0119 0120 void IPv4Widget::loadConfig(const NetworkManager::Setting::Ptr &setting) 0121 { 0122 NetworkManager::Ipv4Setting::Ptr ipv4Setting = setting.staticCast<NetworkManager::Ipv4Setting>(); 0123 0124 // BUG:406118 0125 // We don't have route-metric in the UI, maybe even won't have for now, but that doesn't mean we 0126 // want to loose it when it's configured manually in a config file 0127 m_tmpIpv4Setting.setRouteMetric(ipv4Setting->routeMetric()); 0128 0129 m_tmpIpv4Setting.setRoutes(ipv4Setting->routes()); 0130 m_tmpIpv4Setting.setNeverDefault(ipv4Setting->neverDefault()); 0131 m_tmpIpv4Setting.setIgnoreAutoRoutes(ipv4Setting->ignoreAutoRoutes()); 0132 0133 m_tmpIpv4Setting.setDhcpHostname(ipv4Setting->dhcpHostname()); 0134 m_tmpIpv4Setting.setDhcpSendHostname(ipv4Setting->dhcpSendHostname()); 0135 m_tmpIpv4Setting.setDadTimeout(ipv4Setting->dadTimeout()); 0136 0137 // method 0138 switch (ipv4Setting->method()) { 0139 case NetworkManager::Ipv4Setting::Automatic: 0140 if (ipv4Setting->ignoreAutoDns()) { 0141 m_ui->method->setCurrentIndex(AutomaticOnlyIP); 0142 } else { 0143 m_ui->method->setCurrentIndex(Automatic); 0144 } 0145 break; 0146 case NetworkManager::Ipv4Setting::Manual: 0147 m_ui->method->setCurrentIndex(Manual); 0148 break; 0149 case NetworkManager::Ipv4Setting::LinkLocal: 0150 m_ui->method->setCurrentIndex(LinkLocal); 0151 break; 0152 case NetworkManager::Ipv4Setting::Shared: 0153 m_ui->method->setCurrentIndex(Shared); 0154 break; 0155 case NetworkManager::Ipv4Setting::Disabled: 0156 m_ui->method->setCurrentIndex(Disabled); 0157 break; 0158 } 0159 0160 // dns 0161 QStringList tmp; 0162 for (const QHostAddress &addr : ipv4Setting->dns()) { 0163 tmp.append(addr.toString()); 0164 } 0165 m_ui->dns->setText(tmp.join(QStringLiteral(","))); 0166 m_ui->dnsSearch->setText(ipv4Setting->dnsSearch().join(QStringLiteral(","))); 0167 0168 m_ui->dhcpClientId->setText(ipv4Setting->dhcpClientId()); 0169 0170 // addresses 0171 for (const NetworkManager::IpAddress &addr : ipv4Setting->addresses()) { 0172 QList<QStandardItem *> item{ 0173 new QStandardItem(addr.ip().toString()), 0174 new QStandardItem(addr.netmask().toString()), 0175 new QStandardItem(addr.gateway().toString()), 0176 }; 0177 0178 d->model.appendRow(item); 0179 } 0180 0181 // may-fail 0182 m_ui->ipv4RequiredCB->setChecked(!ipv4Setting->mayFail()); 0183 } 0184 0185 QVariantMap IPv4Widget::setting() const 0186 { 0187 NetworkManager::Ipv4Setting ipv4Setting; 0188 0189 // BUG:406118 0190 // We don't have route-metric in the UI, maybe even won't have for now, but that doesn't mean we 0191 // want to loose it when it's configured manually in a config file 0192 ipv4Setting.setRouteMetric(m_tmpIpv4Setting.routeMetric()); 0193 0194 ipv4Setting.setRoutes(m_tmpIpv4Setting.routes()); 0195 ipv4Setting.setNeverDefault(m_tmpIpv4Setting.neverDefault()); 0196 ipv4Setting.setIgnoreAutoRoutes(m_tmpIpv4Setting.ignoreAutoRoutes()); 0197 0198 ipv4Setting.setDhcpHostname(m_tmpIpv4Setting.dhcpHostname()); 0199 ipv4Setting.setDhcpSendHostname(m_tmpIpv4Setting.dhcpSendHostname()); 0200 ipv4Setting.setDadTimeout(m_tmpIpv4Setting.dadTimeout()); 0201 0202 // method 0203 switch ((MethodIndex)m_ui->method->currentIndex()) { 0204 case Automatic: 0205 ipv4Setting.setMethod(NetworkManager::Ipv4Setting::Automatic); 0206 break; 0207 case IPv4Widget::AutomaticOnlyIP: 0208 ipv4Setting.setMethod(NetworkManager::Ipv4Setting::Automatic); 0209 ipv4Setting.setIgnoreAutoDns(true); 0210 break; 0211 case Manual: 0212 ipv4Setting.setMethod(NetworkManager::Ipv4Setting::Manual); 0213 break; 0214 case LinkLocal: 0215 ipv4Setting.setMethod(NetworkManager::Ipv4Setting::LinkLocal); 0216 break; 0217 case Shared: 0218 ipv4Setting.setMethod(NetworkManager::Ipv4Setting::Shared); 0219 break; 0220 case Disabled: 0221 ipv4Setting.setMethod(NetworkManager::Ipv4Setting::Disabled); 0222 break; 0223 } 0224 0225 // dns 0226 if (m_ui->dns->isEnabled() && !m_ui->dns->text().isEmpty()) { 0227 QStringList tmp = m_ui->dns->text().split(QLatin1Char(',')); 0228 QList<QHostAddress> tmpAddrList; 0229 for (const QString &str : tmp) { 0230 QHostAddress addr(str); 0231 if (!addr.isNull()) 0232 tmpAddrList.append(addr); 0233 } 0234 ipv4Setting.setDns(tmpAddrList); 0235 } 0236 if (m_ui->dnsSearch->isEnabled() && !m_ui->dnsSearch->text().isEmpty()) { 0237 ipv4Setting.setDnsSearch(m_ui->dnsSearch->text().split(QLatin1Char(','))); 0238 } 0239 0240 // dhcp id 0241 if (m_ui->dhcpClientId->isEnabled() && !m_ui->dhcpClientId->text().isEmpty()) { 0242 ipv4Setting.setDhcpClientId(m_ui->dhcpClientId->text()); 0243 } 0244 0245 // addresses 0246 if (m_ui->tableViewAddresses->isEnabled()) { 0247 QList<NetworkManager::IpAddress> list; 0248 for (int i = 0, rowCount = d->model.rowCount(); i < rowCount; i++) { 0249 NetworkManager::IpAddress address; 0250 address.setIp(QHostAddress(d->model.item(i, 0)->text())); 0251 address.setNetmask(QHostAddress(d->model.item(i, 1)->text())); 0252 address.setGateway(QHostAddress(d->model.item(i, 2)->text())); 0253 list << address; 0254 } 0255 if (!list.isEmpty()) { 0256 ipv4Setting.setAddresses(list); 0257 } 0258 } 0259 0260 // may-fail 0261 if (m_ui->ipv4RequiredCB->isEnabled()) { 0262 ipv4Setting.setMayFail(!m_ui->ipv4RequiredCB->isChecked()); 0263 } 0264 0265 return ipv4Setting.toMap(); 0266 } 0267 0268 void IPv4Widget::slotModeComboChanged(int index) 0269 { 0270 if (index == Automatic) { // Automatic 0271 m_ui->dnsLabel->setText(i18n("Other DNS Servers:")); 0272 m_ui->dns->setEnabled(true); 0273 m_ui->dnsMorePushButton->setEnabled(true); 0274 m_ui->dnsSearch->setEnabled(true); 0275 m_ui->dnsSearchMorePushButton->setEnabled(true); 0276 m_ui->dhcpClientId->setEnabled(true); 0277 m_ui->ipv4RequiredCB->setEnabled(true); 0278 m_ui->btnRoutes->setEnabled(true); 0279 m_ui->tableViewAddresses->setEnabled(false); 0280 m_ui->btnAdd->setEnabled(false); 0281 m_ui->btnRemove->setEnabled(false); 0282 } else if (index == AutomaticOnlyIP) { 0283 m_ui->dnsLabel->setText(i18n("DNS Servers:")); 0284 m_ui->dns->setEnabled(true); 0285 m_ui->dnsMorePushButton->setEnabled(true); 0286 m_ui->dnsSearch->setEnabled(true); 0287 m_ui->dnsSearchMorePushButton->setEnabled(true); 0288 m_ui->dhcpClientId->setEnabled(true); 0289 m_ui->ipv4RequiredCB->setEnabled(true); 0290 m_ui->btnRoutes->setEnabled(true); 0291 m_ui->tableViewAddresses->setEnabled(false); 0292 m_ui->btnAdd->setEnabled(false); 0293 m_ui->btnRemove->setEnabled(false); 0294 } else if (index == Manual) { // Manual 0295 m_ui->dnsLabel->setText(i18n("DNS Servers:")); 0296 m_ui->dns->setEnabled(true); 0297 m_ui->dnsMorePushButton->setEnabled(true); 0298 m_ui->dnsSearch->setEnabled(true); 0299 m_ui->dnsSearchMorePushButton->setEnabled(true); 0300 m_ui->dhcpClientId->setEnabled(false); 0301 m_ui->ipv4RequiredCB->setEnabled(true); 0302 m_ui->btnRoutes->setEnabled(true); 0303 m_ui->tableViewAddresses->setEnabled(true); 0304 m_ui->btnAdd->setEnabled(true); 0305 m_ui->btnRemove->setEnabled(true); 0306 } else if (index == LinkLocal || index == Shared) { // Link-local or Shared 0307 m_ui->dnsLabel->setText(i18n("DNS Servers:")); 0308 m_ui->dns->setEnabled(false); 0309 m_ui->dnsMorePushButton->setEnabled(false); 0310 m_ui->dnsSearch->setEnabled(false); 0311 m_ui->dnsSearchMorePushButton->setEnabled(false); 0312 m_ui->dhcpClientId->setEnabled(false); 0313 m_ui->ipv4RequiredCB->setEnabled(true); 0314 m_ui->btnRoutes->setEnabled(false); 0315 m_ui->tableViewAddresses->setEnabled(false); 0316 m_ui->btnAdd->setEnabled(false); 0317 m_ui->btnRemove->setEnabled(false); 0318 } else if (index == Disabled) { // Disabled 0319 m_ui->dnsLabel->setText(i18n("DNS Servers:")); 0320 m_ui->dns->setEnabled(false); 0321 m_ui->dnsMorePushButton->setEnabled(false); 0322 m_ui->dnsSearch->setEnabled(false); 0323 m_ui->dnsSearchMorePushButton->setEnabled(false); 0324 m_ui->dhcpClientId->setEnabled(false); 0325 m_ui->ipv4RequiredCB->setEnabled(false); 0326 m_ui->btnRoutes->setEnabled(false); 0327 m_ui->tableViewAddresses->setEnabled(false); 0328 m_ui->btnAdd->setEnabled(false); 0329 m_ui->btnRemove->setEnabled(false); 0330 } 0331 } 0332 0333 void IPv4Widget::slotAddIPAddress() 0334 { 0335 QList<QStandardItem *> item{new QStandardItem, new QStandardItem, new QStandardItem}; 0336 d->model.appendRow(item); 0337 0338 const int rowCount = d->model.rowCount(); 0339 if (rowCount > 0) { 0340 m_ui->tableViewAddresses->selectRow(rowCount - 1); 0341 0342 QItemSelectionModel *selectionModel = m_ui->tableViewAddresses->selectionModel(); 0343 QModelIndexList list = selectionModel->selectedIndexes(); 0344 if (!list.isEmpty()) { 0345 // QTableView is configured to select only rows. 0346 // So, list[0] - IP address. 0347 m_ui->tableViewAddresses->edit(list[0]); 0348 } 0349 } 0350 } 0351 0352 void IPv4Widget::slotRemoveIPAddress() 0353 { 0354 QItemSelectionModel *selectionModel = m_ui->tableViewAddresses->selectionModel(); 0355 if (selectionModel->hasSelection()) { 0356 QModelIndexList indexes = selectionModel->selectedIndexes(); 0357 d->model.takeRow(indexes[0].row()); 0358 } 0359 m_ui->btnRemove->setEnabled(m_ui->tableViewAddresses->selectionModel()->hasSelection()); 0360 } 0361 0362 void IPv4Widget::selectionChanged(const QItemSelection &selected) 0363 { 0364 m_ui->btnRemove->setEnabled(!selected.isEmpty()); 0365 } 0366 0367 void IPv4Widget::tableViewItemChanged(QStandardItem *item) 0368 { 0369 if (item->text().isEmpty()) { 0370 return; 0371 } 0372 0373 const int column = item->column(); 0374 if (column == 0) { // ip 0375 int row = item->row(); 0376 0377 QStandardItem *netmaskItem = d->model.item(row, column + 1); // netmask 0378 if (netmaskItem && netmaskItem->text().isEmpty()) { 0379 QHostAddress addr(item->text()); 0380 const quint32 netmask = suggestNetmask(addr.toIPv4Address()); 0381 if (netmask) { 0382 QHostAddress v(netmask); 0383 netmaskItem->setText(v.toString()); 0384 } 0385 } 0386 } 0387 } 0388 0389 void IPv4Widget::slotRoutesDialog() 0390 { 0391 QPointer<IpV4RoutesWidget> dlg = new IpV4RoutesWidget(this); 0392 dlg->setAttribute(Qt::WA_DeleteOnClose); 0393 0394 dlg->setRoutes(m_tmpIpv4Setting.routes()); 0395 dlg->setNeverDefault(m_tmpIpv4Setting.neverDefault()); 0396 if (m_ui->method->currentIndex() == 2) { // manual 0397 dlg->setIgnoreAutoRoutesCheckboxEnabled(false); 0398 } else { 0399 dlg->setIgnoreAutoRoutes(m_tmpIpv4Setting.ignoreAutoRoutes()); 0400 } 0401 0402 connect(dlg.data(), &QDialog::accepted, [dlg, this]() { 0403 m_tmpIpv4Setting.setRoutes(dlg->routes()); 0404 m_tmpIpv4Setting.setNeverDefault(dlg->neverDefault()); 0405 m_tmpIpv4Setting.setIgnoreAutoRoutes(dlg->ignoreautoroutes()); 0406 }); 0407 dlg->setModal(true); 0408 dlg->show(); 0409 } 0410 0411 void IPv4Widget::slotAdvancedDialog() 0412 { 0413 auto dlg = new QDialog(this); 0414 dlg->setAttribute(Qt::WA_DeleteOnClose); 0415 0416 auto layout = new QFormLayout(dlg); 0417 dlg->setLayout(layout); 0418 0419 auto label = 0420 new QLabel(i18n("<qt>You can find more information about these values here:<br/><a " 0421 "href='https://developer.gnome.org/NetworkManager/stable/ch01.html'>https://developer.gnome.org/NetworkManager/stable/ch01.html" 0422 "nm-settings-nmcli.html</a></qt>")); 0423 connect(label, &QLabel::linkActivated, this, [](const QString &link) { 0424 QDesktopServices::openUrl(QUrl(link)); 0425 }); 0426 layout->addRow(label); 0427 0428 auto sendHostname = new QCheckBox(dlg); 0429 sendHostname->setChecked(m_tmpIpv4Setting.dhcpSendHostname()); 0430 layout->addRow(i18n("Send hostname:"), sendHostname); 0431 0432 auto dhcpHostname = new QLineEdit(dlg); 0433 dhcpHostname->setText(m_tmpIpv4Setting.dhcpHostname()); 0434 dhcpHostname->setPlaceholderText(QHostInfo::localHostName()); 0435 layout->addRow(i18n("DHCP hostname:"), dhcpHostname); 0436 0437 connect(sendHostname, &QCheckBox::toggled, dhcpHostname, &QLineEdit::setEnabled); 0438 0439 auto dadTimeout = new QSpinBox(dlg); 0440 dadTimeout->setSpecialValueText(i18n("Default")); 0441 dadTimeout->setSuffix(i18nc("Milliseconds", " ms")); 0442 dadTimeout->setMinimum(-1); 0443 dadTimeout->setValue(m_tmpIpv4Setting.dadTimeout()); 0444 layout->addRow(i18n("DAD timeout:"), dadTimeout); 0445 0446 auto box = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, dlg); 0447 connect(box, &QDialogButtonBox::accepted, dlg, &QDialog::accept); 0448 connect(box, &QDialogButtonBox::rejected, dlg, &QDialog::reject); 0449 layout->addWidget(box); 0450 0451 connect(dlg, &QDialog::accepted, this, [this, sendHostname, dhcpHostname, dadTimeout]() { 0452 m_tmpIpv4Setting.setDhcpSendHostname(sendHostname->isChecked()); 0453 m_tmpIpv4Setting.setDhcpHostname(dhcpHostname->text()); 0454 m_tmpIpv4Setting.setDadTimeout(dadTimeout->value()); 0455 }); 0456 0457 dlg->setModal(true); 0458 dlg->show(); 0459 } 0460 0461 void IPv4Widget::slotDnsServers() 0462 { 0463 QPointer<QDialog> dialog = new QDialog(this); 0464 dialog->setAttribute(Qt::WA_DeleteOnClose); 0465 dialog->setWindowTitle(i18n("Edit DNS servers")); 0466 dialog->setLayout(new QVBoxLayout); 0467 auto buttons = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, dialog); 0468 connect(buttons, &QDialogButtonBox::accepted, dialog.data(), &QDialog::accept); 0469 connect(buttons, &QDialogButtonBox::rejected, dialog.data(), &QDialog::reject); 0470 auto listWidget = new KEditListWidget(dialog); 0471 listWidget->setItems(m_ui->dns->text().split(QLatin1Char(',')).replaceInStrings(QStringLiteral(" "), QLatin1String(""))); 0472 listWidget->lineEdit()->setFocus(Qt::OtherFocusReason); 0473 dialog->layout()->addWidget(listWidget); 0474 dialog->layout()->addWidget(buttons); 0475 connect(dialog.data(), &QDialog::accepted, [listWidget, this]() { 0476 QString text = listWidget->items().join(QStringLiteral(",")); 0477 if (text.endsWith(',')) { 0478 text.chop(1); 0479 } 0480 m_ui->dns->setText(text); 0481 }); 0482 dialog->setModal(true); 0483 dialog->show(); 0484 } 0485 0486 void IPv4Widget::slotDnsDomains() 0487 { 0488 QPointer<QDialog> dialog = new QDialog(this); 0489 dialog->setAttribute(Qt::WA_DeleteOnClose); 0490 dialog->setWindowTitle(i18n("Edit DNS search domains")); 0491 dialog->setLayout(new QVBoxLayout); 0492 auto buttons = new QDialogButtonBox(QDialogButtonBox::Ok | QDialogButtonBox::Cancel, dialog); 0493 connect(buttons, &QDialogButtonBox::accepted, dialog.data(), &QDialog::accept); 0494 connect(buttons, &QDialogButtonBox::rejected, dialog.data(), &QDialog::reject); 0495 auto listWidget = new KEditListWidget(dialog); 0496 listWidget->setItems(m_ui->dnsSearch->text().split(QLatin1Char(',')).replaceInStrings(QStringLiteral(" "), QLatin1String(""))); 0497 listWidget->lineEdit()->setFocus(Qt::OtherFocusReason); 0498 dialog->layout()->addWidget(listWidget); 0499 dialog->layout()->addWidget(buttons); 0500 connect(dialog.data(), &QDialog::accepted, [listWidget, this]() { 0501 QString text = listWidget->items().join(QStringLiteral(",")); 0502 if (text.endsWith(',')) { 0503 text.chop(1); 0504 } 0505 m_ui->dnsSearch->setText(text); 0506 }); 0507 dialog->setModal(true); 0508 dialog->show(); 0509 } 0510 0511 bool IPv4Widget::isValid() const 0512 { 0513 if (m_ui->method->currentIndex() == Manual) { 0514 if (!d->model.rowCount()) { 0515 return false; 0516 } 0517 0518 for (int i = 0, rowCount = d->model.rowCount(); i < rowCount; i++) { 0519 QHostAddress ip = QHostAddress(d->model.item(i, 0)->text()); 0520 QHostAddress netmask = QHostAddress(d->model.item(i, 1)->text()); 0521 QHostAddress gateway = QHostAddress(d->model.item(i, 2)->text()); 0522 0523 if (ip.isNull() || netmask.isNull() || (gateway.isNull() && !d->model.item(i, 2)->text().isEmpty())) { 0524 return false; 0525 } 0526 } 0527 } 0528 0529 if (!m_ui->dns->text().isEmpty() 0530 && (m_ui->method->currentIndex() == Automatic || m_ui->method->currentIndex() == Manual || m_ui->method->currentIndex() == AutomaticOnlyIP)) { 0531 const QStringList tmp = m_ui->dns->text().split(QLatin1Char(',')); 0532 for (const QString &str : tmp) { 0533 QHostAddress addr(str); 0534 if (addr.isNull()) { 0535 return false; 0536 } 0537 } 0538 } 0539 0540 return true; 0541 } 0542 0543 #include "moc_ipv4widget.cpp"