You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
tdeedu/kig/scripting/script_mode.cc

363 lines
9.7 KiB

// Copyright (C) 2003 Dominique Devriese <devriese@kde.org>
// 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 <tqlabel.h>
#include <tqpushbutton.h>
#include <kcursor.h>
#include <kiconloader.h>
#include <tdemessagebox.h>
void ScriptModeBase::dragRect( const TQPoint& p, KigWidget& w )
{
if ( mwawd != SelectingArgs ) return;
DragRectMode dm( p, mdoc, w );
mdoc.runMode( &dm );
std::vector<ObjectHolder*> ret = dm.ret();
KigPainter pter( w.screenInfo(), TQT_TQPAINTDEVICE(&w.stillPix), mdoc.document() );
if ( dm.needClear() )
{
std::vector<ObjectHolder*> 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<ObjectHolder*>::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<ObjectHolder*>& 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<ObjectHolder*> sel;
if ( mwawd == SelectingArgs )
sel = std::vector<ObjectHolder*>( margs.begin(), margs.end() );
w->redrawScreen( sel );
w->updateScrollBars();
}
bool ScriptCreationMode::queryFinish()
{
std::vector<ObjectCalcer*> 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<ObjectHolder*>::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<ObjectHolder*>&,
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<ObjectHolder*>& 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<ObjectConstCalcer*>( mcompiledargs[0] )->imp();
assert( dynamic_cast<const StringImp*>( imp ) );
// save the original script text, in case the user modifies the text
// in the editor and aborts the editing
morigscript = static_cast<const StringImp*>( 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<ObjectConstCalcer*>( 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<ObjectConstCalcer*>( 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;
}