kwin/scripting/chelate.cpp
Rohan Ramdas Prabhu 2aec750ebf Trembles the weave as the clock ticks, attain another microstate.
Every disorder causes every duration, which ensures the one that stays.
reality is relative. natural is disorder.
[R]obinhood[P]andey

Merging scripting from
^/branches/work/kwin_scripting TO
^/trunk

svn path=/trunk/KDE/kdebase/workspace/; revision=1177865
2010-09-21 14:31:40 +00:00

393 lines
12 KiB
C++

/********************************************************************
KWin - the KDE window manager
This file is part of the KDE project.
Copyright (C) 2010 Rohan Prabhu <rohan@rohanprabhu.com>
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 option) 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, see <http://www.gnu.org/licenses/>.
*********************************************************************/
#include "chelate.h"
#include "meta.h"
QList<KWin::Chelate::ChelateProxy*> KWin::Chelate::ChelateProxy::chMap;
/**
* ChelateProxy | functions
*/
KWin::Chelate::ChelateProxy::ChelateProxy()
{
engine = 0;
}
void KWin::Chelate::ChelateProxy::setEngine(QScriptEngine* _engine)
{
engine = _engine;
}
void KWin::Chelate::ChelateProxy::setConnectors(QScriptValueList _connectors)
{
connectors = _connectors;
}
void KWin::Chelate::ChelateProxy::setAction(QScriptValue _action)
{
action = _action;
}
void KWin::Chelate::ChelateProxy::setEventStrings(QStringList _on)
{
on = _on;
}
void KWin::Chelate::ChelateProxy::setFilter(QScriptValue _filter)
{
filter = _filter;
}
void KWin::Chelate::ChelateProxy::setId(int _id)
{
id = _id;
}
QScriptValue KWin::Chelate::ChelateProxy::getAction()
{
return action;
}
QScriptValue KWin::Chelate::ChelateProxy::getFilter()
{
return filter;
}
void KWin::Chelate::ChelateProxy::process(int index)
{
if(engine == 0)
{
return;
}
QScriptValue connector = connectors.at(index).property("connect");
QScriptValue _scanner = engine->newFunction(KWin::Chelate::scanner, 0);
_scanner.setData(engine->fromScriptValue<int>(id));
QScriptValueList args;
args<<_scanner;
connector.call(connectors.at(index), args);
}
void KWin::Chelate::ChelateProxy::processAll()
{
for(int i = 0; i<connectors.size(); i++)
{
process(i);
}
}
/** */
// END of ChelateProxy | functions
/** */
/**
* KWin::Chelate | functions
*/
QScriptValue KWin::Chelate::scanner(QScriptContext* ctx, QScriptEngine* eng)
{
QScriptValue index = (ctx->callee()).data();
KWin::Chelate::ChelateProxy* proxy = KWin::Chelate::ChelateProxy::chMap.at(index.toNumber());
QScriptValue filter = proxy->getFilter();
bool ret = (filter.call(QScriptValue(), ctx->argumentsObject())).toBool();
if(ret == true)
{
QScriptValue action = proxy->getAction();
action.call(QScriptValue(), ctx->argumentsObject());
}
return eng->undefinedValue();
}
QScriptValue KWin::Chelate::rule(QScriptContext* ctx, QScriptEngine* eng)
{
ChelateProxy* proxy = new ChelateProxy();
QScriptValue chRule = eng->newObject();
QScriptValue ruleObj;
if(ctx->argumentCount() > 0)
{
ruleObj = ctx->argument(0);
}
else
{
return eng->undefinedValue();
}
/**
* First, process the events that are to be hooked on to
*/
if(ruleObj.property("on").isValid() && !ruleObj.property("on").isUndefined())
{
QStringList eventStrings;
QScriptValueList connectors;
QScriptValueIterator it(ruleObj.property("on"));
while (it.hasNext())
{
it.next();
QScriptValue connector = (eng->globalObject()).property("workspace").property(it.value().toString());
if(connector.isValid() && !connector.isUndefined())
{
eventStrings<<it.value().toString();
connectors<<connector;
}
}
proxy->setConnectors(connectors);
proxy->setEventStrings(eventStrings);
}
/**
* Then we have our filters.. the most daring part of KWin Scripting yet :)
* Actually this is pretty simple here, but just wait to see
* Chelate LazyLogic (tm)
*/
if(ruleObj.property("filter").isValid() && !ruleObj.property("filter").isUndefined())
{
QScriptValue filter = ruleObj.property("filter");
if(filter.isFunction())
{
proxy->setFilter(filter);
}
}
if(ruleObj.property("action").isValid() && !ruleObj.property("action").isUndefined())
{
QScriptValue action = ruleObj.property("action");
if(action.isFunction())
{
proxy->setAction(action);
}
}
proxy->setEngine(eng);
proxy->setId(KWin::Chelate::ChelateProxy::chMap.size());
KWin::Chelate::ChelateProxy::chMap.append(proxy);
proxy->processAll();
return chRule;
}
QScriptValue KWin::Chelate::publishChelate(QScriptEngine* eng)
{
QScriptValue temp = eng->newObject();
temp.setProperty("rule", eng->newFunction(KWin::Chelate::rule, 1), QScriptValue::Undeletable);
temp.setProperty("and", KWin::MetaScripting::getLazyLogicFunction(eng, "ll_and"), QScriptValue::Undeletable);
temp.setProperty("or", KWin::MetaScripting::getLazyLogicFunction(eng, "ll_or"), QScriptValue::Undeletable);
temp.setProperty("not", KWin::MetaScripting::getLazyLogicFunction(eng, "ll_not"), QScriptValue::Undeletable);
temp.setProperty("equiv", eng->newFunction(KWin::Chelate::chelationEquivGen, 0), QScriptValue::Undeletable);
temp.setProperty("regex", eng->newFunction(KWin::Chelate::chelationRegexGen, 0), QScriptValue::Undeletable);
return temp;
}
/**
* Chelation functions. These functions are used to filter
* the incoming clients.
*/
QScriptValue KWin::Chelate::chelationRegex(QScriptContext* ctx, QScriptEngine* eng)
{
QScriptValue key = ((ctx->callee()).data()).property("key");
QScriptValue regex = ((ctx->callee()).data()).property("regex");
QScriptValue post = ((ctx->callee()).data()).property("post");
QRegExp re(regex.toString());
if(!key.isUndefined() && !regex.isUndefined())
{
QScriptValue scCentral = ctx->argument(0);
QScriptValue callBase = scCentral.property(key.toString());
QString final = (callBase.isFunction())?((callBase.call(scCentral)).toString()):(callBase.toString());
int pos = re.indexIn(final);
if(post.isUndefined())
{
if(pos > -1)
{
return eng->toScriptValue<bool>(1);
}
else
{
return eng->toScriptValue<bool>(0);
}
}
else
{
QScriptValueList args;
QStringList list = re.capturedTexts();
args<<eng->toScriptValue<QStringList>(re.capturedTexts());
return eng->toScriptValue<bool>((post.call(QScriptValue(), args)).toBool());
}
}
else
{
return eng->toScriptValue<bool>(0);
}
}
QScriptValue KWin::Chelate::chelationRegexGen(QScriptContext* ctx, QScriptEngine* eng)
{
QScriptValue func = eng->newFunction(chelationRegex, 0);
QScriptValue data = eng->newObject();
data.setProperty("key", ctx->argument(0));
data.setProperty("regex", ctx->argument(1));
data.setProperty("post", ctx->argument(2));
func.setData(data);
return func;
}
QScriptValue KWin::Chelate::chelationEquiv(QScriptContext* ctx, QScriptEngine* eng)
{
QScriptValue key = ((ctx->callee()).data()).property("key");
QScriptValue value = ((ctx->callee()).data()).property("value");
if(!key.isUndefined() && !value.isUndefined())
{
QScriptValue scCentral = ctx->argument(0);
QScriptValue callBase = scCentral.property(key.toString());
QString final = (callBase.isFunction())?((callBase.call(scCentral)).toString()):(callBase.toString());
return eng->toScriptValue<bool>(final.compare(value.toString(), Qt::CaseInsensitive) == 0);
}
else
{
return eng->toScriptValue<bool>(0);
}
}
QScriptValue KWin::Chelate::chelationEquivGen(QScriptContext* ctx, QScriptEngine* eng)
{
QScriptValue func = eng->newFunction(chelationEquiv, 0);
QScriptValue data = eng->newObject();
data.setProperty("key", ctx->argument(0));
data.setProperty("value", ctx->argument(1));
func.setData(data);
return func;
}
QScriptValue KWin::Chelate::chelationCheck(QScriptContext* ctx, QScriptEngine* eng)
{
QScriptValue key = ((ctx->callee()).data()).property("key");
if(!key.isUndefined())
{
QScriptValue scCentral = ctx->argument(0);
QScriptValue callBase = scCentral.property(key.toString());
return (callBase.isFunction())?((callBase.call(scCentral)).toBool()):(callBase.toBool());
}
}
QScriptValue KWin::Chelate::chelationCheckGen(QScriptContext* ctx, QScriptEngine* eng)
{
QScriptValue func = eng->newFunction(chelationCheck, 0);
QScriptValue data = eng->newObject();
data.setProperty("key", ctx->argument(0));
func.setData(data);
return func;
}
/** */
/** LazyLogic (tm) */
/** */
QScriptValue KWin::Chelate::lazyLogicGenerate(QScriptContext* ctx, QScriptEngine* eng)
{
// Assume everything as necessary. If enough or wrong parameters
// are provided, undefined values are used and then the function call
// fails silently (it is non-fatal)
QScriptValue type = (((ctx->callee()).data()).property("lazylogic_type"));
QString typeString = type.toString();
if(!((typeString == "ll_and") || (typeString == "ll_or") || (typeString == "ll_not") || (typeString == "ll_xor")))
{
return eng->undefinedValue();
}
QScriptValue func = eng->newFunction(KWin::Chelate::lazyLogic, 0);
QScriptValue data = eng->newObject();
data.setProperty("lazylogic_type", type);
data.setProperty("lazylogic_operands", ctx->argumentsObject());
func.setData(data);
return func;
}
QScriptValue KWin::Chelate::lazyLogic(QScriptContext* ctx, QScriptEngine* eng)
{
bool init;
QString type = (((ctx->callee()).data()).property("lazylogic_type")).toString();
QScriptValue operands = ((ctx->callee()).data()).property("lazylogic_operands");
if(type == "ll_and")
{
init = 1;
}
else if(type == "ll_or")
{
init = 0;
}
else if(type == "ll_not")
{
QScriptValue current = operands.property("0");
return !(current.isFunction())?((current.call(QScriptValue(), ctx->argumentsObject())).toBool()):(current.toBool());
}
else if(type == "ll_xor")
{
QScriptValue _current = operands.property("0");
QScriptValue current = operands.property("1");
return (( current.isFunction())?(( current.call(QScriptValue(), ctx->argumentsObject())).toBool()): current.toBool() ^
(_current.isFunction())?((_current.call(QScriptValue(), ctx->argumentsObject())).toBool()):_current.toBool()
);
}
else
{
return eng->toScriptValue<bool>(0);
}
for(int i=0; i<operands.property("length").toNumber(); i++)
{
QScriptValue current = operands.property(QString::number(i));
if(current.isFunction())
{
if(type == "ll_and")
{
init = init && (current.isFunction())?((current.call(QScriptValue(), ctx->argumentsObject())).toBool()):(current.toBool());
}
else if(type == "ll_or")
{
init = init || (current.isFunction())?((current.call(QScriptValue(), ctx->argumentsObject())).toBool()):(current.toBool());
}
}
}
return eng->toScriptValue<bool>(init);
}
/** */
// END of KWin::Chelate | functions
/** */