// Copyright (C) 2003 Dominique Devriese // 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, write to the Free Software // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA // 02110-1301, USA. #include "script_mode.h" #include "newscriptwizard.h" #include "python_type.h" #include "python_scripter.h" #include "../kig/kig_commands.h" #include "../kig/kig_part.h" #include "../kig/kig_view.h" #include "../misc/calcpaths.h" #include "../misc/kigpainter.h" #include "../modes/dragrectmode.h" #include "../objects/bogus_imp.h" #include "../objects/object_imp.h" #include #include #include #include #include void ScriptModeBase::dragRect( const TQPoint& p, KigWidget& w ) { if ( mwawd != SelectingArgs ) return; DragRectMode dm( p, mdoc, w ); mdoc.runMode( &dm ); std::vector ret = dm.ret(); KigPainter pter( w.screenInfo(), TQT_TQPAINTDEVICE(&w.stillPix), mdoc.document() ); if ( dm.needClear() ) { std::vector tmp( margs.begin(), margs.begin() ); pter.drawObjects( tmp, false ); margs.clear(); } std::copy( ret.begin(), ret.end(), std::inserter( margs, margs.begin() ) ); pter.drawObjects( ret, true ); w.updateCurPix( pter.overlay() ); w.updateWidget(); } void ScriptModeBase::leftClickedObject( ObjectHolder* o, const TQPoint&, KigWidget& w, bool ) { std::list::iterator dup_o; if ( mwawd != SelectingArgs ) return; KigPainter pter( w.screenInfo(), TQT_TQPAINTDEVICE(&w.stillPix), mdoc.document() ); if ( (dup_o = std::find( margs.begin(), margs.end(), o )) != margs.end() ) { margs.erase( dup_o ); pter.drawObject( o, false ); } else { margs.push_back( o ); pter.drawObject( o, true ); }; w.updateCurPix( pter.overlay() ); w.updateWidget(); } void ScriptModeBase::mouseMoved( const std::vector& os, const TQPoint& pt, KigWidget& w, bool ) { if ( mwawd != SelectingArgs ) return; w.updateCurPix(); if ( os.empty() ) { w.setCursor( KCursor::arrowCursor() ); mdoc.emitStatusBarText( 0 ); w.updateWidget(); } else { // the cursor is over an object, show object type next to cursor // and set statusbar text w.setCursor( KCursor::handCursor() ); TQString selectstat = os.front()->selectStatement(); // statusbar text mdoc.emitStatusBarText( selectstat ); KigPainter p( w.screenInfo(), TQT_TQPAINTDEVICE(&w.curPix), mdoc.document() ); // set the text next to the arrow cursor TQPoint point = pt; point.setX(point.x()+15); p.drawTextStd( point, selectstat ); w.updateWidget( p.overlay() ); } } ScriptModeBase::ScriptModeBase( KigPart& doc ) : BaseMode( doc ), mwizard( 0 ), mpart( doc ), mwawd( SelectingArgs ) { mwizard = new NewScriptWizard( doc.widget(), this ); doc.redrawScreen(); } ScriptModeBase::~ScriptModeBase() { } void ScriptModeBase::killMode() { mdoc.doneMode( this ); } bool ScriptCreationMode::queryCancel() { killMode(); return true; } void ScriptModeBase::argsPageEntered() { mwawd = SelectingArgs; mdoc.redrawScreen(); } void ScriptModeBase::enableActions() { KigMode::enableActions(); // we don't enable any actions.. } void ScriptModeBase::codePageEntered() { if ( mwizard->text().isEmpty() ) { // insert template code.. TQString tempcode = ScriptType::templateCode( mtype, margs ); mwizard->setText( tempcode ); }; mwizard->setFinishEnabled( mwizard->mpcode, true ); mwawd = EnteringCode; mdoc.redrawScreen(); } void ScriptModeBase::redrawScreen( KigWidget* w ) { std::vector sel; if ( mwawd == SelectingArgs ) sel = std::vector( margs.begin(), margs.end() ); w->redrawScreen( sel ); w->updateScrollBars(); } bool ScriptCreationMode::queryFinish() { std::vector args; TQString script = mwizard->text(); args.push_back( new ObjectConstCalcer( new StringImp( script ) ) ); ObjectTypeCalcer* compiledscript = new ObjectTypeCalcer( PythonCompileType::instance(), args ); compiledscript->calc( mdoc.document() ); args.clear(); args.push_back( compiledscript ); for ( std::list::iterator i = margs.begin(); i != margs.end(); ++i ) args.push_back( ( *i )->calcer() ); ObjectTypeCalcer::shared_ptr reto = new ObjectTypeCalcer( PythonExecuteType::instance(), args ); reto->calc( mdoc.document() ); if ( reto->imp()->inherits( InvalidImp::stype() ) ) { PythonScripter* inst = PythonScripter::instance(); TQCString errtrace = inst->lastErrorExceptionTraceback().c_str(); if ( inst->errorOccurred() ) { KMessageBox::detailedSorry( mwizard, i18n( "The Python interpreter caught an error during the execution of your " "script. Please fix the script and click the Finish button again." ), i18n( "The Python Interpreter generated the following error output:\n%1").arg( errtrace.data() ) ); } else { KMessageBox::sorry( mwizard, i18n( "There seems to be an error in your script. The Python interpreter " "reported no errors, but the script does not generate " "a valid object. Please fix the script, and click the Finish button " "again." ) ); } return false; } else { mdoc.addObject( new ObjectHolder( reto.get() ) ); killMode(); return true; } } void ScriptModeBase::midClicked( const TQPoint&, KigWidget& ) { } void ScriptModeBase::rightClicked( const std::vector&, const TQPoint&, KigWidget& ) { } void ScriptModeBase::setScriptType( ScriptType::Type type ) { mtype = type; mwizard->setType( mtype ); if ( mtype != ScriptType::Unknown ) { TDEIconLoader* il = mpart.instance()->iconLoader(); mwizard->setIcon( il->loadIcon( ScriptType::icon( mtype ), TDEIcon::Small ) ); } } void ScriptModeBase::addArgs( const std::vector& obj, KigWidget& w ) { KigPainter pter( w.screenInfo(), TQT_TQPAINTDEVICE(&w.stillPix), mdoc.document() ); std::copy( obj.begin(), obj.end(), std::inserter( margs, margs.begin() ) ); pter.drawObjects( obj, true ); w.updateCurPix( pter.overlay() ); w.updateWidget(); } void ScriptModeBase::goToCodePage() { mwizard->next(); } ScriptCreationMode::ScriptCreationMode( KigPart& doc ) : ScriptModeBase( doc ) { mwizard->show(); } ScriptCreationMode::~ScriptCreationMode() { } ScriptEditMode::ScriptEditMode( ObjectTypeCalcer* exec_calc, KigPart& doc ) : ScriptModeBase( doc ), mexecuted( exec_calc ) { mwawd = EnteringCode; mexecargs = mexecuted->parents(); assert( mexecargs.size() >= 1 ); mcompiledargs = mexecargs[0]->parents(); assert( mcompiledargs.size() == 1 ); const ObjectImp* imp = static_cast( mcompiledargs[0] )->imp(); assert( dynamic_cast( imp ) ); // save the original script text, in case the user modifies the text // in the editor and aborts the editing morigscript = static_cast( imp )->data(); mwizard->setCaption( i18n( "'Edit' is a verb", "Edit Script" ) ); mwizard->setText( morigscript ); mwizard->show(); mwizard->next(); mwizard->backButton()->setEnabled( false ); mwizard->finishButton()->setEnabled( true ); } ScriptEditMode::~ScriptEditMode() { } bool ScriptEditMode::queryFinish() { MonitorDataObjects mon( mcompiledargs ); static_cast( mcompiledargs[0] )->switchImp( new StringImp( mwizard->text() ) ); mexecargs[0]->calc( mpart.document() ); mexecuted->calc( mpart.document() ); mpart.redrawScreen(); KigCommand* comm = new KigCommand( mpart, i18n( "Edit Python Script" ) ); mon.finish( comm ); if ( mexecuted->imp()->inherits( InvalidImp::stype() ) ) { PythonScripter* inst = PythonScripter::instance(); TQCString errtrace = inst->lastErrorExceptionTraceback().c_str(); if ( inst->errorOccurred() ) { KMessageBox::detailedSorry( mpart.widget(), i18n( "The Python interpreter caught an error during the execution of your " "script. Please fix the script." ), i18n( "The Python Interpreter generated the following error output:\n%1").arg( errtrace.data() ) ); } else { KMessageBox::sorry( mpart.widget(), i18n( "There seems to be an error in your script. The Python interpreter " "reported no errors, but the script does not generate " "a valid object. Please fix the script." ) ); } delete comm; return false; } mpart.history()->addCommand( comm ); mpart.setModified( true ); killMode(); return true; } bool ScriptEditMode::queryCancel() { // reverting the original script text static_cast( mcompiledargs[0] )->switchImp( new StringImp( morigscript ) ); mexecargs[0]->calc( mpart.document() ); mexecuted->calc( mpart.document() ); // paranoic check assert( !mexecuted->imp()->inherits( InvalidImp::stype() ) ); mpart.redrawScreen(); // no need to further checks here, as the original script text is ok killMode(); return true; }