bool KviKvsTreeNodeMultipleParameterIdentifier::evaluateReadOnly(KviKvsRunTimeContext * c,KviKvsVariant * pBuffer) { KviKvsVariant * v = c->parameterList()->at(m_iStart); if(!v) { pBuffer->setNothing(); return true; } QString sz; v->asString(sz); if(m_iEnd >= m_iStart) { // only up to m_iEnd int idx = m_iStart; for(v = c->parameterList()->next(); v && (idx < m_iEnd); v = c->parameterList()->next()) { sz += QChar(' '); v->appendAsString(sz); idx++; } } else { // all up to the end of the list for(v = c->parameterList()->next(); v; v = c->parameterList()->next()) { sz += QChar(' '); v->appendAsString(sz); } } pBuffer->setString(sz); return true; }
bool KviKvsTreeNodeSpecialCommandWhile::execute(KviKvsRunTimeContext * c) { for(;;) { KviKvsVariant v; if(!m_pExpression->evaluateReadOnly(c, &v)) return false; if(!v.asBoolean()) break; if(m_pInstruction) { if(!m_pInstruction->execute(c)) { if(c->error()) return false; if(c->breakPending()) { c->handleBreak(); return true; } if(c->continuePending()) { c->handleContinue(); continue; } return false; } } } return true; }
bool urllist_module_event_onUrl(KviKvsModuleEventCall * c) { KviKvsVariant * vUrl = c->firstParam(); QString szUrl; if(vUrl)vUrl->asString(szUrl); if (check_url(c->window(),szUrl) == 0) { KviUrl *tmp = new KviUrl; QString tmpTimestamp; QDate d = QDate::currentDate(); QString date; date.sprintf("%d-%d%d-%d%d",d.year(),d.month() / 10,d.month() % 10,d.day() / 10,d.day() % 10); tmpTimestamp = "["+date+"]"+" ["; tmpTimestamp += QTime::currentTime().toString()+"]"; tmp->url = szUrl; tmp->window = c->window()->plainTextCaption(); tmp->count = 1; tmp->timestamp = tmpTimestamp; g_pList->append(tmp); for (UrlDlgList *tmpitem=g_pUrlDlgList->first();tmpitem;tmpitem=g_pUrlDlgList->next()) { if (tmpitem->dlg) { QString tmpCount; tmpCount.setNum(tmp->count); tmpitem->dlg->addUrl(QString(tmp->url), QString(tmp->window), tmpCount, QString(tmp->timestamp)); tmpitem->dlg->windowListItem()->highlight(false); } } } return true; }
int KviKvsScript::run(KviWindow * pWnd, KviKvsVariantList * pParams, QString & szRetVal, int iRunFlags, KviKvsExtendedRunTimeData * pExtData) { KviKvsVariant retVal; int iRet = run(pWnd, pParams, &retVal, iRunFlags, pExtData); retVal.asString(szRetVal); return iRet; }
KviKvsRWEvaluationResult * KviKvsTreeNodeHashElement::evaluateReadWriteInObjectScope(KviKvsObject *o,KviKvsRunTimeContext * c) { KviKvsVariant key; if(!m_pKey->evaluateReadOnly(c,&key))return 0; QString szKey; key.asString(szKey); if(szKey.isEmpty()) { c->warning(this,__tr2qs_ctx("Hash key evaluated to empty string: fix the script","kvs")); } KviKvsRWEvaluationResult * result; if(o)result = m_pSource->evaluateReadWriteInObjectScope(o,c); else result = m_pSource->evaluateReadWrite(c); if(!result)return 0; if(!result->result()->isHash()) { // convert to hash in some way //#warning "Supply a *real* conversion from other types to array ?" if(!result->result()->isNothing()) { QString szType; result->result()->getTypeName(szType); c->warning(this,__tr2qs_ctx("The argument of the {} subscript didn't evaluate to a hash: automatic conversion from %Q supplied","kvs"),&szType); } result->result()->setHash(new KviKvsHash()); } return new KviKvsHashElement(result,result->result()->hash()->get(szKey),result->result()->hash(),szKey); }
bool KviKvsTreeNodeSpecialCommandSwitchLabelRegexp::execute(KviKvsRunTimeContext * c,KviKvsVariant * pRealParameter, bool * bPassThrough) { if(!(*bPassThrough)) { KviKvsVariant v; if(!m_pParameter->evaluateReadOnly(c,&v))return false; QString reg; v.asString(reg); // QRegExp rx(reg,false,false); QRegExp rx(reg,Qt::CaseInsensitive,QRegExp::RegExp); QString val; pRealParameter->asString(val); if(!rx.exactMatch(val))return true; // no match } *bPassThrough = true; if(m_pInstruction) { if(!m_pInstruction->execute(c))return false; // might be a break too } if(m_bHasTerminatingBreak) { c->setBreakPending(); return false; } return true; }
bool KviKvsVariantList::nextAsString(QString & szBuffer) { KviKvsVariant * v = next(); if(!v) return false; v->asString(szBuffer); return true; }
int KviKvsScript::evaluateAsString(const QString & szCode, KviWindow * pWindow, KviKvsVariantList * pParams, QString & szRetVal) { // static helper KviKvsVariant ret; KviKvsScript s("kvirc::corecall(evaluate)", szCode, Parameter); int iRet = s.run(pWindow, pParams, &ret, PreserveParams); ret.asString(szRetVal); return iRet; }
void KviWindow::getDefaultLogFileName(QString & szBuffer, QDate date, bool bGzip, unsigned int uDatetimeFormat) { QString szLog; // dynamic log path QString szDynamicPath = KVI_OPTION_STRING(KviOption_stringLogsDynamicPath).trimmed(); if(!szDynamicPath.isEmpty()) { KviQString::escapeKvs(&szDynamicPath, KviQString::PermitVariables | KviQString::PermitFunctions); KviKvsVariant vRet; if(KviKvsScript::evaluate(szDynamicPath, this, nullptr, &vRet)) vRet.asString(szDynamicPath); } g_pApp->getLocalKvircDirectory(szLog, KviApplication::Log, szDynamicPath); KviQString::ensureLastCharIs(szLog, KVI_PATH_SEPARATOR_CHAR); //ensure the directory exists KviFileUtils::makeDir(szLog); QString szDate; switch(uDatetimeFormat) { case 1: szDate = date.toString(Qt::ISODate); break; case 2: szDate = date.toString(Qt::SystemLocaleShortDate); break; case 0: default: szDate = date.toString("yyyy.MM.dd"); break; } szDate.replace('_', '-'); // this would confuse the log viewer KviFileUtils::cleanFileName(szDate); QString szBase; getBaseLogFileName(szBase); KviFileUtils::encodeFileName(szBase); szBase = szBase.toLower(); szBase.replace("%%2e", "%2e"); QString szTmp; if(bGzip) szTmp = "%1_%2_%3.log.gz"; else szTmp = "%1_%2_%3.log"; szLog.append(QString(szTmp).arg(typeString(), szBase, szDate)); szBuffer = szLog; }
static bool theme_kvs_cmd_pack(KviKvsModuleCommandCall * c) { QString szPath, szName, szVersion, szDescription, szAuthor, szImage; KviKvsArrayCast aCast; KVSM_PARAMETERS_BEGIN(c) KVSM_PARAMETER("package_path", KVS_PT_NONEMPTYSTRING, 0, szPath) KVSM_PARAMETER("package_name", KVS_PT_NONEMPTYSTRING, 0, szName) KVSM_PARAMETER("package_version", KVS_PT_NONEMPTYSTRING, 0, szVersion) KVSM_PARAMETER("package_description", KVS_PT_STRING, 0, szDescription) KVSM_PARAMETER("package_author", KVS_PT_NONEMPTYSTRING, 0, szAuthor) KVSM_PARAMETER("package_image", KVS_PT_STRING, 0, szImage) KVSM_PARAMETER("theme", KVS_PT_ARRAYCAST, 0, aCast) KVSM_PARAMETERS_END(c) KviKvsArray * pArray = aCast.array(); if((!pArray) || (pArray->size() < 1)) { c->error(__tr2qs_ctx("No themes specified", "theme")); return false; } kvs_uint_t s = pArray->size(); QStringList lThemeList; for(kvs_uint_t i = 0; i < s; i++) { KviKvsVariant * v = pArray->at(i); if(!v) continue; // ? QString szVal; v->asString(szVal); if(szVal.isEmpty()) continue; lThemeList.append(szVal); } KviPointerList<KviThemeInfo> lThemeInfoList; lThemeInfoList.setAutoDelete(true); Q_FOREACH(QString szTheme, lThemeList) { KviThemeInfo * pInfo = new KviThemeInfo(); if(!pInfo->load(szTheme, KviThemeInfo::External)) { QString szErr = pInfo->lastError(); c->error(__tr2qs_ctx("Failed to load theme from directory %Q: %Q", "theme"), &szTheme, &szErr); delete pInfo; return false; } lThemeInfoList.append(pInfo); }
bool KviKvsTreeNodeSpecialCommandSwitchLabelCase::execute(KviKvsRunTimeContext * c,KviKvsVariant * pRealParameter, bool * bPassThrough) { if(!(*bPassThrough)) { KviKvsVariant v; if(!m_pParameter->evaluateReadOnly(c,&v))return false; KviKvsNumber num; if(pRealParameter->asNumber(num)) { KviKvsNumber num2; if(!v.asNumber(num2))return true; // a number and a non number can't match if(num.isInteger()) { if(num2.isInteger()) { if(num.integer() != num2.integer())return true; } else { if(((double)(num.integer())) != num2.real())return true; } } else { if(num2.isInteger()) { if(num.real() != ((double)(num2.integer())))return true; } else { if(num.real() != num2.real())return true; } } } else { // string comparision, case insensitive QString reg; v.asString(reg); QString val; pRealParameter->asString(val); if(reg.toLower() != val.toLower())return true; } } *bPassThrough = true; if(m_pInstruction) { if(!m_pInstruction->execute(c))return false; // might be a break too } if(m_bHasTerminatingBreak) { c->setBreakPending(); return false; } return true; }
bool KviKvsTreeNodeSpecialCommandDefpopup::execute(KviKvsRunTimeContext * c) { KviKvsVariant v; if(!m_pPopupName->evaluateReadOnly(c,&v))return false; QString szName; v.asString(szName); KviKvsSwitchList swl; if(m_pSwitches) { if(!(m_pSwitches->evaluate(c,&swl)))return false; } KviKvsPopupMenu * pPopup = KviKvsPopupManager::instance()->lookup(szName); bool bWasAlreadyThere; if(!pPopup) { if(m_pMainPopup->isEmpty())return true; // we wanted to remove it anyway: exit silently // we want to create it pPopup = new KviKvsPopupMenu(szName); KviKvsPopupManager::instance()->add(szName,pPopup); bWasAlreadyThere = false; } else { bWasAlreadyThere = true; if(pPopup->isHardLocked()) { c->error(__tr2qs_ctx("The popup '%s' is actually locked: 'self-modifications' are not allowed","kvs"),&szName); return false; } if(m_pMainPopup->isEmpty()) { // we want to remove it KviKvsPopupManager::instance()->remove(szName); return true; } // we want to (re)create it if(!swl.find('m',"--merge"))pPopup->doClear(); } if(!m_pMainPopup->fill(c,pPopup)) { if(!bWasAlreadyThere)KviKvsPopupManager::instance()->remove(szName); return false; } KviKvsPopupManager::instance()->emitRefresh(szName); return true; }
void KviKvsVariantList::allAsString(QString & szBuffer) { szBuffer = QString(); bool bFirst = true; for(KviKvsVariant * v = first(); v; v = next()) { if(bFirst) bFirst = false; else szBuffer.append(' '); v->appendAsString(szBuffer); } }
bool KviKvsTreeNodeCompositeData::evaluateReadOnly(KviKvsRunTimeContext * c, KviKvsVariant * pBuffer) { QString * pS = new QString(); pBuffer->setString(pS); KviKvsVariant res; // we need to use an iterator to accommodate recursion KviPointerListIterator<KviKvsTreeNodeData> it(*m_pSubData); while(KviKvsTreeNodeData * d = it.current()) { if(!d->evaluateReadOnly(c, &res)) return false; res.appendAsString(*pS); ++it; } return true; }
KviKvsObject * KviKvsObjectClass::allocateInstance(KviKvsObject * pParent,const QString &szName,KviKvsRunTimeContext * pContext,KviKvsVariantList * pParams) { if(!m_allocProc) return 0; KviKvsObject * pObject = m_allocProc(this,pParent,szName); if(!pObject) return 0; if(!pObject->init(pContext,pParams)) { // internal init failure : abort pObject->dieNow(); return 0; } // copy params KviKvsVariantList copy; copy.setAutoDelete(false); KviKvsVariant * v = pParams->first(); while(v) { copy.append(v); v = pParams->next(); } KviKvsVariant ret; if(!pObject->callFunction(pObject,"constructor",QString(),pContext,&ret,©)) { // ops...constructor failed (script error!) pObject->dieNow(); return 0; } if(!ret.isEmpty()) pContext->warning(__tr2qs_ctx("It's not allowed to return values in the constructor","kvs")); return pObject; }
bool KviKvsTreeNodeHashElement::evaluateReadOnlyInObjectScope(KviKvsObject *o,KviKvsRunTimeContext * c,KviKvsVariant * pBuffer) { KviKvsVariant key; if(!m_pKey->evaluateReadOnly(c,&key))return false; QString szKey; key.asString(szKey); if(szKey.isEmpty()) { c->warning(this,__tr2qs_ctx("Hash key evaluated to empty string: fix the script","kvs")); pBuffer->setNothing(); return true; } KviKvsVariant val; if(o) { if(!m_pSource->evaluateReadOnlyInObjectScope(o,c,&val))return false; } else { if(!m_pSource->evaluateReadOnly(c,&val))return false; } if(!val.isHash()) { if(!val.isNothing()) { QString szType; val.getTypeName(szType); c->warning(this,__tr2qs_ctx("The argument of the {} subscript didn't evaluate to a hash: automatic conversion from type '%Q' supplied","kvs"),&szType); } pBuffer->setNothing(); return true; } KviKvsVariant * v = val.hash()->find(szKey); if(!v) { pBuffer->setNothing(); return true; } pBuffer->copyFrom(v); return true; }
bool KviKvsTreeNodeSpecialCommandFor::execute(KviKvsRunTimeContext * c) { if(m_pInitialization) { if(!m_pInitialization->execute(c)) { // break allowed also here if(c->error()) return false; if(c->breakPending()) { c->handleBreak(); return true; } return false; // propagate false ret value } } for(;;) { if(m_pCondition) { KviKvsVariant v; if(!m_pCondition->evaluateReadOnly(c, &v)) return false; if(!v.asBoolean()) return true; } if(m_pLoop) { if(!m_pLoop->execute(c)) { if(c->error()) return false; if(c->breakPending()) { c->handleBreak(); return true; } if(c->continuePending()) c->handleContinue(); else return false; // propagate false ret value } } if(m_pUpdate) { if(!m_pUpdate->execute(c)) { // break allowed also here if(c->error()) return false; if(c->breakPending()) { c->handleBreak(); return true; } if(c->continuePending()) c->handleContinue(); return false; // propagate false ret value } } } // not reached return false; }
bool process(KviKvsVariantList * pVariantList, KviKvsRunTimeContext * pContext, KviKvsParameterProcessor::ParameterFormat * pFmtArray) { KviKvsVariant * v = pVariantList->first(); while(pFmtArray->szName) { if(!v) { // parameter not present // it MUST be optional if(!(pFmtArray->uFlags & KVS_PF_OPTIONAL)) { // bad luck QString szError = QString(__tr2qs_ctx("Missing non-optional parameter \"%1\"", "kvs")).arg(pFmtArray->szName); pContext->error(szError); return false; } // ok, missing but optional (all the following are implicitly optional too) // set to default values do { setDefaultValue(pFmtArray); pFmtArray++; } while(pFmtArray->szName); return true; } // here we do only "light" casts: hard ones must be done explicitly by the user switch(pFmtArray->uType) { case KVS_PT_STRING: v->asString(*((QString *)(pFmtArray->pContainer))); if(pFmtArray->uFlags & KVS_PF_APPENDREMAINING) { v = pVariantList->next(); while(v) { *((QString *)(pFmtArray->pContainer)) += QChar(' '); v->appendAsString(*((QString *)(pFmtArray->pContainer))); v = pVariantList->next(); } return true; } break; case KVS_PT_STRINGLIST: { ((QStringList *)(pFmtArray->pContainer))->clear(); QString pSz; v->asString(pSz); ((QStringList *)(pFmtArray->pContainer))->append(pSz); v = pVariantList->next(); while(v) { v->asString(pSz); ((QStringList *)(pFmtArray->pContainer))->append(pSz); v = pVariantList->next(); } return true; } break; case KVS_PT_VARIANTLIST: { ((KviKvsVariantList *)(pFmtArray->pContainer))->clear(); ((KviKvsVariantList *)(pFmtArray->pContainer))->setAutoDelete(false); ((KviKvsVariantList *)(pFmtArray->pContainer))->append(v); v = pVariantList->next(); while(v) { ((KviKvsVariantList *)(pFmtArray->pContainer))->append(v); v = pVariantList->next(); } return true; } break; case KVS_PT_NONEMPTYSTRING: { v->asString(*((QString *)(pFmtArray->pContainer))); bool bDoReturn = false; if(pFmtArray->uFlags & KVS_PF_APPENDREMAINING) { v = pVariantList->next(); while(v) { *((QString *)(pFmtArray->pContainer)) += QChar(' '); v->appendAsString(*((QString *)(pFmtArray->pContainer))); v = pVariantList->next(); } bDoReturn = true; } if(((QString *)(pFmtArray->pContainer))->isEmpty()) { QString szError = QString(__tr2qs_ctx("Invalid data type for parameter \"%1\": found empty string while a non empty one was expected", "kvs")).arg(pFmtArray->szName); pContext->error(szError); return false; } if(bDoReturn) return true; } break; case KVS_PT_CSTRING: { QString tmp; v->asString(tmp); if(pFmtArray->uFlags & KVS_PF_APPENDREMAINING) { v = pVariantList->next(); while(v) { *((QByteArray *)(pFmtArray->pContainer)) += ' '; v->appendAsString(tmp); v = pVariantList->next(); } *((QByteArray *)(pFmtArray->pContainer)) = tmp.toUtf8(); return true; } *((QByteArray *)(pFmtArray->pContainer)) = tmp.toUtf8(); } break; case KVS_PT_NONEMPTYCSTRING: { QString tmp; v->asString(tmp); bool bDoReturn = false; if(pFmtArray->uFlags & KVS_PF_APPENDREMAINING) { v = pVariantList->next(); while(v) { *((QByteArray *)(pFmtArray->pContainer)) += ' '; v->appendAsString(tmp); v = pVariantList->next(); } *((QByteArray *)(pFmtArray->pContainer)) = tmp.toUtf8(); bDoReturn = true; } *((QByteArray *)(pFmtArray->pContainer)) = tmp.toUtf8(); if(((QByteArray *)(pFmtArray->pContainer))->isEmpty()) { QString szError = QString(__tr2qs_ctx("Invalid data type for parameter \"%1\": found empty string while a non empty one was expected", "kvs")).arg(pFmtArray->szName); pContext->error(szError); return false; } if(bDoReturn) return true; } break; case KVS_PT_INT: if(!v->asInteger(*((kvs_int_t *)(pFmtArray->pContainer)))) { if(!handleParameterTypeError(pContext, pFmtArray, v, "integer")) return false; } break; case KVS_PT_UINT: { kvs_int_t iTmp; if(!v->asInteger(iTmp)) { if(!handleParameterTypeError(pContext, pFmtArray, v, "unsigned integer")) return false; } if(iTmp < 0) { QString szError = QString(__tr2qs_ctx("Invalid data type for parameter \"%1\": found signed integer \"%2\" where type 'unsigned integer' was expected", "kvs")).arg(pFmtArray->szName).arg(iTmp); pContext->error(szError); return false; } *((kvs_uint_t *)(pFmtArray->pContainer)) = (kvs_uint_t)iTmp; } break; case KVS_PT_DOUBLE: if(!v->asReal(*((kvs_real_t *)(pFmtArray->pContainer)))) { if(!handleParameterTypeError(pContext, pFmtArray, v, "real")) return false; } break; case KVS_PT_HASH: if(!v->isHash()) { if(!handleParameterTypeError(pContext, pFmtArray, v, "hash")) return false; } else { *((KviKvsHash **)(pFmtArray->pContainer)) = v->hash(); } break; case KVS_PT_ARRAYCAST: v->castToArray((KviKvsArrayCast *)(pFmtArray->pContainer)); break; case KVS_PT_ARRAY: if(!v->isArray()) { if(!handleParameterTypeError(pContext, pFmtArray, v, "array")) return false; } else { *((KviKvsArray **)(pFmtArray->pContainer)) = v->array(); } break; case KVS_PT_BOOL: // this never fails: anything is converted to a boolean *((bool *)(pFmtArray->pContainer)) = v->asBoolean(); break; case KVS_PT_VARIANT: *((KviKvsVariant **)(pFmtArray->pContainer)) = v; break; case KVS_PT_HOBJECT: if(!v->asHObject(*((kvs_hobject_t *)(pFmtArray->pContainer)))) { if(!handleParameterTypeError(pContext, pFmtArray, v, "hobject")) return false; } break; case KVS_PT_IGNORE: // ignore break; default: qDebug("Internal error in KviKvsParameterProcessor::processAsParameters(): unknown parameter type %d", pFmtArray->uType); return false; break; } pFmtArray++; v = pVariantList->next(); } return true; }
bool KviKvsTreeNodeSpecialCommandForeach::execute(KviKvsRunTimeContext * c) { KviKvsVariantList l; l.setAutoDelete(true); if(!m_pIterationData->evaluate(c,&l)) return false; KviKvsSwitchList swl; if(m_pSwitches) { if(!(m_pSwitches->evaluate(c,&swl))) return false; } bool bIncludeEmptyScalars = swl.find('a',"all") != 0; for(KviKvsVariant * pArg = l.first(); pArg; pArg = l.next()) { switch(pArg->type()) { case KviKvsVariantData::Array: { unsigned int uCnt = pArg->array()->size(); unsigned int idx = 0; while(idx < uCnt) { // we evaluate this each time (as it may actually be killed at each iteration) // FIXME: maybe some kind of reference counting or a observer pattern might be a bit more efficient here // (but might be far less efficient everywhere else...) KviKvsRWEvaluationResult * v = m_pIterationVariable->evaluateReadWrite(c); if(!v) return false; KviKvsVariant * pOne = pArg->array()->at(idx); if(pOne) { if(bIncludeEmptyScalars || (!pOne->isEmpty())) { v->result()->copyFrom(*pOne); } else { delete v; // we're done with it for this iteration idx++; continue; } } else { if(bIncludeEmptyScalars) { v->result()->setNothing(); } else { delete v; // we're done with it for this iteration idx++; continue; } } delete v; // we're done with it for this iteration if(!m_pLoop->execute(c)) { if(c->error()) return false; // break allowed! if(c->breakPending()) { c->handleBreak(); return true; } if(c->continuePending()) { c->handleContinue(); idx++; continue; } return false; // propagate the false return value } idx++; } } break; case KviKvsVariantData::Hash: { KviKvsHashIterator it(*(pArg->hash()->dict())); while(KviKvsVariant * pOne = it.current()) { // we evaluate this each time (as it may actually be killed at each iteration) // FIXME: maybe some kind of reference counting or a observer pattern might be a bit more efficient here // (but might be far less efficient everywhere else...) KviKvsRWEvaluationResult * v = m_pIterationVariable->evaluateReadWrite(c); if(!v) return false; if(bIncludeEmptyScalars || (!pOne->isEmpty())) { v->result()->copyFrom(*pOne); } else { delete v; // we're done with it for this iteration ++it; continue; } delete v; // we're done with it for this iteration if(!m_pLoop->execute(c)) { if(c->error()) return false; // break allowed! if(c->breakPending()) { c->handleBreak(); return true; } if(c->continuePending()) { c->handleContinue(); ++it; continue; } return false; // propagate the false return value } ++it; } } break; default: if(bIncludeEmptyScalars || (!pArg->isEqualToNothing())) { // we evaluate this each time (as it may actually be killed at each iteration) // FIXME: maybe some kind of reference counting or a observer pattern might be a bit more efficient here // (but might be far less efficient everywhere else...) KviKvsRWEvaluationResult * v = m_pIterationVariable->evaluateReadWrite(c); if(!v) return false; v->result()->copyFrom(*pArg); delete v; // we're done with it for this iteration if(!m_pLoop->execute(c)) { if(c->error()) return false; // break allowed! if(c->breakPending()) { c->handleBreak(); return true; } if(c->continuePending()) { c->handleContinue(); continue; } return false; // propagate the false return value } } break; } } return true; }
KVSO_CLASS_FUNCTION(xmlReader, parse) { KviKvsVariant * pVariantData; KVSO_PARAMETERS_BEGIN(c) KVSO_PARAMETER("string_or_memorybuffer_object", KVS_PT_VARIANT, 0, pVariantData) KVSO_PARAMETERS_END(c) #ifdef QT_NO_XML fatalError(__tr2qs_ctx("XML support not available in the Qt library")); c->returnValue()->setBoolean(false); #else m_szLastError = ""; KviXmlHandler handler(this); QXmlInputSource source; if(pVariantData->isHObject()) { KviKvsObject * pObject; kvs_hobject_t hObject; pVariantData->asHObject(hObject); pObject = KviKvsKernel::instance()->objectController()->lookupObject(hObject); if(!pObject) { c->warning(__tr2qs_ctx("Data parameter is not an object", "objects")); return true; } if(pObject->inheritsClass("memorybuffer")) { source.setData(*((KvsObject_memoryBuffer *)pObject)->pBuffer()); } else { c->warning(__tr2qs_ctx("Data parameter is not a memorybuffer object", "objects")); return true; } } else if(pVariantData->isString()) { QString szString; pVariantData->asString(szString); // We have a problem here.. most kvirc functions already interpret the data // read from files. We should have binary data handling features to get this to work correctly. // The following snippet of code tries to provide a best-effort workaround. QByteArray utf8data = szString.toUtf8(); QByteArray data = utf8data; data.truncate(utf8data.length()); // don't include the null terminator in data source.setData(data); //qDebug("PARSING(%s) LEN(%d)",szString.toUtf8().data(),szString.toUtf8().length()); } else { c->warning(__tr2qs_ctx("Data is not a memorybuffer object or string", "objects")); return true; } QXmlSimpleReader reader; reader.setContentHandler(&handler); reader.setErrorHandler(&handler); c->returnValue()->setBoolean(reader.parse(source)); #endif return true; }
bool KviKvsProcessAsyncOperation::trigger(CallbackEvent e, const QString & szData) { if(m_bDeletePending) return false; if(!g_pApp->windowExists(m_pData->pWnd)) { if(m_pData->iFlags & KVI_KVS_PROCESSDESCRIPTOR_KILLIFNOWINDOW) { return true; } m_pData->pWnd = g_pApp->activeConsole(); } if(m_pData->pCallback) { KviKvsVariantList params; params.setAutoDelete(true); switch(e) { case EventStdout: params.append(new KviKvsVariant(QString("stdout"))); break; case EventStderr: params.append(new KviKvsVariant(QString("stderr"))); break; case EventTerminated: params.append(new KviKvsVariant(QString("terminated"))); break; case EventStarted: params.append(new KviKvsVariant(QString("started"))); break; case EventPing: params.append(new KviKvsVariant(QString("ping"))); break; default: qDebug("Oops! Unknown trigger() CallbackEvent parameter in QProcessDescriptor::trigger()"); return false; break; } params.append(new KviKvsVariant(szData)); if(m_pData->pMagic) { KviKvsVariant * pTmp = new KviKvsVariant(); pTmp->copyFrom(m_pData->pMagic); params.append(pTmp); } KviKvsVariant retVal; int iRet = m_pData->pCallback->run(m_pData->pWnd, ¶ms, &retVal, KviKvsScript::PreserveParams, m_pExtendedRunTimeData); if(!iRet) { m_pData->pWnd->output(KVI_OUT_PARSERERROR, __tr2qs_ctx("Error triggered from process callback handler: killing process", "kvs")); return true; } if(!retVal.isNothing()) { QString sz; retVal.asString(sz); m_pProcess->write(sz.toUtf8().data()); } if(iRet & KviKvsScript::HaltEncountered) { // halt encountered: kill the process return true; } } return false; }
OptionsWidget_textEncoding::OptionsWidget_textEncoding(QWidget * parent) : KviOptionsWidget(parent) { setObjectName("textencoding_options_widget"); createLayout(); KviTalGroupBox* gbox = addGroupBox(0,0,0,0,Qt::Horizontal,__tr2qs_ctx("Encoding","options")); QGridLayout* grid = new QGridLayout; gbox->setLayout(grid); //server encoding grid->addWidget(addLabel(gbox,__tr2qs_ctx("Default server encoding:","options")),0,0); m_pSrvEncodingCombo = new QComboBox(gbox); grid->addWidget(m_pSrvEncodingCombo,0,1); m_pSrvEncodingCombo->addItem(__tr2qs_ctx("Use Language Encoding","options")); //text encoding grid->addWidget(addLabel(gbox,__tr2qs_ctx("Default text encoding:","options")),1,0); m_pTextEncodingCombo = new QComboBox(gbox); grid->addWidget(m_pTextEncodingCombo,1,1); m_pTextEncodingCombo->addItem(__tr2qs_ctx("Use Language Encoding","options")); //common between text and server encoding int i = 0; int iTextMatch = 0, iSrvMatch=0; KviLocale::EncodingDescription * d = KviLocale::instance()->encodingDescription(i); while(d->pcName) { if(KviQString::equalCI(d->pcName,KVI_OPTION_STRING(KviOption_stringDefaultTextEncoding))) iTextMatch = i + 1; if(KviQString::equalCI(d->pcName,KVI_OPTION_STRING(KviOption_stringDefaultSrvEncoding))) iSrvMatch = i + 1; m_pTextEncodingCombo->insertItem(m_pTextEncodingCombo->count(),d->pcName); m_pSrvEncodingCombo->insertItem(m_pSrvEncodingCombo->count(),d->pcName); i++; d = KviLocale::instance()->encodingDescription(i); } m_pTextEncodingCombo->setCurrentIndex(iTextMatch); m_pSrvEncodingCombo->setCurrentIndex(iSrvMatch); gbox = addGroupBox(0,1,0,1,Qt::Horizontal,__tr2qs_ctx("Language","options")); grid = new QGridLayout; gbox->setLayout(grid); grid->addWidget(addLabel(gbox,__tr2qs_ctx("Force language:","options")),0,0); m_pForcedLocaleCombo = new QComboBox(gbox); grid->addWidget(m_pForcedLocaleCombo,0,1); grid->addWidget(addLabel(gbox,__tr2qs_ctx("<b>Note:</b> You must restart KVIrc to apply any language changes","options")),1,0,1,2); m_pForcedLocaleCombo->addItem(__tr2qs_ctx("Automatic detection","options")); m_pForcedLocaleCombo->addItem(__tr2qs_ctx("en","options")); QString szLangFile; g_pApp->getLocalKvircDirectory(szLangFile,KviApplication::None,KVI_FORCE_LOCALE_FILE_NAME); bool bIsDefaultLocale = !KviFileUtils::fileExists(szLangFile); //We Have setted locale, but not restarted kvirc if(!g_szPrevSettedLocale.isEmpty()) m_szLanguage = g_szPrevSettedLocale; else m_szLanguage = KviLocale::instance()->localeName(); QString szLocaleDir; g_pApp->getGlobalKvircDirectory(szLocaleDir,KviApplication::Locale); QStringList list=QDir(szLocaleDir).entryList(QStringList("kvirc_*.mo"),QDir::Files); i = 0; int iMatch = 0; for(QStringList::Iterator it = list.begin(); it != list.end(); ++it) { QString szTmp=*it; szTmp.replace("kvirc_",""); szTmp.replace(".mo",""); m_pForcedLocaleCombo->insertItem(m_pForcedLocaleCombo->count(),szTmp); if(KviQString::equalCI(szTmp,m_szLanguage)) iMatch = i + 2; i++; } if(bIsDefaultLocale) m_pForcedLocaleCombo->setCurrentIndex(0); else if(KviQString::equalCI(m_szLanguage,"en")) m_pForcedLocaleCombo->setCurrentIndex(1); else m_pForcedLocaleCombo->setCurrentIndex(iMatch); #ifdef COMPILE_ENCHANT_SUPPORT { gbox = addGroupBox(0,2,0,2,Qt::Horizontal,__tr2qs_ctx("Spell Checker Dictionaries","options")); KviKvsVariant availableDictionaries; KviKvsScript::evaluate("$spellchecker.availableDictionaries", NULL, NULL, &availableDictionaries); const KviPointerHashTable<QString, KviKvsVariant>* hashTable = availableDictionaries.hash()->dict(); KviPointerHashTableIterator<QString, KviKvsVariant> iter(*hashTable); QMap<QString, QString> dictMap; for (bool b = iter.moveFirst(); b; b = iter.moveNext()) { QString szDescription; iter.current()->asString(szDescription); dictMap[iter.currentKey()] = szDescription; } m_pSpellCheckerDictionaries = new QTableWidget(gbox); m_pSpellCheckerDictionaries->setRowCount(dictMap.size()); m_pSpellCheckerDictionaries->setColumnCount(2); QStringList header; header << __tr2qs_ctx("Language code", "options"); header << __tr2qs_ctx("Provided by", "options"); m_pSpellCheckerDictionaries->setHorizontalHeaderLabels(header); #if (QT_VERSION >= 0x050000) m_pSpellCheckerDictionaries->horizontalHeader()->setSectionResizeMode(QHeaderView::Stretch); #else m_pSpellCheckerDictionaries->horizontalHeader()->setResizeMode(QHeaderView::Stretch); #endif m_pSpellCheckerDictionaries->setSelectionBehavior(QAbstractItemView::SelectRows); m_pSpellCheckerDictionaries->setSelectionMode(QAbstractItemView::SingleSelection); m_pSpellCheckerDictionaries->setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff); int row = 0; for (QMap<QString, QString>::iterator it = dictMap.begin(); it != dictMap.end(); ++it, ++row) { QTableWidgetItem* itemLang = new QTableWidgetItem(it.key()); itemLang->setCheckState(KVI_OPTION_STRINGLIST(KviOption_stringlistSpellCheckerDictionaries).contains(it.key()) ? Qt::Checked : Qt::Unchecked); itemLang->setFlags(itemLang->flags() & ~Qt::ItemIsEditable); m_pSpellCheckerDictionaries->setItem(row,0,itemLang); QTableWidgetItem* itemDesc = new QTableWidgetItem(it.value()); itemDesc->setFlags(itemDesc->flags() & ~Qt::ItemIsEditable); m_pSpellCheckerDictionaries->setItem(row,1,itemDesc); } m_pSpellCheckerDictionaries->resizeColumnsToContents(); m_pSpellCheckerDictionaries->resizeRowsToContents(); } #else addRowSpacer(0,2,0,2); #endif }
void KviIrcContext::terminateConnectionRequest(bool bForce, const QString & szQuitMsg, bool bSimulateUnexpectedDisconnect) { if(!connection()) return; // hm ? connection()->stateData()->setSimulateUnexpectedDisconnect(bSimulateUnexpectedDisconnect); switch(m_eState) { case Connected: { // was connected : send a quit and abort the connection bool bQuitSentJustNow = false; if(!connection()->stateData()->sentQuit()) { KVS_TRIGGER_EVENT_0(KviEvent_OnDisconnectRequest, m_pConsole); QString szQuit = szQuitMsg; if(szQuit.isEmpty()) szQuit = KVI_OPTION_STRING(KviOption_stringQuitMessage); KviQString::escapeKvs(&szQuit, KviQString::PermitVariables | KviQString::PermitFunctions); QString buffer; KviKvsVariant ret; if(KviKvsScript::evaluate(szQuit, console(), nullptr, &ret)) ret.asString(buffer); else buffer = szQuit; QByteArray dat = connection()->encodeText(buffer); connection()->stateData()->setSentQuit(); connection()->sendFmtData("QUIT :%s", dat.data() ? dat.data() : ""); // here theoretically we COULD get disconnected bQuitSentJustNow = true; } // else it was already sent anyway if(KVI_OPTION_BOOL(KviOption_boolForceBrutalQuit) || bForce || (!bQuitSentJustNow)) { if(!bQuitSentJustNow) { // idle for some milliseconds in order to allow the quit message to reach // the remote end without breaking the connection KviThread::msleep(100); } // and brutally abort the connection (if it still exists!!!) if(connection()) connection()->abort(); } else { if(bQuitSentJustNow) m_pConsole->outputNoFmt(KVI_OUT_SYSTEMMESSAGE, __tr2qs("Sent QUIT, waiting for the server to close the connection...")); } } break; case PendingReconnection: case Connecting: case LoggingIn: // was waiting for connection or login, just abort it: it will trigger an error anyway // though act as if we sent the quit message, so we'll not treat the disconnection as "unexpected". connection()->stateData()->setSentQuit(); connection()->abort(); break; default: // should never end here! KVI_ASSERT(false); break; } }
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_ctx("Missing class name","kvs")); return false; } KviKvsVariant * pBaseClassName = l.next(); QString szClassName; QString szBaseClassName; pClassName->asString(szClassName); QRegExp re("[\\w:]+"); if(!re.exactMatch(szClassName)) { c->error(this,__tr2qs_ctx("Class names can contain only letters, digits, underscores and '::' namespace separators","kvs")); return false; } if(pBaseClassName) pBaseClassName->asString(szBaseClassName); if(szClassName.isEmpty()) { c->error(this,__tr2qs_ctx("Missing class name","kvs")); return false; } if(szBaseClassName.isEmpty())szBaseClassName = "object"; // avoid infinite recursion in loading the base class if(KviQString::equalCI(szBaseClassName,szClassName)) { c->error(__tr2qs_ctx("A class can't be a subclass of itself","kvs")); return false; } KviKvsObjectClass * pBaseClass = KviKvsKernel::instance()->objectController()->lookupClass(szBaseClassName); if(!pBaseClass) { c->error(this,__tr2qs_ctx("Couln't find base class named '%Q'","kvs"),&szBaseClassName); return false; } // walk the inheritance tree of the base class in order to detect loops KviKvsObjectClass * pClass = pBaseClass; while(pClass) { if(KviQString::equalCI(pClass->name(),szClassName)) { c->error(this,__tr2qs_ctx("Detected a loop in the inheritance tree of the base class '%Q': redefine that class first","kvs"),&szBaseClassName); return false; } pClass = pClass->parentClass(); } KviKvsObjectClass * pActualClass = KviKvsKernel::instance()->objectController()->lookupClass(szClassName,true); if(pActualClass) { c->error(this,__tr2qs_ctx("Can't override the builtin class '%Q'","kvs"),&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->reminder(),d->handlerFlags()); } return true; }
static bool perl_kvs_cmd_begin(KviKvsModuleCommandCall * c) { // This command is somewhat special in the fact that has a dedicated // parsing routine in the KVS core parser. // The parser sets the perl code as the first parameter of our call, // the remaining params are the context name and the arguments QString szCode,szContext; KviKvsVariantList vList; KVSM_PARAMETERS_BEGIN(c) KVSM_PARAMETER("code",KVS_PT_STRING,0,szCode) KVSM_PARAMETER("context",KVS_PT_STRING,KVS_PF_OPTIONAL,szContext) KVSM_PARAMETER("args",KVS_PT_VARIANTLIST,KVS_PF_OPTIONAL,vList) KVSM_PARAMETERS_END(c) KVS_CHECK_MODULE_STATE(m,c) #ifdef COMPILE_PERL_SUPPORT KviPerlCoreCtrlCommand_execute ex; ex.uSize = sizeof(KviPerlCoreCtrlCommand_execute); ex.pKvsContext = c->context(); ex.szContext = szContext; ex.szCode = szCode; for(KviKvsVariant * v = vList.first();v;v = vList.next()) { QString tmp; v->asString(tmp); ex.lArgs.append(tmp); } ex.bQuiet = c->switches()->find('q',"quiet"); if(!g_pPerlCoreModule->ctrl(KVI_PERLCORECTRLCOMMAND_EXECUTE,&ex)) { if(!c->switches()->find('q',"quiet")) c->warning(__tr2qs_ctx("The perlcore module failed to execute the code: something is wrong with the perl support","perl")); return true; } if(!ex.lWarnings.isEmpty()) { for(QStringList::Iterator it = ex.lWarnings.begin();it != ex.lWarnings.end();++it) c->warning(*it); } if(!ex.bExitOk) { if(!c->switches()->find('q',"quiet")) { if(c->switches()->find('f',"fail-on-error")) { c->warning(__tr2qs_ctx("Perl execution error:","perl")); c->warning(ex.szError); return false; } else { c->warning(__tr2qs_ctx("Perl execution error:","perl")); c->error(ex.szError); } } } if(!c->switches()->find('n',"no-return")) c->context()->returnValue()->setString(ex.szRetVal); #endif //COMPILE_PERL_SUPPORT return true; }