summaryrefslogtreecommitdiffstats
path: root/src/kvirc/ui/kvi_ipeditor.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/kvirc/ui/kvi_ipeditor.cpp')
-rw-r--r--src/kvirc/ui/kvi_ipeditor.cpp453
1 files changed, 453 insertions, 0 deletions
diff --git a/src/kvirc/ui/kvi_ipeditor.cpp b/src/kvirc/ui/kvi_ipeditor.cpp
new file mode 100644
index 0000000..13291c2
--- /dev/null
+++ b/src/kvirc/ui/kvi_ipeditor.cpp
@@ -0,0 +1,453 @@
+//
+// File : kvi_ipeditor.cpp
+// Creation date : Wed Jun 12 2000 14:16:49 by Szymon Stefanek
+//
+// This file is part of the KVirc irc client distribution
+// Copyright (C) 2000 Szymon Stefanek (pragma at kvirc dot net)
+//
+// This program is FREE software. You can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your opinion) any later version.
+//
+// This program is distributed in the HOPE that it will be USEFUL,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+// See the GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, write to the Free Software Foundation,
+// Inc. ,51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+//
+#define __KVIRC__
+#include "kvi_ipeditor.h"
+#include "kvi_qcstring.h"
+
+#include <qapplication.h>
+#include <qlineedit.h>
+#include <qlabel.h>
+#include <qframe.h>
+#include <ctype.h>
+#include <qevent.h>
+
+
+// FIXME: #warning "THIS COULD GO INTO libkvioptions ?"
+
+KviIpEditor::KviIpEditor(QWidget * parent,AddressType addrType,const QString &ipAddr,const char *name)
+:QFrame(parent,name)
+{
+
+ for(int i=0;i<7;i++)
+ {
+ m_pEdit[i] = 0;
+ m_pLabel[i] = 0;
+ }
+ m_pEdit[7] = 0;
+ setFrameStyle(QFrame::Sunken|QFrame::StyledPanel);
+
+#ifdef COMPILE_USE_QT4
+ setBackgroundRole(QPalette::Base);
+#else
+ setBackgroundMode(QWidget::PaletteBase);
+#endif
+
+ setAddressType(addrType);
+
+ setAddress(ipAddr);
+}
+
+KviIpEditor::~KviIpEditor()
+{
+
+}
+
+void KviIpEditor::setEnabled(bool bEnabled)
+{
+ QFrame::setEnabled(bEnabled);
+ for(int i=0;i<8;i++)
+ {
+ if(m_pEdit[i])m_pEdit[i]->setEnabled(bEnabled);
+ if(i<7)if(m_pLabel[i])
+ {
+ // Is this the right way ?
+#ifdef COMPILE_USE_QT4
+ m_pLabel[i]->setBackgroundRole(isEnabled() ? QPalette::Base : QPalette::Background);
+#else
+ m_pLabel[i]->setBackgroundMode(isEnabled() ? QWidget::PaletteBase : QWidget::PaletteBackground);
+#endif
+ m_pLabel[i]->setEnabled(bEnabled);
+ }
+ }
+#ifdef COMPILE_USE_QT4
+ setBackgroundRole(isEnabled() ? QPalette::Base : QPalette::Background);
+#else
+ setBackgroundMode(isEnabled() ? QWidget::PaletteBase : QWidget::PaletteBackground);
+#endif
+}
+
+void KviIpEditor::setAddressType(AddressType addrType)
+{
+ if((addrType != IpV4) && (addrType != IpV6))m_addrType = IpV4;
+ else m_addrType = addrType;
+ recreateChildren();
+}
+
+KviIpEditor::AddressType KviIpEditor::addressType() const
+{
+ return m_addrType;
+}
+
+bool KviIpEditor::hasEmptyFields() const
+{
+ bool bHasEF = false;
+ for(int i=0;i<8;i++)
+ {
+ if(m_pEdit[i])
+ {
+ if(m_pEdit[i]->text().isEmpty())bHasEF = true;
+ }
+ }
+ return bHasEF;
+}
+
+void KviIpEditor::clear()
+{
+ if(!m_pEdit[0])return;
+ int maxW = (m_addrType == IpV4) ? 4 : 8;
+ for(int i=0;i< maxW ;i++)
+ {
+ m_pEdit[i]->setText("");
+ }
+}
+
+bool KviIpEditor::setAddress(const QString &ipAddr)
+{
+ // FIXME We could check if the addres
+ // is valid before effectively setting the fields
+ clear();
+
+ KviQCString ip = ipAddr.ascii(); // ip addresses are digits & latin letters abcdef (IpV6)
+
+ ip = ip.stripWhiteSpace();
+ const char * c = ip.data();
+
+ if(!c)return false; // huh ?....(should never happen at this point)
+
+ 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
+ KviQCString str(anchor,(c - anchor) + 1);
+ 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
+ }
+ }
+ } 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++;
+ KviQCString str(anchor,(c - anchor) + 1);
+ 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
+ }
+ }
+ }
+ if(*c)return false; // trailing garbage (we could avoid this)
+ return true;
+}
+
+QString KviIpEditor::address() const
+{
+ QString ret;
+
+ 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
+#ifdef COMPILE_USE_QT4
+ m_pLabel[i]->setBackgroundRole(isEnabled() ? QPalette::Base : QPalette::Background);
+#else
+ m_pLabel[i]->setBackgroundMode(isEnabled() ? QWidget::PaletteBase : QWidget::PaletteBackground);
+#endif
+ }
+ }
+ // 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] = 0;
+ }
+ if(m_pLabel[i - 1])
+ {
+ delete m_pLabel[i - 1];
+ m_pLabel[i - 1] = 0;
+ }
+ }
+ }
+ //setMinimumWidth(4 + (max * minWidth) + ((max - 1) * m_pLabel[0]->sizeHint().width()));
+ setMinimumHeight(m_pLabel[0]->sizeHint().height() + 4);
+ resizeEvent(0);
+}
+
+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(((unsigned int)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:
+ // a normal key (this part substitutes a QValidator)
+ const char c = tolower(((QKeyEvent *)e)->ascii());
+ if(m_addrType == IpV4)
+ {
+ if((c >= '0') && (c <= '9'))
+ {
+#if QT_VERSION >= 300
+ if(m_pEdit[edIdx]->hasSelectedText())m_pEdit[edIdx]->cut();
+#else
+ if(m_pEdit[edIdx]->hasMarkedText())m_pEdit[edIdx]->cut();
+#endif
+ 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;
+ }
+ }
+#if QT_VERSION >= 300
+ m_pEdit[edIdx]->cursorForward(false);
+#else
+ m_pEdit[edIdx]->cursorRight(false);
+#endif
+ } else {
+ if((c == '.') && (edIdx < edMax))
+ {
+#if QT_VERSION >= 300
+ if(!m_pEdit[edIdx]->hasSelectedText())
+#else
+ if(!m_pEdit[edIdx]->hasMarkedText())
+#endif
+ {
+ m_pEdit[++edIdx]->setFocus();
+ m_pEdit[edIdx]->selectAll();
+ }
+ }
+ }
+ } else {
+ if( ((c >= '0') && (c <= '9')) || ((c >= 'a') && (c <= 'f')) )
+ {
+#if QT_VERSION >= 300
+ if(m_pEdit[edIdx]->hasSelectedText())m_pEdit[edIdx]->cut();
+#else
+ if(m_pEdit[edIdx]->hasMarkedText())m_pEdit[edIdx]->cut();
+#endif
+ 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 {
+#if QT_VERSION >= 300
+ m_pEdit[edIdx]->cursorForward(false);
+#else
+ m_pEdit[edIdx]->cursorRight(false);
+#endif
+ }
+ }
+ } else {
+ if((c == ':') && (edIdx < edMax))
+ {
+#if QT_VERSION >= 300
+ if(!m_pEdit[edIdx]->hasSelectedText())
+#else
+ if(!m_pEdit[edIdx]->hasMarkedText())
+#endif
+ {
+ 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()
+{
+ 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);
+ } else return QFrame::sizeHint();
+}
+
+
+#include "kvi_ipeditor.moc"