[prev in list] [next in list] [prev in thread] [next in thread] 

List:       kde-core-devel
Subject:    New Feature: Script Editing for Kig
From:       Pino Toscano <toscano.pino () tiscali ! it>
Date:       2006-06-10 22:35:17
Message-ID: 200606110035.35870.toscano.pino () tiscali ! it
[Download RAW message or body]

[Attachment #2 (multipart/mixed)]


Hi,

the attached patch implements the possibility to edit a Python script in Kig.
A new entry is added to the context menu of the script object, and it opens a 
dialog where edit the Python code.
The patch is on SVN trunk and in a kig branch (/branches/kig/post-kde-3.5) 
since February.
About the i18n side (hence the CC to kde-i18n-doc): the patch adds three new 
simple strings, namely:
- i18n( "'Edit' is a verb", "Edit Script" )
- i18n( "Edit Python Script" )
- i18n( "Edit Script..." )

Would be ok to add this new feature in KDE 3.5.4 with these new strings?

Regards,

-- 
Pino Toscano

["kig-edit-script.diff" (text/x-diff)]

Index: scripting/newscriptwizard.cc
===================================================================
--- scripting/newscriptwizard.cc	(revisione 550052)
+++ scripting/newscriptwizard.cc	(copia locale)
@@ -56,7 +56,7 @@
   }
 }
 
-NewScriptWizard::NewScriptWizard( QWidget* parent, ScriptMode* mode )
+NewScriptWizard::NewScriptWizard( QWidget* parent, ScriptModeBase* mode )
   : NewScriptWizardBase( parent, "New Script Wizard" ),
     mmode( mode )
 {
Index: scripting/newscriptwizard.h
===================================================================
--- scripting/newscriptwizard.h	(revisione 550052)
+++ scripting/newscriptwizard.h	(copia locale)
@@ -29,15 +29,15 @@
 
 #include <algorithm>
 
-class ScriptMode;
+class ScriptModeBase;
 
 class NewScriptWizard
   : public NewScriptWizardBase
 {
   Q_OBJECT
-  ScriptMode* mmode;
+  ScriptModeBase* mmode;
 public:
-  NewScriptWizard( QWidget* parent, ScriptMode* mode );
+  NewScriptWizard( QWidget* parent, ScriptModeBase* mode );
   ~NewScriptWizard();
 
   void back();
Index: scripting/script_mode.cc
===================================================================
--- scripting/script_mode.cc	(revisione 550052)
+++ scripting/script_mode.cc	(copia locale)
@@ -21,20 +21,23 @@
 #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 <qlabel.h>
+#include <qpushbutton.h>
 
 #include <kcursor.h>
 #include <kiconloader.h>
 #include <kmessagebox.h>
 
-void ScriptMode::dragRect( const QPoint& p, KigWidget& w )
+void ScriptModeBase::dragRect( const QPoint& p, KigWidget& w )
 {
   if ( mwawd != SelectingArgs ) return;
 
@@ -57,8 +60,8 @@
   w.updateWidget();
 }
 
-void ScriptMode::leftClickedObject( ObjectHolder* o, const QPoint&,
-                                    KigWidget& w, bool )
+void ScriptModeBase::leftClickedObject( ObjectHolder* o, const QPoint&,
+                                        KigWidget& w, bool )
 {
   if ( mwawd != SelectingArgs ) return;
 
@@ -78,7 +81,8 @@
   w.updateWidget();
 }
 
-void ScriptMode::mouseMoved( const std::vector<ObjectHolder*>& os, const QPoint& pt, \
KigWidget& w, bool ) +void ScriptModeBase::mouseMoved( const \
std::vector<ObjectHolder*>& os, +                                 const QPoint& pt, \
KigWidget& w, bool )  {
   if ( mwawd != SelectingArgs ) return;
 
@@ -110,44 +114,43 @@
   }
 }
 
-ScriptMode::ScriptMode( KigPart& doc )
+ScriptModeBase::ScriptModeBase( KigPart& doc )
   : BaseMode( doc ), mwizard( 0 ), mpart( doc ),
     mwawd( SelectingArgs )
 {
   mwizard = new NewScriptWizard( doc.widget(), this );
-  mwizard->show();
 
   doc.redrawScreen();
 }
 
-ScriptMode::~ScriptMode()
+ScriptModeBase::~ScriptModeBase()
 {
 }
 
-void ScriptMode::killMode()
+void ScriptModeBase::killMode()
 {
   mdoc.doneMode( this );
 }
 
-bool ScriptMode::queryCancel()
+bool ScriptCreationMode::queryCancel()
 {
   killMode();
   return true;
 }
 
-void ScriptMode::argsPageEntered()
+void ScriptModeBase::argsPageEntered()
 {
   mwawd = SelectingArgs;
   mdoc.redrawScreen();
 }
 
-void ScriptMode::enableActions()
+void ScriptModeBase::enableActions()
 {
   KigMode::enableActions();
   // we don't enable any actions..
 }
 
-void ScriptMode::codePageEntered()
+void ScriptModeBase::codePageEntered()
 {
   if ( mwizard->text().isEmpty() )
   {
@@ -160,7 +163,7 @@
   mdoc.redrawScreen();
 }
 
-void ScriptMode::redrawScreen( KigWidget* w )
+void ScriptModeBase::redrawScreen( KigWidget* w )
 {
   std::vector<ObjectHolder*> sel;
   if ( mwawd == SelectingArgs )
@@ -169,7 +172,7 @@
   w->updateScrollBars();
 }
 
-bool ScriptMode::queryFinish()
+bool ScriptCreationMode::queryFinish()
 {
   std::vector<ObjectCalcer*> args;
 
@@ -219,15 +222,16 @@
   }
 }
 
-void ScriptMode::midClicked( const QPoint&, KigWidget& )
+void ScriptModeBase::midClicked( const QPoint&, KigWidget& )
 {
 }
 
-void ScriptMode::rightClicked( const std::vector<ObjectHolder*>&, const QPoint&, \
KigWidget& ) +void ScriptModeBase::rightClicked( const std::vector<ObjectHolder*>&,
+                                   const QPoint&, KigWidget& )
 {
 }
 
-void ScriptMode::setScriptType( ScriptType::Type type )
+void ScriptModeBase::setScriptType( ScriptType::Type type )
 {
   mtype = type;
   mwizard->setType( mtype );
@@ -238,7 +242,7 @@
   }
 }
 
-void ScriptMode::addArgs( const std::vector<ObjectHolder*>& obj, KigWidget& w )
+void ScriptModeBase::addArgs( const std::vector<ObjectHolder*>& obj, KigWidget& w )
 {
   KigPainter pter( w.screenInfo(), &w.stillPix, mdoc.document() );
 
@@ -249,7 +253,107 @@
   w.updateWidget();
 }
 
-void ScriptMode::goToCodePage()
+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();
+    QCString 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 ) ); +    }
+    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 );
+
+  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;
+}
+
Index: scripting/script_mode.h
===================================================================
--- scripting/script_mode.h	(revisione 550052)
+++ scripting/script_mode.h	(copia locale)
@@ -27,11 +27,14 @@
 class NewScriptWizard;
 
 /**
- * Mode to create a new scripted type..
+ * Base mode to interact with a script.
  */
-class ScriptMode
+class ScriptModeBase
   : public BaseMode
 {
+protected:
+  ScriptModeBase( KigPart& doc );
+
   std::set<ObjectHolder*> margs;
   NewScriptWizard* mwizard;
 
@@ -40,11 +43,11 @@
   enum WAWD { SelectingArgs, EnteringCode };
   WAWD mwawd;
 
+private:
   ScriptType::Type mtype;
 
 public:
-  ScriptMode( KigPart& doc );
-  ~ScriptMode();
+  virtual ~ScriptModeBase();
 
   void dragRect( const QPoint& p, KigWidget& w );
 //  void dragObject( const Objects& os, const QPoint& pointClickedOn, KigWidget& w, \
bool ctrlOrShiftDown ); @@ -58,8 +61,8 @@
   void argsPageEntered();
   void codePageEntered();
 
-  bool queryFinish();
-  bool queryCancel();
+  virtual bool queryFinish() = 0;
+  virtual bool queryCancel() = 0;
 
   void redrawScreen( KigWidget* w );
 
@@ -75,4 +78,39 @@
 
 };
 
+/**
+ * Script mode to create a script.
+ */
+class ScriptCreationMode
+  : public ScriptModeBase
+{
+public:
+  ScriptCreationMode( KigPart& doc );
+  virtual ~ScriptCreationMode();
+
+  virtual bool queryFinish();
+  virtual bool queryCancel();
+};
+
+/**
+ * Script mode to edit an already-built script.
+ */
+class ScriptEditMode
+  : public ScriptModeBase
+{
+private:
+  ObjectTypeCalcer* mexecuted;
+  std::vector<ObjectCalcer*> mexecargs;
+  std::vector<ObjectCalcer*> mcompiledargs;
+
+  QString morigscript;
+
+public:
+  ScriptEditMode( ObjectTypeCalcer* exec_calc, KigPart& doc );
+  virtual ~ScriptEditMode();
+
+  virtual bool queryFinish();
+  virtual bool queryCancel();
+};
+
 #endif
Index: modes/popup.cc
===================================================================
--- modes/popup.cc	(revisione 550052)
+++ modes/popup.cc	(copia locale)
@@ -166,6 +166,7 @@
 #ifdef KIG_ENABLE_PYTHON_SCRIPTING
 #include "../scripting/script-common.h"
 #include "../scripting/script_mode.h"
+#include "../scripting/python_type.h"
 
 class ScriptActionsProvider
   : public PopupActionProvider
@@ -1033,6 +1034,20 @@
 }
 
 #ifdef KIG_ENABLE_PYTHON_SCRIPTING
+/**
+ * this is a local function that looks for a python script associated
+ * to a clicked object
+ */
+static ObjectTypeCalcer* getPythonExecuteTypeFromCalcer( ObjectCalcer* o )
+{
+  ObjectTypeCalcer* oc = dynamic_cast<ObjectTypeCalcer *>( o );
+  if ( !oc ) return 0;
+  const PythonExecuteType* pythonexec = dynamic_cast<const PythonExecuteType*>( \
oc->type() ); +  if ( pythonexec ) return oc;
+
+  return 0;
+}
+
 void ScriptActionsProvider::fillUpMenu( NormalModePopupObjects& popup, int menu, \
int& nextfree )  {
   if ( menu == NormalModePopupObjects::StartMenu )
@@ -1042,6 +1057,15 @@
     popup.addAction( menu, p, i18n( "Python Script" ), nextfree++ );
     mns++;
   }
+  else if ( menu == NormalModePopupObjects::ToplevelMenu )
+  {
+    if ( !popup.objects().empty() &&
+         getPythonExecuteTypeFromCalcer( popup.objects().front()->calcer() ) )
+    {
+      popup.addAction( menu, i18n( "Edit Script..." ), nextfree );
+    }
+    nextfree++;
+  }
 }
 
 bool ScriptActionsProvider::executeAction(
@@ -1052,7 +1076,7 @@
   {
     if ( id == 0 )
     {
-      ScriptMode m( doc );
+      ScriptCreationMode m( doc );
       m.setScriptType( ScriptType::Python );
       if ( os.size() > 0 )
       {
@@ -1068,6 +1092,24 @@
       id -= mns;
     }
   }
+  else if ( menu == NormalModePopupObjects::ToplevelMenu )
+  {
+    if ( id == 0 )
+    {
+      ObjectTypeCalcer* oc = getPythonExecuteTypeFromCalcer( os.front()->calcer() );
+      if ( oc )
+      {
+        ScriptEditMode m( oc, doc );
+        m.setScriptType( ScriptType::Python );
+        doc.runMode( &m );
+      }
+      return true;
+    }
+    else
+    {
+      id -= 1;
+    }
+  }
 
   return false;
 }
Index: misc/guiaction.cc
===================================================================
--- misc/guiaction.cc	(revisione 550052)
+++ misc/guiaction.cc	(copia locale)
@@ -354,7 +354,7 @@
 
 void NewScriptAction::act( KigPart& doc )
 {
-  ScriptMode m( doc );
+  ScriptCreationMode m( doc );
   m.setScriptType( mtype );
   doc.runMode( &m );
 }


[Attachment #6 (application/pgp-signature)]

[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic