|
|
|
//
|
|
|
|
// 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 <tqapplication.h>
|
|
|
|
#include <tqlineedit.h>
|
|
|
|
#include <tqlabel.h>
|
|
|
|
#include <tqframe.h>
|
|
|
|
#include <ctype.h>
|
|
|
|
#include <tqevent.h>
|
|
|
|
|
|
|
|
|
|
|
|
// FIXME: #warning "THIS COULD GO INTO libkvioptions ?"
|
|
|
|
|
|
|
|
KviIpEditor::KviIpEditor(TQWidget * parent,AddressType addrType,const TQString &ipAddr,const char *name)
|
|
|
|
:TQFrame(parent,name)
|
|
|
|
{
|
|
|
|
|
|
|
|
for(int i=0;i<7;i++)
|
|
|
|
{
|
|
|
|
m_pEdit[i] = 0;
|
|
|
|
m_pLabel[i] = 0;
|
|
|
|
}
|
|
|
|
m_pEdit[7] = 0;
|
|
|
|
setFrameStyle(TQFrame::Sunken|TQFrame::StyledPanel);
|
|
|
|
|
|
|
|
#ifdef COMPILE_USE_QT4
|
|
|
|
setBackgroundRole(TQPalette::Base);
|
|
|
|
#else
|
|
|
|
setBackgroundMode(TQWidget::PaletteBase);
|
|
|
|
#endif
|
|
|
|
|
|
|
|
setAddressType(addrType);
|
|
|
|
|
|
|
|
setAddress(ipAddr);
|
|
|
|
}
|
|
|
|
|
|
|
|
KviIpEditor::~KviIpEditor()
|
|
|
|
{
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
void KviIpEditor::setEnabled(bool bEnabled)
|
|
|
|
{
|
|
|
|
TQFrame::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() ? TQPalette::Base : TQPalette::Background);
|
|
|
|
#else
|
|
|
|
m_pLabel[i]->setBackgroundMode(isEnabled() ? TQWidget::PaletteBase : TQWidget::PaletteBackground);
|
|
|
|
#endif
|
|
|
|
m_pLabel[i]->setEnabled(bEnabled);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#ifdef COMPILE_USE_QT4
|
|
|
|
setBackgroundRole(isEnabled() ? TQPalette::Base : TQPalette::Background);
|
|
|
|
#else
|
|
|
|
setBackgroundMode(isEnabled() ? TQWidget::PaletteBase : TQWidget::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 TQString &ipAddr)
|
|
|
|
{
|
|
|
|
// FIXME We could check if the addres
|
|
|
|
// is valid before effectively setting the fields
|
|
|
|
clear();
|
|
|
|
|
|
|
|
KviTQCString 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
|
|
|
|
KviTQCString 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++;
|
|
|
|
KviTQCString 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;
|
|
|
|
}
|
|
|
|
|
|
|
|
TQString KviIpEditor::address() const
|
|
|
|
{
|
|
|
|
TQString 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++)
|
|
|
|
{
|
|
|
|
TQString 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;
|
|
|
|
TQFontMetrics 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 TQLineEdit(this);
|
|
|
|
m_pEdit[i]->installEventFilter(this);
|
|
|
|
m_pEdit[i]->setFrame(false);
|
|
|
|
m_pEdit[i]->setAlignment(TQt::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 TQLabel(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() ? TQPalette::Base : TQPalette::Background);
|
|
|
|
#else
|
|
|
|
m_pLabel[i]->setBackgroundMode(isEnabled() ? TQWidget::PaletteBase : TQWidget::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(TQObject * o,TQEvent *e)
|
|
|
|
{
|
|
|
|
if(o->inherits(TQLINEEDIT_OBJECT_NAME_STRING))
|
|
|
|
{
|
|
|
|
if(e->type() == TQEvent::KeyPress)
|
|
|
|
{
|
|
|
|
TQString s;
|
|
|
|
// find the editor
|
|
|
|
int edIdx = -1;
|
|
|
|
for(int i=0;i<8;i++)
|
|
|
|
{
|
|
|
|
if(TQT_BASE_OBJECT(m_pEdit[i]) == TQT_BASE_OBJECT(o))
|
|
|
|
{
|
|
|
|
edIdx = i;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if(edIdx == -1)return TQFrame::eventFilter(o,e); // user added TQLineEdit child ?
|
|
|
|
int edMax = (m_addrType == IpV4) ? 3 : 7;
|
|
|
|
int cursorPos = ((TQLineEdit *)o)->cursorPosition();
|
|
|
|
switch(((TQKeyEvent *)e)->key())
|
|
|
|
{
|
|
|
|
case TQt::Key_Right:
|
|
|
|
s = ((TQLineEdit *)o)->text();
|
|
|
|
if(((unsigned int)cursorPos) == s.length())
|
|
|
|
{
|
|
|
|
if(edIdx < edMax)
|
|
|
|
{
|
|
|
|
m_pEdit[++edIdx]->setCursorPosition(0);
|
|
|
|
m_pEdit[edIdx]->setFocus();
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case TQt::Key_Left:
|
|
|
|
case TQt::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 TQFrame::eventFilter(o,e);
|
|
|
|
break;
|
|
|
|
case TQt::Key_End:
|
|
|
|
case TQt::Key_Home:
|
|
|
|
case TQt::Key_Delete:
|
|
|
|
case TQt::Key_Tab:
|
|
|
|
return TQFrame::eventFilter(o,e);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
// a normal key (this part substitutes a TQValidator)
|
|
|
|
const char c = tolower(((TQKeyEvent *)e)->ascii());
|
|
|
|
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 TQFrame::eventFilter(o,e);
|
|
|
|
}
|
|
|
|
|
|
|
|
void KviIpEditor::resizeEvent(TQResizeEvent *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)TQFrame::resizeEvent(e);
|
|
|
|
}
|
|
|
|
|
|
|
|
TQSize 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 TQSize((labHint * 3) + (ediHint * 4) + 4,hghHint + 4);
|
|
|
|
else return TQSize((labHint * 7) + (ediHint * 8) + 4,hghHint + 4);
|
|
|
|
} else return TQFrame::sizeHint();
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#include "kvi_ipeditor.moc"
|