00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "action.h"
00021 #include "interpreter.h"
00022 #include "script.h"
00023 #include "manager.h"
00024
00025 #include <QFile>
00026 #include <QFileInfo>
00027 #include <QDir>
00028 #include <QDomElement>
00029
00030 #include <klocale.h>
00031 #include <kicon.h>
00032 #include <kmimetype.h>
00033 #include <kstandarddirs.h>
00034
00035 using namespace Kross;
00036
00037 namespace Kross {
00038
00040 class Action::Private
00041 {
00042 public:
00043
00049 Script* script;
00050
00055 QString description;
00056
00060 QString code;
00061
00066 QString interpretername;
00067
00074 QString scriptfile;
00075
00080 QString currentpath;
00081
00086 QMap<QString, QVariant> options;
00087
00088 Private() : script(0) {}
00089 };
00090
00091 }
00092
00093 Action::Action(KActionCollection* collection, const QString& name)
00094 : KAction( collection, name )
00095 , ChildrenInterface()
00096 , ErrorInterface()
00097 , d( new Private() )
00098 {
00099 setEnabled( false );
00100 }
00101
00102 Action::Action(const QString& file)
00103 : KAction( 0 , file )
00104 , ChildrenInterface()
00105 , ErrorInterface()
00106 , d( new Private() )
00107 {
00108 KUrl url(file);
00109 setText( url.fileName() );
00110 setIcon( KIcon(KMimeType::iconNameForUrl(url)) );
00111 setFile( file );
00112 }
00113
00114 Action::Action(KActionCollection* collection, const QDomElement& element, const QDir& packagepath)
00115 : KAction( collection, element.attribute("name") )
00116 , ChildrenInterface()
00117 , ErrorInterface()
00118 , d( new Private() )
00119 {
00120 setText( element.attribute("text") );
00121 setDescription( element.attribute("description") );
00122 setInterpreter( element.attribute("interpreter") );
00123
00124 QString file = element.attribute("file");
00125 if( ! file.isEmpty() ) {
00126 if(! QFileInfo(file).exists()) {
00127 QFileInfo fi(packagepath, file);
00128 if(fi.exists())
00129 file = fi.absoluteFilePath();
00130 else
00131 setEnabled(false);
00132 }
00133 setFile(file);
00134 }
00135 else {
00136 d->currentpath = packagepath.absolutePath();
00137 }
00138
00139 QString icon = element.attribute("icon");
00140 if( icon.isEmpty() && ! d->scriptfile.isNull() )
00141 icon = KMimeType::iconNameForUrl( KUrl(d->scriptfile) );
00142 setIcon( KIcon(icon) );
00143 }
00144
00145 Action::~Action()
00146 {
00147 krossdebug( QString("Action::~Action() Dtor name='%1'").arg(objectName()) );
00148 finalize();
00149 delete d;
00150 }
00151
00152 QString Action::description() const
00153 {
00154 return d->description;
00155 }
00156
00157 void Action::setDescription(const QString& description)
00158 {
00159 d->description = description;
00160 }
00161
00162 QString Action::code() const
00163 {
00164 return d->code;
00165 }
00166
00167 void Action::setCode(const QString& code)
00168 {
00169 if( d->code != code ) {
00170 finalize();
00171 d->code = code;
00172 }
00173 }
00174
00175 QString Action::interpreter() const
00176 {
00177 return d->interpretername;
00178 }
00179
00180 void Action::setInterpreter(const QString& interpretername)
00181 {
00182 if( d->interpretername != interpretername ) {
00183 finalize();
00184 d->interpretername = interpretername;
00185 setEnabled( Manager::self().interpreters().contains(interpretername) );
00186 }
00187 }
00188
00189 QString Action::file() const
00190 {
00191 return d->scriptfile;
00192 }
00193
00194 bool Action::setFile(const QString& scriptfile)
00195 {
00196 if( d->scriptfile != scriptfile ) {
00197 finalize();
00198 if ( scriptfile.isNull() ) {
00199 if( ! d->scriptfile.isNull() )
00200 d->interpretername.clear();
00201 d->scriptfile.clear();
00202 d->currentpath.clear();
00203 }
00204 else {
00205 d->scriptfile = scriptfile;
00206 d->currentpath = QFileInfo(scriptfile).absolutePath();
00207 d->interpretername = Manager::self().interpreternameForFile(scriptfile);
00208 if( d->interpretername.isNull() )
00209 return false;
00210 }
00211 }
00212 return true;
00213 }
00214
00215 QString Action::currentPath() const
00216 {
00217 return d->currentpath;
00218 }
00219
00220 QMap<QString, QVariant>& Action::options() const
00221 {
00222 return d->options;
00223 }
00224
00225 QVariant Action::option(const QString name, QVariant defaultvalue)
00226 {
00227 if(d->options.contains(name))
00228 return d->options[name];
00229 InterpreterInfo* info = Manager::self().interpreterInfo( d->interpretername );
00230 return info ? info->optionValue(name, defaultvalue) : defaultvalue;
00231 }
00232
00233 bool Action::setOption(const QString name, const QVariant& value)
00234 {
00235 InterpreterInfo* info = Manager::self().interpreterInfo( d->interpretername );
00236 if(info) {
00237 if(info->hasOption(name)) {
00238 d->options.insert(name, value);
00239 return true;
00240 } else krosswarning( QString("Kross::Action::setOption(%1, %2): No such option").arg(name).arg(value.toString()) );
00241 } else krosswarning( QString("Kross::Action::setOption(%1, %2): No such interpreterinfo").arg(name).arg(value.toString()) );
00242 return false;
00243 }
00244
00245 QStringList Action::functionNames()
00246 {
00247 if(! d->script) {
00248 if(! initialize())
00249 return QStringList();
00250 }
00251 return d->script->functionNames();
00252 }
00253
00254 QVariant Action::callFunction(const QString& name, const QVariantList& args)
00255 {
00256 if(! d->script) {
00257 if(! initialize())
00258 return QVariant();
00259 }
00260 return d->script->callFunction(name, args);
00261 }
00262
00263 bool Action::initialize()
00264 {
00265 finalize();
00266
00267 if( ! d->scriptfile.isNull() ) {
00268 QFile f( d->scriptfile );
00269 if( ! f.exists() ) {
00270 setError(i18n("There exists no such scriptfile '%1'", d->scriptfile));
00271 return false;
00272 }
00273 if( d->interpretername.isNull() ) {
00274 setError(i18n("Failed to determinate interpreter for scriptfile '%1'", d->scriptfile));
00275 return false;
00276 }
00277 if( ! f.open(QIODevice::ReadOnly) ) {
00278 setError(i18n("Failed to open scriptfile '%1'", d->scriptfile));
00279 return false;
00280 }
00281 d->code = QString( f.readAll() );
00282 f.close();
00283 }
00284
00285 Interpreter* interpreter = Manager::self().interpreter(d->interpretername);
00286 if( ! interpreter ) {
00287 setError(i18n("Unknown interpreter '%1'", d->interpretername));
00288 return false;
00289 }
00290
00291 d->script = interpreter->createScript(this);
00292 if( ! d->script ) {
00293 setError(i18n("Failed to create script for interpreter '%1'", d->interpretername));
00294 return false;
00295 }
00296
00297 if( d->script->hadError() ) {
00298 setError(d->script);
00299 finalize();
00300 return false;
00301 }
00302
00303 clearError();
00304 return true;
00305 }
00306
00307 void Action::finalize()
00308 {
00309 delete d->script;
00310 d->script = 0;
00311 }
00312
00313 void Action::slotTriggered()
00314 {
00315
00316 emit started(this);
00317
00318 if( ! d->script ) {
00319 if( ! initialize() )
00320 Q_ASSERT( hadError() );
00321 }
00322
00323 if( hadError() ) {
00324 krossdebug( QString("Action::slotTriggered() name=%1 errorMessage=%2").arg(objectName()).arg(errorMessage()) );
00325 emit finished(this);
00326 return;
00327 }
00328
00329 d->script->execute();
00330 if( d->script->hadError() ) {
00331 setError(d->script);
00332 finalize();
00333 }
00334
00335 emit finished(this);
00336 }
00337
00338 #include "action.moc"