From 522dfb2ad8401b0cbe7c8aa2adb2213c669aa132 Mon Sep 17 00:00:00 2001 From: Noldor Date: Tue, 27 Feb 2007 17:11:32 +0000 Subject: objects module QT4 porting (wip) git-svn-id: https://svn.kvirc.de/svn/trunk/kvirc@384 17fca916-40b9-46aa-a4ea-0a15b648b75c --- src/modules/objects/class_button.cpp | 21 +- src/modules/objects/class_buttongroup.cpp | 12 +- src/modules/objects/class_dockwindow.cpp | 14 +- src/modules/objects/class_file.cpp | 444 +--- src/modules/objects/class_groupbox.cpp | 6 + src/modules/objects/class_label.cpp | 51 +- src/modules/objects/class_layout.cpp | 530 ++--- src/modules/objects/class_listview.cpp | 22 +- src/modules/objects/class_listview.h | 2 +- src/modules/objects/class_mainwindow.cpp | 34 +- src/modules/objects/class_mainwindow.h | 2 +- src/modules/objects/class_multilineedit.cpp | 29 +- src/modules/objects/class_painter.cpp | 19 +- src/modules/objects/class_process.cpp | 12 +- src/modules/objects/class_process.h | 13 +- src/modules/objects/class_progressbar.cpp | 34 +- src/modules/objects/class_progressbar.h | 2 +- src/modules/objects/class_socket.cpp | 2633 ++++++++++----------- src/modules/objects/class_spinbox.cpp | 10 +- src/modules/objects/class_tabwidget.cpp | 24 +- src/modules/objects/class_toolbar.cpp | 15 +- src/modules/objects/class_toolbar.h | 2 +- src/modules/objects/class_toolbutton.cpp | 18 +- src/modules/objects/class_urllabel.cpp | 10 +- src/modules/objects/class_widget.cpp | 3319 ++++++++++++++------------- src/modules/objects/class_widget.h | 7 +- src/modules/objects/class_window.cpp | 6 +- src/modules/objects/class_workspace.cpp | 9 +- src/modules/objects/class_wrapper.cpp | 48 +- src/modules/objects/libkviobjects.cpp | 100 +- src/modules/objects/objects_QT4_vc05.vcproj | 2551 ++++++++++---------- 31 files changed, 5016 insertions(+), 4983 deletions(-) (limited to 'src/modules/objects') diff --git a/src/modules/objects/class_button.cpp b/src/modules/objects/class_button.cpp index 56e50d3c0..fd8a4b3b5 100644 --- a/src/modules/objects/class_button.cpp +++ b/src/modules/objects/class_button.cpp @@ -108,14 +108,17 @@ bool KviKvsObject_button::functionSetOn(KviKvsObjectFunctionCall *c) ((QPushButton *)widget())->setOn(bEnabled); return true; } +// FIX ME bool KviKvsObject_button::functionSetIsMenuButton(KviKvsObjectFunctionCall *c) { bool bEnabled; KVSO_PARAMETERS_BEGIN(c) KVSO_PARAMETER("bEnabled",KVS_PT_BOOL,0,bEnabled) KVSO_PARAMETERS_END(c) - if(widget()) + /*if(widget()) ((QPushButton *)widget())->setIsMenuButton(bEnabled); + */ + return true; } bool KviKvsObject_button::functionIsMenuButton(KviKvsObjectFunctionCall *c) @@ -123,6 +126,7 @@ bool KviKvsObject_button::functionIsMenuButton(KviKvsObjectFunctionCall *c) if (widget()) c->returnValue()->setBoolean(((QPushButton *)widget())->isMenuButton()); return true; } +// bool KviKvsObject_button::functionIsOn(KviKvsObjectFunctionCall *c) { if (widget()) c->returnValue()->setBoolean(((QPushButton *)widget())->isOn()); @@ -133,6 +137,7 @@ bool KviKvsObject_button::functionToggle(KviKvsObjectFunctionCall *c) if(widget()) ((QPushButton *)widget())->toggle(); return true; } +// FIX ME bool KviKvsObject_button::functionSetImage(KviKvsObjectFunctionCall *c) { QString icon; @@ -141,10 +146,20 @@ bool KviKvsObject_button::functionSetImage(KviKvsObjectFunctionCall *c) KVSO_PARAMETERS_END(c) if (!widget()) return true; QPixmap * pix = g_pIconManager->getImage(icon); - if(pix) + if(pix){ + #ifdef COMPILE_USE_QT4 + ((QPushButton *)widget())->setIconSet(*pix); + #else ((QPushButton *)widget())->setIconSet(QIconSet(*pix,QIconSet::Small)); - else + #endif + } + else{ + #ifdef COMPILE_USE_QT4 + ((QPushButton *)widget())->setIcon(QIconSet()); + #else ((QPushButton *)widget())->setIconSet(QIconSet()); + #endif + } return true; } bool KviKvsObject_button::functionclickEvent(KviKvsObjectFunctionCall *c) diff --git a/src/modules/objects/class_buttongroup.cpp b/src/modules/objects/class_buttongroup.cpp index 72446f3fe..2a7cfe5b2 100644 --- a/src/modules/objects/class_buttongroup.cpp +++ b/src/modules/objects/class_buttongroup.cpp @@ -69,10 +69,18 @@ KVSO_BEGIN_DESTRUCTOR(KviKvsObject_buttongroup) KVSO_END_CONSTRUCTOR(KviKvsObject_buttongroup) +// CHECK ME bool KviKvsObject_buttongroup::init(KviKvsRunTimeContext * pContext,KviKvsVariantList *pParams) { - QButtonGroup *group=new QButtonGroup(parentScriptWidget(),name()); - setObject(group, true); + #ifdef COMPILE_USE_QT4 + QButtonGroup *group=new QButtonGroup(parentScriptWidget()); + group->setObjectName(name()); + setObject(group,true); + #else + setObject(new QButtonGroup(name(),parentScriptWidget()), true); + #endif + + return true; } diff --git a/src/modules/objects/class_dockwindow.cpp b/src/modules/objects/class_dockwindow.cpp index fdc302420..a6067a505 100644 --- a/src/modules/objects/class_dockwindow.cpp +++ b/src/modules/objects/class_dockwindow.cpp @@ -27,8 +27,13 @@ #include "kvi_frame.h" #include "kvi_locale.h" #include "kvi_qstring.h" - -#include +#ifdef COMPILE_USE_QT4 + #include + #define QT_DOCK_WINDOW Q3DockWindow +#else + #include + #define QT_DOCK_WINDOW QDockWindow +#endif #include /* @@ -87,11 +92,12 @@ KVSO_END_CONSTRUCTOR(KviKvsObject_dockwindow) KVSO_BEGIN_DESTRUCTOR(KviKvsObject_dockwindow) KVSO_END_DESTRUCTOR(KviKvsObject_dockwindow) -#define _pDockWindow ((QDockWindow *)widget()) +#define _pDockWindow ((QT_DOCK_WINDOW *)widget()) bool KviKvsObject_dockwindow::init(KviKvsRunTimeContext * pContext,KviKvsVariantList * pParams) { - setObject(new QDockWindow(g_pFrame,getName()),true); + + setObject(new QT_DOCK_WINDOW(g_pFrame,getName()),true); return true; } diff --git a/src/modules/objects/class_file.cpp b/src/modules/objects/class_file.cpp index 97545b305..55bbd4f29 100644 --- a/src/modules/objects/class_file.cpp +++ b/src/modules/objects/class_file.cpp @@ -40,401 +40,37 @@ const char * const mod_tbl[] = { "Append", "Truncate" }; - +#ifdef COMPILE_USE_QT4 +#define IO_RAW QIODevice::Unbuffered +#define IO_READONLY QIODevice::ReadOnly +#define IO_WRITEONLY QIODevice::WriteOnly +#define IO_READWRITE QIODevice::ReadWrite +#define IO_APPEND QIODevice::Append +#define IO_TRUNCATE QIODevice::Truncate +//#define IO_TRANSLATE QIODevice::Text +#else +#define IO_RAW IO_Raw +#define IO_READONLY IO_ReadOnly +#define IO_WRITEONLY IO_WriteOnly +#define IO_READWRITE IO_ReadWrite +#define IO_APPEND IO_Append +#define IO_TRUNCATE IO_Truncate +#endif +#ifdef COMPILE_USE_QT4 +const QIODevice::OpenMode mod_cod[] = { +#else const int mod_cod[] = { - IO_Raw, - IO_ReadOnly, - IO_WriteOnly, - IO_ReadWrite, - IO_Append, - IO_Truncate +#endif + IO_RAW, + IO_READONLY, + IO_WRITEONLY, + IO_READWRITE, + IO_APPEND, + IO_TRUNCATE }; #define mod_num (sizeof(mod_tbl) / sizeof(mod_tbl[0])) -/* - -static KviScriptObjectClass * g_pFileClass = 0; - -static KviScriptObject * fileClassCreateInstance(KviScriptObjectClass * c, - KviScriptObject * p, const char * n) -{ - return new KviScriptFileObject(c, p, n); -} - -KviScriptFileObject::KviScriptFileObject(KviScriptObjectClass * c, KviScriptObject * p, - const char * n) : KviScriptObject(c, p, n) -{ - m_pFile = new QFile(); -} - -KviScriptFileObject::~KviScriptFileObject() -{ - delete m_pFile; -} - - - -#define fileFuncReg(__nam, __func) \ - g_pFileClass->registerFunctionHandler(__nam, \ - (KviScriptObjectFunctionHandlerProc)(KVI_PTR2MEMBER(KviScriptFileObject::__func)), \ - 0, true); - -void KviScriptFileObject::registerSelf() -{ - KviScriptObjectClass * base = g_pScriptObjectController-> \ - lookupClass("object"); - __range_valid(base); - - g_pFileClass = new KviScriptObjectClass(base, "file", \ - fileClassCreateInstance, true); - - fileFuncReg("setName", functionSetName); - fileFuncReg("name", functionName); - fileFuncReg("open", functionOpen); - fileFuncReg("isOpen", functionIsOpen); - fileFuncReg("close", functionClose); - fileFuncReg("flush", functionFlush); - fileFuncReg("size", functionSize); - fileFuncReg("atEnd", functionAtEnd); - fileFuncReg("where", functionWhere); - fileFuncReg("seek", functionSeek); - fileFuncReg("putch", functionPutch); - fileFuncReg("getch", functionGetch); - fileFuncReg("ungetch", functionUngetch); - fileFuncReg("readBlock", functionReadBlock); - fileFuncReg("writeBlock", functionWriteBlock); - fileFuncReg("readLine", functionReadLine); - fileFuncReg("writeLine", functionWriteLine); - fileFuncReg("hexWrite", functionHexWrite); - fileFuncReg("hexRead", functionHexRead); -} - -void KviScriptFileObject::unregisterSelf() -{ - delete g_pFileClass; - g_pFileClass = 0; -} - -bool KviScriptFileObject::functionSetName(KviCommand * c, KviParameterList * p, - KviStr & b) -{ - ENTER_STACK_FRAME(c, "file::setName"); - KviStr * pS = p->safeFirst(); - if(pS->isEmpty()) - return c->error(KviError_invalidParameter,__tr("Empty string")); - m_pFile->setName(QString::fromUtf8(pS->ptr())); - return c->leaveStackFrame(); -} - -bool KviScriptFileObject::functionName(KviCommand *, KviParameterList *, KviStr & b) -{ - b.append(m_pFile->name().utf8().data()); - return true; -} - -bool KviScriptFileObject::functionOpen(KviCommand * c, KviParameterList * p, KviStr &) -{ - ENTER_STACK_FRAME(c, "file::open"); - if(kvi_strEqualCI(m_pFile->name().utf8().data(), "")) - return c->error(KviError_noSuchFile, \ - __tr("Empty filename string")); - - int mod, sum = 0; - if(!p->count()) // if no parameters given, default to ReadWrite | Append - sum = IO_ReadOnly; - else - { - for(unsigned int i = 0; i < p->count(); i++) - { - mod = 0; - for(unsigned int j = 0; j < mod_num; j++) - { - if(kvi_strEqualCI(p->at(i)->ptr(), mod_tbl[j])) - { - mod = mod_cod[j]; - break; - } - } - - if(mod) - sum = sum | mod; - else - c->warning(__tr("No such open mode: %s"), \ - p->at(i)->ptr()); - } - } - - if(!m_pFile->open(sum)) - return c->error(KviError_unknownError); // signalise with other - // error ? - return c->leaveStackFrame(); -} - -bool KviScriptFileObject::functionIsOpen(KviCommand *, KviParameterList *, KviStr & b) -{ - b.append(m_pFile->isOpen() ? '1' : '0'); - return true; -} - -bool KviScriptFileObject::functionClose(KviCommand * c, KviParameterList *, KviStr &) -{ - if(!m_pFile->isOpen()) - c->warning(__tr("File is not open !")); - - m_pFile->close(); - return true; -} - -bool KviScriptFileObject::functionFlush(KviCommand * c, KviParameterList *, KviStr &) -{ - if(!m_pFile->isOpen()) - c->warning(__tr("File is not open !")); - - m_pFile->flush(); - return true; -} - -bool KviScriptFileObject::functionSize(KviCommand *, KviParameterList *, KviStr & b) -{ - b.append(KviStr::Format, "%d", m_pFile->size()); - return true; -} - -bool KviScriptFileObject::functionAtEnd(KviCommand * c, KviParameterList *,KviStr & b) -{ - if(!m_pFile->isOpen()) - c->warning(__tr("File is not open !")); - - b.append(m_pFile->atEnd() ? '1' : '0'); - return true; -} - -bool KviScriptFileObject::functionWhere(KviCommand * c, KviParameterList *,KviStr & b) -{ - if(!m_pFile->isOpen()) - c->warning(__tr("File is not open !")); - - b.append(KviStr::Format, "%d", m_pFile->at()); - return true; -} - -bool KviScriptFileObject::functionSeek(KviCommand * c, KviParameterList * p, - KviStr & b) -{ - ENTER_STACK_FRAME(c, "file::seek"); - if(!m_pFile->isOpen()) - c->warning(__tr("File is not open !")); - - if(!p->count()) - return c->error(KviError_notEnoughParameters); - - bool bOk; - int val = p->getInt(&bOk); - if(!bOk) - return c->error(KviError_integerParameterExpected); - - if(val < 0) - c->warning(__tr("Negative file index supplied !")); - - m_pFile->at(val); - return c->leaveStackFrame(); -} - -bool KviScriptFileObject::functionPutch(KviCommand * c, KviParameterList * p, - KviStr & b) -{ - ENTER_STACK_FRAME(c, "file::putch"); - if(!p->count()) - return c->error(KviError_notEnoughParameters); - - if(p->first()->len() > 1) - c->warning(__tr("Argument to long, using only first char")); - else - if(p->first()->len() == 0) - c->warning(__tr("Argument length is 0 - empty string")); - - if(!m_pFile->isOpen()) - c->warning(__tr("File is not open !")); - - char ch = p->first()->at(0); - if(m_pFile->putch(ch) < 0) - c->warning(__tr("Write error occured !")); // c->error ? - return c->leaveStackFrame(); -} - -bool KviScriptFileObject::functionGetch(KviCommand * c, KviParameterList * p, - KviStr & b) -{ - if(!m_pFile->isOpen()) - c->warning(__tr("File is not open !")); - - int chInt = m_pFile->getch(); - if(chInt < 0) - c->warning(__tr("Read error occured !")); // c->error ? - else - { - char ch = chInt; - b.append(ch); - } - - return true; -} - -bool KviScriptFileObject::functionUngetch(KviCommand * c, KviParameterList * p, - KviStr & b) -{ - ENTER_STACK_FRAME(c, "file::ungetch"); - if(!p->count()) - return c->error(KviError_notEnoughParameters); - - if(p->first()->len() > 1) - c->warning(__tr("Argument to long, using only first char")); - else - if(p->first()->len() == 0) - c->warning(__tr("Argument length is 0 - empty string")); - - if(!m_pFile->isOpen()) - c->warning(__tr("File is not open !")); - - char ch = p->first()->at(0); - if(m_pFile->ungetch(ch) < 0) - c->warning(__tr("An error occured !")); // c->error ? - return c->leaveStackFrame(); -} - -bool KviScriptFileObject::functionReadBlock(KviCommand * c, KviParameterList * p, - KviStr & b) -{ - ENTER_STACK_FRAME(c, "file::readBlock"); - if(!p->count()) - return c->error(KviError_notEnoughParameters); - - bool ok; - int len = p->getInt(&ok); - if(!ok) - return c->error(KviError_integerParameterExpected); - if(len < 0) - c->warning(__tr("Length is a negative number !")); - - if(!m_pFile->isOpen()) - c->warning(__tr("File is not open !")); - - char * buff = new char[len + 1]; - m_pFile->flush(); // advice from QFile man page (to avoid trash) - int rlen = m_pFile->readBlock(buff, len); - buff[rlen] = '\0'; - b.append(buff); - delete[] buff; - return c->leaveStackFrame(); -} - -bool KviScriptFileObject::functionWriteBlock(KviCommand * c, KviParameterList * p, - KviStr & b) -{ - ENTER_STACK_FRAME(c, "file::writeBlock"); - - if(p->count() < 2) - return c->error(KviError_notEnoughParameters); - - bool ok; - int len = p->getInt(&ok); -// KviStr * pS = p->safeNext(); - KviStr * pS = p->at(1); - if(!ok) - return c->error(KviError_integerParameterExpected); - if(len < 0) - c->warning(__tr("Length is a negative number !")); - - if(!m_pFile->isOpen()) - c->warning(__tr("File is not open !")); - - int rlen = m_pFile->writeBlock(pS->ptr(), len); - b.append(KviStr::Format, "%d", rlen); - m_pFile->flush(); - return c->leaveStackFrame(); -} - -bool KviScriptFileObject::functionReadLine(KviCommand * c, KviParameterList * p, - KviStr & b) -{ -// ENTER_STACK_FRAME(c, "file::readLine"); - - if(!m_pFile->isOpen()) - c->warning(__tr("File is not open !")); - - KviStr tmp; - kvi_readLine(m_pFile,tmp); - b.append(tmp); - - return true; - -// return c->leaveStackFrame(); -} - -bool KviScriptFileObject::functionWriteLine(KviCommand * c, KviParameterList * p, - KviStr & b) -{ - ENTER_STACK_FRAME(c, "file::writeLine"); - - if(!p->count()) - return c->error(KviError_notEnoughParameters); - - if(!m_pFile->isOpen()) - c->warning(__tr("File is not open !")); - - QTextStream ts(m_pFile); - ts << p->first()->ptr(); - - return c->leaveStackFrame(); -} - -bool KviScriptFileObject::functionHexWrite(KviCommand * c, KviParameterList * p, - KviStr & b) -{ - ENTER_STACK_FRAME(c, "file::hexWrite"); - if(!p->count()) - return c->error(KviError_notEnoughParameters); - - char * val = 0; - int len = p->first()->hexToBuffer(&val,false); - - if(len < 1) - { - c->warning(__tr("Nothing to write")); - return c->leaveStackFrame(); - } - - if(!m_pFile->isOpen()) - c->warning(__tr("File is not open !")); - - if(m_pFile->putch(*val) < 0) - c->warning(__tr("Write error occured !")); // c->error ? - - KviStr::freeBuffer(val); - - return c->leaveStackFrame(); -} - -bool KviScriptFileObject::functionHexRead(KviCommand * c, KviParameterList * p, - KviStr & b) -{ - if(!m_pFile->isOpen()) - c->warning(__tr("File is not open !")); - - char ch = m_pFile->getch(); - - KviStr tmp; - tmp.bufferToHex(&ch, 1); - b.append(tmp); - - return true; -} - -*/ - - - /* @doc: file @keyterms: @@ -590,8 +226,31 @@ bool KviKvsObject_file::functionopen(KviKvsObjectFunctionCall *c) c->warning(__tr2qs("Empty filename string")); return true; } - int mod,sum = 0; - if (!modes.first()) sum = IO_ReadOnly; // if no parameters given, default to ReadWrite | Append + #ifdef COMPILE_USE_QT4 + QIODevice::OpenMode mod,sum; + if (modes.empty()) sum = IO_READONLY; // if no parameters given, default to ReadWrite | Append + else + { + for ( int idx=0;idxwarning(__tr2qs("No such open mode: '%Q'"),&modes.at(idx)); + } + } +#else + int mod,sum=0; +if (!modes.first()) sum = IO_READONLY; // if no parameters given, default to ReadWrite | Append else { for ( QStringList::Iterator it = modes.begin(); it != modes.end(); ++it ) @@ -612,6 +271,7 @@ bool KviKvsObject_file::functionopen(KviKvsObjectFunctionCall *c) c->warning(__tr2qs("No such open mode: '%Q'"),&(*it)); } } +#endif m_pFile->open(sum); return true; } diff --git a/src/modules/objects/class_groupbox.cpp b/src/modules/objects/class_groupbox.cpp index 99c2ab01d..ce1a4fdc9 100644 --- a/src/modules/objects/class_groupbox.cpp +++ b/src/modules/objects/class_groupbox.cpp @@ -184,7 +184,13 @@ KVSO_END_CONSTRUCTOR(KviKvsObject_groupbox) bool KviKvsObject_groupbox::init(KviKvsRunTimeContext * pContext,KviKvsVariantList *pParams) { +#ifdef COMPILE_USE_QT4 + KviTalGroupBox *groupbox=new KviTalGroupBox(name(),parentScriptWidget()); + groupbox->setObjectName(name()); + setObject(groupbox,true); +#else setObject(new KviTalGroupBox(name(),parentScriptWidget()), true); +#endif return true; } diff --git a/src/modules/objects/class_label.cpp b/src/modules/objects/class_label.cpp index 9c89fd300..01ae24fe5 100644 --- a/src/modules/objects/class_label.cpp +++ b/src/modules/objects/class_label.cpp @@ -45,16 +45,36 @@ const char * const align_tbl[] = { "Bottom", "WordBreak" }; +#ifdef COMPILE_USE_QT4 + #define QT_LABEL_ALIGNLEFT Qt::AlignLeft + #define QT_LABEL_ALIGNRIGHT Qt::AlignRight + #define QT_LABEL_ALIGNHCENTER Qt::AlignHCenter + #define QT_LABEL_ALIGNVCENTER Qt::AlignVCenter + #define QT_LABEL_ALIGNCENTER Qt::AlignCenter + #define QT_LABEL_ALIGNTOP Qt::AlignTop + #define QT_LABEL_ALIGNBOTTOM Qt::AlignBottom + #define QT_LABEL_JUSTIFY Qt::AlignJustify +#else + #define QT_LABEL_ALIGNLEFT QLabel::AlignLeft + #define QT_LABEL_ALIGNRIGHT QLabel::AlignRight + #define QT_LABEL_ALIGNHCENTER QLabel::AlignHCenter + #define QT_LABEL_ALIGNVCENTER QLabel::AlignVCenter + #define QT_LABEL_ALIGNCENTER QLabel::AlignCenter + #define QT_LABEL_ALIGNTOP QLabel::AlignTop + #define QT_LABEL_ALIGNBOTTOM QLabel::AlignBottom + #define QT_LABEL_JUSTIFY QLabel::WordBreak +#endif + const int align_cod[] = { - QLabel::AlignLeft, - QLabel::AlignRight, - QLabel::AlignHCenter, - QLabel::AlignVCenter, - QLabel::AlignCenter, - QLabel::AlignTop, - QLabel::AlignBottom, - QLabel::WordBreak - }; + QT_LABEL_ALIGNLEFT, + QT_LABEL_ALIGNRIGHT, + QT_LABEL_ALIGNHCENTER, + QT_LABEL_ALIGNVCENTER, + QT_LABEL_ALIGNCENTER, + QT_LABEL_ALIGNTOP, + QT_LABEL_ALIGNBOTTOM, + QT_LABEL_JUSTIFY, + }; #define align_num (sizeof(align_tbl) / sizeof(align_tbl[0])) @@ -250,22 +270,31 @@ bool KviKvsObject_label::functionMargin(KviKvsObjectFunctionCall *c) return true; } +// FIX ME bool KviKvsObject_label::functionSetAutoResize(KviKvsObjectFunctionCall *c) { bool bEnabled; KVSO_PARAMETERS_BEGIN(c) KVSO_PARAMETER("bEnabled",KVS_PT_BOOL,0,bEnabled) KVSO_PARAMETERS_END(c) + #ifdef COMPILE_USE_QT4 + return true; + #else if(widget()) ((QLabel *)widget())->setAutoResize(bEnabled); return true; + #endif } bool KviKvsObject_label::functionAutoResize(KviKvsObjectFunctionCall *c) { - if (widget()) c->returnValue()->setBoolean(((QLabel *)widget())->autoResize()); + #ifdef COMPILE_USE_QT4 + if (widget()) c->returnValue()->setBoolean(true); + #else + if (widget()) c->returnValue()->setBoolean(((QLabel *)widget())->autoResize()); + #endif return true; } - +// bool KviKvsObject_label::functionSetAlignment(KviKvsObjectFunctionCall *c) { QStringList alignment; diff --git a/src/modules/objects/class_layout.cpp b/src/modules/objects/class_layout.cpp index aef8611a7..f895abd7f 100644 --- a/src/modules/objects/class_layout.cpp +++ b/src/modules/objects/class_layout.cpp @@ -1,256 +1,274 @@ -// -// File : class_layout.cpp -// Creation date : Fri Now 22 2002 00:50:01 by Szymon Stefanek -// -// This file is part of the KVirc irc client distribution -// Copyright (C) 2002 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. ,59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// -#define _KVI_DEBUG_CHECK_RANGE_ -#include "kvi_debug.h" - -#include "kvi_locale.h" - -#include "class_layout.h" - -/* - @doc: layout - @keyterms: - layout object class, child widgets - @title: - layout class - @type: - class - @short: - Manages child widget geometry - @inherits: - [class]object[/class] - @description: - The layout is a geometry management tool for child widgets. - You create a layout , give it some widgets to manage and it will layout them - automatically.[br] - The parent of the layout must be the widget for which child widget geometries have to be managed. - A layout is a grid of NxM cells in which you insert child widgets with [classfnc:layout]$addWidget[/classfnc]().[br] - Widgets that must span multiple cells can be added to the layout with [classfnc:layout]$addMultiCellWidget[/classfnc]().[br] - @functions: - !fn: $addWidget(,,) - Adds a widget to this layout placing it at position , in the grid - !fn: $addMultiCellWidget(,,,,) - Adds a widget to this layout spanning multiple grid cells - !fn: $setRowStretch(,) - Sets the stretch value for a particular row of this layout. The - must be a positive integer. The rows with bigger stretch values will take more space - in the layout. - !fn: $setColStretch(,) - Sets the stretch value for a particular column in this layout. The - must be a positive integer. The rows with bigger stretch values will take more space - in the layout. - !fn: $addRowSpacing(,) - Sets the minimum height of the specified to which must be a positive integer - !fn: $addColSpacing(,) - Sets the minimum width of the specigfied to which must be a positive integer - !fn: $setSpacing() - Sets the default spacing of the widgets in pixels - !fn: $setMargin() - Sets the dimension of the layout margin : the distance from the border to the outermost child widget edges. - !fn: $setResizeMode() - Sets the resize mode of the parent widget in relation to this layout. - can be one of:[br] - -Auto: this is the default[br] - -Fixed: the parent widget of this layout is resized to the "sizeHint" value and it cannot be resized by the user.[br] - -Minimum: the minimum size of the parent widget of this layout is set to minimumSize() and it cannot be smaller[br] - -FreeResize: the parent widget of this layout is not constrained at all[br] -*/ - - -KVSO_BEGIN_REGISTERCLASS(KviKvsObject_layout,"layout","object") - KVSO_REGISTER_HANDLER(KviKvsObject_layout,"addWidget", functionAddWidget) - KVSO_REGISTER_HANDLER(KviKvsObject_layout,"addMultiCellWidget", functionAddMultiCellWidget) - KVSO_REGISTER_HANDLER(KviKvsObject_layout,"setRowStretch", functionSetRowStretch) - KVSO_REGISTER_HANDLER(KviKvsObject_layout,"setColStretch", functionSetColStretch) - KVSO_REGISTER_HANDLER(KviKvsObject_layout,"addRowSpacing", functionAddRowSpacing) - KVSO_REGISTER_HANDLER(KviKvsObject_layout,"addColSpacing", functionAddColSpacing) - KVSO_REGISTER_HANDLER(KviKvsObject_layout,"setMargin", functionSetMargin) - KVSO_REGISTER_HANDLER(KviKvsObject_layout,"setSpacing", functionSetSpacing) - KVSO_REGISTER_HANDLER(KviKvsObject_layout,"setResizeMode", functionSetResizeMode) -KVSO_END_REGISTERCLASS(KviKvsObject_layout) - -KVSO_BEGIN_CONSTRUCTOR(KviKvsObject_layout,KviKvsObject) - -KVSO_END_CONSTRUCTOR(KviKvsObject_layout) - - -KVSO_BEGIN_DESTRUCTOR(KviKvsObject_layout) - -KVSO_END_CONSTRUCTOR(KviKvsObject_layout) - -bool KviKvsObject_layout::init(KviKvsRunTimeContext * pContext,KviKvsVariantList *pParams) -{ - QWidget * w = parentScriptWidget(); - - if(!w) - { - pContext->warning(__tr2qs("The parent of a layout must be a widget!")); - return false; - } - setObject(new QGridLayout(w)); - return true; -} - -bool KviKvsObject_layout::functionAddWidget(KviKvsObjectFunctionCall *c) -{ - KviKvsObject * pObject; - kvs_hobject_t hObject; - kvs_uint_t uCol,uRow; - KVSO_PARAMETERS_BEGIN(c) - KVSO_PARAMETER("widget",KVS_PT_HOBJECT,0,hObject) - KVSO_PARAMETER("row",KVS_PT_UNSIGNEDINTEGER,0,uRow) - KVSO_PARAMETER("col",KVS_PT_UNSIGNEDINTEGER,0,uCol) - KVSO_PARAMETERS_END(c) - pObject=KviKvsKernel::instance()->objectController()->lookupObject(hObject); - if(!widget())return true; - if (!pObject) - { - c->warning(__tr2qs("Widget parameter is not an object")); - return true; - } - if (!pObject->object()) - { - c->warning(__tr2qs("Widget parameter is not a valid object")); - return true; - } - if(!pObject->object()->isWidgetType()) - { - c->warning(__tr2qs("Can't add a non-widget object")); - return true; - } - ((QGridLayout *)object())->addWidget(((QWidget *)(pObject->object())),uRow,uCol); - return true; -} -bool KviKvsObject_layout::functionAddMultiCellWidget(KviKvsObjectFunctionCall *c) -{ - KviKvsObject * pObject; - kvs_hobject_t hObject; - kvs_uint_t uStartCol,uStartRow,uEndCol,uEndRow; - KVSO_PARAMETERS_BEGIN(c) - KVSO_PARAMETER("widget",KVS_PT_HOBJECT,0,hObject) - KVSO_PARAMETER("start_row",KVS_PT_UNSIGNEDINTEGER,0,uStartRow) - KVSO_PARAMETER("end_row",KVS_PT_UNSIGNEDINTEGER,0,uEndRow) - KVSO_PARAMETER("start_column",KVS_PT_UNSIGNEDINTEGER,0,uStartCol) - KVSO_PARAMETER("end_column",KVS_PT_UNSIGNEDINTEGER,0,uEndCol) - KVSO_PARAMETERS_END(c) - pObject=KviKvsKernel::instance()->objectController()->lookupObject(hObject); - if(!widget())return true; - if (!pObject) - { - c->warning(__tr2qs("Widget parameter is not an object")); - return true; - } - if (!pObject->object()) - { - c->warning(__tr2qs("Widget parameter is not a valid object")); - return true; - } - if(!pObject->object()->isWidgetType()) - { - c->warning(__tr2qs("Can't add a non-widget object")); - return true; - } - ((QGridLayout *)object())->addMultiCellWidget(((QWidget *)(pObject->object())),uStartRow,uEndRow,uStartCol,uEndCol); - return true; -} -bool KviKvsObject_layout::functionSetRowStretch(KviKvsObjectFunctionCall *c) -{ - kvs_uint_t uRow,uStretch; - KVSO_PARAMETERS_BEGIN(c) - KVSO_PARAMETER("row",KVS_PT_UNSIGNEDINTEGER,0,uRow) - KVSO_PARAMETER("stretch",KVS_PT_UNSIGNEDINTEGER,0,uStretch) - KVSO_PARAMETERS_END(c) - if(!widget())return true; - ((QGridLayout *)object())->setRowStretch(uRow,uStretch); - return true; -} -bool KviKvsObject_layout::functionSetColStretch(KviKvsObjectFunctionCall *c) -{ - kvs_uint_t uCol,uStretch; - KVSO_PARAMETERS_BEGIN(c) - KVSO_PARAMETER("column",KVS_PT_UNSIGNEDINTEGER,0,uCol) - KVSO_PARAMETER("stretch",KVS_PT_UNSIGNEDINTEGER,0,uStretch) - KVSO_PARAMETERS_END(c) - if(!widget())return true; - ((QGridLayout *)object())->setColStretch(uCol,uStretch); - return true; -} - -bool KviKvsObject_layout::functionSetMargin(KviKvsObjectFunctionCall *c) -{ - kvs_uint_t uMargin; - KVSO_PARAMETERS_BEGIN(c) - KVSO_PARAMETER("margin",KVS_PT_UNSIGNEDINTEGER,0,uMargin) - KVSO_PARAMETERS_END(c) - if (widget()) ((QGridLayout *)object())->setMargin(uMargin); - return true; -} - -bool KviKvsObject_layout::functionSetSpacing(KviKvsObjectFunctionCall *c) -{ - kvs_uint_t uSpacing; - KVSO_PARAMETERS_BEGIN(c) - KVSO_PARAMETER("spacing",KVS_PT_UNSIGNEDINTEGER,0,uSpacing) - KVSO_PARAMETERS_END(c) - if (widget()) ((QGridLayout *)object())->setSpacing(uSpacing); - return true; -} - - -bool KviKvsObject_layout::functionAddRowSpacing(KviKvsObjectFunctionCall *c) -{ - kvs_uint_t uSpacing,uRow; - KVSO_PARAMETERS_BEGIN(c) - KVSO_PARAMETER("row",KVS_PT_UNSIGNEDINTEGER,0,uRow) - KVSO_PARAMETER("spacing",KVS_PT_UNSIGNEDINTEGER,0,uSpacing) - KVSO_PARAMETERS_END(c) - if (widget()) ((QGridLayout *)object())->addRowSpacing(uRow,uSpacing); - return true; -} - -bool KviKvsObject_layout::functionAddColSpacing(KviKvsObjectFunctionCall *c) -{ - kvs_uint_t uSpacing,uCol; - KVSO_PARAMETERS_BEGIN(c) - KVSO_PARAMETER("column",KVS_PT_UNSIGNEDINTEGER,0,uCol) - KVSO_PARAMETER("spacing",KVS_PT_UNSIGNEDINTEGER,0,uSpacing) - KVSO_PARAMETERS_END(c) - if (widget()) ((QGridLayout *)object())->addColSpacing(uCol,uSpacing); - return true; -} - -bool KviKvsObject_layout::functionSetResizeMode(KviKvsObjectFunctionCall *c) -{ - QString szMode; - KVSO_PARAMETERS_BEGIN(c) - KVSO_PARAMETER("resize_mode",KVS_PT_STRING,0,szMode) - KVSO_PARAMETERS_END(c) - if(!widget())return true; - QLayout::ResizeMode r = QLayout::Auto; - if(KviQString::equalCI(szMode,"FreeResize")) r = QLayout::FreeResize; - else if(KviQString::equalCI(szMode,"Minimum")) r = QLayout::Minimum; - else if(KviQString::equalCI(szMode,"Fixed"))r = QLayout::Fixed; - else c->warning(__tr2qs("Invalid resize mode defaulting to Auto")); - ((QGridLayout *)object())->setResizeMode(r); - return true; -} - +// +// File : class_layout.cpp +// Creation date : Fri Now 22 2002 00:50:01 by Szymon Stefanek +// +// This file is part of the KVirc irc client distribution +// Copyright (C) 2002 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. ,59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +#define _KVI_DEBUG_CHECK_RANGE_ +#include "kvi_debug.h" + +#include "kvi_locale.h" + +#include "class_layout.h" + +#ifdef COMPILE_USE_QT4 +#define QLAYOUT_AUTO_CONSTRAINT QLayout::SetDefaultConstraint +#define QLAYOUT_FIXED QLayout::SetFixedSize +#define QLAYOUT_FREE_RESIZE QLayout::SetNoConstraint +#define QLAYOUT_MINIMUM QLayout::SetMinimumSize +#else +#define QLAYOUT_AUTO_CONSTRAINT QLayout::Auto +#define QLAYOUT_FIXED QLayout::Fixed +#define QLAYOUT_FREE_RESIZE QLayout::FreeResize +#define QLAYOUT_MINIMUM QLayout::Minimum +#endif + + +/* + @doc: layout + @keyterms: + layout object class, child widgets + @title: + layout class + @type: + class + @short: + Manages child widget geometry + @inherits: + [class]object[/class] + @description: + The layout is a geometry management tool for child widgets. + You create a layout , give it some widgets to manage and it will layout them + automatically.[br] + The parent of the layout must be the widget for which child widget geometries have to be managed. + A layout is a grid of NxM cells in which you insert child widgets with [classfnc:layout]$addWidget[/classfnc]().[br] + Widgets that must span multiple cells can be added to the layout with [classfnc:layout]$addMultiCellWidget[/classfnc]().[br] + @functions: + !fn: $addWidget(,,) + Adds a widget to this layout placing it at position , in the grid + !fn: $addMultiCellWidget(,,,,) + Adds a widget to this layout spanning multiple grid cells + !fn: $setRowStretch(,) + Sets the stretch value for a particular row of this layout. The + must be a positive integer. The rows with bigger stretch values will take more space + in the layout. + !fn: $setColStretch(,) + Sets the stretch value for a particular column in this layout. The + must be a positive integer. The rows with bigger stretch values will take more space + in the layout. + !fn: $addRowSpacing(,) + Sets the minimum height of the specified to which must be a positive integer + !fn: $addColSpacing(,) + Sets the minimum width of the specigfied to which must be a positive integer + !fn: $setSpacing() + Sets the default spacing of the widgets in pixels + !fn: $setMargin() + Sets the dimension of the layout margin : the distance from the border to the outermost child widget edges. + !fn: $setResizeMode() + Sets the resize mode of the parent widget in relation to this layout. + can be one of:[br] + -Auto: this is the default[br] + -Fixed: the parent widget of this layout is resized to the "sizeHint" value and it cannot be resized by the user.[br] + -Minimum: the minimum size of the parent widget of this layout is set to minimumSize() and it cannot be smaller[br] + -FreeResize: the parent widget of this layout is not constrained at all[br] +*/ + + +KVSO_BEGIN_REGISTERCLASS(KviKvsObject_layout,"layout","object") + KVSO_REGISTER_HANDLER(KviKvsObject_layout,"addWidget", functionAddWidget) + KVSO_REGISTER_HANDLER(KviKvsObject_layout,"addMultiCellWidget", functionAddMultiCellWidget) + KVSO_REGISTER_HANDLER(KviKvsObject_layout,"setRowStretch", functionSetRowStretch) + KVSO_REGISTER_HANDLER(KviKvsObject_layout,"setColStretch", functionSetColStretch) + KVSO_REGISTER_HANDLER(KviKvsObject_layout,"addRowSpacing", functionAddRowSpacing) + KVSO_REGISTER_HANDLER(KviKvsObject_layout,"addColSpacing", functionAddColSpacing) + KVSO_REGISTER_HANDLER(KviKvsObject_layout,"setMargin", functionSetMargin) + KVSO_REGISTER_HANDLER(KviKvsObject_layout,"setSpacing", functionSetSpacing) + KVSO_REGISTER_HANDLER(KviKvsObject_layout,"setResizeMode", functionSetResizeMode) +KVSO_END_REGISTERCLASS(KviKvsObject_layout) + +KVSO_BEGIN_CONSTRUCTOR(KviKvsObject_layout,KviKvsObject) + +KVSO_END_CONSTRUCTOR(KviKvsObject_layout) + + +KVSO_BEGIN_DESTRUCTOR(KviKvsObject_layout) + +KVSO_END_CONSTRUCTOR(KviKvsObject_layout) + +bool KviKvsObject_layout::init(KviKvsRunTimeContext * pContext,KviKvsVariantList *pParams) +{ + QWidget * w = parentScriptWidget(); + + if(!w) + { + pContext->warning(__tr2qs("The parent of a layout must be a widget!")); + return false; + } + setObject(new QGridLayout(w)); + return true; +} + +bool KviKvsObject_layout::functionAddWidget(KviKvsObjectFunctionCall *c) +{ + KviKvsObject * pObject; + kvs_hobject_t hObject; + kvs_uint_t uCol,uRow; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("widget",KVS_PT_HOBJECT,0,hObject) + KVSO_PARAMETER("row",KVS_PT_UNSIGNEDINTEGER,0,uRow) + KVSO_PARAMETER("col",KVS_PT_UNSIGNEDINTEGER,0,uCol) + KVSO_PARAMETERS_END(c) + pObject=KviKvsKernel::instance()->objectController()->lookupObject(hObject); + if(!widget())return true; + if (!pObject) + { + c->warning(__tr2qs("Widget parameter is not an object")); + return true; + } + if (!pObject->object()) + { + c->warning(__tr2qs("Widget parameter is not a valid object")); + return true; + } + if(!pObject->object()->isWidgetType()) + { + c->warning(__tr2qs("Can't add a non-widget object")); + return true; + } + ((QGridLayout *)object())->addWidget(((QWidget *)(pObject->object())),uRow,uCol); + return true; +} +bool KviKvsObject_layout::functionAddMultiCellWidget(KviKvsObjectFunctionCall *c) +{ + KviKvsObject * pObject; + kvs_hobject_t hObject; + kvs_uint_t uStartCol,uStartRow,uEndCol,uEndRow; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("widget",KVS_PT_HOBJECT,0,hObject) + KVSO_PARAMETER("start_row",KVS_PT_UNSIGNEDINTEGER,0,uStartRow) + KVSO_PARAMETER("end_row",KVS_PT_UNSIGNEDINTEGER,0,uEndRow) + KVSO_PARAMETER("start_column",KVS_PT_UNSIGNEDINTEGER,0,uStartCol) + KVSO_PARAMETER("end_column",KVS_PT_UNSIGNEDINTEGER,0,uEndCol) + KVSO_PARAMETERS_END(c) + pObject=KviKvsKernel::instance()->objectController()->lookupObject(hObject); + if(!widget())return true; + if (!pObject) + { + c->warning(__tr2qs("Widget parameter is not an object")); + return true; + } + if (!pObject->object()) + { + c->warning(__tr2qs("Widget parameter is not a valid object")); + return true; + } + if(!pObject->object()->isWidgetType()) + { + c->warning(__tr2qs("Can't add a non-widget object")); + return true; + } + ((QGridLayout *)object())->addMultiCellWidget(((QWidget *)(pObject->object())),uStartRow,uEndRow,uStartCol,uEndCol); + return true; +} +bool KviKvsObject_layout::functionSetRowStretch(KviKvsObjectFunctionCall *c) +{ + kvs_uint_t uRow,uStretch; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("row",KVS_PT_UNSIGNEDINTEGER,0,uRow) + KVSO_PARAMETER("stretch",KVS_PT_UNSIGNEDINTEGER,0,uStretch) + KVSO_PARAMETERS_END(c) + if(!widget())return true; + ((QGridLayout *)object())->setRowStretch(uRow,uStretch); + return true; +} +bool KviKvsObject_layout::functionSetColStretch(KviKvsObjectFunctionCall *c) +{ + kvs_uint_t uCol,uStretch; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("column",KVS_PT_UNSIGNEDINTEGER,0,uCol) + KVSO_PARAMETER("stretch",KVS_PT_UNSIGNEDINTEGER,0,uStretch) + KVSO_PARAMETERS_END(c) + if(!widget())return true; + ((QGridLayout *)object())->setColStretch(uCol,uStretch); + return true; +} + +bool KviKvsObject_layout::functionSetMargin(KviKvsObjectFunctionCall *c) +{ + kvs_uint_t uMargin; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("margin",KVS_PT_UNSIGNEDINTEGER,0,uMargin) + KVSO_PARAMETERS_END(c) + if (widget()) ((QGridLayout *)object())->setMargin(uMargin); + return true; +} + +bool KviKvsObject_layout::functionSetSpacing(KviKvsObjectFunctionCall *c) +{ + kvs_uint_t uSpacing; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("spacing",KVS_PT_UNSIGNEDINTEGER,0,uSpacing) + KVSO_PARAMETERS_END(c) + if (widget()) ((QGridLayout *)object())->setSpacing(uSpacing); + return true; +} + + +bool KviKvsObject_layout::functionAddRowSpacing(KviKvsObjectFunctionCall *c) +{ + kvs_uint_t uSpacing,uRow; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("row",KVS_PT_UNSIGNEDINTEGER,0,uRow) + KVSO_PARAMETER("spacing",KVS_PT_UNSIGNEDINTEGER,0,uSpacing) + KVSO_PARAMETERS_END(c) + if (widget()) ((QGridLayout *)object())->addRowSpacing(uRow,uSpacing); + return true; +} + +bool KviKvsObject_layout::functionAddColSpacing(KviKvsObjectFunctionCall *c) +{ + kvs_uint_t uSpacing,uCol; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("column",KVS_PT_UNSIGNEDINTEGER,0,uCol) + KVSO_PARAMETER("spacing",KVS_PT_UNSIGNEDINTEGER,0,uSpacing) + KVSO_PARAMETERS_END(c) + if (widget()) ((QGridLayout *)object())->addColSpacing(uCol,uSpacing); + return true; +} + +bool KviKvsObject_layout::functionSetResizeMode(KviKvsObjectFunctionCall *c) +{ + QString szMode; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("resize_mode",KVS_PT_STRING,0,szMode) + KVSO_PARAMETERS_END(c) + if(!widget())return true; +#ifdef COMPILE_USE_QT4 + QLayout::SizeConstraint r = QLAYOUT_AUTO_CONSTRAINT; +#else + QLayout::ResizeMode r = QLAYOUT_AUTO_CONSTRAINT; +#endif + if(KviQString::equalCI(szMode,"FreeResize")) r = QLAYOUT_FREE_RESIZE; + else if(KviQString::equalCI(szMode,"Minimum")) r = QLAYOUT_MINIMUM; + else if(KviQString::equalCI(szMode,"Fixed"))r = QLAYOUT_FIXED; + else c->warning(__tr2qs("Invalid resize mode defaulting to Auto")); + ((QGridLayout *)object())->setResizeMode(r); + return true; + +} + diff --git a/src/modules/objects/class_listview.cpp b/src/modules/objects/class_listview.cpp index 735a55384..2bc889a71 100644 --- a/src/modules/objects/class_listview.cpp +++ b/src/modules/objects/class_listview.cpp @@ -26,7 +26,12 @@ #include "kvi_tal_listview.h" +#ifdef COMPILE_USE_QT4 +#include +#include +#else #include +#endif #include "class_listview.h" #include "kvi_error.h" #include "kvi_debug.h" @@ -351,12 +356,12 @@ bool KviKvsObject_listview::function_setAllColumnsShowFocus(KviKvsObjectFunction bool KviKvsObject_listview::function_hideListViewHeader(KviKvsObjectFunctionCall *c) { - ((KviTalListView *)widget())->header()->hide(); +// ((KviTalListView *)widget())->header()->hide(); return true; } bool KviKvsObject_listview::function_showListViewHeader(KviKvsObjectFunctionCall *c) { - ((KviTalListView *)widget())->header()->show(); +// ((KviTalListView *)widget())->header()->show(); return true; } bool KviKvsObject_listview::function_listViewHeaderIsVisible(KviKvsObjectFunctionCall *c) @@ -519,12 +524,11 @@ KviKvsMdmListView::~KviKvsMdmListView() void KviKvsMdmListView::contentsDragEnterEvent( QDragEnterEvent *e ) { - debug ("DragEnterEvent"); - if ( !QUriDrag::canDecode(e) ) - { - e->ignore(); - return; - } + if ( !KviUriDrag::canDecode(e)) + { + e->ignore(); + return; + } } @@ -532,7 +536,7 @@ void KviKvsMdmListView::contentsDragEnterEvent( QDragEnterEvent *e ) void KviKvsMdmListView::contentsDropEvent(QDropEvent *e) { QStringList list; - if(QUriDrag::decodeLocalFiles(e,list)) + if(KviUriDrag::decodeLocalFiles(e,list)) { if(!list.isEmpty()) { diff --git a/src/modules/objects/class_listview.h b/src/modules/objects/class_listview.h index bd5f749cf..bfccbdd78 100644 --- a/src/modules/objects/class_listview.h +++ b/src/modules/objects/class_listview.h @@ -27,7 +27,7 @@ //================================================================================= #include "kvi_tal_listview.h" -#include +#include "kvi_draganddrop.h" #include "class_widget.h" #include "class_listviewitem.h" diff --git a/src/modules/objects/class_mainwindow.cpp b/src/modules/objects/class_mainwindow.cpp index 7c5224437..90f91731c 100644 --- a/src/modules/objects/class_mainwindow.cpp +++ b/src/modules/objects/class_mainwindow.cpp @@ -21,7 +21,7 @@ // Inc. ,59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // -#include +#include "kvi_tal_mainwindow.h" #include "class_mainwindow.h" #include "kvi_error.h" #include "kvi_debug.h" @@ -68,7 +68,7 @@ KVSO_END_CONSTRUCTOR(KviKvsObject_mainwindow) bool KviKvsObject_mainwindow::init(KviKvsRunTimeContext * pContext,KviKvsVariantList *pParams) { - setObject(new QMainWindow(parentScriptWidget(), name()), true); + setObject(new KviTalMainWindow(parentScriptWidget(), name()), true); return true; } @@ -95,7 +95,7 @@ bool KviKvsObject_mainwindow::functionsetCentralWidget(KviKvsObjectFunctionCall c->warning(__tr2qs("Widget object required")); return TRUE; } - if(widget()) ((QMainWindow *)widget())->setCentralWidget(((QWidget *)(pObject->object()))); + if(widget()) ((KviTalMainWindow *)widget())->setCentralWidget(((QWidget *)(pObject->object()))); return true; } bool KviKvsObject_mainwindow::functionsetDockEnabled(KviKvsObjectFunctionCall *c) @@ -109,19 +109,19 @@ bool KviKvsObject_mainwindow::functionsetDockEnabled(KviKvsObjectFunctionCall *c if(widget()) { if(KviQString::equalCI(szDockarea,"Top")) - ((QMainWindow *)widget())->setDockEnabled(Qt::DockTop,bFlag); + ((KviTalMainWindow *)widget())->setDockEnabled(Qt::DockTop,bFlag); else if(KviQString::equalCI(szDockarea,"Left")) - ((QMainWindow *)widget())->setDockEnabled(Qt::DockLeft,bFlag); + ((KviTalMainWindow *)widget())->setDockEnabled(Qt::DockLeft,bFlag); else if(KviQString::equalCI(szDockarea,"Right")) - ((QMainWindow *)widget())->setDockEnabled(Qt::DockRight,bFlag); + ((KviTalMainWindow *)widget())->setDockEnabled(Qt::DockRight,bFlag); else if(KviQString::equalCI(szDockarea,"Bottom")) - ((QMainWindow *)widget())->setDockEnabled(Qt::DockBottom,bFlag); + ((KviTalMainWindow *)widget())->setDockEnabled(Qt::DockBottom,bFlag); else if(KviQString::equalCI(szDockarea,"Minimized")) - ((QMainWindow *)widget())->setDockEnabled(Qt::DockMinimized,bFlag); + ((KviTalMainWindow *)widget())->setDockEnabled(Qt::DockMinimized,bFlag); else if(KviQString::equalCI(szDockarea,"TornOff")) - ((QMainWindow *)widget())->setDockEnabled(Qt::DockTornOff,bFlag); + ((KviTalMainWindow *)widget())->setDockEnabled(Qt::DockTornOff,bFlag); else if(KviQString::equalCI(szDockarea,"Unmanaged")) - ((QMainWindow *)widget())->setDockEnabled(Qt::DockUnmanaged,bFlag); + ((KviTalMainWindow *)widget())->setDockEnabled(Qt::DockUnmanaged,bFlag); else c->warning(__tr2qs("Unknown dock area '%Q'"),&szDockarea); } return true; @@ -136,13 +136,13 @@ bool KviKvsObject_mainwindow::functionisDockEnabled(KviKvsObjectFunctionCall *c) KVSO_PARAMETER("dock_area",KVS_PT_STRING,0,szDockarea) KVSO_PARAMETERS_END(c) if(!widget()) return true; - if(KviQString::equalCI(szDockarea,"Top")) bFlag=((QMainWindow *)widget())->isDockEnabled(Qt::DockTop); - else if(KviQString::equalCI(szDockarea,"Left")) bFlag=((QMainWindow *)widget())->isDockEnabled(Qt::DockLeft); - else if(KviQString::equalCI(szDockarea,"Right")) bFlag=((QMainWindow *)widget())->isDockEnabled(Qt::DockRight); - else if(KviQString::equalCI(szDockarea,"Bottom"))bFlag=((QMainWindow *)widget())->isDockEnabled(Qt::DockBottom); - else if(KviQString::equalCI(szDockarea,"Minimized")) bFlag=((QMainWindow *)widget())->isDockEnabled(Qt::DockMinimized); - else if(KviQString::equalCI(szDockarea,"TornOff")) bFlag=((QMainWindow *)widget())->isDockEnabled(Qt::DockTornOff); - else if(KviQString::equalCI(szDockarea,"Unmanaged")) bFlag=((QMainWindow *)widget())->isDockEnabled(Qt::DockUnmanaged); + if(KviQString::equalCI(szDockarea,"Top")) bFlag=((KviTalMainWindow *)widget())->isDockEnabled(Qt::DockTop); + else if(KviQString::equalCI(szDockarea,"Left")) bFlag=((KviTalMainWindow *)widget())->isDockEnabled(Qt::DockLeft); + else if(KviQString::equalCI(szDockarea,"Right")) bFlag=((KviTalMainWindow *)widget())->isDockEnabled(Qt::DockRight); + else if(KviQString::equalCI(szDockarea,"Bottom"))bFlag=((KviTalMainWindow *)widget())->isDockEnabled(Qt::DockBottom); + else if(KviQString::equalCI(szDockarea,"Minimized")) bFlag=((KviTalMainWindow *)widget())->isDockEnabled(Qt::DockMinimized); + else if(KviQString::equalCI(szDockarea,"TornOff")) bFlag=((KviTalMainWindow *)widget())->isDockEnabled(Qt::DockTornOff); + else if(KviQString::equalCI(szDockarea,"Unmanaged")) bFlag=((KviTalMainWindow *)widget())->isDockEnabled(Qt::DockUnmanaged); else { c->warning(__tr2qs("Unknown dock area '%Q'"),&szDockarea); diff --git a/src/modules/objects/class_mainwindow.h b/src/modules/objects/class_mainwindow.h index 7ca2cb6a5..c8cb266a2 100644 --- a/src/modules/objects/class_mainwindow.h +++ b/src/modules/objects/class_mainwindow.h @@ -23,7 +23,7 @@ // Inc. ,59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // -#include +//#include #include "class_widget.h" #include "object_macros.h" diff --git a/src/modules/objects/class_multilineedit.cpp b/src/modules/objects/class_multilineedit.cpp index 12d330bd8..c9c7cebfb 100644 --- a/src/modules/objects/class_multilineedit.cpp +++ b/src/modules/objects/class_multilineedit.cpp @@ -26,17 +26,28 @@ #include "kvi_error.h" #include "kvi_debug.h" - #include "kvi_locale.h" #include "kvi_malloc.h" #include - #ifdef COMPILE_USE_QT4 #include - #define KviTalMultiLineEdit Q3MultiLineEdit +#include + +#include +#define KviTalMultiLineEdit Q3MultiLineEdit +#define QTEXTEDIT_AUTO_ALL Q3TextEdit::AutoAll +#define QTEXTEDIT_AUTO_NONE Q3TextEdit::AutoNone +#define QTEXTEDIT_AUTO_BULLET_LIST Q3TextEdit::AutoBulletList + #else + #include + #include #define KviTalMultiLineEdit QMultiLineEdit + #define QTEXTEDIT_AUTO_ALL QTextEdit::AutoAll + #define QTEXTEDIT_AUTO_NONE QTextEdit::AutoNone + #define QTEXTEDIT_AUTO_BULLET_LIST QTextEdit::AutoBulletList + #endif @@ -1070,9 +1081,15 @@ bool KviKvsObject_mledit::functionloadFile(KviKvsObjectFunctionCall *c) QTextStream ts( &file ); QString txt = ts.read(); +#ifdef COMPILE_USE_QT4 + if ( !Q3StyleSheet::mightBeRichText( txt ) ) + txt = Q3StyleSheet::convertFromPlainText( txt, Q3StyleSheetItem::WhiteSpacePre ); +#else if ( !QStyleSheet::mightBeRichText( txt ) ) txt = QStyleSheet::convertFromPlainText( txt, QStyleSheetItem::WhiteSpacePre ); +#endif ((KviTalMultiLineEdit *)widget())->setText( txt ); + file.close(); return true; } @@ -1106,11 +1123,11 @@ bool KviKvsObject_mledit::functionsetAutoFormatting(KviKvsObjectFunctionCall *c) KVSO_PARAMETERS_END(c) if(!widget()) return true; if(KviQString::equalCI(szAutoformatting,"AutoNone")) - ((KviTalMultiLineEdit *)widget())->setAlignment(KviTalMultiLineEdit::AutoNone); + ((KviTalMultiLineEdit *)widget())->setAutoFormatting(QTEXTEDIT_AUTO_NONE); else if(KviQString::equalCI(szAutoformatting,"BulletList")) - ((KviTalMultiLineEdit *)widget())->setAlignment(KviTalMultiLineEdit::AutoBulletList); + ((KviTalMultiLineEdit *)widget())->setAutoFormatting(QTEXTEDIT_AUTO_BULLET_LIST); else if(KviQString::equalCI(szAutoformatting,"AutoAll")) - ((KviTalMultiLineEdit *)widget())->setAlignment(KviTalMultiLineEdit::AutoAll); + ((KviTalMultiLineEdit *)widget())->setAutoFormatting(QTEXTEDIT_AUTO_ALL); else c->warning(__tr2qs("Unknown auto formatting mode '%Q'"),&szAutoformatting); return true; } diff --git a/src/modules/objects/class_painter.cpp b/src/modules/objects/class_painter.cpp index 2b1ebdc67..ae200b704 100644 --- a/src/modules/objects/class_painter.cpp +++ b/src/modules/objects/class_painter.cpp @@ -564,6 +564,7 @@ bool KviKvsObject_painter::functiondrawRect(KviKvsObjectFunctionCall *c) if(m_pPainter) m_pPainter->drawRect(iX,iY,iW,iH); return true; } +// FIX ME: REMOVE functiondrawWinFocusRect bool KviKvsObject_painter::functiondrawWinFocusRect(KviKvsObjectFunctionCall *c) { KviKvsVariant * pXOrArray; @@ -576,7 +577,9 @@ bool KviKvsObject_painter::functiondrawWinFocusRect(KviKvsObjectFunctionCall *c) KVSO_PARAMETERS_END(c) QString function="$drawWinFocusRect"; KVSO_PARAMETERS_PAINTER(pXOrArray,iY,iW,iH) - if(m_pPainter) m_pPainter->drawWinFocusRect(iX,iY,iW,iH); +#ifndef COMPILE_USE_QT4 + if(m_pPainter) m_pPainter->drawWinFocusRect(iX,iY,iW,iH); +#endif return true; } bool KviKvsObject_painter::functiondrawEllipse(KviKvsObjectFunctionCall *c) @@ -820,10 +823,24 @@ bool KviKvsObject_painter::functiondrawText(KviKvsObjectFunctionCall *c) KVSO_PARAMETER("mode",KVS_PT_STRING,0,szMode) KVSO_PARAMETERS_END(c) if(!m_pPainter)return true; +#ifdef COMPILE_USE_QT4 + if (!szMode.isEmpty()){ + if(KviQString::equalCI(szMode,"RTL"))m_pPainter->setLayoutDirection(Qt::RightToLeft); + else if(KviQString::equalCI(szMode,"LTR"))m_pPainter->setLayoutDirection(Qt::LeftToRight); + else + { + c->warning(__tr2qs("Invalid mode '%Q'"),&szMode); + return true; + } + } + m_pPainter->drawText(iX,iY,szText); +#else if(KviQString::equalCI(szMode,"Auto")) m_pPainter->drawText(iX,iY,szText,iLen,QPainter::Auto); else if(KviQString::equalCI(szMode,"RTL")) m_pPainter->drawText(iX,iY,szText,iLen,QPainter::RTL); else if(KviQString::equalCI(szMode,"LTR"))m_pPainter->drawText(iX,iY,szText,iLen,QPainter::LTR); else c->warning(__tr2qs("Invalid mode '%Q'"),&szMode); + +#endif return true; } diff --git a/src/modules/objects/class_process.cpp b/src/modules/objects/class_process.cpp index 5850f2701..11cbacee6 100644 --- a/src/modules/objects/class_process.cpp +++ b/src/modules/objects/class_process.cpp @@ -23,10 +23,14 @@ #include "class_process.h" #include "kvi_error.h" #include "kvi_debug.h" - +#include "kvi_settings.h" #include "kvi_locale.h" #include - +#ifdef COMPILE_USE_QT4 +#include +#else +#include +#endif /* @doc: process @@ -180,7 +184,11 @@ KVSO_BEGIN_REGISTERCLASS(KviKvsObject_process,"process","object") KVSO_BEGIN_CONSTRUCTOR(KviKvsObject_process,KviKvsObject) +#ifdef COMPILE_USE_QT4 + m_pProcess = new Q3Process(); +#else m_pProcess = new QProcess(); +#endif connect(m_pProcess,SIGNAL(readyReadStdout()),this,SLOT(slotReadStdout())); connect(m_pProcess,SIGNAL(readyReadStderr()),this,SLOT(slotReadStderr())); diff --git a/src/modules/objects/class_process.h b/src/modules/objects/class_process.h index 6b66a0908..3259a6a2f 100644 --- a/src/modules/objects/class_process.h +++ b/src/modules/objects/class_process.h @@ -22,12 +22,17 @@ // along with this program. If not, write to the Free Software Foundation, // Inc. ,59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -#include + #include #include "class_widget.h" #include "object_macros.h" +#ifdef COMPILE_USE_QT4 +#include +#else +#include +#endif class KviKvsObject_process : public KviKvsObject @@ -36,7 +41,13 @@ class KviKvsObject_process : public KviKvsObject public: KVSO_DECLARE_OBJECT(KviKvsObject_process) protected: + +#ifdef COMPILE_USE_QT4 + Q3Process * m_pProcess; +#else QProcess * m_pProcess; +#endif + public: bool functionaddArgument(KviKvsObjectFunctionCall *c); diff --git a/src/modules/objects/class_progressbar.cpp b/src/modules/objects/class_progressbar.cpp index cece149a7..05dc045b7 100644 --- a/src/modules/objects/class_progressbar.cpp +++ b/src/modules/objects/class_progressbar.cpp @@ -21,13 +21,19 @@ // Inc. ,59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // -#include #include "class_progressbar.h" #include "kvi_error.h" #include "kvi_debug.h" #include "kvi_locale.h" #include "kvi_iconmanager.h" +#ifdef COMPILE_USE_QT4 +#include +#define KVI_PROGRESS_BAR Q3ProgressBar +#else +#include +#define KVI_PROGRESS_BAR QProgressBar +#endif /* @doc: progressbar @@ -88,9 +94,15 @@ KVSO_BEGIN_DESTRUCTOR(KviKvsObject_progressbar) KVSO_END_CONSTRUCTOR(KviKvsObject_progressbar) bool KviKvsObject_progressbar::init(KviKvsRunTimeContext * pContext,KviKvsVariantList *pParams) -{ - setObject(new QProgressBar(parentScriptWidget(), name()), true); - return true; +{ + #ifdef COMPILE_USE_QT4 + Q3ProgressBar *pbar=new Q3ProgressBar(parentScriptWidget()); + pbar->setObjectName(name()); + setObject(pbar,true); + #else + setObject(new QProgressBar(parentScriptWidget(), name()), true); + #endif +return true; } bool KviKvsObject_progressbar::functionSetProgress(KviKvsObjectFunctionCall *c) @@ -99,7 +111,7 @@ bool KviKvsObject_progressbar::functionSetProgress(KviKvsObjectFunctionCall *c) KVSO_PARAMETERS_BEGIN(c) KVSO_PARAMETER("step_value",KVS_PT_UNSIGNEDINTEGER,0,iProgress) KVSO_PARAMETERS_END(c) - if (widget()) ((QProgressBar *)widget())->setProgress(iProgress); + if (widget()) ((KVI_PROGRESS_BAR *)widget())->setProgress(iProgress); return true; } bool KviKvsObject_progressbar::functionSetTotalSteps(KviKvsObjectFunctionCall *c) @@ -108,13 +120,13 @@ bool KviKvsObject_progressbar::functionSetTotalSteps(KviKvsObjectFunctionCall *c KVSO_PARAMETERS_BEGIN(c) KVSO_PARAMETER("total_steps",KVS_PT_UNSIGNEDINTEGER,0,iSteps) KVSO_PARAMETERS_END(c) - if (widget()) ((QProgressBar *)widget())->setTotalSteps(iSteps); + if (widget()) ((KVI_PROGRESS_BAR *)widget())->setTotalSteps(iSteps); return true; } bool KviKvsObject_progressbar::functionReset(KviKvsObjectFunctionCall *c) { - if (widget()) ((QProgressBar *)widget())->reset(); + if (widget()) ((KVI_PROGRESS_BAR *)widget())->reset(); return true; } @@ -124,12 +136,12 @@ bool KviKvsObject_progressbar::functionSetCenterIndicator(KviKvsObjectFunctionCa KVSO_PARAMETERS_BEGIN(c) KVSO_PARAMETER("bEnabled",KVS_PT_BOOL,0,bFlag) KVSO_PARAMETERS_END(c) - if(widget()) ((QProgressBar *)widget())->setCenterIndicator(bFlag); + if(widget()) ((KVI_PROGRESS_BAR *)widget())->setCenterIndicator(bFlag); return true; } bool KviKvsObject_progressbar::functionCenterIndicator(KviKvsObjectFunctionCall *c) { - if (widget()) c->returnValue()->setBoolean(((QProgressBar *)widget())->centerIndicator()); + if (widget()) c->returnValue()->setBoolean(((KVI_PROGRESS_BAR *)widget())->centerIndicator()); return true; } @@ -140,11 +152,11 @@ bool KviKvsObject_progressbar::functionSetPercentageVisible(KviKvsObjectFunction KVSO_PARAMETER("bEnabled",KVS_PT_BOOL,0,bEnabled) KVSO_PARAMETERS_END(c) if(widget()) - ((QProgressBar *)widget())->setPercentageVisible(bEnabled); + ((KVI_PROGRESS_BAR *)widget())->setPercentageVisible(bEnabled); return true; } bool KviKvsObject_progressbar::functionPercentageVisible(KviKvsObjectFunctionCall *c) { - if (widget()) c->returnValue()->setBoolean(((QProgressBar *)widget())->percentageVisible()); + if (widget()) c->returnValue()->setBoolean(((KVI_PROGRESS_BAR *)widget())->percentageVisible()); return true; } diff --git a/src/modules/objects/class_progressbar.h b/src/modules/objects/class_progressbar.h index 0e4ea3b0d..549487a4a 100644 --- a/src/modules/objects/class_progressbar.h +++ b/src/modules/objects/class_progressbar.h @@ -24,7 +24,7 @@ // Inc. ,59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // -#include +//#include #include "class_widget.h" #include "object_macros.h" diff --git a/src/modules/objects/class_socket.cpp b/src/modules/objects/class_socket.cpp index 09bc0fb57..b180f43cd 100644 --- a/src/modules/objects/class_socket.cpp +++ b/src/modules/objects/class_socket.cpp @@ -1,1316 +1,1317 @@ -// -// File : class_socket.cpp -// Creation date : Sun Nov 11 03:13:45 2001 GMT by Szymon Stefanek -// -// This file is part of the KVirc irc client distribution -// Copyright (C) 2001 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. ,59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// - -#include "kvi_settings.h" - -#define _KVI_DEBUG_CHECK_RANGE_ -#include "kvi_debug.h" - - -#include "kvi_locale.h" -#include "kvi_error.h" -#include "kvi_netutils.h" -#include "kvi_dns.h" -#include "kvi_error.h" -#include "kvi_socket.h" -#include "kvi_malloc.h" -#include "kvi_memmove.h" -#include "kvi_databuffer.h" - -#include "class_socket.h" - -//#include - -#define KVI_IN_BUFFER_ALLOC_CHUNK 4096 -#define KVI_READ_CHUNK 1024 -/* -static KviScriptObjectClass * g_pSocketClass = 0; - -static KviScriptObject * socketClassCreateInstance(KviScriptObjectClass * cls,KviScriptObject *par,const char * nam) -{ - return new KviScriptSocketObject(cls,par,nam); -} - -KviScriptSocketObject::KviScriptSocketObject(KviScriptObjectClass * cla,KviScriptObject * par,const char * nam) -: KviScriptObject(cla,par,nam) -{ - m_uConnectionId = 0; - m_sock = KVI_INVALID_SOCKET; - m_iStatus = KVI_SCRIPT_SOCKET_STATUS_DISCONNECTED; - m_uRemotePort = 0; - m_uSecondaryPort = 0; - m_pSn = 0; - m_pDns = 0; - m_pDelayTimer = 0; - m_uConnectTimeout = 60000; - m_pInBuffer = 0; - m_uInBufferLen = 0; - m_uInDataLen = 0; - m_pOutBuffer = new KviDataBuffer(); - m_pFlushTimer = new QTimer(); - m_bIpV6 = false; - m_uLocalPort = 0; - m_secondarySock = KVI_INVALID_SOCKET; - connect(m_pFlushTimer,SIGNAL(timeout()),this,SLOT(tryFlush())); -} - -KviScriptSocketObject::~KviScriptSocketObject() -{ - delete m_pOutBuffer; - delete m_pFlushTimer; - - if(m_pInBuffer)kvi_free(m_pInBuffer); - if(m_pDelayTimer)delete m_pDelayTimer; - if(m_pDns)delete m_pDns; - if(m_pSn)delete m_pSn; - if(m_sock != KVI_INVALID_SOCKET)kvi_socket_close(m_sock); - if(m_secondarySock != KVI_INVALID_SOCKET)kvi_socket_close(m_secondarySock); -} - -void KviScriptSocketObject::reset() -{ - m_uConnectionId++; // this is the only place where this is incremented! - if(m_pDelayTimer) - { - delete m_pDelayTimer; - m_pDelayTimer = 0; - } - if(m_pDns) - { - delete m_pDns; - m_pDns = 0; - } - if(m_pSn) - { - delete m_pSn; - m_pSn = 0; - } - if(m_sock != KVI_INVALID_SOCKET) - { - kvi_socket_close(m_sock); - m_sock = KVI_INVALID_SOCKET; - } - if(m_pInBuffer) - { - kvi_free(m_pInBuffer); - m_pInBuffer = 0; - } - if(m_secondarySock) - { - kvi_socket_close(m_secondarySock); - m_secondarySock = KVI_INVALID_SOCKET; - } - m_uSecondaryPort = 0; - m_szSecondaryIp.clear(); - delete m_pOutBuffer; - if(m_pFlushTimer->isActive())m_pFlushTimer->stop(); - m_pOutBuffer = new KviDataBuffer(); - m_uInBufferLen = 0; - m_uInDataLen = 0; - m_iStatus = KVI_SCRIPT_SOCKET_STATUS_DISCONNECTED; - m_uRemotePort = 0; - m_szRemoteIp.clear(); - m_uLocalPort = 0; - m_szLocalIp.clear(); - m_bIpV6 = false; -} - -/* - @doc: socket - @keyterms: - socket object class - @title: - socket class - @type: - class - @short: - A Ipv4/Ipv6 TCP socket - @inherits: - [class]object[/class] - @description: - This class provides a standard TCP/IP socket functionality.[br] - It can be used either for connecting to a remote host or to listening for incoming connections.[br] - If the KVIrc executable has been compiled with the IPV6 protocol support , this socket also supports it.[br] - @functions: - !fn: $status() - Returns the status of the socket :[br] - 4=connected[br] - 3=listening[br] - 2=connecting[br] - 1=in dns call[br] - 0=disconnected - - !fn: $connectTimeout() - Returns the value of the connect attempt timeout in milliseconds.[br] - This is the timeout after that a connection attempt will be considered as failed if the remote - host is not responding. You can set it with [classfnc:socket]$setConnectTimeout[/classfnc](). - - !fn: $setConnectTimeout() - Sets the connect timeout for this socket. must be a positive value in milliseconds.[br] - The default timeout is 60000. - - !fn: $connect(,) - Attempts a connection to on port .[br] - can be a numeric internet address (either Ipv4 or Ipv6 (if supported)) or a hostname.[br] - If a hostname is used, a DNS lookup is performed (the socket enters the "dns call" state).[br] - This function returns 1 if the connect attempt can be succesfully initiated, - 0 otherwise.[br] In fact , this function returns 0 only if the supplied parameter - is invalid or the socket is in an incoherent state (already connected or listening): - for a newly created socket and with a valid number you can safely ignore - the return value.[br] - Please note that the connection is asynchronous: when this function returns - the socket is NOT connected: it has just initiated the connect attempt - and you will be notified of the attempt result by an asynchronous event call: - in case of failure , $connectFailedEvent() will be called , in case of - succes , $connectEvent() will be called. - - !fn: $listen([[,[,]]]) - Attempts to listen on the specified and .[br] - If is not passed it is assumed to be 0 , if is not passed , it is assumed to be - "any interface" (INADDR_ANY).[br] Port 0 means that the kernel should choose a "random" port to listen on.[br] - If the is recognized as IPV6 address , and IPV6 is supported , the socket listens - in IPV6 mode. If is an empty string and is 1 the socket listens - on "any ipv6 interface".[br] - This function returns '1' in case of success and '0' in case of failure.[br] - On some systems listening in the IPV6 namespace allows to accept also IPV4 connections (this includes - linux but not windows afaik).[br] - When an incoming connection will arrive , $incomingConnectionEvent() will be called. - - !fn: $accept() - This function can be called only from inside $incomingConnectionEvent().[br] - must be a newly created socket sub-class instance object.[br] - The passed object will be set up to handle the incoming connection and this object - will remain in listening state (unless you explicitly close it).[br] - This function returns '1' in case of success and '0' in case of failure. - - !fn: $connectEvent() - This function is called when a connection attempt has been succesfully completed. - The socket is actually connected to [classfnc:socket]$remoteIp[/classfnc]() on - [classfnc:socket]$remotePort[/classfnc](). You can start - writing data and you may expect [classfnc:socket]$dataAvailableEvent[/classfnc]() to be - triggered. - - !fn: $incomingConnectionEvent() - This function is called when an incoming connection arrives over a socket in listening state.[br] - You must call [classfnc:socket]$accept[/classfnc]() passing a newly created socket object - to accept and handle the connection.[br] If you don't call [classfnc:socket]$accept[/classfnc]() - the incoming connection will be automatically terminated. - - !fn: $connectFailedEvent() - This function is called when a connection attempt fails for some reason. contains - the error string.[br] - This function may be called only between a call to [classfnc:socket]$connect[/classfnc]() and - the [classfnc:socket]$connectEvent[/classfnc](). - - !fn: $disconnectEvent([error]) - This function is called when a connection is terminated either cleanly or because of an error.[br] - [error] is an empty string in case of a "clean" termination (connection closed by the remote host) - or is a message describing the socket error that caused the connection to be interrupted. - - !fn: $dataAvailableEvent() - This function is called when some data is available to be read: the parameter specifies - the length of the available data in bytes.[br] - You can use one of the $read* functions to obtain the data. - - !fn: $read() - Reads at most bytes of data from the socket. If is anything "outside" the - available data range ( < 0 or > available_data_length), this function - returns all the available data.[br] - Please note that this function can't deal withi binary data: NULL characters are transformed to - ASCII characters 255. - - !fn: $readHex() - Reads at most bytes of data from the socket. If is anything "outside" the - available data range ( < 0 or > available_data_length), this function - returns all the available data.[br] - Returns the data encoded as hexadecimal digit string: this function can deal with binary data too. - - !fn: $write() - Writes to the socket.[br] - This function can't deal with binary data (you can't send a NULL character)[br] - Please note that when this function finishes it does not mean that the data has reached the remote end.[br] - Basically it does not even mean that the data has been sent to the remote host.[br] - The data is enqueued for sending and will be sent as soon as possible.[br] - If you're going to [cmd]delete[/cmd] this object just after the $write call, you should - call [classfnc:socket]$close[/classfnc]() just before [cmd]delete[/cmd] to ensure the data delivery. - - !fn: $writeHex() - Writes to the socket.[br] - is expected to be a hexadecimal rappresentation of the bytes to be sent (two HEX characters - for each byte). This means that the length of string must be a multiple of 2.[br] - Returns the length of the actually decoded and sent data in bytes or -1 in case of error (the string - was not a valid hexadecimla rappresentation).[br] - Please note that when this function finishes it does not mean that the data has reached the remote end.[br] - Basically it does not even mean that the data has been sent to the remote host.[br] - The data is enqueued for sending and will be sent as soon as possible.[br] - If you're going to [cmd]delete[/cmd] this object just after the $writeHex call, you should - call [classfnc:socket]$close[/classfnc]() just before [cmd]delete[/cmd] to ensure the data delivery. - - !fn: $close() - Resets this socket state: kills any pending or active connection. After a close() call - the socket may be used for a new connection.[br] - If there is an active connection, there is a last attempt to flush the pending outgoing data.[br] - You don't need to call $close() if you [cmd]delete[/cmd] the socket: KVIrc will - reset the socket state automatically and free the memory. But if you want to ensure data delivery - after a $write call sequece and just before a [cmd]delete[/cmd], $close() is the only chance to do it. - - !fn: $remoteIp() - Returns the IP address of the remote end of this socket.[br] - The return value is meaningful only if the socket is in connected or connecting state. - - !fn: $remotePort() - Returns the port of the remote end of this socket.[br] - The return value is meaningful only if the socket is in connected or connecting state. - - !fn: $localIp() - Returns the IP address of the local end of this socket.[br] - The return value is meaningful only if the socket is in connected , listening or connecting state. - - !fn: $localPort() - Returns the port of the local end of this socket.[br] - The return value is meaningful only if the socket is in connected , listening or connecting state. - -@examples: - [example] - #Server socket: listen 80 port and answer to requests (multi-threaded)[br] -[br] - class (webserver,socket) {[br] - constructor () {[br] - $$->$listen(80, "127.0.0.1")[br] - }[br] - incomingConnectionEvent()[br] - {[br] - %tmp = $new(socket)[br] - $$->$accept(%tmp)[br] - echo "Webserver incoming Conection from: %tmp->$remoteIp : %tmp->$remotePort"[br] - %tmp->$write("HTTP/1.1 200 OK\n\n

KVIrc Webserver

\n")[br] - %tmp->$close()[br] - delete %tmp[br] - }[br] - }[br] - [br] - #finally start webserver[br] - %WebS = $new(webserver)[br] - [br] - [/example] - [example] - #Client socket - go to google and grab request header[br] - class (httprequest,socket) {[br] - constructor () [br] - {[br] - # connect to the server[br] - $$->$connect("www.google.de",80)[br] - }[br] - destructor()[br] - {[br] - # if the socket is still open close it[br] - if($$->$status() == 4) $$->$close()[br] - }[br] - connectFailedEvent() [br] - {[br] - # the connection to the server failed[br] - echo "Connection failed: "$0[br] - delete $$[br] - }[br] - connectEvent() [br] - {[br] - # connection is complete[br] - # send a request to receive the headers only from http://www.google.de/[br] - $$->$write("HEAD / HTTP/1.1\r\nHost: www.google.de\r\nConnction: Close\r\nUser-Agent: KVIrc socket\r\n\r\n");[br] - }[br] - dataAvailableEvent() [br] - {[br] - # reading the received data[br] - %newdata = $$->$read($0)[br] - echo %newdata[br] - #close and delete the socket[br] - $$->$close()[br] - delete $$[br] - }[br] - disconnectEvent() [br] - {[br] - # connection has been closed[br] - echo "Connection closed"[br] - delete $$[br] - }[br] -}[br] - -#Creating the socket[br] -%Temp = $new(httprequest)[br] - [/example] -*/ - -KVSO_BEGIN_REGISTERCLASS(KviKvsObject_socket,"socket","object") - - KVSO_REGISTER_HANDLER(KviKvsObject_socket,"status",functionStatus) - KVSO_REGISTER_HANDLER(KviKvsObject_socket,"remotePort",functionRemotePort) - KVSO_REGISTER_HANDLER(KviKvsObject_socket,"remoteIp",functionRemoteIp) - KVSO_REGISTER_HANDLER(KviKvsObject_socket,"localIp",functionLocalIp) - KVSO_REGISTER_HANDLER(KviKvsObject_socket,"localPort",functionLocalPort) - KVSO_REGISTER_HANDLER(KviKvsObject_socket,"connect",functionConnect) - KVSO_REGISTER_HANDLER(KviKvsObject_socket,"connectTimeout",functionConnectTimeout) - KVSO_REGISTER_HANDLER(KviKvsObject_socket,"setConnectTimeout",functionSetConnectTimeout) - KVSO_REGISTER_HANDLER(KviKvsObject_socket,"close",functionClose) - KVSO_REGISTER_HANDLER(KviKvsObject_socket,"read",functionRead) - KVSO_REGISTER_HANDLER(KviKvsObject_socket,"readHex",functionReadHex) - KVSO_REGISTER_HANDLER(KviKvsObject_socket,"write",functionWrite) - KVSO_REGISTER_HANDLER(KviKvsObject_socket,"writeHex",functionWriteHex) - KVSO_REGISTER_HANDLER(KviKvsObject_socket,"listen",functionListen) - KVSO_REGISTER_HANDLER(KviKvsObject_socket,"accept",functionAccept) - - KVSO_REGISTER_STANDARD_NOTHINGRETURN_HANDLER(KviKvsObject_socket,"connectEvent") - KVSO_REGISTER_STANDARD_NOTHINGRETURN_HANDLER(KviKvsObject_socket,"connectFailedEvent") - KVSO_REGISTER_STANDARD_NOTHINGRETURN_HANDLER(KviKvsObject_socket,"disconnectEvent") - KVSO_REGISTER_STANDARD_NOTHINGRETURN_HANDLER(KviKvsObject_socket,"dataAvailableEvent") - KVSO_REGISTER_STANDARD_NOTHINGRETURN_HANDLER(KviKvsObject_socket,"incomingConnectionEvent") - -KVSO_END_REGISTERCLASS(KviKvsObject_socket) - - -KVSO_BEGIN_CONSTRUCTOR(KviKvsObject_socket,KviKvsObject) - - - - m_uConnectionId = 0; - m_sock = KVI_INVALID_SOCKET; - m_iStatus = KVI_SCRIPT_SOCKET_STATUS_DISCONNECTED; - m_uRemotePort = 0; - m_uSecondaryPort = 0; - m_pSn = 0; - m_pDns = 0; - m_pDelayTimer = 0; - m_uConnectTimeout = 60000; - m_pInBuffer = 0; - m_uInBufferLen = 0; - m_uInDataLen = 0; - m_pOutBuffer = new KviDataBuffer(); - m_pFlushTimer = new QTimer(); - m_bIpV6 = false; - m_uLocalPort = 0; - m_secondarySock = KVI_INVALID_SOCKET; - connect(m_pFlushTimer,SIGNAL(timeout()),this,SLOT(tryFlush())); -KVSO_END_CONSTRUCTOR(KviKvsObject_socket) - -KVSO_BEGIN_DESTRUCTOR(KviKvsObject_socket) - delete m_pOutBuffer; - delete m_pFlushTimer; - - if(m_pInBuffer)kvi_free(m_pInBuffer); - if(m_pDelayTimer)delete m_pDelayTimer; - if(m_pDns)delete m_pDns; - if(m_pSn)delete m_pSn; - if(m_sock != KVI_INVALID_SOCKET)kvi_socket_close(m_sock); - if(m_secondarySock != KVI_INVALID_SOCKET)kvi_socket_close(m_secondarySock); -KVSO_END_DESTRUCTOR(KviKvsObject_socket) -//---------------------- - - -bool KviKvsObject_socket::functionStatus(KviKvsObjectFunctionCall *c) -{ - c->returnValue()->setInteger(m_iStatus); - return true; -} - -bool KviKvsObject_socket::functionClose(KviKvsObjectFunctionCall *c) -{ - if((m_pOutBuffer->size() != 0) && (m_iStatus == KVI_SCRIPT_SOCKET_STATUS_CONNECTED)) - tryFlush(); - - reset(); - return true; -} - -bool KviKvsObject_socket::functionConnectTimeout(KviKvsObjectFunctionCall *c) -{ - c->returnValue()->setInteger(m_uConnectTimeout); - return true; -} - -bool KviKvsObject_socket::functionSetConnectTimeout(KviKvsObjectFunctionCall *c) -{ - kvs_uint_t uTimeout; - KVSO_PARAMETERS_BEGIN(c) - KVSO_PARAMETER("time_out",KVS_PT_UNSIGNEDINTEGER,0,uTimeout) - KVSO_PARAMETERS_END(c) - m_uConnectTimeout = uTimeout; - return true; -} - -bool KviKvsObject_socket::functionRemotePort(KviKvsObjectFunctionCall *c) -{ - c->returnValue()->setInteger(m_uRemotePort); - return true; -} - -bool KviKvsObject_socket::functionRemoteIp(KviKvsObjectFunctionCall *c) -{ - c->returnValue()->setString(m_szRemoteIp); - return true; -} - -bool KviKvsObject_socket::functionLocalPort(KviKvsObjectFunctionCall *c) -{ - c->returnValue()->setInteger(m_uLocalPort); - return true; -} - -bool KviKvsObject_socket::functionLocalIp(KviKvsObjectFunctionCall *c) -{ - c->returnValue()->setString(m_szLocalIp); - return true; -} - -bool KviKvsObject_socket::functionAccept(KviKvsObjectFunctionCall *c) -{ - KviKvsObject * pObject; - kvs_hobject_t hObject; - KVSO_PARAMETERS_BEGIN(c) - KVSO_PARAMETER("object_socket",KVS_PT_HOBJECT,0,hObject) - KVSO_PARAMETERS_END(c) - - pObject = KviKvsKernel::instance()->objectController()->lookupObject(hObject); - - if(!pObject) - { - c->warning(__tr2qs("No socket object specified")); - return true; - } - - if(!pObject->inherits("KviKvsObject_socket")) - { - c->warning(__tr2qs("Invalid socket object specified (it doesn't inherit from socket)")); - return true; - } - - if(m_secondarySock != KVI_INVALID_SOCKET) - { - ((KviKvsObject_socket *)pObject)->acceptConnection(m_secondarySock,m_uSecondaryPort,m_szSecondaryIp); - - m_secondarySock = KVI_INVALID_SOCKET; - m_uSecondaryPort = 0; - m_szSecondaryIp=""; - } else { - c->warning(__tr2qs("There is no connection to accept!")); - } - return true; -} - - - - -bool KviKvsObject_socket::functionWriteHex(KviKvsObjectFunctionCall *c) -{ - QString m_szHex; - KVSO_PARAMETERS_BEGIN(c) - KVSO_PARAMETER("hex_string",KVS_PT_STRING,0,m_szHex) - KVSO_PARAMETERS_END(c) - - if(m_szHex.length() > 0) - { - bool bOk; - QString szTmp; - szTmp=m_szHex.setNum(m_szHex.toInt(&bOk,16),16); - if(szTmp.length()>0) - { - QCString szData8 = szTmp.utf8(); - m_pOutBuffer->append((const unsigned char *)(szData8.data()),szData8.length()); - delayedFlush(0); - c->returnValue()->setInteger(szData8.length()); - } - } - - /* - if(pszData) - { - if(pszData->len() > 0) - { - char * ptr; - len = pszData->hexToBuffer(&ptr); - if(len > 0) - { - m_pOutBuffer->append((const unsigned char *)(ptr),len); - delayedFlush(0); - KviStr::freeBuffer(ptr); - } - } - } - buffer.append(KviStr::Format,"%d",len); -*/ - return true; -} - - - - - -bool KviKvsObject_socket::functionConnect(KviKvsObjectFunctionCall *c) -{ - KVSO_PARAMETERS_BEGIN(c) - KVSO_PARAMETER("remote_ip",KVS_PT_STRING,0,m_szRemoteIp) - KVSO_PARAMETER("remote_port",KVS_PT_UNSIGNEDINTEGER,0,m_uRemotePort) - KVSO_PARAMETERS_END(c) - debug ("Function connect"); - - - if (m_uRemotePort>65535) - { - c->warning(__tr2qs("Value %d for port is out of range (values allowed are from 0 to 65535"),m_uRemotePort); - return true; - } - if((m_sock != KVI_INVALID_SOCKET) || (m_iStatus != KVI_SCRIPT_SOCKET_STATUS_DISCONNECTED)) - { - c->warning(__tr2qs("Another connection in progress")); - c->returnValue()->setBoolean(true); - return true; - } - - -#ifdef COMPILE_IPV6_SUPPORT - if(kvi_isValidStringIp(m_szRemoteIp) || kvi_isValidStringIp_V6(m_szRemoteIp)) -#else - if(kvi_isValidStringIp(m_szRemoteIp)) -#endif - { - debug ("ok connecting"); - debug ("connectinhg on ip %s ",m_szRemoteIp.latin1()); - debug ("non so ip"); - m_iStatus = KVI_SCRIPT_SOCKET_STATUS_CONNECTING; - delayedConnect(); - } else { - debug ("connectinhg on ip %s port %d",m_szRemoteIp.latin1(),m_uRemotePort); - m_iStatus = KVI_SCRIPT_SOCKET_STATUS_DNS; - delayedLookupRemoteIp(); - } - c->returnValue()->setBoolean(true); - return true; -} - - - - - - -bool KviKvsObject_socket::functionListen(KviKvsObjectFunctionCall *c) -{ - if((m_sock != KVI_INVALID_SOCKET) || (m_iStatus != KVI_SCRIPT_SOCKET_STATUS_DISCONNECTED)) - { - c->warning(__tr2qs("Another connection in progress")); - c->returnValue()->setBoolean(false); - return true; - } - kvs_uint_t uLocalPort; - QString m_szLocalIp; - bool m_bIpV6; - KVSO_PARAMETERS_BEGIN(c) - KVSO_PARAMETER("local_port",KVS_PT_UNSIGNEDINTEGER,0,uLocalPort) - KVSO_PARAMETER("local_ip",KVS_PT_STRING,KVS_PF_OPTIONAL,m_szLocalIp) - KVSO_PARAMETER("bool_ipV6",KVS_PT_BOOLEAN,KVS_PF_OPTIONAL,m_bIpV6) - KVSO_PARAMETERS_END(c) - m_uLocalPort=uLocalPort; - -#ifndef COMPILE_IPV6_SUPPORT - if(m_bIpV6) - { - c->warning(__tr2qs("No IPV6 support in this executable")); - c->returnValue()->setBoolean(false); - reset(); - return true; - } -#endif - - bool bGotIp = false; - - if(!m_szLocalIp.isEmpty()) - { - - // Check the address type - if(kvi_isValidStringIp(m_szLocalIp))bGotIp = true; - else { -#ifdef COMPILE_IPV6_SUPPORT - if(kvi_isValidStringIp_V6(m_szLocalIp)) - { - bGotIp = true; - m_bIpV6 = true; - } else { -#else - c->warning(__tr2qs("Invalid IP address specified ('%Q')"),&m_szLocalIp); - c->returnValue()->setBoolean(false); - reset(); - return true; -#endif -#ifdef COMPILE_IPV6_SUPPORT - } -#endif - } - } - - -#ifdef COMPILE_IPV6_SUPPORT - m_sock = kvi_socket_create(m_bIpV6 ? KVI_SOCKET_PF_INET6 : KVI_SOCKET_PF_INET, - KVI_SOCKET_TYPE_STREAM,KVI_SOCKET_PROTO_TCP); -#else - m_sock = kvi_socket_create(KVI_SOCKET_PF_INET,KVI_SOCKET_TYPE_STREAM,KVI_SOCKET_PROTO_TCP); -#endif - - if(m_sock == KVI_INVALID_SOCKET) - { - c->warning(__tr2qs("Socket creation failed")); - c->returnValue()->setBoolean(false); - reset(); - return true; - } - - if(!m_szLocalIp.isEmpty()) - { -#ifdef COMPILE_IPV6_SUPPORT - KviSockaddr sa(m_szLocalIp,m_uLocalPort,m_bIpV6); -#else - KviSockaddr sa(m_szLocalIp,m_uLocalPort,false); -#endif - if(!sa.socketAddress()) - { - c->warning(__tr2qs("Invalid socket address")); - reset(); - c->returnValue()->setBoolean(false); - return true; - } - - if(!kvi_socket_bind(m_sock,sa.socketAddress(),((int)(sa.addressLength())))) - { - c->warning(__tr2qs("Bind failure")); - reset(); - c->returnValue()->setBoolean(false); - return true; - } - } else { -#ifdef COMPILE_IPV6_SUPPORT - KviSockaddr sa(m_uLocalPort,m_bIpV6); -#else - KviSockaddr sa(m_uLocalPort,false); -#endif - if(!sa.socketAddress()) - { - c->warning(__tr2qs("Invalid socket address")); - reset(); - c->returnValue()->setBoolean(false); - return true; - } - - if(!kvi_socket_bind(m_sock,sa.socketAddress(),((int)(sa.addressLength())))) - { - c->warning(__tr2qs("Bind failure")); - reset(); - c->returnValue()->setBoolean(false); - return true; - } - } - - - if(!kvi_socket_listen(m_sock,5)) - { - c->warning(__tr2qs("Listen failure")); - reset(); - c->returnValue()->setBoolean(false); - return true; - } - - - // Reread the port in case we're binding to a random one (0) - -#ifdef COMPILE_IPV6_SUPPORT - KviSockaddr sareal(0,m_bIpV6); -#else - KviSockaddr sareal(0,false); -#endif - - int size = (int)sareal.addressLength(); - - if(kvi_socket_getsockname(m_sock,sareal.socketAddress(),&size)) - { - m_uLocalPort = sareal.port(); - sareal.getStringAddress(m_szLocalIp); - } - - // and setup the READ notifier... - m_pSn = new QSocketNotifier(m_sock,QSocketNotifier::Read); - QObject::connect(m_pSn,SIGNAL(activated(int)),this,SLOT(incomingConnection(int))); - m_pSn->setEnabled(true); - - m_iStatus = KVI_SCRIPT_SOCKET_STATUS_LISTENING; - - c->returnValue()->setBoolean(true); - return true; -} - -void KviKvsObject_socket::incomingConnection(int) -{ -#ifdef COMPILE_IPV6_SUPPORT - struct sockaddr_in6 hostSockAddr6; -#endif - struct sockaddr_in hostSockAddr; - - int size = sizeof(hostSockAddr); - struct sockaddr * addr = (struct sockaddr *)&hostSockAddr; - -#ifdef COMPILE_IPV6_SUPPORT - if(m_bIpV6) - { - addr = (struct sockaddr *)&hostSockAddr6; - size = sizeof(hostSockAddr6); - } -#endif - - // Incoming connection - m_secondarySock = kvi_socket_accept(m_sock,addr,&size); - if(m_secondarySock != KVI_INVALID_SOCKET) - { - // Connected -#ifdef COMPILE_IPV6_SUPPORT - if(m_bIpV6) - { - m_uSecondaryPort = ntohs(((struct sockaddr_in6 *)addr)->sin6_port); - if(!kvi_binaryIpToStringIp_V6(((struct sockaddr_in6 *)addr)->sin6_addr,m_szSecondaryIp)) - m_szSecondaryIp = __tr("unknown"); - } else { -#endif - m_uSecondaryPort = ntohs(((struct sockaddr_in *)addr)->sin_port); - if(!kvi_binaryIpToStringIp(((struct sockaddr_in *)addr)->sin_addr,m_szSecondaryIp)) - m_szSecondaryIp = __tr("unknown"); -#ifdef COMPILE_IPV6_SUPPORT - } -#endif - KviKvsVariantList *params=0; - callFunction(this,"incomingConnectionEvent",params); - if(m_secondarySock != KVI_INVALID_SOCKET) - { - kvi_socket_close(m_secondarySock); - m_secondarySock = KVI_INVALID_SOCKET; - m_uSecondaryPort = 0; - m_szSecondaryIp=""; - } - - } // else..huh ?... wait for the next notifier call -} - -void KviKvsObject_socket::acceptConnection(kvi_socket_t s,kvi_u32_t uPort,const char * szIp) -{ - reset(); - m_sock = s; - m_uRemotePort = uPort; - m_szRemoteIp = szIp; -#ifdef COMPILE_IPV6_SUPPORT - KviSockaddr sareal(0,m_bIpV6); -#else - KviSockaddr sareal(0,false); -#endif - - int size = (int)sareal.addressLength(); - - if(kvi_socket_getsockname(m_sock,sareal.socketAddress(),&size)) - { - m_uLocalPort = sareal.port(); - sareal.getStringAddress(m_szLocalIp); - } - - m_iStatus = KVI_SCRIPT_SOCKET_STATUS_CONNECTED; - - m_pSn = new QSocketNotifier((int)m_sock,QSocketNotifier::Read); - QObject::connect(m_pSn,SIGNAL(activated(int)),this,SLOT(readNotifierFired(int))); - m_pSn->setEnabled(true); -} - -void KviKvsObject_socket::delayedConnect() -{ - if(m_pDelayTimer)delete m_pDelayTimer; - m_pDelayTimer = new QTimer(); - connect(m_pDelayTimer,SIGNAL(timeout()),this,SLOT(doConnect())); - m_pDelayTimer->start(0,true); -} - -void KviKvsObject_socket::doConnect() -{ - debug ("doConnect function"); - if(m_pDelayTimer)delete m_pDelayTimer; - m_pDelayTimer = 0; - - - KviSockaddr sa(m_szRemoteIp,m_uRemotePort,!kvi_isValidStringIp(m_szRemoteIp)); - - if(!sa.socketAddress()) - { - unsigned int uOldConnectionId = m_uConnectionId; - QString ipAddressError=__tr2qs("Invalid ip address "); - - ipAddressError.append(m_szRemoteIp); - - KviKvsVariantList params; - QString tmp; - KviQString::sprintf(tmp,__tr2qs("Invalid ip address (%Q)"),&m_szRemoteIp); - params.append(new KviKvsVariant(tmp)); - callFunction(this,"connectFailedEvent",¶ms); - /* callEventFunction("connectFailedEvent",0,new KviParameterList( - new KviStr(KviStr::Format,__tr("Invalid ip address (%s)"),m_szRemoteIp.ptr()))); - */ if(m_uConnectionId == uOldConnectionId)reset(); - // else it has already been called! - return; - } -debug ("Socket created"); - - // create the socket -#ifdef COMPILE_IPV6_SUPPORT - m_bIpV6 = sa.isIpV6(); - m_sock = kvi_socket_create(sa.isIpV6() ? KVI_SOCKET_PF_INET6 : KVI_SOCKET_PF_INET,KVI_SOCKET_TYPE_STREAM,KVI_SOCKET_PROTO_TCP); -#else - m_bIpV6 = false; - m_sock = kvi_socket_create(KVI_SOCKET_PF_INET,KVI_SOCKET_TYPE_STREAM,KVI_SOCKET_PROTO_TCP); -#endif - - if(m_sock == KVI_INVALID_SOCKET) - { - unsigned int uOldConnectionId = m_uConnectionId; - callFunction(this,"connectFailedEvent",new KviKvsVariantList( - new KviKvsVariant(__tr2qs("Failed to create the socket")))); - if(m_uConnectionId == uOldConnectionId)reset(); - // else it has already been called! - return; - } - debug ("Valid socket"); - - if(!kvi_socket_setNonBlocking(m_sock)) - { - unsigned int uOldConnectionId = m_uConnectionId; - - callFunction(this,"connectFailedEvent",new KviKvsVariantList( - new KviKvsVariant(__tr2qs("Failed to setup a nonblocking socket")))); - if(m_uConnectionId == uOldConnectionId)reset(); - // else it has already been called! - return; - } - - if(!kvi_socket_connect(m_sock,sa.socketAddress(),((int)(sa.addressLength())))) - { - int err = kvi_socket_error(); - if(!kvi_socket_recoverableConnectError(err)) - { - // Ops... - int sockError=err; - if(sockError==0) - { - // Zero error ?...let's look closer - int iSize=sizeof(int); - if(!kvi_socket_getsockopt(m_sock,SOL_SOCKET,SO_ERROR, - (void *)&sockError,&iSize))sockError=0; - } - unsigned int uOldConnectionId = m_uConnectionId; - QString callBackError=__tr2qs("Connect failure: "); - - callBackError.append((KviError::getDescription(KviError::translateSystemError(sockError)).utf8().data())); - callFunction(this,"connectFailedEvent",new KviKvsVariantList( - new KviKvsVariant(callBackError))); - -/* callEventFunction("connectFailedEvent",0,new KviParameterList( - new KviStr(KviStr::Format,__tr("Connect failure: %s"),KviError::getDescription(KviError::translateSystemError(sockError)).utf8().data()))); -*/ if(m_uConnectionId == uOldConnectionId)reset(); - // else it has already been called! - return; - } - } - debug ("Socket connected"); - m_pDelayTimer = new QTimer(); - connect(m_pDelayTimer,SIGNAL(timeout()),this,SLOT(connectTimeout())); - m_pDelayTimer->start(m_uConnectTimeout,true); - - m_pSn = new QSocketNotifier((int)m_sock,QSocketNotifier::Write); - QObject::connect(m_pSn,SIGNAL(activated(int)),this,SLOT(writeNotifierFired(int))); - m_pSn->setEnabled(true); -} - -void KviKvsObject_socket::connectTimeout() -{ - unsigned int uOldConnectionId = m_uConnectionId; - - callFunction(this,"connectFailedEvent",new KviKvsVariantList( - new KviKvsVariant(__tr2qs("Connect attempt timed out")))); - if(m_uConnectionId == uOldConnectionId)reset(); - // else it has already been called! -} - -void KviKvsObject_socket::delayedLookupRemoteIp() -{ - if(m_pDelayTimer)delete m_pDelayTimer; - m_pDelayTimer = new QTimer(); - connect(m_pDelayTimer,SIGNAL(timeout()),this,SLOT(lookupRemoteIp())); - m_pDelayTimer->start(0,true); -} - -void KviKvsObject_socket::lookupRemoteIp() -{ - debug ("Resolve dns"); - if(m_pDelayTimer)delete m_pDelayTimer; - m_pDelayTimer = 0; - if(m_pDns)delete m_pDns; - m_pDns = new KviDns(); - connect(m_pDns,SIGNAL(lookupDone(KviDns *)),this,SLOT(lookupDone(KviDns *))); - if(!m_pDns->lookup(m_szRemoteIp,KviDns::Any)) - { - unsigned int uOldConnectionId = m_uConnectionId; - - callFunction(this,"connectFailedEvent",new KviKvsVariantList( - new KviKvsVariant(__tr2qs("Can't start the DNS thread")))); - if(m_uConnectionId == uOldConnectionId)reset(); - // else it has already been called! - } -} - -void KviKvsObject_socket::lookupDone(KviDns *pDns) -{ - - if(pDns->state() != KviDns::Success) - { - unsigned int uOldConnectionId = m_uConnectionId; - - callFunction(this,"connectFailedEvent",new KviKvsVariantList( - new KviKvsVariant(KviError::getDescription(pDns->error())))); - - if(m_uConnectionId == uOldConnectionId)reset(); - // else it has already been called! - return; - } - m_szRemoteIp = pDns->firstIpAddress(); - debug ("Dns resolved in %s",m_szRemoteIp.latin1()); - - delete m_pDns; - m_pDns = 0; - doConnect(); -} - -void KviKvsObject_socket::writeNotifierFired(int) -{ - debug ("Here in the writeNotifierFired"); - if(m_pSn) - { - delete m_pSn; - m_pSn = 0; - } - if(m_pDelayTimer) - { - delete m_pDelayTimer; - m_pDelayTimer = 0; - } - - // Check for errors... - int sockError; - int iSize=sizeof(int); - if(!kvi_socket_getsockopt(m_sock,SOL_SOCKET,SO_ERROR,(void *)&sockError,&iSize))sockError = -1; - //sockError = 0; - if(sockError != 0) - { - //debug("Failed here %d",sockError); - //failed - if(sockError > 0)sockError = KviError::translateSystemError(sockError); - else sockError = KviError_unknownError; //Error 0 ? - unsigned int uOldConnectionId = m_uConnectionId; - callFunction(this,"connectFailedEvent",new KviKvsVariantList( - new KviKvsVariant(KviError::getDescription(sockError)))); - if(m_uConnectionId == uOldConnectionId)reset(); - // else it has already been called! - } else { - // Succesfully connected - // create the correct read notifier now... - m_pSn = new QSocketNotifier((int)m_sock,QSocketNotifier::Read); - QObject::connect(m_pSn,SIGNAL(activated(int)),this,SLOT(readNotifierFired(int))); - m_pSn->setEnabled(true); - -#ifdef COMPILE_IPV6_SUPPORT - KviSockaddr sareal(0,m_bIpV6); -#else - KviSockaddr sareal(0,false); -#endif - int size = (int)sareal.addressLength(); - if(kvi_socket_getsockname(m_sock,sareal.socketAddress(),&size)) - { - m_uLocalPort = sareal.port(); - sareal.getStringAddress(m_szLocalIp); - } - unsigned int uOldConnectionId = m_uConnectionId; - KviKvsVariantList *params=0; - callFunction(this,"connectEvent",params); - if(m_uConnectionId == uOldConnectionId) - m_iStatus = KVI_SCRIPT_SOCKET_STATUS_CONNECTED; - // else the connection has been already changed! - } -} - -void KviKvsObject_socket::readNotifierFired(int) -{ - debug ("here in the readNotifierFired"); - //read data - if((m_uInBufferLen - m_uInDataLen) < KVI_READ_CHUNK) - { - m_uInBufferLen += KVI_IN_BUFFER_ALLOC_CHUNK; - m_pInBuffer = (char *)kvi_realloc(m_pInBuffer,m_uInBufferLen); - } - - int readLength = kvi_socket_recv(m_sock,m_pInBuffer + m_uInDataLen,KVI_READ_CHUNK); - - if(readLength <= 0) - { - if(readLength==0) - { - unsigned int uOldConnectionId = m_uConnectionId; - KviKvsVariantList *params=0; - callFunction(this,"disconnectEvent",params); - if(m_uConnectionId == uOldConnectionId)reset(); - // else it has already been called! - return; - } else { - //check for transmission errors - int err = kvi_socket_error(); -#ifdef COMPILE_ON_WINDOWS - if((err != EAGAIN) && (err != EINTR) && (err != WSAEWOULDBLOCK)) -#else - if((err != EAGAIN) && (err != EINTR)) -#endif - { - unsigned int uOldConnectionId = m_uConnectionId; - if(err > 0) - - { - // QString error=KviError::translateSystemError(err); - callFunction(this,"disconnectEvent",new KviKvsVariantList( - new KviKvsVariant((kvs_int_t)KviError::translateSystemError(err)))); - } else { - callFunction(this,"disconnectEvent",new KviKvsVariantList( - new KviKvsVariant(KviError::getDescription(KviError_remoteEndClosedConnection)))); - - } - if(m_uConnectionId == uOldConnectionId)reset(); - // else it has already been called! - return; - } //else transient error...wait again... - } - return; // can do nothing - } - // readLength > 0 - m_uInDataLen += readLength; - - //KviStr * s = new KviStr(); - QString s; - s.setNum(m_uInDataLen); - - - unsigned int uOldConnectionId = m_uConnectionId; - callFunction(this,"dataAvailableEvent",new KviKvsVariantList(new KviKvsVariant(s))); - if(m_uConnectionId == uOldConnectionId) - { - if(m_uInDataLen > (4096 * 1024)) // too much data in buffer (not reading) - { - callFunction(this,"disconnectEvent",new KviKvsVariantList( - new KviKvsVariant(__tr2qs("Too much unprocessed incoming data (you've left this socket unmanaged ?)")))); - reset(); - } - } -} - -void KviKvsObject_socket::eatInData(unsigned int uLen) -{ - if(uLen > m_uInDataLen)uLen = m_uInDataLen; - - m_uInDataLen -= uLen; - - if(m_uInDataLen > 0) - { - kvi_memmove(m_pInBuffer,m_pInBuffer + uLen,m_uInDataLen); - } - - unsigned int uSpace = m_uInBufferLen - m_uInDataLen; - - if(uSpace > KVI_IN_BUFFER_ALLOC_CHUNK) - { - m_uInBufferLen -= KVI_IN_BUFFER_ALLOC_CHUNK; - m_pInBuffer = (char *)kvi_realloc(m_pInBuffer,m_uInBufferLen); - } -} - -void KviKvsObject_socket::delayedFlush(unsigned int uTimeout) -{ - if(m_pFlushTimer->isActive())m_pFlushTimer->stop(); - m_pFlushTimer->start(uTimeout); -} - -void KviKvsObject_socket::tryFlush() -{ - if(m_pFlushTimer->isActive())m_pFlushTimer->stop(); - - if(m_pOutBuffer->size() == 0) - { - return; - } - - int result = kvi_socket_send(m_sock,m_pOutBuffer->data(),m_pOutBuffer->size()); - - if(result >= 0) - { - if(result == m_pOutBuffer->size()) - { - m_pOutBuffer->clear(); - } else { - if(result > 0)m_pOutBuffer->remove(result); - delayedFlush(500); - } - } else { - // Oops...error ? - int err = kvi_socket_error(); -#ifdef COMPILE_ON_WINDOWS - if((err == EAGAIN) || (err == EINTR) || (err = WSAEWOULDBLOCK)) -#else - if((err == EAGAIN)||(err == EINTR)) -#endif - { - // Transient error...partial send as before... - // Async continue... - delayedFlush(500); - return; - } else { - // Disconnected... :( - unsigned int uOldConnectionId = m_uConnectionId; - callFunction(this,"disconnectEvent",0,new KviKvsVariantList( - new KviKvsVariant(KviError::getDescription(KviError::translateSystemError(err))))); - if(m_uConnectionId == uOldConnectionId)reset(); - // else it has already been called! - return; - } - } -} -void KviKvsObject_socket::reset() -{ - m_uConnectionId++; // this is the only place where this is incremented! - if(m_pDelayTimer) - { - delete m_pDelayTimer; - m_pDelayTimer = 0; - } - if(m_pDns) - { - delete m_pDns; - m_pDns = 0; - } - if(m_pSn) - { - delete m_pSn; - m_pSn = 0; - } - if(m_sock != KVI_INVALID_SOCKET) - { - kvi_socket_close(m_sock); - m_sock = KVI_INVALID_SOCKET; - } - if(m_pInBuffer) - { - kvi_free(m_pInBuffer); - m_pInBuffer = 0; - } - if(m_secondarySock) - { - kvi_socket_close(m_secondarySock); - m_secondarySock = KVI_INVALID_SOCKET; - } - m_uSecondaryPort = 0; - m_szSecondaryIp=""; - delete m_pOutBuffer; - if(m_pFlushTimer->isActive())m_pFlushTimer->stop(); - m_pOutBuffer = new KviDataBuffer(); - m_uInBufferLen = 0; - m_uInDataLen = 0; - m_iStatus = KVI_SCRIPT_SOCKET_STATUS_DISCONNECTED; - m_uRemotePort = 0; - m_szRemoteIp=""; - m_uLocalPort = 0; - m_szLocalIp=""; - m_bIpV6 = false; -} -unsigned int KviKvsObject_socket::readGetLength(KviKvsObjectFunctionCall *c) -{ - kvs_uint_t uLen; - KVSO_PARAMETERS_BEGIN(c) - KVSO_PARAMETER("length",KVS_PT_UNSIGNEDINTEGER,KVS_PF_OPTIONAL,uLen) - KVSO_PARAMETERS_END(c) - if (uLen>m_uInDataLen || !uLen) return m_uInDataLen; - else return uLen; - } - -bool KviKvsObject_socket::functionRead(KviKvsObjectFunctionCall *c) -{ - unsigned int uLen = readGetLength(c); - - if(uLen > 0) - { - // convert NULLS to char 255 - for(unsigned int i = 0;i < uLen;i++) - { - if(!m_pInBuffer[i])m_pInBuffer[i] = (char)(255); - } - QString tmpBuffer = QString::fromUtf8(m_pInBuffer,uLen); - c->returnValue()->setString(tmpBuffer); - - eatInData(uLen); - } - return true; -} - -bool KviKvsObject_socket::functionReadHex(KviKvsObjectFunctionCall *c) -{ - //??? funzioner� - unsigned int uLen = readGetLength(c); - bool bOk; - if(uLen > 0) - { - QString szTmp; - szTmp =m_pInBuffer; - szTmp.toInt(&bOk,16); - c->returnValue()->setString(szTmp); - eatInData(uLen); - } - return true; -} - -bool KviKvsObject_socket::functionWrite(KviKvsObjectFunctionCall *c) -{ - QString szData; - KVSO_PARAMETERS_BEGIN(c) - KVSO_PARAMETER("szData",KVS_PT_STRING,0,szData) - KVSO_PARAMETERS_END(c) - -QCString szData8 = szData.utf8(); - if(szData8.length() > 0) - { - m_pOutBuffer->append((const unsigned char*)szData8.data(),szData8.length()); - delayedFlush(0); - } - return true; -} - - - -//-------------- - -#include "m_class_socket.moc" +// +// File : class_socket.cpp +// Creation date : Sun Nov 11 03:13:45 2001 GMT by Szymon Stefanek +// +// This file is part of the KVirc irc client distribution +// Copyright (C) 2001 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. ,59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// + +#include "kvi_settings.h" + +#define _KVI_DEBUG_CHECK_RANGE_ +#include "kvi_debug.h" + + +#include "kvi_locale.h" +#include "kvi_error.h" +#include "kvi_netutils.h" +#include "kvi_dns.h" +#include "kvi_error.h" +#include "kvi_socket.h" +#include "kvi_malloc.h" +#include "kvi_memmove.h" +#include "kvi_databuffer.h" +#include "kvi_qcstring.h" + +#include "class_socket.h" + +//#include + +#define KVI_IN_BUFFER_ALLOC_CHUNK 4096 +#define KVI_READ_CHUNK 1024 +/* +static KviScriptObjectClass * g_pSocketClass = 0; + +static KviScriptObject * socketClassCreateInstance(KviScriptObjectClass * cls,KviScriptObject *par,const char * nam) +{ + return new KviScriptSocketObject(cls,par,nam); +} + +KviScriptSocketObject::KviScriptSocketObject(KviScriptObjectClass * cla,KviScriptObject * par,const char * nam) +: KviScriptObject(cla,par,nam) +{ + m_uConnectionId = 0; + m_sock = KVI_INVALID_SOCKET; + m_iStatus = KVI_SCRIPT_SOCKET_STATUS_DISCONNECTED; + m_uRemotePort = 0; + m_uSecondaryPort = 0; + m_pSn = 0; + m_pDns = 0; + m_pDelayTimer = 0; + m_uConnectTimeout = 60000; + m_pInBuffer = 0; + m_uInBufferLen = 0; + m_uInDataLen = 0; + m_pOutBuffer = new KviDataBuffer(); + m_pFlushTimer = new QTimer(); + m_bIpV6 = false; + m_uLocalPort = 0; + m_secondarySock = KVI_INVALID_SOCKET; + connect(m_pFlushTimer,SIGNAL(timeout()),this,SLOT(tryFlush())); +} + +KviScriptSocketObject::~KviScriptSocketObject() +{ + delete m_pOutBuffer; + delete m_pFlushTimer; + + if(m_pInBuffer)kvi_free(m_pInBuffer); + if(m_pDelayTimer)delete m_pDelayTimer; + if(m_pDns)delete m_pDns; + if(m_pSn)delete m_pSn; + if(m_sock != KVI_INVALID_SOCKET)kvi_socket_close(m_sock); + if(m_secondarySock != KVI_INVALID_SOCKET)kvi_socket_close(m_secondarySock); +} + +void KviScriptSocketObject::reset() +{ + m_uConnectionId++; // this is the only place where this is incremented! + if(m_pDelayTimer) + { + delete m_pDelayTimer; + m_pDelayTimer = 0; + } + if(m_pDns) + { + delete m_pDns; + m_pDns = 0; + } + if(m_pSn) + { + delete m_pSn; + m_pSn = 0; + } + if(m_sock != KVI_INVALID_SOCKET) + { + kvi_socket_close(m_sock); + m_sock = KVI_INVALID_SOCKET; + } + if(m_pInBuffer) + { + kvi_free(m_pInBuffer); + m_pInBuffer = 0; + } + if(m_secondarySock) + { + kvi_socket_close(m_secondarySock); + m_secondarySock = KVI_INVALID_SOCKET; + } + m_uSecondaryPort = 0; + m_szSecondaryIp.clear(); + delete m_pOutBuffer; + if(m_pFlushTimer->isActive())m_pFlushTimer->stop(); + m_pOutBuffer = new KviDataBuffer(); + m_uInBufferLen = 0; + m_uInDataLen = 0; + m_iStatus = KVI_SCRIPT_SOCKET_STATUS_DISCONNECTED; + m_uRemotePort = 0; + m_szRemoteIp.clear(); + m_uLocalPort = 0; + m_szLocalIp.clear(); + m_bIpV6 = false; +} + +/* + @doc: socket + @keyterms: + socket object class + @title: + socket class + @type: + class + @short: + A Ipv4/Ipv6 TCP socket + @inherits: + [class]object[/class] + @description: + This class provides a standard TCP/IP socket functionality.[br] + It can be used either for connecting to a remote host or to listening for incoming connections.[br] + If the KVIrc executable has been compiled with the IPV6 protocol support , this socket also supports it.[br] + @functions: + !fn: $status() + Returns the status of the socket :[br] + 4=connected[br] + 3=listening[br] + 2=connecting[br] + 1=in dns call[br] + 0=disconnected + + !fn: $connectTimeout() + Returns the value of the connect attempt timeout in milliseconds.[br] + This is the timeout after that a connection attempt will be considered as failed if the remote + host is not responding. You can set it with [classfnc:socket]$setConnectTimeout[/classfnc](). + + !fn: $setConnectTimeout() + Sets the connect timeout for this socket. must be a positive value in milliseconds.[br] + The default timeout is 60000. + + !fn: $connect(,) + Attempts a connection to on port .[br] + can be a numeric internet address (either Ipv4 or Ipv6 (if supported)) or a hostname.[br] + If a hostname is used, a DNS lookup is performed (the socket enters the "dns call" state).[br] + This function returns 1 if the connect attempt can be succesfully initiated, + 0 otherwise.[br] In fact , this function returns 0 only if the supplied parameter + is invalid or the socket is in an incoherent state (already connected or listening): + for a newly created socket and with a valid number you can safely ignore + the return value.[br] + Please note that the connection is asynchronous: when this function returns + the socket is NOT connected: it has just initiated the connect attempt + and you will be notified of the attempt result by an asynchronous event call: + in case of failure , $connectFailedEvent() will be called , in case of + succes , $connectEvent() will be called. + + !fn: $listen([[,[,]]]) + Attempts to listen on the specified and .[br] + If is not passed it is assumed to be 0 , if is not passed , it is assumed to be + "any interface" (INADDR_ANY).[br] Port 0 means that the kernel should choose a "random" port to listen on.[br] + If the is recognized as IPV6 address , and IPV6 is supported , the socket listens + in IPV6 mode. If is an empty string and is 1 the socket listens + on "any ipv6 interface".[br] + This function returns '1' in case of success and '0' in case of failure.[br] + On some systems listening in the IPV6 namespace allows to accept also IPV4 connections (this includes + linux but not windows afaik).[br] + When an incoming connection will arrive , $incomingConnectionEvent() will be called. + + !fn: $accept() + This function can be called only from inside $incomingConnectionEvent().[br] + must be a newly created socket sub-class instance object.[br] + The passed object will be set up to handle the incoming connection and this object + will remain in listening state (unless you explicitly close it).[br] + This function returns '1' in case of success and '0' in case of failure. + + !fn: $connectEvent() + This function is called when a connection attempt has been succesfully completed. + The socket is actually connected to [classfnc:socket]$remoteIp[/classfnc]() on + [classfnc:socket]$remotePort[/classfnc](). You can start + writing data and you may expect [classfnc:socket]$dataAvailableEvent[/classfnc]() to be + triggered. + + !fn: $incomingConnectionEvent() + This function is called when an incoming connection arrives over a socket in listening state.[br] + You must call [classfnc:socket]$accept[/classfnc]() passing a newly created socket object + to accept and handle the connection.[br] If you don't call [classfnc:socket]$accept[/classfnc]() + the incoming connection will be automatically terminated. + + !fn: $connectFailedEvent() + This function is called when a connection attempt fails for some reason. contains + the error string.[br] + This function may be called only between a call to [classfnc:socket]$connect[/classfnc]() and + the [classfnc:socket]$connectEvent[/classfnc](). + + !fn: $disconnectEvent([error]) + This function is called when a connection is terminated either cleanly or because of an error.[br] + [error] is an empty string in case of a "clean" termination (connection closed by the remote host) + or is a message describing the socket error that caused the connection to be interrupted. + + !fn: $dataAvailableEvent() + This function is called when some data is available to be read: the parameter specifies + the length of the available data in bytes.[br] + You can use one of the $read* functions to obtain the data. + + !fn: $read() + Reads at most bytes of data from the socket. If is anything "outside" the + available data range ( < 0 or > available_data_length), this function + returns all the available data.[br] + Please note that this function can't deal withi binary data: NULL characters are transformed to + ASCII characters 255. + + !fn: $readHex() + Reads at most bytes of data from the socket. If is anything "outside" the + available data range ( < 0 or > available_data_length), this function + returns all the available data.[br] + Returns the data encoded as hexadecimal digit string: this function can deal with binary data too. + + !fn: $write() + Writes to the socket.[br] + This function can't deal with binary data (you can't send a NULL character)[br] + Please note that when this function finishes it does not mean that the data has reached the remote end.[br] + Basically it does not even mean that the data has been sent to the remote host.[br] + The data is enqueued for sending and will be sent as soon as possible.[br] + If you're going to [cmd]delete[/cmd] this object just after the $write call, you should + call [classfnc:socket]$close[/classfnc]() just before [cmd]delete[/cmd] to ensure the data delivery. + + !fn: $writeHex() + Writes to the socket.[br] + is expected to be a hexadecimal rappresentation of the bytes to be sent (two HEX characters + for each byte). This means that the length of string must be a multiple of 2.[br] + Returns the length of the actually decoded and sent data in bytes or -1 in case of error (the string + was not a valid hexadecimla rappresentation).[br] + Please note that when this function finishes it does not mean that the data has reached the remote end.[br] + Basically it does not even mean that the data has been sent to the remote host.[br] + The data is enqueued for sending and will be sent as soon as possible.[br] + If you're going to [cmd]delete[/cmd] this object just after the $writeHex call, you should + call [classfnc:socket]$close[/classfnc]() just before [cmd]delete[/cmd] to ensure the data delivery. + + !fn: $close() + Resets this socket state: kills any pending or active connection. After a close() call + the socket may be used for a new connection.[br] + If there is an active connection, there is a last attempt to flush the pending outgoing data.[br] + You don't need to call $close() if you [cmd]delete[/cmd] the socket: KVIrc will + reset the socket state automatically and free the memory. But if you want to ensure data delivery + after a $write call sequece and just before a [cmd]delete[/cmd], $close() is the only chance to do it. + + !fn: $remoteIp() + Returns the IP address of the remote end of this socket.[br] + The return value is meaningful only if the socket is in connected or connecting state. + + !fn: $remotePort() + Returns the port of the remote end of this socket.[br] + The return value is meaningful only if the socket is in connected or connecting state. + + !fn: $localIp() + Returns the IP address of the local end of this socket.[br] + The return value is meaningful only if the socket is in connected , listening or connecting state. + + !fn: $localPort() + Returns the port of the local end of this socket.[br] + The return value is meaningful only if the socket is in connected , listening or connecting state. + +@examples: + [example] + #Server socket: listen 80 port and answer to requests (multi-threaded)[br] +[br] + class (webserver,socket) {[br] + constructor () {[br] + $$->$listen(80, "127.0.0.1")[br] + }[br] + incomingConnectionEvent()[br] + {[br] + %tmp = $new(socket)[br] + $$->$accept(%tmp)[br] + echo "Webserver incoming Conection from: %tmp->$remoteIp : %tmp->$remotePort"[br] + %tmp->$write("HTTP/1.1 200 OK\n\n

KVIrc Webserver

\n")[br] + %tmp->$close()[br] + delete %tmp[br] + }[br] + }[br] + [br] + #finally start webserver[br] + %WebS = $new(webserver)[br] + [br] + [/example] + [example] + #Client socket - go to google and grab request header[br] + class (httprequest,socket) {[br] + constructor () [br] + {[br] + # connect to the server[br] + $$->$connect("www.google.de",80)[br] + }[br] + destructor()[br] + {[br] + # if the socket is still open close it[br] + if($$->$status() == 4) $$->$close()[br] + }[br] + connectFailedEvent() [br] + {[br] + # the connection to the server failed[br] + echo "Connection failed: "$0[br] + delete $$[br] + }[br] + connectEvent() [br] + {[br] + # connection is complete[br] + # send a request to receive the headers only from http://www.google.de/[br] + $$->$write("HEAD / HTTP/1.1\r\nHost: www.google.de\r\nConnction: Close\r\nUser-Agent: KVIrc socket\r\n\r\n");[br] + }[br] + dataAvailableEvent() [br] + {[br] + # reading the received data[br] + %newdata = $$->$read($0)[br] + echo %newdata[br] + #close and delete the socket[br] + $$->$close()[br] + delete $$[br] + }[br] + disconnectEvent() [br] + {[br] + # connection has been closed[br] + echo "Connection closed"[br] + delete $$[br] + }[br] +}[br] + +#Creating the socket[br] +%Temp = $new(httprequest)[br] + [/example] +*/ + +KVSO_BEGIN_REGISTERCLASS(KviKvsObject_socket,"socket","object") + + KVSO_REGISTER_HANDLER(KviKvsObject_socket,"status",functionStatus) + KVSO_REGISTER_HANDLER(KviKvsObject_socket,"remotePort",functionRemotePort) + KVSO_REGISTER_HANDLER(KviKvsObject_socket,"remoteIp",functionRemoteIp) + KVSO_REGISTER_HANDLER(KviKvsObject_socket,"localIp",functionLocalIp) + KVSO_REGISTER_HANDLER(KviKvsObject_socket,"localPort",functionLocalPort) + KVSO_REGISTER_HANDLER(KviKvsObject_socket,"connect",functionConnect) + KVSO_REGISTER_HANDLER(KviKvsObject_socket,"connectTimeout",functionConnectTimeout) + KVSO_REGISTER_HANDLER(KviKvsObject_socket,"setConnectTimeout",functionSetConnectTimeout) + KVSO_REGISTER_HANDLER(KviKvsObject_socket,"close",functionClose) + KVSO_REGISTER_HANDLER(KviKvsObject_socket,"read",functionRead) + KVSO_REGISTER_HANDLER(KviKvsObject_socket,"readHex",functionReadHex) + KVSO_REGISTER_HANDLER(KviKvsObject_socket,"write",functionWrite) + KVSO_REGISTER_HANDLER(KviKvsObject_socket,"writeHex",functionWriteHex) + KVSO_REGISTER_HANDLER(KviKvsObject_socket,"listen",functionListen) + KVSO_REGISTER_HANDLER(KviKvsObject_socket,"accept",functionAccept) + + KVSO_REGISTER_STANDARD_NOTHINGRETURN_HANDLER(KviKvsObject_socket,"connectEvent") + KVSO_REGISTER_STANDARD_NOTHINGRETURN_HANDLER(KviKvsObject_socket,"connectFailedEvent") + KVSO_REGISTER_STANDARD_NOTHINGRETURN_HANDLER(KviKvsObject_socket,"disconnectEvent") + KVSO_REGISTER_STANDARD_NOTHINGRETURN_HANDLER(KviKvsObject_socket,"dataAvailableEvent") + KVSO_REGISTER_STANDARD_NOTHINGRETURN_HANDLER(KviKvsObject_socket,"incomingConnectionEvent") + +KVSO_END_REGISTERCLASS(KviKvsObject_socket) + + +KVSO_BEGIN_CONSTRUCTOR(KviKvsObject_socket,KviKvsObject) + + + + m_uConnectionId = 0; + m_sock = KVI_INVALID_SOCKET; + m_iStatus = KVI_SCRIPT_SOCKET_STATUS_DISCONNECTED; + m_uRemotePort = 0; + m_uSecondaryPort = 0; + m_pSn = 0; + m_pDns = 0; + m_pDelayTimer = 0; + m_uConnectTimeout = 60000; + m_pInBuffer = 0; + m_uInBufferLen = 0; + m_uInDataLen = 0; + m_pOutBuffer = new KviDataBuffer(); + m_pFlushTimer = new QTimer(); + m_bIpV6 = false; + m_uLocalPort = 0; + m_secondarySock = KVI_INVALID_SOCKET; + connect(m_pFlushTimer,SIGNAL(timeout()),this,SLOT(tryFlush())); +KVSO_END_CONSTRUCTOR(KviKvsObject_socket) + +KVSO_BEGIN_DESTRUCTOR(KviKvsObject_socket) + delete m_pOutBuffer; + delete m_pFlushTimer; + + if(m_pInBuffer)kvi_free(m_pInBuffer); + if(m_pDelayTimer)delete m_pDelayTimer; + if(m_pDns)delete m_pDns; + if(m_pSn)delete m_pSn; + if(m_sock != KVI_INVALID_SOCKET)kvi_socket_close(m_sock); + if(m_secondarySock != KVI_INVALID_SOCKET)kvi_socket_close(m_secondarySock); +KVSO_END_DESTRUCTOR(KviKvsObject_socket) +//---------------------- + + +bool KviKvsObject_socket::functionStatus(KviKvsObjectFunctionCall *c) +{ + c->returnValue()->setInteger(m_iStatus); + return true; +} + +bool KviKvsObject_socket::functionClose(KviKvsObjectFunctionCall *c) +{ + if((m_pOutBuffer->size() != 0) && (m_iStatus == KVI_SCRIPT_SOCKET_STATUS_CONNECTED)) + tryFlush(); + + reset(); + return true; +} + +bool KviKvsObject_socket::functionConnectTimeout(KviKvsObjectFunctionCall *c) +{ + c->returnValue()->setInteger(m_uConnectTimeout); + return true; +} + +bool KviKvsObject_socket::functionSetConnectTimeout(KviKvsObjectFunctionCall *c) +{ + kvs_uint_t uTimeout; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("time_out",KVS_PT_UNSIGNEDINTEGER,0,uTimeout) + KVSO_PARAMETERS_END(c) + m_uConnectTimeout = uTimeout; + return true; +} + +bool KviKvsObject_socket::functionRemotePort(KviKvsObjectFunctionCall *c) +{ + c->returnValue()->setInteger(m_uRemotePort); + return true; +} + +bool KviKvsObject_socket::functionRemoteIp(KviKvsObjectFunctionCall *c) +{ + c->returnValue()->setString(m_szRemoteIp); + return true; +} + +bool KviKvsObject_socket::functionLocalPort(KviKvsObjectFunctionCall *c) +{ + c->returnValue()->setInteger(m_uLocalPort); + return true; +} + +bool KviKvsObject_socket::functionLocalIp(KviKvsObjectFunctionCall *c) +{ + c->returnValue()->setString(m_szLocalIp); + return true; +} + +bool KviKvsObject_socket::functionAccept(KviKvsObjectFunctionCall *c) +{ + KviKvsObject * pObject; + kvs_hobject_t hObject; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("object_socket",KVS_PT_HOBJECT,0,hObject) + KVSO_PARAMETERS_END(c) + + pObject = KviKvsKernel::instance()->objectController()->lookupObject(hObject); + + if(!pObject) + { + c->warning(__tr2qs("No socket object specified")); + return true; + } + + if(!pObject->inherits("KviKvsObject_socket")) + { + c->warning(__tr2qs("Invalid socket object specified (it doesn't inherit from socket)")); + return true; + } + + if(m_secondarySock != KVI_INVALID_SOCKET) + { + ((KviKvsObject_socket *)pObject)->acceptConnection(m_secondarySock,m_uSecondaryPort,m_szSecondaryIp); + + m_secondarySock = KVI_INVALID_SOCKET; + m_uSecondaryPort = 0; + m_szSecondaryIp=""; + } else { + c->warning(__tr2qs("There is no connection to accept!")); + } + return true; +} + + + + +bool KviKvsObject_socket::functionWriteHex(KviKvsObjectFunctionCall *c) +{ + QString m_szHex; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("hex_string",KVS_PT_STRING,0,m_szHex) + KVSO_PARAMETERS_END(c) + + if(m_szHex.length() > 0) + { + bool bOk; + QString szTmp; + szTmp=m_szHex.setNum(m_szHex.toInt(&bOk,16),16); + if(szTmp.length()>0) + { + KviQCString szData8 = szTmp.utf8(); + m_pOutBuffer->append((const unsigned char *)(szData8.data()),szData8.length()); + delayedFlush(0); + c->returnValue()->setInteger(szData8.length()); + } + } + + /* + if(pszData) + { + if(pszData->len() > 0) + { + char * ptr; + len = pszData->hexToBuffer(&ptr); + if(len > 0) + { + m_pOutBuffer->append((const unsigned char *)(ptr),len); + delayedFlush(0); + KviStr::freeBuffer(ptr); + } + } + } + buffer.append(KviStr::Format,"%d",len); +*/ + return true; +} + + + + + +bool KviKvsObject_socket::functionConnect(KviKvsObjectFunctionCall *c) +{ + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("remote_ip",KVS_PT_STRING,0,m_szRemoteIp) + KVSO_PARAMETER("remote_port",KVS_PT_UNSIGNEDINTEGER,0,m_uRemotePort) + KVSO_PARAMETERS_END(c) + debug ("Function connect"); + + + if (m_uRemotePort>65535) + { + c->warning(__tr2qs("Value %d for port is out of range (values allowed are from 0 to 65535"),m_uRemotePort); + return true; + } + if((m_sock != KVI_INVALID_SOCKET) || (m_iStatus != KVI_SCRIPT_SOCKET_STATUS_DISCONNECTED)) + { + c->warning(__tr2qs("Another connection in progress")); + c->returnValue()->setBoolean(true); + return true; + } + + +#ifdef COMPILE_IPV6_SUPPORT + if(kvi_isValidStringIp(m_szRemoteIp) || kvi_isValidStringIp_V6(m_szRemoteIp)) +#else + if(kvi_isValidStringIp(m_szRemoteIp)) +#endif + { + debug ("ok connecting"); + debug ("connectinhg on ip %s ",m_szRemoteIp.latin1()); + debug ("non so ip"); + m_iStatus = KVI_SCRIPT_SOCKET_STATUS_CONNECTING; + delayedConnect(); + } else { + debug ("connectinhg on ip %s port %d",m_szRemoteIp.latin1(),m_uRemotePort); + m_iStatus = KVI_SCRIPT_SOCKET_STATUS_DNS; + delayedLookupRemoteIp(); + } + c->returnValue()->setBoolean(true); + return true; +} + + + + + + +bool KviKvsObject_socket::functionListen(KviKvsObjectFunctionCall *c) +{ + if((m_sock != KVI_INVALID_SOCKET) || (m_iStatus != KVI_SCRIPT_SOCKET_STATUS_DISCONNECTED)) + { + c->warning(__tr2qs("Another connection in progress")); + c->returnValue()->setBoolean(false); + return true; + } + kvs_uint_t uLocalPort; + QString m_szLocalIp; + bool m_bIpV6; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("local_port",KVS_PT_UNSIGNEDINTEGER,0,uLocalPort) + KVSO_PARAMETER("local_ip",KVS_PT_STRING,KVS_PF_OPTIONAL,m_szLocalIp) + KVSO_PARAMETER("bool_ipV6",KVS_PT_BOOLEAN,KVS_PF_OPTIONAL,m_bIpV6) + KVSO_PARAMETERS_END(c) + m_uLocalPort=uLocalPort; + +#ifndef COMPILE_IPV6_SUPPORT + if(m_bIpV6) + { + c->warning(__tr2qs("No IPV6 support in this executable")); + c->returnValue()->setBoolean(false); + reset(); + return true; + } +#endif + + bool bGotIp = false; + + if(!m_szLocalIp.isEmpty()) + { + + // Check the address type + if(kvi_isValidStringIp(m_szLocalIp))bGotIp = true; + else { +#ifdef COMPILE_IPV6_SUPPORT + if(kvi_isValidStringIp_V6(m_szLocalIp)) + { + bGotIp = true; + m_bIpV6 = true; + } else { +#else + c->warning(__tr2qs("Invalid IP address specified ('%Q')"),&m_szLocalIp); + c->returnValue()->setBoolean(false); + reset(); + return true; +#endif +#ifdef COMPILE_IPV6_SUPPORT + } +#endif + } + } + + +#ifdef COMPILE_IPV6_SUPPORT + m_sock = kvi_socket_create(m_bIpV6 ? KVI_SOCKET_PF_INET6 : KVI_SOCKET_PF_INET, + KVI_SOCKET_TYPE_STREAM,KVI_SOCKET_PROTO_TCP); +#else + m_sock = kvi_socket_create(KVI_SOCKET_PF_INET,KVI_SOCKET_TYPE_STREAM,KVI_SOCKET_PROTO_TCP); +#endif + + if(m_sock == KVI_INVALID_SOCKET) + { + c->warning(__tr2qs("Socket creation failed")); + c->returnValue()->setBoolean(false); + reset(); + return true; + } + + if(!m_szLocalIp.isEmpty()) + { +#ifdef COMPILE_IPV6_SUPPORT + KviSockaddr sa(m_szLocalIp,m_uLocalPort,m_bIpV6); +#else + KviSockaddr sa(m_szLocalIp,m_uLocalPort,false); +#endif + if(!sa.socketAddress()) + { + c->warning(__tr2qs("Invalid socket address")); + reset(); + c->returnValue()->setBoolean(false); + return true; + } + + if(!kvi_socket_bind(m_sock,sa.socketAddress(),((int)(sa.addressLength())))) + { + c->warning(__tr2qs("Bind failure")); + reset(); + c->returnValue()->setBoolean(false); + return true; + } + } else { +#ifdef COMPILE_IPV6_SUPPORT + KviSockaddr sa(m_uLocalPort,m_bIpV6); +#else + KviSockaddr sa(m_uLocalPort,false); +#endif + if(!sa.socketAddress()) + { + c->warning(__tr2qs("Invalid socket address")); + reset(); + c->returnValue()->setBoolean(false); + return true; + } + + if(!kvi_socket_bind(m_sock,sa.socketAddress(),((int)(sa.addressLength())))) + { + c->warning(__tr2qs("Bind failure")); + reset(); + c->returnValue()->setBoolean(false); + return true; + } + } + + + if(!kvi_socket_listen(m_sock,5)) + { + c->warning(__tr2qs("Listen failure")); + reset(); + c->returnValue()->setBoolean(false); + return true; + } + + + // Reread the port in case we're binding to a random one (0) + +#ifdef COMPILE_IPV6_SUPPORT + KviSockaddr sareal(0,m_bIpV6); +#else + KviSockaddr sareal(0,false); +#endif + + int size = (int)sareal.addressLength(); + + if(kvi_socket_getsockname(m_sock,sareal.socketAddress(),&size)) + { + m_uLocalPort = sareal.port(); + sareal.getStringAddress(m_szLocalIp); + } + + // and setup the READ notifier... + m_pSn = new QSocketNotifier(m_sock,QSocketNotifier::Read); + QObject::connect(m_pSn,SIGNAL(activated(int)),this,SLOT(incomingConnection(int))); + m_pSn->setEnabled(true); + + m_iStatus = KVI_SCRIPT_SOCKET_STATUS_LISTENING; + + c->returnValue()->setBoolean(true); + return true; +} + +void KviKvsObject_socket::incomingConnection(int) +{ +#ifdef COMPILE_IPV6_SUPPORT + struct sockaddr_in6 hostSockAddr6; +#endif + struct sockaddr_in hostSockAddr; + + int size = sizeof(hostSockAddr); + struct sockaddr * addr = (struct sockaddr *)&hostSockAddr; + +#ifdef COMPILE_IPV6_SUPPORT + if(m_bIpV6) + { + addr = (struct sockaddr *)&hostSockAddr6; + size = sizeof(hostSockAddr6); + } +#endif + + // Incoming connection + m_secondarySock = kvi_socket_accept(m_sock,addr,&size); + if(m_secondarySock != KVI_INVALID_SOCKET) + { + // Connected +#ifdef COMPILE_IPV6_SUPPORT + if(m_bIpV6) + { + m_uSecondaryPort = ntohs(((struct sockaddr_in6 *)addr)->sin6_port); + if(!kvi_binaryIpToStringIp_V6(((struct sockaddr_in6 *)addr)->sin6_addr,m_szSecondaryIp)) + m_szSecondaryIp = __tr("unknown"); + } else { +#endif + m_uSecondaryPort = ntohs(((struct sockaddr_in *)addr)->sin_port); + if(!kvi_binaryIpToStringIp(((struct sockaddr_in *)addr)->sin_addr,m_szSecondaryIp)) + m_szSecondaryIp = __tr("unknown"); +#ifdef COMPILE_IPV6_SUPPORT + } +#endif + KviKvsVariantList *params=0; + callFunction(this,"incomingConnectionEvent",params); + if(m_secondarySock != KVI_INVALID_SOCKET) + { + kvi_socket_close(m_secondarySock); + m_secondarySock = KVI_INVALID_SOCKET; + m_uSecondaryPort = 0; + m_szSecondaryIp=""; + } + + } // else..huh ?... wait for the next notifier call +} + +void KviKvsObject_socket::acceptConnection(kvi_socket_t s,kvi_u32_t uPort,const char * szIp) +{ + reset(); + m_sock = s; + m_uRemotePort = uPort; + m_szRemoteIp = szIp; +#ifdef COMPILE_IPV6_SUPPORT + KviSockaddr sareal(0,m_bIpV6); +#else + KviSockaddr sareal(0,false); +#endif + + int size = (int)sareal.addressLength(); + + if(kvi_socket_getsockname(m_sock,sareal.socketAddress(),&size)) + { + m_uLocalPort = sareal.port(); + sareal.getStringAddress(m_szLocalIp); + } + + m_iStatus = KVI_SCRIPT_SOCKET_STATUS_CONNECTED; + + m_pSn = new QSocketNotifier((int)m_sock,QSocketNotifier::Read); + QObject::connect(m_pSn,SIGNAL(activated(int)),this,SLOT(readNotifierFired(int))); + m_pSn->setEnabled(true); +} + +void KviKvsObject_socket::delayedConnect() +{ + if(m_pDelayTimer)delete m_pDelayTimer; + m_pDelayTimer = new QTimer(); + connect(m_pDelayTimer,SIGNAL(timeout()),this,SLOT(doConnect())); + m_pDelayTimer->start(0,true); +} + +void KviKvsObject_socket::doConnect() +{ + debug ("doConnect function"); + if(m_pDelayTimer)delete m_pDelayTimer; + m_pDelayTimer = 0; + + + KviSockaddr sa(m_szRemoteIp,m_uRemotePort,!kvi_isValidStringIp(m_szRemoteIp)); + + if(!sa.socketAddress()) + { + unsigned int uOldConnectionId = m_uConnectionId; + QString ipAddressError=__tr2qs("Invalid ip address "); + + ipAddressError.append(m_szRemoteIp); + + KviKvsVariantList params; + QString tmp; + KviQString::sprintf(tmp,__tr2qs("Invalid ip address (%Q)"),&m_szRemoteIp); + params.append(new KviKvsVariant(tmp)); + callFunction(this,"connectFailedEvent",¶ms); + /* callEventFunction("connectFailedEvent",0,new KviParameterList( + new KviStr(KviStr::Format,__tr("Invalid ip address (%s)"),m_szRemoteIp.ptr()))); + */ if(m_uConnectionId == uOldConnectionId)reset(); + // else it has already been called! + return; + } +debug ("Socket created"); + + // create the socket +#ifdef COMPILE_IPV6_SUPPORT + m_bIpV6 = sa.isIpV6(); + m_sock = kvi_socket_create(sa.isIpV6() ? KVI_SOCKET_PF_INET6 : KVI_SOCKET_PF_INET,KVI_SOCKET_TYPE_STREAM,KVI_SOCKET_PROTO_TCP); +#else + m_bIpV6 = false; + m_sock = kvi_socket_create(KVI_SOCKET_PF_INET,KVI_SOCKET_TYPE_STREAM,KVI_SOCKET_PROTO_TCP); +#endif + + if(m_sock == KVI_INVALID_SOCKET) + { + unsigned int uOldConnectionId = m_uConnectionId; + callFunction(this,"connectFailedEvent",new KviKvsVariantList( + new KviKvsVariant(__tr2qs("Failed to create the socket")))); + if(m_uConnectionId == uOldConnectionId)reset(); + // else it has already been called! + return; + } + debug ("Valid socket"); + + if(!kvi_socket_setNonBlocking(m_sock)) + { + unsigned int uOldConnectionId = m_uConnectionId; + + callFunction(this,"connectFailedEvent",new KviKvsVariantList( + new KviKvsVariant(__tr2qs("Failed to setup a nonblocking socket")))); + if(m_uConnectionId == uOldConnectionId)reset(); + // else it has already been called! + return; + } + + if(!kvi_socket_connect(m_sock,sa.socketAddress(),((int)(sa.addressLength())))) + { + int err = kvi_socket_error(); + if(!kvi_socket_recoverableConnectError(err)) + { + // Ops... + int sockError=err; + if(sockError==0) + { + // Zero error ?...let's look closer + int iSize=sizeof(int); + if(!kvi_socket_getsockopt(m_sock,SOL_SOCKET,SO_ERROR, + (void *)&sockError,&iSize))sockError=0; + } + unsigned int uOldConnectionId = m_uConnectionId; + QString callBackError=__tr2qs("Connect failure: "); + + callBackError.append((KviError::getDescription(KviError::translateSystemError(sockError)).utf8().data())); + callFunction(this,"connectFailedEvent",new KviKvsVariantList( + new KviKvsVariant(callBackError))); + +/* callEventFunction("connectFailedEvent",0,new KviParameterList( + new KviStr(KviStr::Format,__tr("Connect failure: %s"),KviError::getDescription(KviError::translateSystemError(sockError)).utf8().data()))); +*/ if(m_uConnectionId == uOldConnectionId)reset(); + // else it has already been called! + return; + } + } + debug ("Socket connected"); + m_pDelayTimer = new QTimer(); + connect(m_pDelayTimer,SIGNAL(timeout()),this,SLOT(connectTimeout())); + m_pDelayTimer->start(m_uConnectTimeout,true); + + m_pSn = new QSocketNotifier((int)m_sock,QSocketNotifier::Write); + QObject::connect(m_pSn,SIGNAL(activated(int)),this,SLOT(writeNotifierFired(int))); + m_pSn->setEnabled(true); +} + +void KviKvsObject_socket::connectTimeout() +{ + unsigned int uOldConnectionId = m_uConnectionId; + + callFunction(this,"connectFailedEvent",new KviKvsVariantList( + new KviKvsVariant(__tr2qs("Connect attempt timed out")))); + if(m_uConnectionId == uOldConnectionId)reset(); + // else it has already been called! +} + +void KviKvsObject_socket::delayedLookupRemoteIp() +{ + if(m_pDelayTimer)delete m_pDelayTimer; + m_pDelayTimer = new QTimer(); + connect(m_pDelayTimer,SIGNAL(timeout()),this,SLOT(lookupRemoteIp())); + m_pDelayTimer->start(0,true); +} + +void KviKvsObject_socket::lookupRemoteIp() +{ + debug ("Resolve dns"); + if(m_pDelayTimer)delete m_pDelayTimer; + m_pDelayTimer = 0; + if(m_pDns)delete m_pDns; + m_pDns = new KviDns(); + connect(m_pDns,SIGNAL(lookupDone(KviDns *)),this,SLOT(lookupDone(KviDns *))); + if(!m_pDns->lookup(m_szRemoteIp,KviDns::Any)) + { + unsigned int uOldConnectionId = m_uConnectionId; + + callFunction(this,"connectFailedEvent",new KviKvsVariantList( + new KviKvsVariant(__tr2qs("Can't start the DNS thread")))); + if(m_uConnectionId == uOldConnectionId)reset(); + // else it has already been called! + } +} + +void KviKvsObject_socket::lookupDone(KviDns *pDns) +{ + + if(pDns->state() != KviDns::Success) + { + unsigned int uOldConnectionId = m_uConnectionId; + + callFunction(this,"connectFailedEvent",new KviKvsVariantList( + new KviKvsVariant(KviError::getDescription(pDns->error())))); + + if(m_uConnectionId == uOldConnectionId)reset(); + // else it has already been called! + return; + } + m_szRemoteIp = pDns->firstIpAddress(); + debug ("Dns resolved in %s",m_szRemoteIp.latin1()); + + delete m_pDns; + m_pDns = 0; + doConnect(); +} + +void KviKvsObject_socket::writeNotifierFired(int) +{ + debug ("Here in the writeNotifierFired"); + if(m_pSn) + { + delete m_pSn; + m_pSn = 0; + } + if(m_pDelayTimer) + { + delete m_pDelayTimer; + m_pDelayTimer = 0; + } + + // Check for errors... + int sockError; + int iSize=sizeof(int); + if(!kvi_socket_getsockopt(m_sock,SOL_SOCKET,SO_ERROR,(void *)&sockError,&iSize))sockError = -1; + //sockError = 0; + if(sockError != 0) + { + //debug("Failed here %d",sockError); + //failed + if(sockError > 0)sockError = KviError::translateSystemError(sockError); + else sockError = KviError_unknownError; //Error 0 ? + unsigned int uOldConnectionId = m_uConnectionId; + callFunction(this,"connectFailedEvent",new KviKvsVariantList( + new KviKvsVariant(KviError::getDescription(sockError)))); + if(m_uConnectionId == uOldConnectionId)reset(); + // else it has already been called! + } else { + // Succesfully connected + // create the correct read notifier now... + m_pSn = new QSocketNotifier((int)m_sock,QSocketNotifier::Read); + QObject::connect(m_pSn,SIGNAL(activated(int)),this,SLOT(readNotifierFired(int))); + m_pSn->setEnabled(true); + +#ifdef COMPILE_IPV6_SUPPORT + KviSockaddr sareal(0,m_bIpV6); +#else + KviSockaddr sareal(0,false); +#endif + int size = (int)sareal.addressLength(); + if(kvi_socket_getsockname(m_sock,sareal.socketAddress(),&size)) + { + m_uLocalPort = sareal.port(); + sareal.getStringAddress(m_szLocalIp); + } + unsigned int uOldConnectionId = m_uConnectionId; + KviKvsVariantList *params=0; + callFunction(this,"connectEvent",params); + if(m_uConnectionId == uOldConnectionId) + m_iStatus = KVI_SCRIPT_SOCKET_STATUS_CONNECTED; + // else the connection has been already changed! + } +} + +void KviKvsObject_socket::readNotifierFired(int) +{ + debug ("here in the readNotifierFired"); + //read data + if((m_uInBufferLen - m_uInDataLen) < KVI_READ_CHUNK) + { + m_uInBufferLen += KVI_IN_BUFFER_ALLOC_CHUNK; + m_pInBuffer = (char *)kvi_realloc(m_pInBuffer,m_uInBufferLen); + } + + int readLength = kvi_socket_recv(m_sock,m_pInBuffer + m_uInDataLen,KVI_READ_CHUNK); + + if(readLength <= 0) + { + if(readLength==0) + { + unsigned int uOldConnectionId = m_uConnectionId; + KviKvsVariantList *params=0; + callFunction(this,"disconnectEvent",params); + if(m_uConnectionId == uOldConnectionId)reset(); + // else it has already been called! + return; + } else { + //check for transmission errors + int err = kvi_socket_error(); +#ifdef COMPILE_ON_WINDOWS + if((err != EAGAIN) && (err != EINTR) && (err != WSAEWOULDBLOCK)) +#else + if((err != EAGAIN) && (err != EINTR)) +#endif + { + unsigned int uOldConnectionId = m_uConnectionId; + if(err > 0) + + { + // QString error=KviError::translateSystemError(err); + callFunction(this,"disconnectEvent",new KviKvsVariantList( + new KviKvsVariant((kvs_int_t)KviError::translateSystemError(err)))); + } else { + callFunction(this,"disconnectEvent",new KviKvsVariantList( + new KviKvsVariant(KviError::getDescription(KviError_remoteEndClosedConnection)))); + + } + if(m_uConnectionId == uOldConnectionId)reset(); + // else it has already been called! + return; + } //else transient error...wait again... + } + return; // can do nothing + } + // readLength > 0 + m_uInDataLen += readLength; + + //KviStr * s = new KviStr(); + QString s; + s.setNum(m_uInDataLen); + + + unsigned int uOldConnectionId = m_uConnectionId; + callFunction(this,"dataAvailableEvent",new KviKvsVariantList(new KviKvsVariant(s))); + if(m_uConnectionId == uOldConnectionId) + { + if(m_uInDataLen > (4096 * 1024)) // too much data in buffer (not reading) + { + callFunction(this,"disconnectEvent",new KviKvsVariantList( + new KviKvsVariant(__tr2qs("Too much unprocessed incoming data (you've left this socket unmanaged ?)")))); + reset(); + } + } +} + +void KviKvsObject_socket::eatInData(unsigned int uLen) +{ + if(uLen > m_uInDataLen)uLen = m_uInDataLen; + + m_uInDataLen -= uLen; + + if(m_uInDataLen > 0) + { + kvi_memmove(m_pInBuffer,m_pInBuffer + uLen,m_uInDataLen); + } + + unsigned int uSpace = m_uInBufferLen - m_uInDataLen; + + if(uSpace > KVI_IN_BUFFER_ALLOC_CHUNK) + { + m_uInBufferLen -= KVI_IN_BUFFER_ALLOC_CHUNK; + m_pInBuffer = (char *)kvi_realloc(m_pInBuffer,m_uInBufferLen); + } +} + +void KviKvsObject_socket::delayedFlush(unsigned int uTimeout) +{ + if(m_pFlushTimer->isActive())m_pFlushTimer->stop(); + m_pFlushTimer->start(uTimeout); +} + +void KviKvsObject_socket::tryFlush() +{ + if(m_pFlushTimer->isActive())m_pFlushTimer->stop(); + + if(m_pOutBuffer->size() == 0) + { + return; + } + + int result = kvi_socket_send(m_sock,m_pOutBuffer->data(),m_pOutBuffer->size()); + + if(result >= 0) + { + if(result == m_pOutBuffer->size()) + { + m_pOutBuffer->clear(); + } else { + if(result > 0)m_pOutBuffer->remove(result); + delayedFlush(500); + } + } else { + // Oops...error ? + int err = kvi_socket_error(); +#ifdef COMPILE_ON_WINDOWS + if((err == EAGAIN) || (err == EINTR) || (err = WSAEWOULDBLOCK)) +#else + if((err == EAGAIN)||(err == EINTR)) +#endif + { + // Transient error...partial send as before... + // Async continue... + delayedFlush(500); + return; + } else { + // Disconnected... :( + unsigned int uOldConnectionId = m_uConnectionId; + callFunction(this,"disconnectEvent",0,new KviKvsVariantList( + new KviKvsVariant(KviError::getDescription(KviError::translateSystemError(err))))); + if(m_uConnectionId == uOldConnectionId)reset(); + // else it has already been called! + return; + } + } +} +void KviKvsObject_socket::reset() +{ + m_uConnectionId++; // this is the only place where this is incremented! + if(m_pDelayTimer) + { + delete m_pDelayTimer; + m_pDelayTimer = 0; + } + if(m_pDns) + { + delete m_pDns; + m_pDns = 0; + } + if(m_pSn) + { + delete m_pSn; + m_pSn = 0; + } + if(m_sock != KVI_INVALID_SOCKET) + { + kvi_socket_close(m_sock); + m_sock = KVI_INVALID_SOCKET; + } + if(m_pInBuffer) + { + kvi_free(m_pInBuffer); + m_pInBuffer = 0; + } + if(m_secondarySock) + { + kvi_socket_close(m_secondarySock); + m_secondarySock = KVI_INVALID_SOCKET; + } + m_uSecondaryPort = 0; + m_szSecondaryIp=""; + delete m_pOutBuffer; + if(m_pFlushTimer->isActive())m_pFlushTimer->stop(); + m_pOutBuffer = new KviDataBuffer(); + m_uInBufferLen = 0; + m_uInDataLen = 0; + m_iStatus = KVI_SCRIPT_SOCKET_STATUS_DISCONNECTED; + m_uRemotePort = 0; + m_szRemoteIp=""; + m_uLocalPort = 0; + m_szLocalIp=""; + m_bIpV6 = false; +} +unsigned int KviKvsObject_socket::readGetLength(KviKvsObjectFunctionCall *c) +{ + kvs_uint_t uLen; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("length",KVS_PT_UNSIGNEDINTEGER,KVS_PF_OPTIONAL,uLen) + KVSO_PARAMETERS_END(c) + if (uLen>m_uInDataLen || !uLen) return m_uInDataLen; + else return uLen; + } + +bool KviKvsObject_socket::functionRead(KviKvsObjectFunctionCall *c) +{ + unsigned int uLen = readGetLength(c); + + if(uLen > 0) + { + // convert NULLS to char 255 + for(unsigned int i = 0;i < uLen;i++) + { + if(!m_pInBuffer[i])m_pInBuffer[i] = (char)(255); + } + QString tmpBuffer = QString::fromUtf8(m_pInBuffer,uLen); + c->returnValue()->setString(tmpBuffer); + + eatInData(uLen); + } + return true; +} + +bool KviKvsObject_socket::functionReadHex(KviKvsObjectFunctionCall *c) +{ + //??? funzioner� + unsigned int uLen = readGetLength(c); + bool bOk; + if(uLen > 0) + { + QString szTmp; + szTmp =m_pInBuffer; + szTmp.toInt(&bOk,16); + c->returnValue()->setString(szTmp); + eatInData(uLen); + } + return true; +} + +bool KviKvsObject_socket::functionWrite(KviKvsObjectFunctionCall *c) +{ + QString szData; + KVSO_PARAMETERS_BEGIN(c) + KVSO_PARAMETER("szData",KVS_PT_STRING,0,szData) + KVSO_PARAMETERS_END(c) + +KviQCString szData8 = szData.utf8(); + if(szData8.length() > 0) + { + m_pOutBuffer->append((const unsigned char*)szData8.data(),szData8.length()); + delayedFlush(0); + } + return true; +} + + + +//-------------- + +#include "m_class_socket.moc" diff --git a/src/modules/objects/class_spinbox.cpp b/src/modules/objects/class_spinbox.cpp index ce32f5cdc..6b0147f24 100644 --- a/src/modules/objects/class_spinbox.cpp +++ b/src/modules/objects/class_spinbox.cpp @@ -196,7 +196,15 @@ bool KviKvsObject_spinbox::functionmaxValue(KviKvsObjectFunctionCall *c) } bool KviKvsObject_spinbox::functionlineStep(KviKvsObjectFunctionCall *c) { - if (widget()) c->returnValue()->setInteger(((QSpinBox *)widget())->lineStep()); + if (widget()) + { + #ifdef COMPILE_USE_QT4 + c->returnValue()->setInteger(((QSpinBox *)widget())->singleStep()); + #else + c->returnValue()->setInteger(((QSpinBox *)widget())->lineStep()); + #endif + } + return true; } diff --git a/src/modules/objects/class_tabwidget.cpp b/src/modules/objects/class_tabwidget.cpp index 351fa7045..998bb3f44 100644 --- a/src/modules/objects/class_tabwidget.cpp +++ b/src/modules/objects/class_tabwidget.cpp @@ -215,7 +215,13 @@ bool KviKvsObject_tabwidget::functionaddTab(KviKvsObjectFunctionCall *c) } QPixmap * pix = g_pIconManager->getImage(szIcon); - if(pix)((QTabWidget *)widget())->addTab(((QWidget *)(ob->object())),QIconSet(*pix,QIconSet::Small),szLabel); + if(pix){ +#ifdef COMPILE_USE_QT4 + ((QTabWidget *)widget())->addTab(((QWidget *)(ob->object())),QIconSet(*pix),szLabel); +#else + ((QTabWidget *)widget())->addTab(((QWidget *)(ob->object())),QIconSet(*pix,QIconSet::Small),szLabel); +#endif + } else((QTabWidget *)widget())->addTab(((QWidget *)(ob->object())),szLabel); return true; } @@ -250,7 +256,13 @@ bool KviKvsObject_tabwidget::functioninsertTab(KviKvsObjectFunctionCall *c) return true; } QPixmap * pix = g_pIconManager->getImage(szIcon); - if(pix) ((QTabWidget *)widget())->insertTab(((QWidget *)(ob->object())),QIconSet(*pix,QIconSet::Small),szLabel,uIndex); + if(pix){ + #ifdef COMPILE_USE_QT4 + ((QTabWidget *)widget())->insertTab( ((QWidget *)(ob->object())),QIconSet(*pix),szLabel,uIndex); + #else + ((QTabWidget *)widget())->insertTab(((QWidget *)(ob->object())),QIconSet(*pix,QIconSet::Small),szLabel,uIndex); + #endif + } else ((QTabWidget *)widget())->insertTab(((QWidget *)(ob->object())),szLabel,uIndex); return true; } @@ -486,7 +498,13 @@ bool KviKvsObject_tabwidget::functionchangeTab(KviKvsObjectFunctionCall *c) return true; } QPixmap * pix = g_pIconManager->getImage(szIcon); - if(pix) ((QTabWidget *)widget())->changeTab(((QWidget *)(ob->object())),QIconSet(*pix,QIconSet::Small),szLabel); + if(pix){ + #ifdef COMPILE_USE_QT4 + ((QTabWidget *)widget())->changeTab(((QWidget *)(ob->object())),QIconSet(*pix),szLabel); + #else + ((QTabWidget *)widget())->changeTab(((QWidget *)(ob->object())),QIconSet(*pix,QIconSet::Small),szLabel); + #endif + } else ((QTabWidget *)widget())->changeTab(((QWidget *)(ob->object())),szLabel); return true; } diff --git a/src/modules/objects/class_toolbar.cpp b/src/modules/objects/class_toolbar.cpp index 2a1a4eb81..c8391afea 100644 --- a/src/modules/objects/class_toolbar.cpp +++ b/src/modules/objects/class_toolbar.cpp @@ -24,7 +24,8 @@ #include "class_toolbar.h" #include "kvi_error.h" #include "kvi_debug.h" - +#include "kvi_tal_toolbar.h" +#include "kvi_tal_mainwindow.h" #include "kvi_locale.h" #include "kvi_iconmanager.h" #include "class_mainwindow.h" @@ -85,7 +86,7 @@ bool KviKvsObject_toolbar::init(KviKvsRunTimeContext * pContext,KviKvsVariantLis } if(parentObject()->inherits("KviKvsObject_mainwindow")) { - setObject(new QToolBar(((QMainWindow *)parentScriptWidget()), name()), true); + setObject(new KviTalToolBar(((KviTalMainWindow *)parentScriptWidget()), name()), true); } else { @@ -97,7 +98,7 @@ bool KviKvsObject_toolbar::init(KviKvsRunTimeContext * pContext,KviKvsVariantLis bool KviKvsObject_toolbar::functionaddSeparator(KviKvsObjectFunctionCall *c) { - if(widget()) ((QToolBar *)widget())->addSeparator(); + if(widget()) ((KviTalToolBar *)widget())->addSeparator(); return true; } bool KviKvsObject_toolbar::functionsetLabel(KviKvsObjectFunctionCall *c) @@ -106,12 +107,12 @@ bool KviKvsObject_toolbar::functionsetLabel(KviKvsObjectFunctionCall *c) KVSO_PARAMETERS_BEGIN(c) KVSO_PARAMETER("label",KVS_PT_STRING,0,szLabel) KVSO_PARAMETERS_END(c) - if (widget()) ((QToolBar *)widget())->setLabel(szLabel); + if (widget()) ((KviTalToolBar *)widget())->setLabel(szLabel); return true; } bool KviKvsObject_toolbar::functionlabel(KviKvsObjectFunctionCall *c) { - if (widget()) c->returnValue()->setString(((QToolBar *)widget())->label()); + if (widget()) c->returnValue()->setString(((KviTalToolBar *)widget())->label()); return true; } bool KviKvsObject_toolbar::functionsetStretchableWidget(KviKvsObjectFunctionCall *c) @@ -138,13 +139,13 @@ bool KviKvsObject_toolbar::functionsetStretchableWidget(KviKvsObjectFunctionCall c->warning(__tr2qs("Widget object required")); return TRUE; } - if(widget()) ((QToolBar *)widget())->setStretchableWidget(((QWidget *)(ob->object()))); + if(widget()) ((KviTalToolBar *)widget())->setStretchableWidget(((QWidget *)(ob->object()))); return true; } bool KviKvsObject_toolbar::functionclear(KviKvsObjectFunctionCall *c) { if (widget()) - ((QToolBar *)object())->clear(); + ((KviTalToolBar *)object())->clear(); return true; } diff --git a/src/modules/objects/class_toolbar.h b/src/modules/objects/class_toolbar.h index 1d52f8f94..7b18ff78d 100644 --- a/src/modules/objects/class_toolbar.h +++ b/src/modules/objects/class_toolbar.h @@ -25,7 +25,7 @@ -#include + #include "class_widget.h" #include "object_macros.h" diff --git a/src/modules/objects/class_toolbutton.cpp b/src/modules/objects/class_toolbutton.cpp index 4508540bc..3a531da30 100644 --- a/src/modules/objects/class_toolbutton.cpp +++ b/src/modules/objects/class_toolbutton.cpp @@ -142,7 +142,13 @@ bool KviKvsObject_toolbutton::functionsetImage(KviKvsObjectFunctionCall *c) KVSO_PARAMETERS_END(c) if (!widget()) return true; QPixmap * pix = g_pIconManager->getImage(icon); - if(pix) ((QToolButton *)widget())->setIconSet(QIconSet(*pix,QIconSet::Small)); + if(pix){ + #ifdef COMPILE_USE_QT4 + ((QToolButton *)widget())->setIconSet(QIconSet(*pix)); + #else + ((QToolButton *)widget())->setIconSet(QIconSet(*pix,QIconSet::Small)); + #endif + } else ((QToolButton *)widget())->setIconSet(QIconSet()); return true; @@ -231,8 +237,14 @@ bool KviKvsObject_toolbutton::functionsetTextLabel(KviKvsObjectFunctionCall *c) KVSO_PARAMETER("tooltip",KVS_PT_STRING,KVS_PF_OPTIONAL,szTip) KVSO_PARAMETERS_END(c) if(!widget()) return true; - if (szTip.isEmpty()) ((QToolButton *)widget())->setTextLabel(szLabel); - else ((QToolButton *)widget())->setTextLabel(szLabel,szTip); + + #ifdef COMPILE_USE_QT4 + ((QToolButton *)widget())->setText(szLabel); + if (!szTip.isEmpty()) ((QToolButton *)widget())->setToolTip(szTip); + #else + if (szTip.isEmpty()) ((QToolButton *)widget())->setTextLabel(szLabel); + else ((QToolButton *)widget())->setTextLabel(szLabel,szTip); + #endif return true; } bool KviKvsObject_toolbutton::functiontextLabel(KviKvsObjectFunctionCall *c) diff --git a/src/modules/objects/class_urllabel.cpp b/src/modules/objects/class_urllabel.cpp index f37d76e20..e43aa074b 100644 --- a/src/modules/objects/class_urllabel.cpp +++ b/src/modules/objects/class_urllabel.cpp @@ -32,6 +32,12 @@ #include "kvi_window.h" #include "kvi_kvs_script.h" +#ifdef COMPILE_USE_QT4 +#include +#define QT_LEFT_BUTTON Qt::LeftButton +#else +#define QT_LEFT_BUTTON QEvent::LeftButton +#endif //#warning "Functions to change colors for different states" //#warning "$setUnderline(), $underline()" @@ -197,7 +203,7 @@ bool KviKvsObject_urlabel::eventFilter(QObject * o, QEvent * e) break; case QEvent::Leave: // this doesn't work... - if(((QMouseEvent *)e)->state() & QEvent::LeftButton) + if(((QMouseEvent *)e)->state() & QT_LEFT_BUTTON) pal.setColor(QColorGroup::Foreground, \ m_activeClr); else @@ -222,7 +228,7 @@ bool KviKvsObject_urlabel::eventFilter(QObject * o, QEvent * e) case QEvent::MouseButtonPress: m_lastClickWasDbl = false; if(!((QMouseEvent * )e)->button() & \ - QEvent::LeftButton || !m_useSingleClick) + QT_LEFT_BUTTON || !m_useSingleClick) break; pal.setColor(QColorGroup::Foreground, m_activeClr); break; diff --git a/src/modules/objects/class_widget.cpp b/src/modules/objects/class_widget.cpp index a78e62306..a2bd7e601 100644 --- a/src/modules/objects/class_widget.cpp +++ b/src/modules/objects/class_widget.cpp @@ -1,1640 +1,1679 @@ -//============================================================================= -// -// File : class_widget.cpp -// Creation date : Mon Sep 11 16:35:32 CET 2000 by Krzysztof Godlewski -// -// This file is part of the KVirc irc client distribution -// Copyright (C) 1999-2005 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. ,59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. -// -//============================================================================= - -#include "kvi_malloc.h" -#include "kvi_debug.h" - -#include "kvi_error.h" -#include "kvi_locale.h" -#include "kvi_iconmanager.h" -#include "kvi_window.h" -#include "kvi_out.h" -#include "kvi_mirccntrl.h" -#include "kvi_app.h" -#include "kvi_string.h" -#include -#include -#include -#include -#include -#include "class_widget.h" -#include "class_pixmap.h" -#include -#include -#include -#include -#include - -const char * const widgettypes_tbl[] = { - "TopLevel", - "Dialog", - "Popup", - "Desktop", - "Customize", - "Title", - "StaysOnTop", - "SysMenu", - "Minimize", - "Maximize", - "NoAutoErase" - }; -const int widgettypes_cod[] = { - Qt::WType_TopLevel, - Qt::WType_Dialog, - Qt::WType_Popup, - Qt::WType_Desktop, - Qt::WStyle_Customize, - Qt::WStyle_Title, - Qt::WStyle_StaysOnTop, - Qt::WStyle_SysMenu, - Qt::WStyle_Minimize, - Qt::WStyle_Maximize, - Qt::WNoAutoErase -}; - -#define widgettypes_num (sizeof(widgettypes_tbl) / sizeof(widgettypes_tbl[0])) - -/* - @doc: widget - @keyterms: - widget object class - @title: - widget class - @type: - class - @short: - Base class for all widgets - @inherits: - [class]object[/class] - @description: - This object class is the rappresentation of a widget. - All the other widget-type classes inherit from this one. - @functions: - !fn: $show() - Shows this widget and the children. - See also [classfnc]$hide[/classfnc]() and [classfnc]$isVisible[/classfnc]. - !fn: $hide() - Hides this widget (and conseguently all the children). - See also [classfnc]$show[/classfnc]() and [classfnc]$isVisible[/classfnc]. - !fn: $repaint() - Repaints the widget directly by calling [classfnc]$paintEvent[/classfnc]() immediately.[br] - If erase is TRUE, erases the widget before the $paintEvent() call. - !fn: $x() - Returns the x coordinate of the upper-left corner - of this widget relative to the parent widget, - or to the desktop if this widget is a toplevel one. - !fn: $y() - Returns the y coordinate of the uspper-left corner - of this widget relative to the parent widget, - or to the desktop if this widget is a toplevel one. - !fn: $width() - Returns the width of this widget in pixels. - !fn: $height() - Returns the height of this widget in pixels. - !fn: $geometry() - Returns the widget geometry in this form:[br] - x, y, width, height. - !fn: $setGeometry(,[,,]) - Sets the geometry of this widget. and are relative - to the parent widget or to the desktop (if this widget is - a toplevel one). All the parameters are in pixels. - !fn: $setMinimumWidth() - Sets the minimum width of this widget to . - The user will not be able to resize the widget to a smaller - value. This value is also used by the [class:layout]layout class[/class]. - !fn: $setMinimumHeight() - Sets the minimum height of this widget to . - The user will not be able to resize the widget to a smaller - value. This value is also used by the [class:layout]layout class[/class]. - !fn: $setMaximumWidth() - Sets the maximum width of this widget to . - The user will not be able to resize the widget to a bigger - value. This value is also used by the [class:layout]layout class[/class]. - !fn: $setMaximumHeight() - Sets the maximum height of this widget to . - The user will not be able to resize the widget to a bigger - value. This value is also used by the [class:layout]layout class[/class]. - !fn: $move([,]) - Moves this widget to the coordinate and relative to its - parent widget (or the desktop if this widget is a toplevel one). - This is equivalent to [classfnc]$setGeometry[/classfnc](,, - [classfnc]$width[/classfnc](),[classfnc]$height[/classfnc]()). - !fn: $resize(,[height]) - Changes the widget's width to and height to . - See also [classfnc]$setGeometry[/classfnc](). - !fn: $isEnabled() - Returns '1' if the widget is enabled , '0' otherwise. - See also [classfnc:widget]$setEnabled[/classfnc](). - !fn: $setEnabled() - Sets the widget state to enabled or disabled if is 1 or 0 respectively. - A disabled widget does not receive keyboard nor mouse input. - !fn: $setCaption() - Sets the caption of this widget to . - This is meaningful for toplevel widgets only. - !fn: $setToolTip() - Set the tooltip of this widget; the text can contain HTML formatting. - !fn: $window.caption() - Returns the caption text of this widget. - !fn: $isTopLevel() - Returns '1' if this widget is a toplevel (parentless) one, - '0' otherwise. - !fn: $isVisible() - Returns '1' if this widget is currently visible (read: is managed - by the window manager and displayed by the X server; the widget - may be hidden behind other widgets). If the widget is not visible - this function returns '0'. - See also [classfnc]$show[/classfnc]() and [classfnc]$hide[/classfnc](). - !fn: $raise() - Moves this widget to the top of the stack of the widgets relative - to its parent. See also [classfnc]$lower[/classfnc]. - !fn: $lower() - Moves this widget to the bottom of the stack of the widgets relative - to its parent. See also [classfnc]$raise[/classfnc] - !fn: $hasFocus() - Returns '1' if this widget has the keyboard focus. - See also [classfnc]$setFocus[/classfnc]. - !fn: $setFocus() - Sets this widget to be the one that receives keyboard events. - See also [classfnc]$hasFocus[/classfnc] - !fn: $parentWidget() - Returns the object id of the parent widget, or '0' if this - widget is a toplevel one. - !fn: $backgroundColor() - Returns the background color of this widget in hexadecimal - html-like format. For example , for a black bacground you will get - the string "000000" , for a red one , "FF0000", for a white one - "FFFFFF". See also [classfnc]$setBackgroundColor[/classfnc]() - !fn: $setBackgroundColor(,[geen:integer],[blue:integer]) - Sets the background color of this widget to :valid values are: - - hex string: must be a string with 6 hexadecimal digits (like the ones used to - specify colors in html pages). The first two digits specify - the RED component, the third and fourth digit specify the GREEN component - and the last two specify the BLUE component. - For example "FFFF00" means full red, full green and no blue that gives - a yellow color, "808000" designates a brown color (dark yellow), - "A000A0" is a kind of violet. - - array(red:integer,green:integer,blue:integer) - - red:integer,green:integer,blue:integer. - See also [classfnc]$foregroundColor[/classfnc]. - !fn: $setForegroundColor(,[geen:integer],[blue:integer]) - Sets the foreground color of this widget to :valid values are: - - hex string: must be a string with 6 hexadecimal digits (like the ones used to - specify colors in html pages). The first two digits specify - the RED component, the third and fourth digit specify the GREEN component - and the last two specify the BLUE component. - For example "FFFF00" means full red, full green and no blue that gives - a yellow color, "808000" designates a brown color (dark yellow), - "A000A0" is a kind of violet. - - array(red:integer,green:integer,blue:integer) - - red:integer,green:integer,blue:integer. - See also [classfnc]$foregroundColor[/classfnc]. - !fn: $foregroundColor() - Returns the foreground color of this widget in hexadecimal - html-like format. - See also [classfnc]$setForegroundColor[/classfnc]. - !fn: $setMouseTracking() - Enables or disables the mouse tracking if is '1' or '0' respectively. - When mouse tracking is enabled you will receive mouse move events - even if no button is pressed, otherwise you will receive it only - when a mouse button is being pressed (so after a mousePressEvent). - !fn: $mousePressEvent(