• Skip to content
  • Skip to link menu
KDE 4.2 API Reference
  • KDE API Reference
  • kdelibs
  • Sitemap
  • Contact Us
 

Kross

action.cpp

Go to the documentation of this file.
00001 /***************************************************************************
00002  * action.cpp
00003  * This file is part of the KDE project
00004  * copyright (C)2004-2006 by Sebastian Sauer (mail@dipe.org)
00005  *
00006  * This program is free software; you can redistribute it and/or
00007  * modify it under the terms of the GNU Library General Public
00008  * License as published by the Free Software Foundation; either
00009  * version 2 of the License, or (at your option) any later version.
00010  * This program is distributed in the hope that it will be useful,
00011  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013  * Library General Public License for more details.
00014  * You should have received a copy of the GNU Library General Public License
00015  * along with this program; see the file COPYING.  If not, write to
00016  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00017  * Boston, MA 02110-1301, USA.
00018  ***************************************************************************/
00019 
00020 #include "action.h"
00021 #include "actioncollection.h"
00022 #include "interpreter.h"
00023 #include "script.h"
00024 #include "manager.h"
00025 #include "wrapperinterface.h"
00026 
00027 #include <QtCore/QFile>
00028 #include <QtCore/QFileInfo>
00029 
00030 #include <kdebug.h>
00031 #include <klocale.h>
00032 #include <kicon.h>
00033 #include <kmimetype.h>
00034 
00035 using namespace Kross;
00036 
00037 namespace Kross {
00038 
00040     class Action::Private
00041     {
00042         public:
00043 
00049             Script* script;
00050 
00055             int version;
00056 
00061             QString description;
00062 
00066             QString iconname;
00067 
00071             QByteArray code;
00072 
00077             QString interpretername;
00078 
00085             QString scriptfile;
00086 
00091             QString currentpath;
00092 
00097             QMap< QString, QVariant > options;
00098 
00099             Private() : script(0), version(0) {}
00100     };
00101 
00102 }
00103 
00104 Action::Action(QObject* parent, const QString& name, const QDir& packagepath)
00105     : QAction(parent)
00106     , QScriptable()
00107     , ChildrenInterface()
00108     , ErrorInterface()
00109     , d( new Private() )
00110 {
00111     setObjectName(name);
00112     #ifdef KROSS_ACTION_DEBUG
00113         krossdebug( QString("Action::Action(QObject*,QString,QDir) Ctor name='%1'").arg(objectName()) );
00114     #endif
00115     setEnabled( false );
00116     d->currentpath = packagepath.absolutePath();
00117     connect(this, SIGNAL(triggered(bool)), this, SLOT(slotTriggered()));
00118 }
00119 
00120 Action::Action(QObject* parent, const QUrl& url)
00121     : QAction(parent)
00122     , ChildrenInterface()
00123     , ErrorInterface()
00124     , d( new Private() )
00125 {
00126     setObjectName( url.path() /*url.fileName()*/ );
00127     #ifdef KROSS_ACTION_DEBUG
00128         krossdebug( QString("Action::Action(QObject*,QUrl) Ctor name='%1'").arg(objectName()) );
00129     #endif
00130     QFileInfo fi( url.toLocalFile() );
00131     setText( fi.fileName() );
00132     setIconName( KMimeType::iconNameForUrl(url) );
00133     setFile( url.toLocalFile() );
00134     connect(this, SIGNAL(triggered(bool)), this, SLOT(slotTriggered()));
00135 }
00136 
00137 Action::~Action()
00138 {
00139     #ifdef KROSS_ACTION_DEBUG
00140         krossdebug( QString("Action::~Action() Dtor name='%1'").arg(objectName()) );
00141     #endif
00142     finalize();
00143     ActionCollection *coll = qobject_cast<ActionCollection*>(parent());
00144     if ( coll ) {
00145         coll->removeAction(this);
00146     }
00147     delete d;
00148 }
00149 
00150 void Action::fromDomElement(const QDomElement& element)
00151 {
00152     if( element.isNull() )
00153         return;
00154 
00155     QDir packagepath( d->currentpath );
00156     QString file = element.attribute("file");
00157     if( ! file.isEmpty() ) {
00158         if( QFileInfo(file).exists() ) {
00159             setFile(file);
00160         }
00161         else {
00162             QFileInfo fi(packagepath, file);
00163             if( fi.exists() )
00164                 setFile( fi.absoluteFilePath() );
00165         }
00166     }
00167 
00168     d->version = QVariant( element.attribute("version",QString(d->version)) ).toInt();
00169 
00170     setText( i18n( element.attribute("text").toUtf8() ) );
00171     setDescription( i18n( element.attribute("comment").toUtf8() ) );
00172     setEnabled( true );
00173     setInterpreter( element.attribute("interpreter") );
00174     setEnabled( QVariant(element.attribute("enabled","true")).toBool() && isEnabled() );
00175 
00176     QString icon = element.attribute("icon");
00177     if( icon.isEmpty() && ! d->scriptfile.isNull() )
00178         icon = KMimeType::iconNameForUrl( KUrl(d->scriptfile) );
00179     setIconName( icon );
00180 
00181     const QString code = element.attribute("code");
00182     if( ! code.isNull() )
00183         setCode(code.toUtf8());
00184 
00185     for(QDomNode node = element.firstChild(); ! node.isNull(); node = node.nextSibling()) {
00186         QDomElement e = node.toElement();
00187         if( ! e.isNull() ) {
00188             if( e.tagName() == "property" ) {
00189                 const QString n = e.attribute("name", QString());
00190                 if( ! n.isNull() ) {
00191                     #ifdef KROSS_ACTION_DEBUG
00192                         krossdebug(QString("Action::readDomElement: Setting property name=%1 value=%2").arg(n).arg(e.text()));
00193                     #endif
00194                     setProperty(n.toLatin1().constData(), QVariant(e.text()));
00195                 }
00196             }
00197         }
00198     }
00199 }
00200 
00201 QDomElement Action::toDomElement() const
00202 {
00203     QDomDocument doc;
00204     QDomElement e = doc.createElement("script");
00205     e.setAttribute("name", objectName());
00206     if( d->version > 0 )
00207         e.setAttribute("version", QString(d->version));
00208     if( ! text().isNull() )
00209         e.setAttribute("text", text());
00210     if( ! description().isNull() )
00211         e.setAttribute("comment", description());
00212     if( ! iconName().isNull() )
00213         e.setAttribute("icon", iconName());
00214     if( ! isEnabled() )
00215         e.setAttribute("enabled", "false");
00216     if( ! interpreter().isNull() )
00217         e.setAttribute("interpreter", interpreter());
00218 
00219     if( ! file().isNull() ) {
00220         e.setAttribute("file", file());
00221     }
00222     /*
00223     else if( ! code().isNull() ) {
00224         e.setAttribute("code", code());
00225     }
00226     */
00227 
00228     return e;
00229 }
00230 
00231 Kross::Script* Action::script() const
00232 {
00233     return d->script;
00234 }
00235 
00236 QString Action::name() const
00237 {
00238     return objectName();
00239 }
00240 
00241 int Action::version() const
00242 {
00243     return d->version;
00244 }
00245 
00246 QString Action::description() const
00247 {
00248     return d->description;
00249 }
00250 
00251 void Action::setDescription(const QString& description)
00252 {
00253     d->description = description;
00254     emit dataChanged(this);
00255     emit updated();
00256 }
00257 
00258 QString Action::iconName() const
00259 {
00260     return d->iconname;
00261 }
00262 
00263 void Action::setIconName(const QString& iconname)
00264 {
00265     setIcon( KIcon(iconname) );
00266     d->iconname = iconname;
00267     emit dataChanged(this);
00268     emit updated();
00269 }
00270 
00271 bool Action::isEnabled() const
00272 {
00273     return QAction::isEnabled();
00274 }
00275 
00276 void Action::setEnabled(bool enabled)
00277 {
00278     QAction::setEnabled(enabled);
00279     emit dataChanged(this);
00280     emit updated();
00281 }
00282 
00283 QByteArray Action::code() const
00284 {
00285     return d->code;
00286 }
00287 
00288 void Action::setCode(const QByteArray& code)
00289 {
00290     if( d->code != code ) {
00291         finalize();
00292         d->code = code;
00293         emit dataChanged(this);
00294         emit updated();
00295     }
00296 }
00297 
00298 QString Action::interpreter() const
00299 {
00300     return d->interpretername;
00301 }
00302 
00303 void Action::setInterpreter(const QString& interpretername)
00304 {
00305     if( d->interpretername != interpretername ) {
00306         finalize();
00307         d->interpretername = interpretername;
00308         setEnabled( Manager::self().interpreters().contains(interpretername) );
00309         if (!isEnabled())
00310             kWarning(410)<<"interpreter not found:"<<interpretername;
00311         emit dataChanged(this);
00312         emit updated();
00313     }
00314 }
00315 
00316 QString Action::file() const
00317 {
00318     return d->scriptfile;
00319 }
00320 
00321 bool Action::setFile(const QString& scriptfile)
00322 {
00323     if( d->scriptfile != scriptfile ) {
00324         finalize();
00325         if ( scriptfile.isNull() ) {
00326             if( ! d->scriptfile.isNull() )
00327                 d->interpretername.clear();
00328             d->scriptfile.clear();
00329             d->currentpath.clear();
00330         }
00331         else {
00332             d->scriptfile = scriptfile;
00333             d->currentpath = QFileInfo(scriptfile).absolutePath();
00334             d->interpretername = Manager::self().interpreternameForFile(scriptfile);
00335             if( d->interpretername.isNull() )
00336                 return false;
00337         }
00338     }
00339     return true;
00340 }
00341 
00342 QString Action::currentPath() const
00343 {
00344     return d->currentpath;
00345 }
00346 
00347 QVariantMap Action::options() const
00348 {
00349     return d->options;
00350 }
00351 
00352 void Action::addQObject(QObject* obj, const QString &name)
00353 {
00354     this->addObject(obj, name);
00355 }
00356 
00357 QObject* Action::qobject(const QString &name) const
00358 {
00359     return this->object(name);
00360 }
00361 
00362 QStringList Action::qobjectNames() const
00363 {
00364     return this->objects().keys();
00365 }
00366 
00367 QVariant Action::option(const QString& name, const QVariant& defaultvalue)
00368 {
00369     if(d->options.contains(name))
00370         return d->options[name];
00371     InterpreterInfo* info = Manager::self().interpreterInfo( d->interpretername );
00372     return info ? info->optionValue(name, defaultvalue) : defaultvalue;
00373 }
00374 
00375 bool Action::setOption(const QString& name, const QVariant& value)
00376 {
00377     InterpreterInfo* info = Manager::self().interpreterInfo( d->interpretername );
00378     if(info) {
00379         if(info->hasOption(name)) {
00380             d->options.insert(name, value);
00381             return true;
00382         } else krosswarning( QString("Kross::Action::setOption(%1, %2): No such option").arg(name).arg(value.toString()) );
00383     } else krosswarning( QString("Kross::Action::setOption(%1, %2): No such interpreterinfo").arg(name).arg(value.toString()) );
00384     return false;
00385 }
00386 
00387 QStringList Action::functionNames()
00388 {
00389     if(! d->script) {
00390         if(! initialize())
00391             return QStringList();
00392     }
00393     return d->script->functionNames();
00394 }
00395 
00396 QVariant Action::callFunction(const QString& name, const QVariantList& args)
00397 {
00398     if(! d->script) {
00399         if(! initialize())
00400             return QVariant();
00401     }
00402     return d->script->callFunction(name, args);
00403 }
00404 
00405 QVariant Action::evaluate(const QByteArray& code)
00406 {
00407     if(! d->script) {
00408         if(! initialize())
00409             return QVariant();
00410     }
00411     return d->script->evaluate(code);
00412 }
00413 
00414 bool Action::initialize()
00415 {
00416     finalize();
00417 
00418     if( ! d->scriptfile.isNull() ) {
00419         QFile f( d->scriptfile );
00420         if( ! f.exists() ) {
00421             setError(i18n("Scriptfile \"%1\" does not exist.", d->scriptfile));
00422             return false;
00423         }
00424         if( d->interpretername.isNull() ) {
00425             setError(i18n("Failed to determine interpreter for scriptfile \"%1\"", d->scriptfile));
00426             return false;
00427         }
00428         if( ! f.open(QIODevice::ReadOnly) ) {
00429             setError(i18n("Failed to open scriptfile \"%1\"", d->scriptfile));
00430             return false;
00431         }
00432         d->code = f.readAll();
00433         f.close();
00434     }
00435 
00436     Interpreter* interpreter = Manager::self().interpreter(d->interpretername);
00437     if( ! interpreter ) {
00438         InterpreterInfo* info = Manager::self().interpreterInfo(d->interpretername);
00439         if( info )
00440             setError(i18n("Failed to load interpreter \"%1\"", d->interpretername));
00441         else
00442             setError(i18n("No such interpreter \"%1\"", d->interpretername));
00443         return false;
00444     }
00445 
00446     d->script = interpreter->createScript(this);
00447     if( ! d->script ) {
00448         setError(i18n("Failed to create script for interpreter \"%1\"", d->interpretername));
00449         return false;
00450     }
00451 
00452     if( d->script->hadError() ) {
00453         setError(d->script);
00454         finalize();
00455         return false;
00456     }
00457 
00458     clearError(); // clear old exception
00459     return true;
00460 }
00461 
00462 void Action::finalize()
00463 {
00464     if( d->script )
00465         emit finalized(this);
00466     delete d->script;
00467     d->script = 0;
00468 }
00469 
00470 bool Action::isFinalized() const
00471 {
00472     return d->script == 0;
00473 }
00474 
00475 void Action::slotTriggered()
00476 {
00477     #ifdef KROSS_ACTION_DEBUG
00478         krossdebug( QString("Action::slotTriggered() name=%1").arg(objectName()) );
00479     #endif
00480 
00481     emit started(this);
00482 
00483     if( ! d->script ) {
00484         if( ! initialize() )
00485             Q_ASSERT( hadError() );
00486     }
00487 
00488     if( hadError() ) {
00489         #ifdef KROSS_ACTION_DEBUG
00490             krossdebug( QString("Action::slotTriggered() on init, errorMessage=%2").arg(errorMessage()) );
00491         #endif
00492     }
00493     else {
00494         d->script->execute();
00495         if( d->script->hadError() ) {
00496             #ifdef KROSS_ACTION_DEBUG
00497                 krossdebug( QString("Action::slotTriggered() after exec, errorMessage=%2").arg(errorMessage()) );
00498             #endif
00499             setError(d->script);
00500             //emit finished(this);
00501             finalize();
00502             //return;
00503         }
00504     }
00505 
00506     emit finished(this);
00507 }
00508 
00509 // --------
00510 
00511 // interface files
00512 WrapperInterface::~WrapperInterface()
00513 {
00514 }
00515 
00516 #include "action.moc"

Kross

Skip menu "Kross"
  • Main Page
  • Namespace List
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Namespace Members
  • Class Members
  • Related Pages

kdelibs

Skip menu "kdelibs"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • Kate
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • Kross
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
Generated for kdelibs by doxygen 1.5.7
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal