aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorGravatar IceN9ne2016-11-11 23:19:46 -0500
committerGravatar IceN9ne2016-11-11 23:19:46 -0500
commit60501807b361ced9f594ba9c58331857e2011834 (patch)
tree412fb3e1619cb8e8937677d8f967c8017d2a4702 /src
parentInput History: Added skipping of input lines if consecutive lines are the same (diff)
downloadKVIrc-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.cpp424
-rw-r--r--src/kvirc/ui/KviIpEditor.h29
-rw-r--r--src/modules/options/OptionsWidget_proxy.cpp13
-rw-r--r--src/modules/options/OptionsWidget_servers.cpp16
-rw-r--r--src/modules/options/OptionsWidget_servers.h1
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);