diff options
| author | 2016-11-11 23:19:46 -0500 | |
|---|---|---|
| committer | 2016-11-11 23:19:46 -0500 | |
| commit | 60501807b361ced9f594ba9c58331857e2011834 (patch) | |
| tree | 412fb3e1619cb8e8937677d8f967c8017d2a4702 /src | |
| parent | Input History: Added skipping of input lines if consecutive lines are the same (diff) | |
| download | KVIrc-60501807b361ced9f594ba9c58331857e2011834.tar.gz KVIrc-60501807b361ced9f594ba9c58331857e2011834.tar.bz2 KVIrc-60501807b361ced9f594ba9c58331857e2011834.zip | |
KviIpEditor: Change to a QLineEdit and update code.
* Changes from a multi-QLineEdit box for each part of the IP address
to a single QLineEdit which allows pasting of IP addresses rather
than having to hand type them in.
* Uses Qt5's QHostAddress to proccess the input and validate the IPs
* Fixes the OptionsWidget_servers to enable/disable the KviIpEditor
depending on if the Cache IP checkbox is checked or not.
Diffstat (limited to 'src')
| -rw-r--r-- | src/kvirc/ui/KviIpEditor.cpp | 424 | ||||
| -rw-r--r-- | src/kvirc/ui/KviIpEditor.h | 29 | ||||
| -rw-r--r-- | src/modules/options/OptionsWidget_proxy.cpp | 13 | ||||
| -rw-r--r-- | src/modules/options/OptionsWidget_servers.cpp | 16 | ||||
| -rw-r--r-- | src/modules/options/OptionsWidget_servers.h | 1 |
5 files changed, 57 insertions, 426 deletions
diff --git a/src/kvirc/ui/KviIpEditor.cpp b/src/kvirc/ui/KviIpEditor.cpp index ead3381dc..b85f5464c 100644 --- a/src/kvirc/ui/KviIpEditor.cpp +++ b/src/kvirc/ui/KviIpEditor.cpp @@ -24,428 +24,74 @@ #include "KviIpEditor.h" -#include <QApplication> -#include <QByteArray> -#include <QEvent> -#include <QFrame> -#include <QKeyEvent> -#include <QLabel> -#include <QLineEdit> - -#include <ctype.h> +#include <QHostAddress> +#include <QRegExpValidator> +#include <QString> // FIXME: #warning "THIS COULD GO INTO libkvioptions ?" KviIpEditor::KviIpEditor(QWidget * parent, AddressType addrType, const QString & ipAddr, const char * name) - : QFrame(parent) + : QLineEdit(parent) { setObjectName(name); - for(int i = 0; i < 7; i++) - { - m_pEdit[i] = nullptr; - m_pLabel[i] = nullptr; - } - m_pEdit[7] = nullptr; - setFrameStyle(QFrame::Sunken | QFrame::StyledPanel); - setBackgroundRole(QPalette::Base); setAddressType(addrType); setAddress(ipAddr); } -KviIpEditor::~KviIpEditor() - = default; - -void KviIpEditor::setEnabled(bool bEnabled) +void KviIpEditor::setAddressType(AddressType addrType) { - QFrame::setEnabled(bEnabled); - for(int i = 0; i < 8; i++) + if(addrType == IPv4) { - if(m_pEdit[i]) - m_pEdit[i]->setEnabled(bEnabled); - if(i < 7) - if(m_pLabel[i]) - { - // Is this the right way ? - m_pLabel[i]->setBackgroundRole(isEnabled() ? QPalette::Base : QPalette::Background); - m_pLabel[i]->setEnabled(bEnabled); - } + m_addrType = addrType; + QString tmp = text(); + setText(QHostAddress{QHostAddress::AnyIPv4}.toString()); + if (!tmp.isEmpty()) + setAddress(tmp); } - setBackgroundRole(isEnabled() ? QPalette::Base : QPalette::Background); -} - -void KviIpEditor::setAddressType(AddressType addrType) -{ - if((addrType != IPv4) && (addrType != IPv6)) - m_addrType = IPv4; - else + else if (addrType == IPv6) + { m_addrType = addrType; - recreateChildren(); -} - -KviIpEditor::AddressType KviIpEditor::addressType() const -{ - return m_addrType; -} - -bool KviIpEditor::hasEmptyFields() const -{ - for(auto i : m_pEdit) - if(i && i->text().isEmpty()) - return true; - return false; + QString tmp = text(); + setText(QHostAddress{QHostAddress::AnyIPv6}.toString()); + if (!tmp.isEmpty()) + setAddress(tmp); + } } -void KviIpEditor::clear() +bool KviIpEditor::isValid() const { - if(!m_pEdit[0]) - return; - int maxW = (m_addrType == IPv4) ? 4 : 8; - for(int i = 0; i < maxW; i++) - m_pEdit[i]->setText(""); + return !QHostAddress{text()}.isNull(); } bool KviIpEditor::setAddress(const QString & ipAddr) { - // FIXME We could check if the address - // is valid before effectively setting the fields - clear(); - - QByteArray ip = ipAddr.toLatin1(); // ip addresses are digits & latin letters abcdef (IPv6) - - ip = ip.trimmed(); - const char * c = ip.data(); - - if(!c) - return false; // huh ?....(should never happen at this point) + QHostAddress addr{ipAddr}; + if(addr.isNull()) + return false; if(m_addrType == IPv4) { - for(int i = 0; i < 4; i++) - { - const char * anchor = c; - while(isdigit(*c)) - c++; - if(c == anchor) - return false; // Invalid empty field - QByteArray str(anchor, c - anchor); - bool bOk; - int num = str.toInt(&bOk); - if(!bOk) - return false; // should never happen, but just to be sure - if((num < 0) || (num > 255)) - return false; // Invalid field - m_pEdit[i]->setText(str.data()); - if(i < 3) - { - if(*c == '.') - c++; - else - return false; // missing separator - } - } + bool bOk = true; + (void)addr.toIPv4Address(&bOk); + if(!bOk) + return false; + setText(QHostAddress{addr.toIPv4Address()}.toString()); } else { - for(int i = 0; i < 8; i++) - { - const char * anchor = c; - while(isdigit(*c) || ((tolower(*c) >= 'a') && (tolower(*c) <= 'f')) || ((tolower(*c) >= 'A') && (tolower(*c) <= 'F'))) - c++; - QByteArray str(anchor, c - anchor); - if(str.length() > 4) - return false; // Too long - m_pEdit[i]->setText(str.data()); - if(i < 7) - { - if(*c == ':') - c++; - else - return false; // missing separator - } - } + setText(QHostAddress{addr.toIPv6Address()}.toString()); } - if(*c) - return false; // trailing garbage (we could avoid this) + return true; } QString KviIpEditor::address() const { - QString ret; - + QHostAddress addr{text()}; + if(addr.isNull()) + return ""; if(m_addrType == IPv6) - { - for(int i = 0; i < 8; i++) - { - ret.append(m_pEdit[i]->text()); - if(i < 7) - ret.append(":"); - } - } - else - { - for(int i = 0; i < 4; i++) - { - QString tmp = m_pEdit[i]->text(); - bool bOk; - int num = tmp.toInt(&bOk); - if(!bOk) - num = 0; - tmp.setNum(num); - ret.append(tmp); - if(i < 3) - ret.append("."); - } - } - return ret; -} - -void KviIpEditor::recreateChildren() -{ - // A bit slow, but compact - bool bIPv4 = (m_addrType == IPv4); - int max = bIPv4 ? 4 : 8; - QFontMetrics fm(font()); - //int minWidth = fm.width(bIPv4 ? "000" : "AAAA") + 4; - for(int i = 0; i < max; i++) - { - if(!m_pEdit[i]) - { - m_pEdit[i] = new QLineEdit(this); - m_pEdit[i]->installEventFilter(this); - m_pEdit[i]->setFrame(false); - m_pEdit[i]->setAlignment(Qt::AlignCenter); - } - //m_pEdit[i]->setMinimumWidth(minWidth); - m_pEdit[i]->setMaxLength(bIPv4 ? 3 : 4); - m_pEdit[i]->show(); - if(i < (max - 1)) - { - if(!m_pLabel[i]) - m_pLabel[i] = new QLabel(this); - m_pLabel[i]->setText(bIPv4 ? "." : ":"); - m_pLabel[i]->show(); - // Is this the right way ? setBackgroundMode seems to not work well - m_pLabel[i]->setBackgroundRole(isEnabled() ? QPalette::Base : QPalette::Background); - } - } - // Kill the unused widgets, if any - if(bIPv4) - { - for(int i = 4; i < 8; i++) - { - if(m_pEdit[i]) - { - delete m_pEdit[i]; - m_pEdit[i] = nullptr; - } - if(m_pLabel[i - 1]) - { - delete m_pLabel[i - 1]; - m_pLabel[i - 1] = nullptr; - } - } - } - //setMinimumWidth(4 + (max * minWidth) + ((max - 1) * m_pLabel[0]->sizeHint().width())); - setMinimumHeight(m_pLabel[0]->sizeHint().height() + 4); - resizeEvent(nullptr); -} - -bool KviIpEditor::eventFilter(QObject * o, QEvent * e) -{ - if(o->inherits("QLineEdit")) - { - if(e->type() == QEvent::KeyPress) - { - QString s; - // find the editor - int edIdx = -1; - for(int i = 0; i < 8; i++) - { - if(m_pEdit[i] == o) - { - edIdx = i; - break; - } - } - if(edIdx == -1) - return QFrame::eventFilter(o, e); // user added QLineEdit child ? - int edMax = (m_addrType == IPv4) ? 3 : 7; - int cursorPos = ((QLineEdit *)o)->cursorPosition(); - switch(((QKeyEvent *)e)->key()) - { - case Qt::Key_Right: - s = ((QLineEdit *)o)->text(); - if(cursorPos == s.length()) - { - if(edIdx < edMax) - { - m_pEdit[++edIdx]->setCursorPosition(0); - m_pEdit[edIdx]->setFocus(); - return true; - } - } - break; - case Qt::Key_Left: - case Qt::Key_Backspace: - if(cursorPos == 0) - { - if(edIdx > 0) - { - s = m_pEdit[--edIdx]->text(); - m_pEdit[edIdx]->setCursorPosition(s.length()); - m_pEdit[edIdx]->setFocus(); - return true; - } - } - return QFrame::eventFilter(o, e); - break; - case Qt::Key_End: - case Qt::Key_Home: - case Qt::Key_Delete: - case Qt::Key_Tab: - return QFrame::eventFilter(o, e); - break; - default: - if(((QKeyEvent *)e)->text().size() < 1) - return false; - // a normal key (this part substitutes a QValidator) - const char c = tolower(((QKeyEvent *)e)->text().toLatin1().at(0)); - if(m_addrType == IPv4) - { - if((c >= '0') && (c <= '9')) - { - if(m_pEdit[edIdx]->hasSelectedText()) - m_pEdit[edIdx]->cut(); - cursorPos = m_pEdit[edIdx]->cursorPosition(); - s = m_pEdit[edIdx]->text(); - s.insert(cursorPos, c); - bool bOk = false; - int num = s.toInt(&bOk); - if(!bOk) - return true; //should never happen, but just to be sure - if((num < 0) || (num > 255)) - return true; //invalid field - m_pEdit[edIdx]->setText(s); - if(num > 25) - { - // The focus goes to the next editor - if(edIdx < edMax) - { - m_pEdit[++edIdx]->setFocus(); - m_pEdit[edIdx]->selectAll(); - //m_pEdit[edIdx]->setCursorPosition(0); - return true; - } - } - m_pEdit[edIdx]->cursorForward(false); - } - else - { - if((c == '.') && (edIdx < edMax)) - { - if(!m_pEdit[edIdx]->hasSelectedText()) - { - m_pEdit[++edIdx]->setFocus(); - m_pEdit[edIdx]->selectAll(); - } - } - } - } - else - { - if(((c >= '0') && (c <= '9')) || ((c >= 'a') && (c <= 'f'))) - { - if(m_pEdit[edIdx]->hasSelectedText()) - m_pEdit[edIdx]->cut(); - cursorPos = m_pEdit[edIdx]->cursorPosition(); - s = m_pEdit[edIdx]->text(); - - if(s.length() == 4) - { - if((cursorPos == 4) && (edIdx < edMax)) - { - // the char goes in the next editor - s = c; - m_pEdit[++edIdx]->setText(s); - m_pEdit[edIdx]->end(false); - m_pEdit[edIdx]->setFocus(); - } // else either no space or invalid place in the string - } - else - { - // ok .. can insert - s.insert(cursorPos, c); - m_pEdit[edIdx]->setText(s); - if((s.length() == 4) && (edIdx < edMax)) - { - // the focus now goes to the next editor - m_pEdit[++edIdx]->setFocus(); - m_pEdit[edIdx]->selectAll(); - //m_pEdit[edIdx]->setCursorPosition(0); - } - else - { - m_pEdit[edIdx]->cursorForward(false); - } - } - } - else - { - if((c == ':') && (edIdx < edMax)) - { - if(!m_pEdit[edIdx]->hasSelectedText()) - { - m_pEdit[++edIdx]->setFocus(); - m_pEdit[edIdx]->selectAll(); - } - } - } - } - return true; - break; - } - } - } - return QFrame::eventFilter(o, e); -} - -void KviIpEditor::resizeEvent(QResizeEvent * e) -{ - if(m_pEdit[0]) - { - int maxW = (m_addrType == IPv4) ? 4 : 8; - int labHint = m_pLabel[0]->sizeHint().width(); - int hghHint = height() - 4; - int ediWdth = ((width() - 4) - ((maxW - 1) * labHint)) / maxW; - int curX = 2; - for(int i = 0; i < maxW; i++) - { - if(i > 0) - { - m_pLabel[i - 1]->setGeometry(curX, 2, labHint, hghHint); - curX += labHint; - } - m_pEdit[i]->setGeometry(curX, 2, ediWdth, hghHint); - curX += ediWdth; - } - } - if(e) - QFrame::resizeEvent(e); -} - -QSize KviIpEditor::sizeHint() const -{ - if(m_pEdit[0]) - { - int labHint = m_pLabel[0]->sizeHint().width(); - int hghHint = m_pEdit[0]->sizeHint().height(); - int ediHint = m_pEdit[0]->sizeHint().width(); - if(m_addrType == IPv4) - return QSize((labHint * 3) + (ediHint * 4) + 4, hghHint + 4); - else - return QSize((labHint * 7) + (ediHint * 8) + 4, hghHint + 4); - } + return QHostAddress{addr.toIPv6Address()}.toString(); else - return QFrame::sizeHint(); + return QHostAddress{addr.toIPv4Address()}.toString(); } diff --git a/src/kvirc/ui/KviIpEditor.h b/src/kvirc/ui/KviIpEditor.h index c688eafda..56e0e8a07 100644 --- a/src/kvirc/ui/KviIpEditor.h +++ b/src/kvirc/ui/KviIpEditor.h @@ -26,14 +26,9 @@ #include "kvi_settings.h" -#include <QFrame> -#include <QString> -#include <QWidget> +#include <QLineEdit> -class QLabel; -class QLineEdit; - -class KVIRC_API KviIpEditor : public QFrame +class KVIRC_API KviIpEditor : public QLineEdit { Q_OBJECT public: @@ -42,30 +37,18 @@ public: IPv4, IPv6 }; - KviIpEditor(QWidget * parent, AddressType = IPv4, const QString & ipAddr = QString(), const char * name = 0); - ~KviIpEditor(); + KviIpEditor(QWidget * parent, AddressType = IPv4, const QString & ipAddr = QString(), const char * name = nullptr); + ~KviIpEditor() = default; private: - QLabel * m_pLabel[7]; - QLineEdit * m_pEdit[8]; AddressType m_addrType; public: bool setAddress(const QString & ipAddr); QString address() const; void setAddressType(AddressType addrType); - AddressType addressType() const; - bool hasEmptyFields() const; - void clear(); - virtual void setEnabled(bool bEnabled); - -protected: - virtual bool eventFilter(QObject * o, QEvent * e); - virtual void resizeEvent(QResizeEvent * e); - virtual QSize sizeHint() const; - -private: - void recreateChildren(); + inline AddressType addressType() const { return m_addrType; } + bool isValid() const; }; #endif //_KVI_IPEDITOR_H_ diff --git a/src/modules/options/OptionsWidget_proxy.cpp b/src/modules/options/OptionsWidget_proxy.cpp index ad3d29c11..f05012f33 100644 --- a/src/modules/options/OptionsWidget_proxy.cpp +++ b/src/modules/options/OptionsWidget_proxy.cpp @@ -268,25 +268,20 @@ void OptionsWidget_proxy::saveLastItem() #endif m_pLastEditedItem->m_pProxyData->m_szIp = ""; - QString tmpAddr = m_pIpEditor->address(); - - if(!m_pIpEditor->hasEmptyFields()) + if(m_pIpEditor->isValid()) { + QString tmpAddr = m_pIpEditor->address(); #ifdef COMPILE_IPV6_SUPPORT if(m_pIPv6Check->isChecked()) { - if((!KviQString::equalCI(tmpAddr, "0:0:0:0:0:0:0:0")) && KviNetUtils::isValidStringIPv6(tmpAddr)) - { + if(tmpAddr != "::" && KviNetUtils::isValidStringIPv6(tmpAddr)) m_pLastEditedItem->m_pProxyData->m_szIp = tmpAddr; - } } else { #endif - if((!KviQString::equalCI(tmpAddr, "0.0.0.0")) && KviNetUtils::isValidStringIp(tmpAddr)) - { + if(tmpAddr != "0.0.0.0" && KviNetUtils::isValidStringIp(tmpAddr)) m_pLastEditedItem->m_pProxyData->m_szIp = tmpAddr; - } #ifdef COMPILE_IPV6_SUPPORT } #endif diff --git a/src/modules/options/OptionsWidget_servers.cpp b/src/modules/options/OptionsWidget_servers.cpp index 6e3af5daf..f8eeac761 100644 --- a/src/modules/options/OptionsWidget_servers.cpp +++ b/src/modules/options/OptionsWidget_servers.cpp @@ -703,6 +703,8 @@ IrcServerDetailsWidget::IrcServerDetailsWidget(QWidget * par, KviIrcServer * s) "unreachable or you want to avoid the round-robin lookups.", "options")); m_pCacheIpCheck->setChecked(s->cacheIp()); + m_pIpEditor->setEnabled(m_pCacheIpCheck->isChecked()); + connect(m_pCacheIpCheck, SIGNAL(toggled(bool)), this, SLOT(useCacheIpCheckToggled(bool))); m_pUseAutoConnect = new QCheckBox(__tr2qs_ctx("Connect to this server at startup", "options"), tab); m_pUseAutoConnect->setChecked(s->autoConnect()); @@ -1014,6 +1016,11 @@ IrcServerDetailsWidget::~IrcServerDetailsWidget() KviScriptEditor::destroyInstance(m_pOnLoginEditor); } +void IrcServerDetailsWidget::useCacheIpCheckToggled(bool) +{ + m_pIpEditor->setEnabled(m_pCacheIpCheck->isChecked()); +} + void IrcServerDetailsWidget::useIPV6CheckToggled(bool) { #ifdef COMPILE_IPV6_SUPPORT @@ -1148,14 +1155,13 @@ void IrcServerDetailsWidget::fillData(KviIrcServer * s) if(m_pIpEditor) { - QString tmpAddr = m_pIpEditor->address(); - - if(!m_pIpEditor->hasEmptyFields()) + if(m_pIpEditor->isValid()) { + QString tmpAddr = m_pIpEditor->address(); #ifdef COMPILE_IPV6_SUPPORT if(s->isIPv6()) { - if((!KviQString::equalCI(tmpAddr, "0:0:0:0:0:0:0:0")) && KviNetUtils::isValidStringIp(tmpAddr)) + if(tmpAddr != "::" && KviNetUtils::isValidStringIp(tmpAddr)) { s->setIp(tmpAddr); } @@ -1168,7 +1174,7 @@ void IrcServerDetailsWidget::fillData(KviIrcServer * s) else { #endif - if((!KviQString::equalCI(tmpAddr, "0.0.0.0")) && KviNetUtils::isValidStringIp(tmpAddr)) + if(tmpAddr != "0.0.0.0" && KviNetUtils::isValidStringIp(tmpAddr)) { s->setIp(tmpAddr); } diff --git a/src/modules/options/OptionsWidget_servers.h b/src/modules/options/OptionsWidget_servers.h index 9744b271a..b6a2fdb68 100644 --- a/src/modules/options/OptionsWidget_servers.h +++ b/src/modules/options/OptionsWidget_servers.h @@ -159,6 +159,7 @@ protected: protected slots: void useDefaultInitUModeToggled(bool); void portEditorTextChanged(const QString &); + void useCacheIpCheckToggled(bool); void useIPV6CheckToggled(bool); void useSSLCheckToggled(bool); |
