~ubuntu-branches/ubuntu/oneiric/kig/oneiric

« back to all changes in this revision

Viewing changes to scripting/script_mode.cc

  • Committer: Bazaar Package Importer
  • Author(s): Harald Sitter
  • Date: 2011-07-10 11:57:38 UTC
  • Revision ID: james.westby@ubuntu.com-20110710115738-gdjnn1kctr49lmy9
Tags: upstream-4.6.90+repack
ImportĀ upstreamĀ versionĀ 4.6.90+repack

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
// Copyright (C)  2003  Dominique Devriese <devriese@kde.org>
 
2
 
 
3
// This program is free software; you can redistribute it and/or
 
4
// modify it under the terms of the GNU General Public License
 
5
// as published by the Free Software Foundation; either version 2
 
6
// of the License, or (at your option) any later version.
 
7
 
 
8
// This program is distributed in the hope that it will be useful,
 
9
// but WITHOUT ANY WARRANTY; without even the implied warranty of
 
10
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
11
// GNU General Public License for more details.
 
12
 
 
13
// You should have received a copy of the GNU General Public License
 
14
// along with this program; if not, write to the Free Software
 
15
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
 
16
// 02110-1301, USA.
 
17
 
 
18
#include "script_mode.h"
 
19
 
 
20
#include "newscriptwizard.h"
 
21
#include "python_type.h"
 
22
#include "python_scripter.h"
 
23
 
 
24
#include "../kig/kig_commands.h"
 
25
#include "../kig/kig_part.h"
 
26
#include "../kig/kig_view.h"
 
27
#include "../misc/calcpaths.h"
 
28
#include "../misc/kigpainter.h"
 
29
#include "../modes/dragrectmode.h"
 
30
#include "../objects/bogus_imp.h"
 
31
#include "../objects/object_imp.h"
 
32
#include "../objects/object_factory.h"
 
33
 
 
34
#include <qbytearray.h>
 
35
#include <qlabel.h>
 
36
#include <qpushbutton.h>
 
37
 
 
38
#include <kcursor.h>
 
39
#include <kdialog.h>
 
40
#include <kicon.h>
 
41
#include <kmessagebox.h>
 
42
 
 
43
void ScriptModeBase::dragRect( const QPoint& p, KigWidget& w )
 
44
{
 
45
  if ( mwawd != SelectingArgs ) return;
 
46
 
 
47
  DragRectMode dm( p, mdoc, w );
 
48
  mdoc.runMode( &dm );
 
49
  std::vector<ObjectHolder*> ret = dm.ret();
 
50
 
 
51
  KigPainter pter( w.screenInfo(), &w.stillPix, mdoc.document() );
 
52
  if ( dm.needClear() )
 
53
  {
 
54
    std::vector<ObjectHolder*> tmp( margs.begin(), margs.begin() );
 
55
    pter.drawObjects( tmp, false );
 
56
    margs.clear();
 
57
  }
 
58
 
 
59
  std::copy( ret.begin(), ret.end(), std::inserter( margs, margs.begin() ) );
 
60
  pter.drawObjects( ret, true );
 
61
 
 
62
  w.updateCurPix( pter.overlay() );
 
63
  w.updateWidget();
 
64
}
 
65
 
 
66
void ScriptModeBase::leftClickedObject( ObjectHolder* o, const QPoint&,
 
67
                                        KigWidget& w, bool )
 
68
{
 
69
  std::list<ObjectHolder*>::iterator dup_o;
 
70
 
 
71
  if ( mwawd != SelectingArgs ) return;
 
72
 
 
73
  KigPainter pter( w.screenInfo(), &w.stillPix, mdoc.document() );
 
74
 
 
75
  if ( (dup_o = std::find( margs.begin(), margs.end(), o )) != margs.end() )
 
76
  {
 
77
    margs.erase( dup_o );
 
78
    pter.drawObject( o, false );
 
79
  }
 
80
  else
 
81
  {
 
82
    margs.push_back( o );
 
83
    pter.drawObject( o, true );
 
84
  };
 
85
  w.updateCurPix( pter.overlay() );
 
86
  w.updateWidget();
 
87
}
 
88
 
 
89
void ScriptModeBase::mouseMoved( const std::vector<ObjectHolder*>& os,
 
90
                                 const QPoint& pt, KigWidget& w, bool )
 
91
{
 
92
  if ( mwawd != SelectingArgs ) return;
 
93
 
 
94
  w.updateCurPix();
 
95
  if ( os.empty() )
 
96
  {
 
97
    w.setCursor( Qt::ArrowCursor );
 
98
    mdoc.emitStatusBarText( 0 );
 
99
    w.updateWidget();
 
100
  }
 
101
  else
 
102
  {
 
103
    // the cursor is over an object, show object type next to cursor
 
104
    // and set statusbar text
 
105
 
 
106
    w.setCursor( Qt::PointingHandCursor );
 
107
    QString selectstat = os.front()->selectStatement();
 
108
 
 
109
    // statusbar text
 
110
    mdoc.emitStatusBarText( selectstat );
 
111
    KigPainter p( w.screenInfo(), &w.curPix, mdoc.document() );
 
112
 
 
113
    // set the text next to the arrow cursor
 
114
    QPoint point = pt;
 
115
    point.setX(point.x()+15);
 
116
 
 
117
    p.drawTextStd( point, selectstat );
 
118
    w.updateWidget( p.overlay() );
 
119
  }
 
120
}
 
121
 
 
122
ScriptModeBase::ScriptModeBase( KigPart& doc )
 
123
  : BaseMode( doc ), mwizard( 0 ), mpart( doc ),
 
124
    mwawd( SelectingArgs )
 
125
{
 
126
  mwizard = new NewScriptWizard( doc.widget(), this, doc.iconLoader() );
 
127
 
 
128
  doc.redrawScreen();
 
129
}
 
130
 
 
131
ScriptModeBase::~ScriptModeBase()
 
132
{
 
133
}
 
134
 
 
135
void ScriptModeBase::killMode()
 
136
{
 
137
  mdoc.doneMode( this );
 
138
}
 
139
 
 
140
bool ScriptCreationMode::queryCancel()
 
141
{
 
142
  killMode();
 
143
  return true;
 
144
}
 
145
 
 
146
void ScriptModeBase::argsPageEntered()
 
147
{
 
148
  mwawd = SelectingArgs;
 
149
  mdoc.redrawScreen();
 
150
}
 
151
 
 
152
void ScriptModeBase::enableActions()
 
153
{
 
154
  KigMode::enableActions();
 
155
  // we don't enable any actions..
 
156
}
 
157
 
 
158
void ScriptModeBase::codePageEntered()
 
159
{
 
160
  if ( mwizard->text().isEmpty() )
 
161
  {
 
162
    // insert template code..
 
163
    QString tempcode = ScriptType::templateCode( mtype, margs );
 
164
    mwizard->setText( tempcode );
 
165
  };
 
166
  mwawd = EnteringCode;
 
167
  mdoc.redrawScreen();
 
168
}
 
169
 
 
170
void ScriptModeBase::redrawScreen( KigWidget* w )
 
171
{
 
172
  std::vector<ObjectHolder*> sel;
 
173
  if ( mwawd == SelectingArgs )
 
174
    sel = std::vector<ObjectHolder*>( margs.begin(), margs.end() );
 
175
  w->redrawScreen( sel );
 
176
  w->updateScrollBars();
 
177
}
 
178
 
 
179
bool ScriptCreationMode::queryFinish()
 
180
{
 
181
  std::vector<ObjectCalcer*> args;
 
182
 
 
183
  QString script = mwizard->text();
 
184
  args.push_back( new ObjectConstCalcer( new StringImp( script ) ) );
 
185
 
 
186
  ObjectTypeCalcer* compiledscript =
 
187
    new ObjectTypeCalcer( PythonCompileType::instance(), args );
 
188
  compiledscript->calc( mdoc.document() );
 
189
 
 
190
  args.clear();
 
191
  args.push_back( compiledscript );
 
192
  for ( std::list<ObjectHolder*>::iterator i = margs.begin();
 
193
        i != margs.end(); ++i )
 
194
    args.push_back( ( *i )->calcer() );
 
195
 
 
196
  ObjectTypeCalcer::shared_ptr reto =
 
197
    new ObjectTypeCalcer( PythonExecuteType::instance(), args );
 
198
  reto->calc( mdoc.document() );
 
199
 
 
200
  if ( reto->imp()->inherits( InvalidImp::stype() ) )
 
201
  {
 
202
    PythonScripter* inst = PythonScripter::instance();
 
203
    QByteArray errtrace = inst->lastErrorExceptionTraceback().c_str();
 
204
    if ( inst->errorOccurred() )
 
205
    {
 
206
      KMessageBox::detailedSorry(
 
207
        mwizard, i18n( "The Python interpreter caught an error during the execution of your "
 
208
                       "script. Please fix the script and click the Finish button again." ),
 
209
        i18n( "The Python Interpreter generated the following error output:\n%1", QString( errtrace ) ) );
 
210
    }
 
211
    else
 
212
    {
 
213
      KMessageBox::sorry(
 
214
        mwizard, i18n( "There seems to be an error in your script. The Python interpreter "
 
215
                       "reported no errors, but the script does not generate "
 
216
                       "a valid object. Please fix the script, and click the Finish button "
 
217
                       "again." ) );
 
218
    }
 
219
    return false;
 
220
  }
 
221
  else
 
222
  {
 
223
    if ( reto->imp()->inherits( DoubleImp::stype() ) || 
 
224
         reto->imp()->inherits( IntImp::stype() ) )
 
225
    {
 
226
      /*
 
227
       * if the python script returns a DoubleImp (IntImp) we need a way to let the user
 
228
       * interact with the result.  We do this by adding a text label (located at
 
229
       * the origin) that contains the DoubleImp (IntImp) value.
 
230
       */
 
231
      QString s = QString("%1");
 
232
      Coordinate coord = Coordinate( 0., 0. );
 
233
      bool needframe = false;
 
234
      std::vector<ObjectCalcer*> args;
 
235
      args.push_back( reto.get() );
 
236
      ObjectHolder* label = 0;
 
237
      label = ObjectFactory::instance()->label( s, coord, needframe, args, mdoc.document() );
 
238
      mdoc.addObject( label );
 
239
    } else if ( reto->imp()->inherits( StringImp::stype() ) )
 
240
    {
 
241
      /*
 
242
       * if the python script returns a StringImp we need a way to let the user
 
243
       * interact with the result, see above.
 
244
       */
 
245
      QString s = QString("%1");
 
246
      Coordinate coord = Coordinate( 0., 0. );
 
247
      bool needframe = false;
 
248
      std::vector<ObjectCalcer*> args;
 
249
      args.push_back( reto.get() );
 
250
      ObjectHolder* label = 0;
 
251
      label = ObjectFactory::instance()->label( s, coord, needframe, args, mdoc.document() );
 
252
      mdoc.addObject( label );
 
253
    } else mdoc.addObject( new ObjectHolder( reto.get() ) );
 
254
    killMode();
 
255
    return true;
 
256
  }
 
257
}
 
258
 
 
259
void ScriptModeBase::midClicked( const QPoint&, KigWidget& )
 
260
{
 
261
}
 
262
 
 
263
void ScriptModeBase::rightClicked( const std::vector<ObjectHolder*>&,
 
264
                                   const QPoint&, KigWidget& )
 
265
{
 
266
}
 
267
 
 
268
void ScriptModeBase::setScriptType( ScriptType::Type type )
 
269
{
 
270
  mtype = type;
 
271
  mwizard->setType( mtype );
 
272
}
 
273
 
 
274
void ScriptModeBase::addArgs( const std::vector<ObjectHolder*>& obj, KigWidget& w )
 
275
{
 
276
  KigPainter pter( w.screenInfo(), &w.stillPix, mdoc.document() );
 
277
 
 
278
  std::copy( obj.begin(), obj.end(), std::inserter( margs, margs.begin() ) );
 
279
  pter.drawObjects( obj, true );
 
280
 
 
281
  w.updateCurPix( pter.overlay() );
 
282
  w.updateWidget();
 
283
}
 
284
 
 
285
void ScriptModeBase::goToCodePage()
 
286
{
 
287
  mwizard->next();
 
288
}
 
289
 
 
290
ScriptCreationMode::ScriptCreationMode( KigPart& doc )
 
291
  : ScriptModeBase( doc )
 
292
{
 
293
  mwizard->show();
 
294
}
 
295
 
 
296
ScriptCreationMode::~ScriptCreationMode()
 
297
{
 
298
}
 
299
 
 
300
ScriptEditMode::ScriptEditMode( ObjectTypeCalcer* exec_calc, KigPart& doc )
 
301
  : ScriptModeBase( doc ), mexecuted( exec_calc )
 
302
{
 
303
  mwawd = EnteringCode;
 
304
 
 
305
  mexecargs = mexecuted->parents();
 
306
  assert( mexecargs.size() >= 1 );
 
307
 
 
308
  mcompiledargs = mexecargs[0]->parents();
 
309
  assert( mcompiledargs.size() == 1 );
 
310
 
 
311
  const ObjectImp* imp = static_cast<ObjectConstCalcer*>( mcompiledargs[0] )->imp();
 
312
  assert( dynamic_cast<const StringImp*>( imp ) );
 
313
  // save the original script text, in case the user modifies the text
 
314
  // in the editor and aborts the editing
 
315
  morigscript = static_cast<const StringImp*>( imp )->data();
 
316
 
 
317
  mwizard->setWindowTitle( KDialog::makeStandardCaption( i18nc( "'Edit' is a verb", "Edit Script" ) ) );
 
318
  mwizard->setText( morigscript );
 
319
  mwizard->show();
 
320
  mwizard->next();
 
321
  mwizard->button( QWizard::BackButton )->setEnabled( false );
 
322
}
 
323
 
 
324
ScriptEditMode::~ScriptEditMode()
 
325
{
 
326
}
 
327
 
 
328
bool ScriptEditMode::queryFinish()
 
329
{
 
330
  MonitorDataObjects mon( mcompiledargs );
 
331
 
 
332
  static_cast<ObjectConstCalcer*>( mcompiledargs[0] )->switchImp( new StringImp( mwizard->text() ) );
 
333
  mexecargs[0]->calc( mpart.document() );
 
334
 
 
335
  mexecuted->calc( mpart.document() );
 
336
 
 
337
  mpart.redrawScreen();
 
338
 
 
339
  KigCommand* comm = new KigCommand( mpart, i18n( "Edit Python Script" ) );
 
340
  mon.finish( comm );
 
341
 
 
342
  if ( mexecuted->imp()->inherits( InvalidImp::stype() ) )
 
343
  {
 
344
    PythonScripter* inst = PythonScripter::instance();
 
345
    QByteArray errtrace = inst->lastErrorExceptionTraceback().c_str();
 
346
    if ( inst->errorOccurred() )
 
347
    {
 
348
      KMessageBox::detailedSorry(
 
349
        mwizard, i18n( "The Python interpreter caught an error during the execution of your "
 
350
                              "script. Please fix the script." ),
 
351
        i18n( "The Python Interpreter generated the following error output:\n%1", QString( errtrace ) ) );
 
352
    }
 
353
    else
 
354
    {
 
355
      KMessageBox::sorry(
 
356
        mwizard, i18n( "There seems to be an error in your script. The Python interpreter "
 
357
                              "reported no errors, but the script does not generate "
 
358
                              "a valid object. Please fix the script." ) );
 
359
    }
 
360
    delete comm;
 
361
    return false;
 
362
  }
 
363
 
 
364
  mpart.history()->push( comm );
 
365
  mpart.setModified( true );
 
366
 
 
367
  killMode();
 
368
  return true;
 
369
}
 
370
 
 
371
bool ScriptEditMode::queryCancel()
 
372
{
 
373
  // reverting the original script text
 
374
  static_cast<ObjectConstCalcer*>( mcompiledargs[0] )->switchImp( new StringImp( morigscript ) );
 
375
  mexecargs[0]->calc( mpart.document() );
 
376
 
 
377
  mexecuted->calc( mpart.document() );
 
378
  // paranoic check
 
379
  assert( !mexecuted->imp()->inherits( InvalidImp::stype() ) );
 
380
 
 
381
  mpart.redrawScreen();
 
382
 
 
383
  // no need to further checks here, as the original script text is ok
 
384
 
 
385
  killMode();
 
386
  return true;
 
387
}
 
388