You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
kvirc/src/kvirc/kvs/kvi_kvs_treenode_specialcom...

158 lines
5.1 KiB

//=============================================================================
//
// File : kvi_kvs_treenode_specialcommandclass.cpp
// Created on Fri 12 Aug 2005 03:23:31 by Szymon Stefanek
//
// This file is part of the KVIrc IRC Client distribution
// Copyright (C) 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. ,51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
//=============================================================================
#define __KVIRC__
#include "kvi_locale.h"
#include "kvi_kvs_variantlist.h"
#include "kvi_kvs_variant.h"
#include "kvi_kvs_treenode_specialcommandclass.h"
#include "kvi_kvs_kernel.h"
#include "kvi_kvs_object_controller.h"
#include "kvi_kvs_object_class.h"
KviKvsTreeNodeSpecialCommandClassFunctionDefinition::KviKvsTreeNodeSpecialCommandClassFunctionDefinition(const TQChar * pLocation,const TQString &szName,const TQString &szBuffer,unsigned int uHandlerFlags)
: KviKvsTreeNode(pLocation)
{
m_uHandlerFlags = uHandlerFlags;
m_szName = szName;
m_szBuffer = szBuffer;
}
void KviKvsTreeNodeSpecialCommandClassFunctionDefinition::dump(const char * prefix)
{
tqDebug("%s SpecialCommandClassFunctionDefinition(%s)",prefix,m_szName.utf8().data());
tqDebug("%s (command buffer with %d characters)",prefix,m_szBuffer.length());
}
void KviKvsTreeNodeSpecialCommandClassFunctionDefinition::contextDescription(TQString &szBuffer)
{
KviTQString::sprintf(szBuffer,"Object Member Function Definition \"%Q\"",&m_szName);
}
KviKvsTreeNodeSpecialCommandClass::KviKvsTreeNodeSpecialCommandClass(const TQChar * pLocation,KviKvsTreeNodeDataList * pParams)
: KviKvsTreeNodeSpecialCommand(pLocation,"class")
{
m_pParams = pParams;
m_pParams->setParent(this);
m_pFunctions = new KviPointerList<KviKvsTreeNodeSpecialCommandClassFunctionDefinition>;
m_pFunctions->setAutoDelete(true);
}
KviKvsTreeNodeSpecialCommandClass::~KviKvsTreeNodeSpecialCommandClass()
{
delete m_pParams;
delete m_pFunctions;
}
void KviKvsTreeNodeSpecialCommandClass::addFunctionDefinition(KviKvsTreeNodeSpecialCommandClassFunctionDefinition * pDef)
{
pDef->setParent(this);
m_pFunctions->append(pDef);
}
void KviKvsTreeNodeSpecialCommandClass::contextDescription(TQString &szBuffer)
{
szBuffer = "Special Command \"class\"";
}
void KviKvsTreeNodeSpecialCommandClass::dump(const char * prefix)
{
tqDebug("%s SpecialCommandClass",prefix);
TQString tmp = prefix;
tmp.append(" ");
m_pParams->dump(tmp.utf8().data());
for(KviKvsTreeNodeSpecialCommandClassFunctionDefinition * d = m_pFunctions->first();d;d = m_pFunctions->next())
d->dump(tmp.utf8().data());
}
bool KviKvsTreeNodeSpecialCommandClass::execute(KviKvsRunTimeContext * c)
{
KviKvsVariantList l;
if(!m_pParams->evaluate(c,&l))return false;
KviKvsVariant * pClassName = l.first();
if(!pClassName)
{
c->error(this,__tr2qs("Missing class name"));
return false;
}
KviKvsVariant * pBaseClassName = l.next();
TQString szClassName;
TQString szBaseClassName;
pClassName->asString(szClassName);
if(pBaseClassName)
pBaseClassName->asString(szBaseClassName);
if(szClassName.isEmpty())
{
c->error(this,__tr2qs("Missing class name"));
return false;
}
if(szBaseClassName.isEmpty())szBaseClassName = "object";
// avoid infinite recursion in loading the base class
if(KviTQString::equalCI(szBaseClassName,szClassName))
{
c->error(__tr2qs("A class can't be a subclass of itself"));
return false;
}
KviKvsObjectClass * pBaseClass = KviKvsKernel::instance()->objectController()->lookupClass(szBaseClassName);
if(!pBaseClass)
{
c->error(this,__tr2qs("Couln't find base class named \"%Q\""),&szBaseClassName);
return false;
}
// walk the inheritance tree of the base class in order to detect loops
KviKvsObjectClass * pClass = pBaseClass;
while(pClass)
{
if(KviTQString::equalCI(pClass->name(),szClassName))
{
c->error(this,__tr2qs("Detected a loop in the inheritance tree of the base class \"%Q\": redefine that class first"),&szBaseClassName);
return false;
}
pClass = pClass->parentClass();
}
KviKvsObjectClass * pActualClass = KviKvsKernel::instance()->objectController()->lookupClass(szClassName,true);
if(pActualClass)
{
c->error(this,__tr2qs("Can't override the builtin class \"%Q\""),&szClassName);
return false;
}
pActualClass = new KviKvsObjectClass(pBaseClass,szClassName,0,false);
for(KviKvsTreeNodeSpecialCommandClassFunctionDefinition * d = m_pFunctions->first();d;d = m_pFunctions->next())
{
pActualClass->registerFunctionHandler(d->name(),d->buffer(),d->handlerFlags());
}
return true;
}