kexi

context.cpp

00001 /***************************************************************************
00002  * This file is part of the KDE project
00003  * copyright (C) 2005 by Sebastian Sauer (mail@dipe.org)
00004  * copyright (C) 2005 by Tobi Krebs (tobi.krebs@gmail.com)
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 "context.h"
00021 #include "action.h"
00022 #include "macro.h"
00023 #include "macroitem.h"
00024 #include "exception.h"
00025 
00026 //#include <qtimer.h>
00027 #include <kdebug.h>
00028 
00029 using namespace KoMacro;
00030 
00031 namespace KoMacro {
00032 
00037     class Context::Private
00038     {
00039         public:
00040 
00044             KSharedPtr<Macro> macro;
00045 
00050             QValueList<KSharedPtr<MacroItem > > items;
00051 
00056             KSharedPtr<MacroItem> macroitem;
00057 
00062             QMap<QString, KSharedPtr<Variable > > variables;
00063 
00068             Exception* exception;
00069 
00071             explicit Private(KSharedPtr<Macro> m)
00072                 : macro(m) // remember the macro
00073                 , items(m->items()) // set d-pointer children to macro children
00074                 , exception(0) // no exception yet.
00075             {
00076             }
00077 
00079             ~Private()
00080             {
00081                 delete exception;
00082             }
00083     };
00084 
00085 }
00086 //Constructor with initialization of our Private.object (d-pointer)
00087 Context::Context(KSharedPtr<Macro> macro)
00088     : QObject()
00089     , d( new Private(macro) ) // create the private d-pointer instance.
00090 {
00091 }
00092 
00093 //Destructor.
00094 Context::~Context()
00095 {
00096     delete d;
00097 }
00098 
00099 //return if we have (d-pointer) variables
00100 bool Context::hasVariable(const QString& name) const
00101 {
00102     //Use QMap?s contains to check if a variable with name exists
00103     return d->variables.contains(name);
00104 }
00105 
00106 //return variable with name or throw an exception if none is found in variables
00107 KSharedPtr<Variable> Context::variable(const QString& name) const
00108 {
00109     //Use QMap?s contains to check if a variable with name exists in context    
00110     if (d->variables.contains(name)) {
00111         //return it
00112         return d->variables[name];
00113     }
00114     //if there is a macroitem try to get variable from it 
00115     if(d->macroitem.data()) {
00116         KSharedPtr<Variable> v = d->macroitem->variable(name, true);
00117         if(v.data()) {
00118             return v;
00119         }
00120     }
00121     //none found throw exception
00122     throw Exception(QString("Variable name='%1' does not exist.").arg(name));
00123 }
00124 
00125 //return a map of our (d-pointer) variables
00126 Variable::Map Context::variables() const
00127 {
00128     return d->variables;
00129 }
00130 
00131 //set a variable
00132 void Context::setVariable(const QString& name, KSharedPtr<Variable> variable)
00133 {
00134     //debuging infos
00135     kdDebug() << QString("KoMacro::Context::setVariable name='%1' variable='%2'").arg(name).arg(variable->toString()) << endl;
00136     //Use QMap?s replace to set/replace the variable named name
00137     d->variables.replace(name, variable);
00138 }
00139 
00140 //return the associated Macro
00141 KSharedPtr<Macro> Context::macro() const
00142 {
00143     return d->macro;
00144 }
00145 
00146 //return the currently selected MacroItem
00147 KSharedPtr<MacroItem> Context::macroItem() const
00148 {
00149     return d->macroitem;
00150 }
00151 
00152 //return if this context had an exception
00153 bool Context::hadException() const
00154 {
00155     return d->exception != 0;
00156 }
00157 
00158 //return the (d-pointer) exception
00159 Exception* Context::exception() const
00160 {
00161     return d->exception;
00162 }
00163 
00164 //try to activate all action?s in this context
00165 void Context::activate(QValueList<KSharedPtr<MacroItem > >::ConstIterator it)
00166 {
00167     //debuging infos
00168     kdDebug() << "Context::activate()" << endl;
00169     //Q_ASSIGN(d->macro);
00170 
00171     //set end to constEnd
00172     QValueList<KSharedPtr<MacroItem > >::ConstIterator end(d->items.constEnd());
00173     //loop through actions
00174     for(;it != end; ++it) {
00175         // fetch the MacroItem we are currently pointing to.
00176         d->macroitem = KSharedPtr<MacroItem>(*it);
00177         //skip empty macroitems
00178         if(! d->macroitem.data()) {
00179             kdDebug() << "Context::activate() Skipping empty MacroItem" << endl;
00180             continue;
00181         }
00182 
00183         // fetch the Action, the MacroItem points to.
00184         KSharedPtr<Action> action = d->macroitem->action();
00185         //skip macroitems without an action
00186         if(! action.data()) {
00187             kdDebug() << "Context::activate() Skipping MacroItem with no action" << endl;
00188             continue;
00189         }
00190 
00191         try {
00192             // activate the action
00193             action->activate(this);
00194         }
00195         //catch exceptions
00196         catch(Exception& e) {
00197             //create a new exception from caugth one and set internal exception 
00198             d->exception = new Exception(e);
00199             //add new tracemessages
00200             //the macro name
00201             d->exception->addTraceMessage( QString("macro=%1").arg(d->macro->name()) );
00202             //the action name
00203             d->exception->addTraceMessage( QString("action=%1").arg(action->name()) );
00204             //and all variables wich belong to the action/macro
00205             QStringList variables = action->variableNames();
00206             for(QStringList::Iterator vit = variables.begin(); vit != variables.end(); ++vit) {
00207                 KSharedPtr<Variable> v = d->macroitem->variable(*vit, true);
00208                 d->exception->addTraceMessage( QString("%1=%2").arg(*vit).arg(v->toString()) );
00209             }
00210             return; // abort execution
00211         }
00212     }
00213 
00214     // The run is done. So, let's remove the currently selected item to
00215     // outline, that we did the job and there stays no dangling item.
00216     d->macroitem = KSharedPtr<MacroItem>(0);
00217 }
00218 
00219 //try to activated an context
00220 void Context::activate(KSharedPtr<Context> context)
00221 {
00222     //setup context
00223     delete d->exception; d->exception = 0;
00224     
00225     if(context->hadException()) {
00226         // if the context in which this context should run in already had an exception,
00227         // we adopt this exception and abort the execution. 
00228         d->exception = new Exception( *context->exception() );
00229         return;
00230     }
00231 
00232     // Merge the passed context into this context
00233     Variable::Map variables = context->variables();
00234     //copy variables
00235     Variable::Map::ConstIterator it, end( variables.constEnd() );
00236     for( it = variables.constBegin(); it != end; ++it)
00237         setVariable(it.key(), it.data());
00238     
00239     //activate copied context.
00240     activate(d->items.constBegin());
00241 }
00242 
00243 //try to continue activation of a context
00244 void Context::activateNext()
00245 {   
00246     //setup/clear context,
00247     //allows us to continue activation even when an exception happend before
00248     delete d->exception; d->exception = 0;
00249 
00250     if(! d->macroitem) { // if no MacroItem is defined, we don't need to try to continue execution
00251         return;
00252     }
00253 
00254     //find the macroitem from which to continue
00255     QValueList<KSharedPtr<MacroItem > >::ConstIterator it = d->items.find(d->macroitem);
00256     if (it != d->items.constEnd()) {
00257         activate(++it); // try to continue the execution.
00258     }
00259 }
00260 
00261 #include "context.moc"
KDE Home | KDE Accessibility Home | Description of Access Keys