// // 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 #include #include #include #include #include // 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;iinstallEventFilter(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")) { if(e->type() == TQEvent::KeyPress) { TQString 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 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 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"