KTutorial  0.5.1
ScriptingModule.cpp
00001 /***************************************************************************
00002  *   Copyright (C) 2009 by Daniel Calviño Sánchez <danxuliu@gmail.com>     *
00003  *   Copyright (C) 2010 by Daniel Calviño Sánchez <danxuliu@gmail.com>     *
00004  *   Copyright (C) 2011 by Daniel Calviño Sánchez <danxuliu@gmail.com>     *
00005  *   Copyright (C) 2012 by Daniel Calviño Sánchez <danxuliu@gmail.com>     *
00006  *                                                                         *
00007  *   This program is free software; you can redistribute it and/or modify  *
00008  *   it under the terms of the GNU General Public License as published by  *
00009  *   the Free Software Foundation; either version 2 of the License, or     *
00010  *   (at your option) any later version.                                   *
00011  *                                                                         *
00012  *   This program is distributed in the hope that it will be useful,       *
00013  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
00014  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
00015  *   GNU General Public License for more details.                          *
00016  *                                                                         *
00017  *   You should have received a copy of the GNU General Public License     *
00018  *   along with this program; If not, see <http://www.gnu.org/licenses/>.  *
00019  ***************************************************************************/
00020 
00021 #include "ScriptingModule.h"
00022 
00023 #include <QMetaMethod>
00024 
00025 #include <KDebug>
00026 
00027 #include "ScriptedStep.h"
00028 #include "../KTutorial.h"
00029 #include "../Option.h"
00030 #include "../WaitFor.h"
00031 #include "../WaitForAnd.h"
00032 #include "../WaitForEvent.h"
00033 #include "../WaitForNot.h"
00034 #include "../WaitForOr.h"
00035 #include "../WaitForProperty.h"
00036 #include "../WaitForSignal.h"
00037 #include "../WaitForStepActivation.h"
00038 #include "../WaitForWindow.h"
00039 
00040 namespace ktutorial {
00041 extern int debugArea();
00042 }
00043 
00044 namespace ktutorial {
00045 namespace scripting {
00046 
00047 ScriptingModule* ScriptingModule::self() {
00048     if (sSelf == 0) {
00049         sSelf = new ScriptingModule();
00050 
00051         //The WaitFor types are registered with an specific name instead of the
00052         //default one, as the default one includes a leading "ktutorial::".
00053         sSelf->registerWaitForMetaObject(WaitForAnd::staticMetaObject,
00054                                          "WaitForAnd");
00055         sSelf->registerWaitForMetaObject(WaitForEvent::staticMetaObject,
00056                                          "WaitForEvent");
00057         sSelf->registerWaitForMetaObject(WaitForNot::staticMetaObject,
00058                                          "WaitForNot");
00059         sSelf->registerWaitForMetaObject(WaitForOr::staticMetaObject,
00060                                          "WaitForOr");
00061         sSelf->registerWaitForMetaObject(WaitForProperty::staticMetaObject,
00062                                          "WaitForProperty");
00063         sSelf->registerWaitForMetaObject(WaitForSignal::staticMetaObject,
00064                                          "WaitForSignal");
00065         sSelf->registerWaitForMetaObject(
00066                                     WaitForStepActivation::staticMetaObject,
00067                                     "WaitForStepActivation");
00068         sSelf->registerWaitForMetaObject(WaitForWindow::staticMetaObject,
00069                                          "WaitForWindow");
00070     }
00071 
00072     return sSelf;
00073 }
00074 
00075 ScriptingModule::~ScriptingModule() {
00076 }
00077 
00078 bool ScriptingModule::registerWaitForMetaObject(
00079                             const QMetaObject& waitForMetaObject,
00080                             const QString& typeName /*= QString()*/) {
00081     if (mWaitForMetaObjects.contains(typeName)) {
00082         kWarning(debugArea()) << "Can't register"
00083                               << QString(waitForMetaObject.className())
00084                               << ", as" << typeName << "is already registered";
00085         return false;
00086     }
00087 
00088     if (!inheritsWaitFor(waitForMetaObject)) {
00089         kWarning(debugArea()) << "Can't register"
00090                               << QString(waitForMetaObject.className())
00091                               << ", as it does not inherit WaitFor";
00092         return false;
00093     }
00094 
00095     if (!hasInvokableDefaultConstructor(waitForMetaObject)) {
00096         kWarning(debugArea()) << "Can't register"
00097                               << QString(waitForMetaObject.className())
00098                               << ", as it does not have an invokable default"
00099                               << "constructor";
00100         return false;
00101     }
00102 
00103     QString key = typeName.isNull()? waitForMetaObject.className(): typeName;
00104     mWaitForMetaObjects.insert(key, waitForMetaObject);
00105 
00106     return true;
00107 }
00108 
00109 QObject* ScriptingModule::findObject(const QString& name) {
00110     return KTutorial::self()->findObject<QObject*>(name);
00111 }
00112 
00113 QObject* ScriptingModule::newOption(const QString& name) {
00114     return new Option(name);
00115 }
00116 
00117 QObject* ScriptingModule::newStep(const QString& id) {
00118     return new ScriptedStep(id);
00119 }
00120 
00121 QObject* ScriptingModule::newWaitFor(const QString& typeName) {
00122     if (!mWaitForMetaObjects.contains(typeName)) {
00123         return 0;
00124     }
00125 
00126     QObject* object = mWaitForMetaObjects.find(typeName).value().newInstance();
00127     return qobject_cast<WaitFor*>(object);
00128 }
00129 
00130 //private:
00131 
00132 ScriptingModule* ScriptingModule::sSelf = 0;
00133 
00134 ScriptingModule::ScriptingModule() {
00135 }
00136 
00137 bool ScriptingModule::inheritsWaitFor(const QMetaObject& metaObject) const {
00138     const QMetaObject* currentSuperClass = &metaObject;
00139     do {
00140         if (currentSuperClass->className() == QString("ktutorial::WaitFor")) {
00141             return true;
00142         }
00143     } while ((currentSuperClass = currentSuperClass->superClass()) != 0);
00144 
00145     return false;
00146 }
00147 
00148 bool ScriptingModule::hasInvokableDefaultConstructor(
00149                                         const QMetaObject& metaObject) const {
00150     for (int i=0; i<metaObject.constructorCount(); ++i) {
00151         QMetaMethod constructor = metaObject.constructor(i);
00152         if (constructor.parameterTypes().count() == 0 &&
00153                 constructor.access() == QMetaMethod::Public) {
00154             return true;
00155         }
00156     }
00157 
00158     return false;
00159 }
00160 
00161 }
00162 }