00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "a2dprec.h"
00016
00017 #ifdef __BORLANDC__
00018 #pragma hdrstop
00019 #endif
00020
00021 #ifndef WX_PRECOMP
00022 #include "wx/wx.h"
00023 #endif
00024
00025 #include "wx/canvas/canmod.h"
00026
00027
00028 #include <float.h>
00029 #include "wx/editor/sttool.h"
00030 #include "wx/editor/sttool2.h"
00031 #include "wx/editor/mastertool.h"
00032 #include <wx/general/id.inl>
00033
00034 IMPLEMENT_CLASS(a2dGraphicsMasterTool,a2dStTool)
00035
00036 A2D_BEGIN_EVENT_TABLE( a2dGraphicsMasterTool,a2dStTool )
00037 A2D_EVT_MOUSE_EVENTS( a2dGraphicsMasterTool::OnMouseEvent )
00038 A2D_EVT_CHAR( a2dGraphicsMasterTool::OnChar )
00039 A2D_EVT_KEY_DOWN( a2dGraphicsMasterTool::OnKeyDown )
00040 A2D_END_EVENT_TABLE()
00041
00042 a2dGraphicsMasterTool::a2dGraphicsMasterTool(a2dStToolContr* controller):a2dStTool(controller)
00043 {
00044 m_toolcursor = a2dCanvasGlobals->GetCursor( a2dCURSOR_ARROW );
00045 m_mode = mode_none;
00046 m_canvasobject=0;
00047 m_modehit = 0;
00048
00049 controller->SetDefaultBehavior( controller->GetDefaultBehavior() | wxTC_NoDefaultKeys | wxTC_NoDefaultMouseActions );
00050 }
00051
00052 a2dGraphicsMasterTool::~a2dGraphicsMasterTool()
00053 {
00054 }
00055
00056 void a2dGraphicsMasterTool::PushDrawWireTool( a2dCanvasObject *WXUNUSED(hit) )
00057 {
00058 a2dDrawWirePolylineLTool *tool = new a2dDrawWirePolylineLTool( GetStToolContr() );
00059 tool->SetOneShot();
00060 m_controller->PushTool( tool );
00061 }
00062
00063 void a2dGraphicsMasterTool::PushDragTool( a2dCanvasObject *hit )
00064 {
00065 SelectHitObject( hit );
00066 a2dDragTool *tool = new a2dDragTool( GetStToolContr() );
00067 tool->SetOneShot();
00068 tool->SetCursorType( a2dCanvasGlobals->GetCursor( a2dCURSOR_Drag ) );
00069 tool->SetBusyCursorType( a2dCanvasGlobals->GetCursor( a2dCURSOR_Drag ) );
00070 tool->SetDeleteOnOutsideDrop( true );
00071 m_controller->PushTool( tool );
00072 }
00073
00074 void a2dGraphicsMasterTool::PushDragMultiTool( a2dCanvasObject *WXUNUSED(hit) )
00075 {
00076 a2dDragMultiTool *tool = new a2dDragMultiTool( GetStToolContr() );
00077 tool->SetOneShot();
00078 tool->SetCursorType( a2dCanvasGlobals->GetCursor( a2dCURSOR_Drag ) );
00079 tool->SetBusyCursorType( a2dCanvasGlobals->GetCursor( a2dCURSOR_Drag ) );
00080 m_controller->PushTool( tool );
00081 }
00082
00083 void a2dGraphicsMasterTool::PushCopyTool( a2dCanvasObject *hit )
00084 {
00085 SelectHitObject( hit );
00086 a2dCopyTool *tool = new a2dCopyTool( GetStToolContr() );
00087 tool->SetOneShot();
00088 tool->SetCursorType( a2dCanvasGlobals->GetCursor( a2dCURSOR_Drag ) );
00089 tool->SetBusyCursorType( a2dCanvasGlobals->GetCursor( a2dCURSOR_Drag ) );
00090 tool->SetDeleteOnOutsideDrop( true );
00091 m_controller->PushTool( tool );
00092 }
00093
00094 void a2dGraphicsMasterTool::PushCopyMultiTool( a2dCanvasObject *WXUNUSED(hit) )
00095 {
00096 a2dCopyMultiTool *tool = new a2dCopyMultiTool( GetStToolContr() );
00097 tool->SetOneShot();
00098 tool->SetCursorType( a2dCanvasGlobals->GetCursor( a2dCURSOR_Copy ) );
00099 tool->SetBusyCursorType( a2dCanvasGlobals->GetCursor( a2dCURSOR_Copy ) );
00100 m_controller->PushTool( tool );
00101 }
00102
00103 void a2dGraphicsMasterTool::PushSelectTool()
00104 {
00105 a2dSelectTool *tool = new a2dSelectTool( GetStToolContr() );
00106 tool->SetShiftIsAdd();
00107 tool->SetOneShot();
00108
00109 m_controller->PushTool( tool );
00110 }
00111
00112 void a2dGraphicsMasterTool::PushEditWireVertexTool( a2dCanvasObject *hit, int vertex )
00113 {
00114 a2dPolygonL *poly = wxStaticCast( hit, a2dPolygonL );
00115 SelectHitObject( hit );
00116 a2dSimpleEditPolygonTool *tool = new a2dSimpleEditPolygonTool( GetStToolContr(), hit, vertex, poly->GetSegments()->size(), a2dSimpleEditPolygonTool::action_movevertex );
00117 tool->SetOneShot();
00118 tool->SetCursorType( a2dCanvasGlobals->GetCursor( a2dCURSOR_EditWireVertex ) );
00119 tool->SetBusyCursorType( a2dCanvasGlobals->GetCursor( a2dCURSOR_EditWireVertex ) );
00120 m_controller->PushTool( tool );
00121 }
00122
00123 void a2dGraphicsMasterTool::PushEditWireSegmentHorizontalTool( a2dCanvasObject *hit, int segment )
00124 {
00125 a2dPolygonL *poly = wxStaticCast( hit, a2dPolygonL );
00126 SelectHitObject( hit );
00127 a2dSimpleEditPolygonTool *tool = new a2dSimpleEditPolygonTool( GetStToolContr(), hit, segment, poly->GetSegments()->size(), a2dSimpleEditPolygonTool::action_movesegment );
00128 tool->SetOneShot();
00129 tool->SetCursorType( a2dCanvasGlobals->GetCursor( a2dCURSOR_EditWireSegmentHorizontal ) );
00130 tool->SetBusyCursorType( a2dCanvasGlobals->GetCursor( a2dCURSOR_EditWireSegmentHorizontal ) );
00131 m_controller->PushTool( tool );
00132 }
00133
00134 void a2dGraphicsMasterTool::PushEditWireSegmentVerticalTool( a2dCanvasObject *hit, int segment )
00135 {
00136 a2dPolygonL *poly = wxStaticCast( hit, a2dPolygonL );
00137 SelectHitObject( hit );
00138 a2dSimpleEditPolygonTool *tool = new a2dSimpleEditPolygonTool( GetStToolContr(), hit, segment, poly->GetSegments()->size(), a2dSimpleEditPolygonTool::action_movesegment );
00139 tool->SetOneShot();
00140 tool->SetCursorType( a2dCanvasGlobals->GetCursor( a2dCURSOR_EditWireSegmentVertical ) );
00141 tool->SetBusyCursorType( a2dCanvasGlobals->GetCursor( a2dCURSOR_EditWireSegmentVertical ) );
00142 m_controller->PushTool( tool );
00143 }
00144
00145 void a2dGraphicsMasterTool::PushEditWireSegmentInsertTool( a2dCanvasObject *hit, int segment )
00146 {
00147 a2dPolygonL *poly = wxStaticCast( hit, a2dPolygonL );
00148 SelectHitObject( hit );
00149 a2dSimpleEditPolygonTool *tool = new a2dSimpleEditPolygonTool( GetStToolContr(), hit, segment, poly->GetSegments()->size(), a2dSimpleEditPolygonTool::action_insertvertex );
00150 tool->SetOneShot();
00151 tool->SetCursorType( a2dCanvasGlobals->GetCursor( a2dCURSOR_WireSegmentInsert ) );
00152 tool->SetBusyCursorType( a2dCanvasGlobals->GetCursor( a2dCURSOR_WireSegmentInsert ) );
00153 m_controller->PushTool( tool );
00154 }
00155
00156 void a2dGraphicsMasterTool::DeselectAll()
00157 {
00158 GetCanvasCommandProcessor()->Submit( new a2dCommand_Select( a2dCommand_Select::Args().what(a2dCommand_Select::DeSelectAll) ) );
00159 }
00160
00161 bool a2dGraphicsMasterTool::ZoomSave()
00162 {
00163 return true;
00164 }
00165
00166 void a2dGraphicsMasterTool::DoStopTool( bool abort )
00167 {
00168 a2dStTool::DoStopTool( abort );
00169 }
00170
00171 void a2dGraphicsMasterTool::OnChar(wxKeyEvent& event)
00172 {
00173 switch( event.GetKeyCode() )
00174 {
00175 case WXK_DELETE:
00176 {
00177 wxASSERT( m_parentobject == GetCanvasView()->GetShowObject() );
00178
00179 OpenCommandGroupNamed( _("Delete selected objects") );
00180 a2dCanvasObjectList list;
00181 m_parentobject->CollectObjects(
00182 &list,
00183 wxT(""), a2dCanvasOFlags::SELECTED, NULL );
00184
00185 for( a2dCanvasObjectList::iterator iter = list.begin(); iter != list.end(); ++iter )
00186 {
00187 a2dCanvasObject *obj = (*iter);
00188
00189 obj->ClearAllPinConnections( GetCanvasCommandProcessor() );
00190
00191 GetCanvasCommandProcessor()->Submit( new a2dCommand_ReleaseObject( m_parentobject, obj ));
00192 }
00193 CloseCommandGroup( );
00194 break;
00195 }
00196 default:
00197 event.Skip();
00198 }
00199 }
00200
00201
00202 void a2dGraphicsMasterTool::OnKeyDown(wxKeyEvent& event)
00203 {
00204
00205 a2dBaseTool* first = m_stcontroller->GetFirstTool();
00206
00207 switch(event.GetKeyCode())
00208 {
00209 case WXK_ESCAPE:
00210 {
00211 if ( first && first->AllowPop() )
00212 first->StopTool( false );
00213 return;
00214 }
00215 break;
00216 default:
00217 event.Skip();
00218 }
00219
00220 if ( !m_active )
00221 {
00222 event.Skip();
00223 return;
00224 }
00225
00226 switch(event.GetKeyCode())
00227 {
00228
00229 case WXK_CONTROL:
00230 {
00231 if ( !first || ( first && !first->GetBusy()) )
00232 {
00233 if ( !wxDynamicCast(first, a2dDragTool) )
00234 {
00235 a2dDragTool* drag = new a2dDragTool(m_stcontroller);
00236 m_stcontroller->PushTool(drag);
00237 drag->SetOneShot();
00238 }
00239 }
00240 }
00241 break;
00242 case 'Z':
00243 case 'z':
00244 {
00245 if ( event.m_controlDown && event.m_shiftDown )
00246 GetCanvasCommandProcessor()->Redo();
00247 else if ( event.m_controlDown )
00248 GetCanvasCommandProcessor()->Undo();
00249 else if ( !first || ( first && !first->GetBusy()) )
00250 {
00251 a2dZoomTool* zoom = new a2dZoomTool(m_stcontroller);
00252 m_stcontroller->PushTool(zoom);
00253 }
00254 break;
00255 }
00256 case 'Y':
00257 case 'y':
00258 {
00259 if ( event.m_controlDown )
00260 GetCanvasCommandProcessor()->Redo();
00261 break;
00262 }
00263 case WXK_NUMPAD_ADD:
00264 {
00265 if ( event.m_controlDown )
00266 m_stcontroller->ZoomIn2AtMouse();
00267 else
00268 m_stcontroller->Zoomin2();
00269 break;
00270 }
00271 case WXK_NUMPAD_SUBTRACT:
00272 {
00273 if ( event.m_controlDown )
00274 m_stcontroller->ZoomOut2AtMouse();
00275 else
00276 m_stcontroller->Zoomout2();
00277 break;
00278 }
00279 default:
00280 event.Skip();
00281 }
00282 }
00283
00284 void a2dGraphicsMasterTool::OnMouseEvent(wxMouseEvent& event)
00285 {
00286 if (!m_active)
00287 {
00288 event.Skip();
00289 return;
00290 }
00291 m_x = event.GetX();
00292 m_y = event.GetY();
00293
00294
00295 double xw;
00296 double yw;
00297
00298 xw = GetDrawer2D()->DeviceToWorldX(m_x);
00299 yw = GetDrawer2D()->DeviceToWorldY(m_y);
00300
00301 if ( event.Moving() && !GetBusy() && !event.ShiftDown() && !event.ControlDown() )
00302 {
00303
00304 a2dPin::sm_feedbackOnPinmapConnect.SetMode( 2 );
00305 a2dPin::sm_feedbackOnPinmapConnect.SetTask( a2d_ToConnectPinClassWire_ObjectPinClass_InOut );
00306 a2dPin::sm_feedbackOnPinmapConnect.SetPinClass( a2dPinClass::Any );
00307 a2dIterC ic( GetCanvasView() );
00308 GetCanvasView()->GetShowObject()->EditFeedback( ic, &a2dPin::sm_feedbackOnPinmapConnect, NULL, 2, 0, xw, yw );
00309 }
00310
00311 a2dHitEvent hitinfo( xw, yw, false, a2dCANOBJHITOPTION_NONE, true );
00312 a2dCanvasObject* hit = GetCanvasView()->IsHitWorld( hitinfo, wxLAYER_ALL );
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357 if ( event.Moving() && !GetBusy() )
00358 {
00359 m_mode = mode_none;
00360 m_modehit = 0;
00361 m_modehitinfo = a2dHit();
00362
00363 if( hit )
00364 {
00365 a2dHit how2;
00366
00367
00368
00369
00370 a2dPin* pin = NULL;
00371 if ( !event.ShiftDown() && !event.ControlDown() )
00372 pin = FindUnConnectedPin( GetCanvasView()->GetShowObject(), xw, yw );
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416 a2dWirePolylineL *wire = 0;
00417 if( !pin )
00418 {
00419 int i;
00420 float minDist = FLT_MAX;
00421 for( i=0; i< hitinfo.m_extended.size(); i++ )
00422 {
00423 a2dWirePolylineL *wire2 = wxDynamicCast( hitinfo.m_extended[i].GetObject(), a2dWirePolylineL );
00424 if( wire2 && hitinfo.m_extended[i].GetHitType().m_distance < minDist && hitinfo.m_extended[i].GetHitType().IsDirectStrokeHit() )
00425 {
00426 wire = wire2;
00427 how2 = hitinfo.m_extended[i].GetHitType();
00428 minDist = how2.m_distance;
00429 }
00430 }
00431 }
00432
00433 if( pin )
00434 {
00435
00436 GetCanvasView()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_DrawWire ) );
00437 m_mode = mode_drawwire;
00438 m_modehit = pin;
00439 }
00440 else if ( wire )
00441 {
00442
00443
00444 m_modehit = wire;
00445 m_modehitinfo = how2;
00446 switch( how2.m_stroke2 )
00447 {
00448 case a2dHit::stroke2_vertex:
00449 GetCanvasView()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_EditWireVertex ) );
00450 m_mode = mode_editwire_vertex;
00451 break;
00452 case a2dHit::stroke2_edgehor:
00453 GetCanvasView()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_EditWireSegmentHorizontal ) );
00454 m_mode = mode_editwire_segmenthorizontal;
00455 break;
00456 case a2dHit::stroke2_edgevert:
00457 GetCanvasView()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_EditWireSegmentVertical ) );
00458 m_mode = mode_editwire_segmentvertical;
00459 break;
00460 case a2dHit::stroke2_edgeother:
00461 GetCanvasView()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_WireSegmentInsert ) );
00462 m_mode = mode_editwire_segmentinsert;
00463 break;
00464 default:
00465 assert(0);
00466 m_modehit = 0;
00467 m_modehitinfo = a2dHit();
00468 }
00469 }
00470 else if ( !event.ShiftDown() && hit->GetDraggable() &&
00471 ( hitinfo.m_how.IsInsideHit() ||
00472 wxDynamicCast( hit, a2dPolylineL )
00473 )
00474 )
00475 {
00476 if( !event.ControlDown() )
00477 {
00478 if( hit->GetSelected() )
00479 {
00480
00481 GetCanvasView()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_Drag ) );
00482 m_mode = mode_dragmulti;
00483 m_modehit = hit;
00484 }
00485 else
00486 {
00487
00488 GetCanvasView()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_Drag ) );
00489 m_mode = mode_drag;
00490 m_modehit = hit;
00491 }
00492 }
00493 else
00494 {
00495 if( hit->GetSelected() )
00496 {
00497
00498 GetCanvasView()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_Copy ) );
00499 m_mode = mode_copymulti;
00500 m_modehit = hit;
00501 }
00502 else
00503 {
00504
00505 GetCanvasView()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_Copy ) );
00506 m_mode = mode_copy;
00507 m_modehit = hit;
00508 }
00509 }
00510 }
00511 else if ( event.ShiftDown() && hitinfo.m_how.IsInsideHit() )
00512 {
00513 GetCanvasView()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_ARROW ) );
00514 m_mode = mode_select;
00515 m_modehit = hit;
00516 }
00517 else
00518 {
00519 GetCanvasView()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_ARROW ) );
00520 m_mode = mode_select;
00521 m_modehit = hit;
00522 }
00523 }
00524 else
00525 {
00526 GetCanvasView()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_ARROW ) );
00527 m_mode = mode_select;
00528 m_modehit = hit;
00529 }
00530 event.Skip();
00531 }
00532 else if( event.LeftDown() && !GetBusy() )
00533 {
00534 switch( m_mode )
00535 {
00536 case mode_none:
00537 event.Skip();
00538 break;
00539 case mode_select:
00540 PushSelectTool();
00541 event.Skip();
00542 break;
00543 case mode_drag:
00544 PushDragTool(m_modehit);
00545 event.Skip();
00546 break;
00547 case mode_dragmulti:
00548 PushDragMultiTool(m_modehit);
00549 event.Skip();
00550 break;
00551 case mode_copy:
00552 PushCopyTool(m_modehit);
00553 event.Skip();
00554 break;
00555 case mode_copymulti:
00556 PushCopyMultiTool(m_modehit);
00557 event.Skip();
00558 break;
00559 case mode_drawwire:
00560 PushDrawWireTool(m_modehit);
00561 event.Skip();
00562 break;
00563 case mode_editwire_vertex:
00564 PushEditWireVertexTool( m_modehit, m_modehitinfo.m_index );
00565 event.Skip();
00566 break;
00567 case mode_editwire_segmenthorizontal:
00568 PushEditWireSegmentHorizontalTool( m_modehit, m_modehitinfo.m_index );
00569 event.Skip();
00570 break;
00571 case mode_editwire_segmentvertical:
00572 PushEditWireSegmentVerticalTool( m_modehit, m_modehitinfo.m_index );
00573 event.Skip();
00574 break;
00575 case mode_editwire_segmentinsert:
00576 PushEditWireSegmentInsertTool( m_modehit, m_modehitinfo.m_index );
00577 event.Skip();
00578 break;
00579 default:
00580 event.Skip();
00581 }
00582 }
00583 else
00584 {
00585 event.Skip();
00586 }
00587 }
00588
00589 void a2dGraphicsMasterTool::SelectHitObject( a2dCanvasObject *hit )
00590 {
00591 OpenCommandGroupNamed( _("Select") );
00592
00593 DeselectAll();
00594
00595 GetCanvasCommandProcessor()->Submit(
00596 new a2dCommand_SetFlag( hit, a2dCanvasOFlags::SELECTED, true ));
00597
00598 CloseCommandGroup();
00599 }
00600
00601 IMPLEMENT_CLASS(a2dSimpleEditPolygonTool,a2dStTool)
00602
00603 A2D_BEGIN_EVENT_TABLE(a2dSimpleEditPolygonTool,a2dStTool)
00604 A2D_EVT_MOUSE_EVENTS(a2dSimpleEditPolygonTool::OnMouseEvent)
00605 A2D_EVT_CHAR(a2dSimpleEditPolygonTool::OnChar)
00606 A2D_END_EVENT_TABLE()
00607
00608 a2dSimpleEditPolygonTool::a2dSimpleEditPolygonTool( a2dStToolContr* controller, a2dCanvasObject *hit, int index, int count, Action action )
00609 :
00610 a2dStTool(controller)
00611 {
00612 a2dDocviewGlobals->GetEventDistributer()->Register( this );
00613
00614 m_toolcursor = a2dCanvasGlobals->GetCursor( a2dCURSOR_ARROW );
00615 m_original = hit;
00616 m_index = index;
00617 m_count = count;
00618 m_action = action;
00619
00620 m_mode = 1;
00621 GetCanvasView()->SetMouseEvents(false);
00622 }
00623
00624 a2dSimpleEditPolygonTool::~a2dSimpleEditPolygonTool()
00625 {
00626 a2dDocviewGlobals->GetEventDistributer()->Unregister( this );
00627
00628 if ( GetCanvasView() )
00629 GetCanvasView()->SetMouseEvents(true);
00630 }
00631
00632 bool a2dSimpleEditPolygonTool::EnterBusyMode()
00633 {
00634 m_preserve_select = m_original->GetSelected();
00635
00636 if( !a2dStTool::EnterBusyMode() )
00637 return false;
00638
00639 m_controller->GetCanvasView()->FindAndSetCorridorPath( m_canvasobject, true );
00640 return true;
00641 }
00642
00643 void a2dSimpleEditPolygonTool::FinishBusyMode()
00644 {
00645 if ( GetCanvasView() )
00646 {
00647 GetCanvasView()->ClearCorridorPath( true );
00648 }
00649
00650 wxASSERT( GetBusy() );
00651
00652
00653 a2dCanvasObject::a2dDoUpdateImmediateData data( true, this, NULL );
00654 if( m_action == action_movevertex )
00655 {
00656 if( m_index == 0 )
00657 data.m_allowreconnectbegin = true;
00658 else if( m_index == m_count-1 )
00659 data.m_allowreconnectend = true;
00660 }
00661 m_connectedwirecopies.UpdateImmediate( true, this, m_canvasobject, NULL, &data );
00662
00663 m_original->SetSelected( m_preserve_select );
00664
00665 a2dStTool::FinishBusyMode();
00666 }
00667
00668 void a2dSimpleEditPolygonTool::AbortBusyMode()
00669 {
00670 if ( GetCanvasView() )
00671 GetCanvasView()->ClearCorridorPath( true );
00672
00673 a2dStTool::FinishBusyMode();
00674 }
00675
00676 void a2dSimpleEditPolygonTool::DoStopTool( bool abort )
00677 {
00678 if ( GetCanvasView() )
00679 GetCanvasView()->ClearCorridorPath( true );
00680
00681 a2dStTool::DoStopTool( abort );
00682 }
00683
00684 void a2dSimpleEditPolygonTool::OnChar(wxKeyEvent& event)
00685 {
00686 event.Skip();
00687 }
00688
00689 void a2dSimpleEditPolygonTool::OnMouseEvent(wxMouseEvent& event)
00690 {
00691 if (!m_active)
00692 {
00693 event.Skip();
00694 return;
00695 }
00696 m_x = event.GetX();
00697 m_y = event.GetY();
00698
00699
00700 double xw;
00701 double yw;
00702
00703 xw = GetDrawer2D()->DeviceToWorldX(m_x);
00704 yw = GetDrawer2D()->DeviceToWorldY(m_y);
00705
00706 if( event.LeftDown() && !GetBusy() )
00707 {
00708 if ( !EnterBusyMode() )
00709 return;
00710
00711
00712
00713
00714
00715 a2dPolygonL* poly = wxDynamicCast( m_canvasobject.Get(), a2dPolygonL );
00716 a2dPolygonL* original = wxDynamicCast( poly->GetOriginal(), a2dPolygonL );
00717 a2dVertexList::iterator iter = poly->GetSegments()->begin();
00718 a2dVertexList::iterator iterorg = original->GetSegments()->begin();
00719 switch( m_action )
00720 {
00721 case action_movevertex:
00722 m_handle = new a2dPolyHandleL( poly, iter, iterorg, poly->GetSegments(), original->GetSegments(), 0.0, 0.0, wxT("__index__") );
00723 break;
00724
00725 case action_movesegment:
00726 m_handle = new a2dPolyHandleL( poly, iter, iterorg, poly->GetSegments(), original->GetSegments(), 0.0, 0.0, wxT("__segment__") );
00727 break;
00728
00729 case action_insertvertex:
00730 m_handle = new a2dPolyHandleL( poly, iter, iterorg, poly->GetSegments(), original->GetSegments(), 0.0, 0.0, wxT("__insert__") );
00731 break;
00732
00733 default:
00734 wxASSERT(0);
00735 }
00736 }
00737
00738
00739
00740
00741
00742
00743
00744
00745
00746
00747
00748
00749
00750
00751
00752
00753
00754 if( event.LeftDown() || event.LeftUp() || event.Dragging() )
00755 {
00756 a2dPolygonL* poly = wxDynamicCast( m_canvasobject.Get(), a2dPolygonL );
00757 poly->SetHandleToIndex( m_handle, m_index );
00758
00759 a2dHandleMouseEvent handleEvent( 0, m_handle.Get(), xw, yw, event );
00760 bool isHit;
00761 GetCanvasView()->ProcessCanvasObjectEvent( handleEvent, isHit, xw, yw, 5 );
00762
00763
00764
00765
00766
00767 m_connectedwirecopies.UpdateImmediate( false, this );
00768 }
00769
00770 if( event.LeftUp() && GetBusy() )
00771 {
00772 FinishBusyMode();
00773 }
00774 }
00775
00776 bool a2dSimpleEditPolygonTool::CreateToolObjects()
00777 {
00778
00779 m_canvasobject = m_original->StartEdit( this, m_mode, wxEDITSTYLE_COPY | wxEDITSTYLE_NOHANDLES | wxEDITSTYLE_CONNECTED );
00780 if ( !m_canvasobject )
00781 return false;
00782
00783
00784 a2dCanvasObjectList connectedwires;
00785 connectedwires.push_back( m_original );
00786 m_original->CreateWireEditCopies( &connectedwires, &m_connectedwirecopies );
00787 m_canvasobject->RestoreConnectionsAfterCloning();
00788 m_connectedwirecopies.RestoreConnectionsAfterCloning();
00789
00790
00791 AdjustRenderOptions();
00792 m_original->SetVisible( m_renderOriginal );
00793 connectedwires.SetSpecificFlags( m_renderOriginal, a2dCanvasOFlags::VISIBLE );
00794
00795
00796
00797 for( a2dCanvasObjectList::iterator iter = m_connectedwirecopies.begin(); iter != m_connectedwirecopies.end(); ++iter )
00798 {
00799 a2dCanvasObject *obj = (*iter);
00800 AddEditobject( obj );
00801 }
00802
00803 m_pending = true;
00804
00805 return true;
00806 }
00807
00808 void a2dSimpleEditPolygonTool::CleanupToolObjects()
00809 {
00810 a2dStTool::CleanupToolObjects();
00811 m_connectedwirecopies.clear();
00812 }
00813
00814
00815
00816
00817
00818 IMPLEMENT_CLASS(a2dMasterDrawBase,a2dStTool)
00819
00820 A2D_BEGIN_EVENT_TABLE( a2dMasterDrawBase,a2dStTool )
00821 A2D_EVT_MOUSE_EVENTS( a2dMasterDrawBase::OnMouseEvent )
00822 A2D_EVT_CHAR( a2dMasterDrawBase::OnChar )
00823 A2D_EVT_KEY_DOWN( a2dMasterDrawBase::OnKeyDown )
00824 A2D_EVT_KEY_UP( a2dMasterDrawBase::OnKeyUp )
00825 A2D_END_EVENT_TABLE()
00826
00827 a2dMasterDrawBase::a2dMasterDrawBase(a2dStToolContr* controller):a2dStTool(controller)
00828 {
00829 m_dragStarted = false;
00830 m_toolBusy = false;
00831
00832 m_fastTools = false;
00833 m_spaceDown = false;
00834 m_allowMultiEdit = true;
00835 m_toolcursor = a2dCanvasGlobals->GetCursor( a2dCURSOR_Select );
00836 m_mode = mode_none;
00837 m_canvasobject=0;
00838 m_modehit = 0;
00839
00840 controller->SetDefaultBehavior( controller->GetDefaultBehavior() | wxTC_NoDefaultKeys | wxTC_NoDefaultMouseActions );
00841
00842 m_eventHandler = new a2dStToolFixedToolStyleEvtHandler( controller );
00843
00844 if ( GetCanvasView()->GetDrawer2D()->HasAlpha() || GetCanvasView()->GetTrippleBufHasAlpha() )
00845 {
00846 SetFill( a2dFill( wxColour( 66, 159, 235, 150 ) ) );
00847 SetStroke( a2dStroke( wxColour( 66, 159, 235, 165 ), 2, a2dSTROKE_LONG_DASH) );
00848 }
00849 else
00850 {
00851 SetFill( *a2dTRANSPARENT_FILL );
00852 SetStroke( a2dStroke(*wxBLACK, 2, a2dSTROKE_LONG_DASH) );
00853 }
00854
00855 if ( GetCanvasView()->GetDrawer2D()->HasAlpha() || GetCanvasView()->GetTrippleBufHasAlpha() )
00856 {
00857 m_selectFill = a2dFill( wxColour( 233, 15, 23, 150 ) );
00858 m_selectStroke = a2dStroke( wxColour( 255, 59, 25, 255 ), 2, a2dSTROKE_LONG_DASH );
00859 }
00860 else
00861 {
00862 m_selectFill = *a2dTRANSPARENT_FILL;
00863 m_selectStroke = a2dStroke(*wxRED, 2, a2dSTROKE_LONG_DASH);
00864 }
00865
00866 }
00867
00868 a2dMasterDrawBase::~a2dMasterDrawBase()
00869 {
00870 }
00871
00872 void a2dMasterDrawBase::PushZoomTool()
00873 {
00874 a2dStTool* tool;
00875 if ( m_fastTools )
00876 tool = new a2dZoomFast( GetStToolContr() );
00877 else
00878 tool = new a2dZoomTool( GetStToolContr() );
00879
00880 tool->SetOneShot();
00881 tool->SetFill( m_fill );
00882 tool->SetStroke( m_stroke );
00883 m_controller->PushTool( tool );
00884 }
00885
00886 void a2dMasterDrawBase::PushDragTool( a2dCanvasObject *hit )
00887 {
00888 SelectHitObject( hit );
00889 a2dDragTool* tool;
00890 if ( m_fastTools )
00891 tool = new a2dDragTool( GetStToolContr() );
00892 else
00893 tool = new a2dDragTool( GetStToolContr() );
00894
00895 tool->SetOneShot();
00896 tool->SetCursorType( a2dCanvasGlobals->GetCursor( a2dCURSOR_Drag ) );
00897 tool->SetBusyCursorType( a2dCanvasGlobals->GetCursor( a2dCURSOR_Drag ) );
00898 tool->SetDeleteOnOutsideDrop( true );
00899 m_controller->PushTool( tool );
00900 }
00901
00902 void a2dMasterDrawBase::PushDragMultiTool( a2dCanvasObject *WXUNUSED(hit) )
00903 {
00904 a2dStTool* tool;
00905 if ( m_fastTools )
00906 tool = new a2dFastDragMultiTool( GetStToolContr() );
00907 else
00908 tool = new a2dDragMultiTool( GetStToolContr() );
00909 tool->SetOneShot();
00910 tool->SetCursorType( a2dCanvasGlobals->GetCursor( a2dCURSOR_Drag ) );
00911 tool->SetBusyCursorType( a2dCanvasGlobals->GetCursor( a2dCURSOR_Drag ) );
00912 m_controller->PushTool( tool );
00913 }
00914
00915 void a2dMasterDrawBase::PushCopyTool( a2dCanvasObject *hit )
00916 {
00917 SelectHitObject( hit );
00918 a2dCopyTool* tool;
00919 if ( m_fastTools )
00920 tool = new a2dCopyTool( GetStToolContr() );
00921 else
00922 tool = new a2dCopyTool( GetStToolContr() );
00923 tool->SetOneShot();
00924 tool->SetCursorType( a2dCanvasGlobals->GetCursor( a2dCURSOR_Drag ) );
00925 tool->SetBusyCursorType( a2dCanvasGlobals->GetCursor( a2dCURSOR_Drag ) );
00926 tool->SetDeleteOnOutsideDrop( true );
00927 m_controller->PushTool( tool );
00928 }
00929
00930 void a2dMasterDrawBase::PushCopyMultiTool( a2dCanvasObject *WXUNUSED(hit) )
00931 {
00932 a2dStTool* tool;
00933 if ( m_fastTools )
00934 tool = new a2dFastCopyMultiTool( GetStToolContr() );
00935 else
00936 tool = new a2dCopyMultiTool( GetStToolContr() );
00937 tool->SetOneShot();
00938 tool->SetCursorType( a2dCanvasGlobals->GetCursor( a2dCURSOR_Copy ) );
00939 tool->SetBusyCursorType( a2dCanvasGlobals->GetCursor( a2dCURSOR_Copy ) );
00940 m_controller->PushTool( tool );
00941 }
00942
00943 void a2dMasterDrawBase::PushSelectTool()
00944 {
00945 a2dStTool* tool;
00946 if ( m_fastTools )
00947 {
00948 tool = new a2dFastSelect( GetStToolContr() );
00949 ((a2dFastSelect*)tool)->SetShiftIsAdd();
00950 }
00951 else
00952 {
00953 tool = new a2dSelectTool( GetStToolContr() );
00954 ((a2dSelectTool*)tool)->SetShiftIsAdd();
00955 }
00956 tool->SetOneShot();
00957 tool->SetFill( m_selectFill );
00958 tool->SetStroke( m_selectStroke );
00959
00960 m_controller->PushTool( tool );
00961 }
00962
00963 void a2dMasterDrawBase::PushDeSelectTool()
00964 {
00965 a2dStTool* tool;
00966 if ( m_fastTools )
00967 {
00968 tool = new a2dFastSelect2( GetStToolContr() );
00969 ((a2dFastSelect2*)tool)->SetSelectMode(false);
00970 }
00971 else
00972 {
00973 tool = new a2dFastSelect2( GetStToolContr() );
00974 ((a2dFastSelect2*)tool)->SetSelectMode(false);
00975 }
00976 tool->SetOneShot();
00977 tool->SetFill( m_selectFill );
00978 tool->SetStroke( m_selectStroke );
00979
00980 m_controller->PushTool( tool );
00981 }
00982
00983 void a2dMasterDrawBase::PushEditVertexTool( a2dCanvasObject *hit, int vertex )
00984 {
00985 a2dPolygonL *poly = wxStaticCast( hit, a2dPolygonL );
00986 SelectHitObject( hit );
00987 a2dSimpleEditPolygonTool *tool = new a2dSimpleEditPolygonTool( GetStToolContr(), hit, vertex, poly->GetSegments()->size(), a2dSimpleEditPolygonTool::action_movevertex );
00988 tool->SetOneShot();
00989 tool->SetCursorType( a2dCanvasGlobals->GetCursor( a2dCURSOR_EditVertex ) );
00990 tool->SetBusyCursorType( a2dCanvasGlobals->GetCursor( a2dCURSOR_EditVertex ) );
00991 m_controller->PushTool( tool );
00992 }
00993
00994 void a2dMasterDrawBase::PushEditSegmentTool( a2dCanvasObject *hit, int segment )
00995 {
00996 a2dPolygonL *poly = wxStaticCast( hit, a2dPolygonL );
00997 SelectHitObject( hit );
00998 a2dSimpleEditPolygonTool *tool = new a2dSimpleEditPolygonTool( GetStToolContr(), hit, segment, poly->GetSegments()->size(), a2dSimpleEditPolygonTool::action_movesegment );
00999 tool->SetOneShot();
01000 tool->SetCursorType( a2dCanvasGlobals->GetCursor( a2dCURSOR_Edit ) );
01001 tool->SetBusyCursorType( a2dCanvasGlobals->GetCursor( a2dCURSOR_Edit ) );
01002 m_controller->PushTool( tool );
01003 }
01004
01005 void a2dMasterDrawBase::PushEditTool( a2dCanvasObject *hit )
01006 {
01007 SelectHitObject( hit );
01008 a2dObjectEditTool* tool = new a2dObjectEditTool( m_stcontroller );
01009 tool->StartToEdit( hit );
01010 tool->SetOneShot();
01011 tool->SetCursorType( a2dCanvasGlobals->GetCursor( a2dCURSOR_EditSegment ) );
01012 tool->SetBusyCursorType( a2dCanvasGlobals->GetCursor( a2dCURSOR_EditSegment ) );
01013 m_stcontroller->PushTool( tool );
01014 }
01015
01016 void a2dMasterDrawBase::PushMultiEditTool( a2dCanvasObject *hit )
01017 {
01018 a2dMultiEditTool* tool = new a2dMultiEditTool( m_stcontroller );
01019 tool->StartEditingSelected();
01020 tool->SetOneShot();
01021 tool->SetCursorType( a2dCanvasGlobals->GetCursor( a2dCURSOR_EditSegment ) );
01022 tool->SetBusyCursorType( a2dCanvasGlobals->GetCursor( a2dCURSOR_EditSegment ) );
01023 m_stcontroller->PushTool( tool );
01024 }
01025
01026 void a2dMasterDrawBase::DeselectAll()
01027 {
01028 GetCanvasCommandProcessor()->Submit( new a2dCommand_Select( a2dCommand_Select::Args().what(a2dCommand_Select::DeSelectAll) ) );
01029 }
01030
01031 bool a2dMasterDrawBase::ZoomSave()
01032 {
01033 return true;
01034 }
01035
01036 void a2dMasterDrawBase::DoStopTool( bool abort )
01037 {
01038 a2dStTool::DoStopTool( abort );
01039 }
01040
01041 void a2dMasterDrawBase::OnChar(wxKeyEvent& event)
01042 {
01043 switch( event.GetKeyCode() )
01044 {
01045 case WXK_DELETE:
01046 {
01047 wxASSERT( m_parentobject == GetCanvasView()->GetShowObject() );
01048
01049 GetCanvasCommandProcessor()->Submit( new a2dCommand_DeleteMask() );
01050 break;
01051 }
01052 default:
01053 event.Skip();
01054 }
01055 }
01056
01057
01058 void a2dMasterDrawBase::OnKeyDown(wxKeyEvent& event)
01059 {
01060 a2dBaseTool* first = m_stcontroller->GetFirstTool();
01061
01062 switch(event.GetKeyCode())
01063 {
01064 case WXK_ESCAPE:
01065 {
01066 if ( first && first->AllowPop() )
01067 first->StopTool( false );
01068 return;
01069 }
01070 break;
01071 default:;
01072 }
01073
01074 if ( !m_active )
01075 {
01076 event.Skip();
01077 return;
01078 }
01079
01080
01081
01082 switch(event.GetKeyCode())
01083 {
01084 case WXK_CONTROL:
01085 {
01086 if ( !first || ( first && !first->GetBusy()) )
01087 {
01088 if ( !wxDynamicCast(first, a2dDragTool) )
01089 {
01090
01091
01092
01093 }
01094 }
01095 }
01096 break;
01097 case 'Z':
01098 case 'z':
01099 {
01100 if ( !first || ( first && !first->GetBusy()) )
01101 PushZoomTool();
01102 else
01103 event.Skip();
01104
01105 break;
01106 }
01107 case WXK_NUMPAD_ADD:
01108 {
01109 if ( event.m_controlDown )
01110 m_stcontroller->ZoomIn2AtMouse();
01111 else
01112 m_stcontroller->Zoomin2();
01113 break;
01114 }
01115 case WXK_NUMPAD_SUBTRACT:
01116 {
01117 if ( event.m_controlDown )
01118 m_stcontroller->ZoomOut2AtMouse();
01119 else
01120 m_stcontroller->Zoomout2();
01121 break;
01122 }
01123 case WXK_SPACE:
01124 {
01125 m_spaceDown = true;
01126 m_mode = mode_zoom;
01127 m_modehit = NULL;
01128 event.Skip();
01129 break;
01130 }
01131 default:
01132 event.Skip();
01133 }
01134 }
01135
01136 void a2dMasterDrawBase::OnKeyUp(wxKeyEvent& event)
01137 {
01138 if ( !m_active )
01139 {
01140 event.Skip();
01141 return;
01142 }
01143 event.Skip();
01144 }
01145
01146 void a2dMasterDrawBase::SelectHitObject( a2dCanvasObject *hit )
01147 {
01148 OpenCommandGroupNamed( _("Select") );
01149
01150 DeselectAll();
01151
01152 GetCanvasCommandProcessor()->Submit(
01153 new a2dCommand_SetFlag( hit, a2dCanvasOFlags::SELECTED, true ));
01154
01155 CloseCommandGroup();
01156 }
01157
01158
01159
01160
01161
01162 IMPLEMENT_CLASS(a2dMasterDrawSelectFirst,a2dMasterDrawBase)
01163
01164 A2D_BEGIN_EVENT_TABLE( a2dMasterDrawSelectFirst,a2dMasterDrawBase )
01165 A2D_EVT_MOUSE_EVENTS( a2dMasterDrawSelectFirst::OnMouseEvent )
01166 A2D_EVT_CHAR( a2dMasterDrawSelectFirst::OnChar )
01167 A2D_EVT_KEY_DOWN( a2dMasterDrawSelectFirst::OnKeyDown )
01168 A2D_EVT_KEY_UP( a2dMasterDrawSelectFirst::OnKeyUp )
01169 A2D_END_EVENT_TABLE()
01170
01171 a2dMasterDrawSelectFirst::a2dMasterDrawSelectFirst(a2dStToolContr* controller):a2dMasterDrawBase( controller )
01172 {
01173 controller->SetDefaultBehavior( controller->GetDefaultBehavior() | wxTC_NoDefaultKeys | wxTC_NoDefaultMouseActions );
01174 }
01175
01176 a2dMasterDrawSelectFirst::~a2dMasterDrawSelectFirst()
01177 {
01178 }
01179
01180 void a2dMasterDrawSelectFirst::OnChar(wxKeyEvent& event)
01181 {
01182 event.Skip();
01183 }
01184
01185 void a2dMasterDrawSelectFirst::OnKeyDown(wxKeyEvent& event)
01186 {
01187 if ( !m_active )
01188 {
01189 event.Skip();
01190 return;
01191 }
01192
01193
01194 a2dBaseTool* first = m_stcontroller->GetFirstTool();
01195
01196 switch(event.GetKeyCode())
01197 {
01198 case WXK_SPACE:
01199 {
01200 m_spaceDown = true;
01201 m_mode = mode_zoom;
01202 m_modehit = NULL;
01203 break;
01204 }
01205 case WXK_CONTROL:
01206 {
01207 m_mode = mode_copy;
01208 m_modehit = NULL;
01209 break;
01210 }
01211 case WXK_SHIFT:
01212 {
01213 DecideMode( m_modehit, true, false );
01214 break;
01215 }
01216 default:
01217 event.Skip();
01218 }
01219 }
01220
01221 void a2dMasterDrawSelectFirst::OnKeyUp(wxKeyEvent& event)
01222 {
01223 if ( !m_active )
01224 {
01225 event.Skip();
01226 return;
01227 }
01228
01229 switch(event.GetKeyCode())
01230 {
01231 case WXK_SPACE:
01232 {
01233 m_spaceDown = false;
01234 m_mode = mode_zoom;
01235 m_modehit = NULL;
01236 break;
01237 }
01238 case WXK_SHIFT:
01239 {
01240 DecideMode( m_modehit, false, false );
01241 break;
01242 }
01243 default:
01244 event.Skip();
01245 }
01246 }
01247
01248
01249 void a2dMasterDrawSelectFirst::DecideMode( a2dCanvasObject* hit, bool shift, bool control )
01250 {
01251
01252 m_mode = mode_select;
01253 GetCanvasView()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_Select ) );
01254 m_modehit = 0;
01255 m_modehitinfo = a2dHit();
01256
01257 if ( m_spaceDown )
01258 {
01259 GetCanvasView()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_Zoom ) );
01260 m_mode = mode_zoom;
01261 }
01262 else if( hit )
01263 {
01264 m_modehit = hit;
01265 if ( !shift && hit->GetDraggable() && hit->GetSelected() )
01266 {
01267 if ( control )
01268 {
01269 GetCanvasView()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_Copy ) );
01270
01271 m_mode = mode_copymulti;
01272 }
01273 else
01274 {
01275 GetCanvasView()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_Drag ) );
01276 m_mode = mode_dragmulti;
01277 }
01278 }
01279 if ( shift && hit->GetDraggable() )
01280 {
01281 GetCanvasView()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_Select ) );
01282 }
01283 }
01284 }
01285
01286 void a2dMasterDrawSelectFirst::OnMouseEvent(wxMouseEvent& event)
01287 {
01288 if (!m_active)
01289 {
01290 event.Skip();
01291 return;
01292 }
01293 m_x = event.GetX();
01294 m_y = event.GetY();
01295
01296 double xWorld, yWorld;
01297 GetCanvasView()->MouseToToolWorld( m_x, m_y, xWorld, yWorld );
01298
01299 GetCanvasView()->Update( a2dCANVIEW_UPDATE_PENDING );
01300 a2dIterC ic( GetCanvasView() );
01301 ic.SetLayer( wxLAYER_ALL );
01302 ic.SetObjectFilter( new a2dCanvasObjectFilterLayerMask( wxLAYER_ALL, a2dCanvasOFlags::VISIBLE | a2dCanvasOFlags::SELECTABLE ) );
01303 a2dHitEvent hitinfo( xWorld, yWorld );
01304 if ( event.ShiftDown() && event.ControlDown() )
01305 hitinfo.m_option |= a2dCANOBJHITOPTION_NOTSELECTED;
01306
01307
01308 hitinfo.m_xyRelToChildren = false;
01309 a2dCanvasObject* hit = GetCanvasView()->GetShowObject()->ChildIsHitWorld( ic, hitinfo, true );
01310
01311
01312 if ( hit && event.LeftDClick() && !GetBusy())
01313 {
01314 int i = 0;
01315 GetCanvasView()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_ARROW ) );
01316 m_modehit = hit;
01317 a2dCanvasObjectList* objects = m_parentobject->GetChildObjectList();
01318 forEachIn( a2dCanvasObjectList, objects )
01319 {
01320 a2dCanvasObject *obj = *iter;
01321 if ( obj->GetSelected() )
01322 i++;
01323 }
01324
01325 if ( i <= 1 )
01326 {
01327 m_mode = mode_edit;
01328 PushEditTool( m_modehit );
01329 }
01330 else
01331 {
01332 m_mode = mode_multiedit;
01333 PushMultiEditTool( m_modehit );
01334 }
01335 }
01336 else if ( event.Moving() && !GetBusy() )
01337 {
01338 DecideMode( hit, event.ShiftDown(), event.ControlDown() );
01339 event.Skip();
01340 }
01341 else if( event.LeftDown() && !GetBusy() )
01342 {
01343 DecideMode( hit, event.ShiftDown(), event.ControlDown() );
01344
01345
01346 switch( m_mode )
01347 {
01348 case mode_none:
01349 event.Skip();
01350 break;
01351 case mode_zoom:
01352 PushZoomTool();
01353 event.Skip();
01354 break;
01355 case mode_zoomdrag:
01356 break;
01357 case mode_select:
01358 PushSelectTool();
01359 event.Skip();
01360 break;
01361 case mode_dragmulti:
01362 PushDragMultiTool(m_modehit);
01363 event.Skip();
01364 break;
01365 case mode_copymulti:
01366 PushCopyMultiTool(m_modehit);
01367 event.Skip();
01368 break;
01369 case mode_vertex:
01370 PushEditVertexTool( m_modehit, m_modehitinfo.m_index );
01371 event.Skip();
01372 break;
01373 case mode_segment:
01374 PushEditSegmentTool( m_modehit, m_modehitinfo.m_index );
01375 event.Skip();
01376 break;
01377 default:
01378 event.Skip();
01379 }
01380 }
01381 else if( event.RightDown() && !GetBusy() )
01382 {
01383 PushZoomTool();
01384 event.Skip();
01385 }
01386 else
01387 {
01388 event.Skip();
01389 }
01390 }
01391
01392
01393
01394
01395
01396 IMPLEMENT_CLASS(a2dMasterDrawZoomFirst,a2dMasterDrawBase)
01397
01398 A2D_BEGIN_EVENT_TABLE( a2dMasterDrawZoomFirst, a2dMasterDrawBase )
01399 A2D_EVT_MOUSE_EVENTS( a2dMasterDrawZoomFirst::OnMouseEvent )
01400 A2D_EVT_CHAR( a2dMasterDrawZoomFirst::OnChar )
01401 A2D_EVT_KEY_DOWN( a2dMasterDrawZoomFirst::OnKeyDown )
01402 A2D_EVT_KEY_UP( a2dMasterDrawZoomFirst::OnKeyUp )
01403 A2D_END_EVENT_TABLE()
01404
01405 a2dMasterDrawZoomFirst::a2dMasterDrawZoomFirst(a2dStToolContr* controller):a2dMasterDrawBase(controller)
01406 {
01407 controller->SetDefaultBehavior( controller->GetDefaultBehavior() | wxTC_NoDefaultKeys | wxTC_NoDefaultMouseActions );
01408 m_toolcursor = a2dCanvasGlobals->GetCursor( a2dCURSOR_Zoom );
01409 }
01410
01411 a2dMasterDrawZoomFirst::~a2dMasterDrawZoomFirst()
01412 {
01413 }
01414
01415 void a2dMasterDrawZoomFirst::Render()
01416 {
01417 }
01418
01419 void a2dMasterDrawZoomFirst::OnChar(wxKeyEvent& event)
01420 {
01421
01422 a2dBaseTool* first = m_stcontroller->GetFirstTool();
01423
01424 switch(event.GetKeyCode())
01425 {
01426 case WXK_SPACE:
01427 {
01428 m_stcontroller->Zoomout();
01429 break;
01430 }
01431 default:
01432 event.Skip();
01433 }
01434 }
01435
01436 void a2dMasterDrawZoomFirst::OnKeyDown(wxKeyEvent& event)
01437 {
01438 if ( !m_active )
01439 {
01440 event.Skip();
01441 return;
01442 }
01443 event.Skip();
01444 }
01445
01446 void a2dMasterDrawZoomFirst::OnKeyUp(wxKeyEvent& event)
01447 {
01448 if ( !m_active )
01449 {
01450 event.Skip();
01451 return;
01452 }
01453 event.Skip();
01454 }
01455
01456 void a2dMasterDrawZoomFirst::OnMouseEvent(wxMouseEvent& event)
01457 {
01458 if (!m_active)
01459 {
01460 event.Skip();
01461 return;
01462 }
01463 m_x = event.GetX();
01464 m_y = event.GetY();
01465
01466 MouseToToolWorld( m_x, m_y, m_xwprev, m_ywprev );
01467
01468
01469 a2dIterC ic( GetCanvasView() );
01470 ic.SetLayer( wxLAYER_ALL );
01471 ic.SetObjectFilter( new a2dCanvasObjectFilterLayerMask( wxLAYER_ALL, a2dCanvasOFlags::VISIBLE | a2dCanvasOFlags::SELECTABLE ) );
01472 a2dHitEvent hitinfo( m_xwprev, m_ywprev );
01473 hitinfo.m_option = a2dCANOBJHITOPTION_LAYERS;
01474
01475
01476 hitinfo.m_xyRelToChildren = false;
01477
01478 if ( event.LeftDClick() && !m_toolBusy && !GetBusy())
01479 {
01480 a2dCanvasObject* hit = GetCanvasView()->GetShowObject()->ChildIsHitWorld( ic, hitinfo, true );
01481 if ( hit )
01482 {
01483 hit->SetSelected( m_modehitLastSelectState );
01484 int i = 0;
01485 GetCanvasView()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_Select ) );
01486 m_modehit = hit;
01487 a2dCanvasObjectList* objects = m_parentobject->GetChildObjectList();
01488 forEachIn( a2dCanvasObjectList, objects )
01489 {
01490 a2dCanvasObject *obj = *iter;
01491 if ( obj->GetSelected() )
01492 i++;
01493 }
01494
01495 if ( i > 1 && m_allowMultiEdit )
01496 {
01497 m_mode = mode_multiedit;
01498 PushMultiEditTool( m_modehit );
01499 }
01500 else
01501 {
01502 m_mode = mode_edit;
01503 PushEditTool( m_modehit );
01504 }
01505 }
01506 }
01507 else if ( event.Dragging() && m_toolBusy && !m_dragStarted && !event.AltDown())
01508 {
01509 if (abs( m_x - m_dragstartx ) > 3 && abs( m_y - m_dragstarty ) > 3)
01510 {
01511 if ( event.ControlDown() )
01512 {
01513 a2dCanvasObject* hit = GetCanvasView()->GetShowObject()->ChildIsHitWorld( ic, hitinfo, true );
01514 m_mode = mode_cntrlselect;
01515 m_modehit = hit;
01516 }
01517 else if ( event.ShiftDown() )
01518 {
01519 a2dCanvasObject* hit = GetCanvasView()->GetShowObject()->ChildIsHitWorld( ic, hitinfo, true );
01520 m_mode = mode_select;
01521 m_modehit = hit;
01522 }
01523 else
01524 {
01525 m_mode = mode_zoom;
01526 m_modehit = NULL;
01527 }
01528
01529 switch( m_mode )
01530 {
01531 case mode_zoom:
01532 case mode_select:
01533 case mode_cntrlselect:
01534 {
01535 m_dragStarted = true;
01536 m_parentobject = GetCanvasView()->GetShowObject();
01537 MouseToToolWorld( m_dragstartx, m_dragstarty, m_xwprev, m_ywprev );
01538
01539 a2dRect* rec = new a2dRect( m_xwprev, m_ywprev , 0, 0, 0);
01540 m_canvasobject = rec;
01541 if ( m_mode == mode_select || m_mode == mode_cntrlselect )
01542 {
01543 rec->SetFill( m_selectFill );
01544 rec->SetStroke( m_selectStroke );
01545 }
01546 else
01547 {
01548 rec->SetFill( m_fill );
01549 rec->SetStroke( m_stroke );
01550 }
01551 rec->Update( a2dCanvasObject::updatemask_force );
01552 GetCanvasDocument()->SetIgnorePendingObjects( true );
01553 if ( GetCanvasView()->GetTrippleBuf() )
01554 GetCanvasView()->AddOverlayObject( rec );
01555 else
01556 GetCanvasView()->AddOverlayObject( rec );
01557
01558 GetCanvasDocument()->SetIgnorePendingObjects( false );
01559 GetCanvasView()->AddOverlayAreas( true );
01560 m_pending = true;
01561 event.Skip();
01562 EnterBusyMode();
01563 }
01564 default:
01565 break;
01566 }
01567 switch( m_mode )
01568 {
01569 case mode_zoom:
01570 GetCanvasView()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_Zoom ) );
01571 break;
01572 case mode_select:
01573 case mode_cntrlselect:
01574 GetCanvasView()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_Select ) );
01575 break;
01576 default:
01577 break;
01578 }
01579 }
01580 }
01581 else if ( event.Dragging() && m_toolBusy && m_dragStarted )
01582 {
01583 switch( m_mode )
01584 {
01585 case mode_zoom:
01586 case mode_select:
01587 case mode_cntrlselect:
01588 {
01589 a2dRect* rec = wxStaticCast( m_canvasobject.Get(), a2dRect );
01590
01591 MouseToToolWorld( m_x, m_y, m_xwprev, m_ywprev );
01592
01593 GetCanvasDocument()->SetIgnorePendingObjects( true );
01594 rec->SetWidth( m_xwprev - rec->GetPosX() );
01595 rec->SetHeight( m_ywprev - rec->GetPosY() );
01596 rec->SetPending( true );
01597 GetCanvasDocument()->SetIgnorePendingObjects( false );
01598 GetCanvasView()->AddOverlayAreas( true );
01599
01600 break;
01601 }
01602 default:
01603 break;
01604 }
01605 }
01606 else if ( event.Moving() && !GetBusy() && event.AltDown() )
01607 {
01608
01609 m_mode = mode_none;
01610 m_modehit = 0;
01611 m_modehitinfo = a2dHit();
01612 a2dCanvasObject* hit = GetCanvasView()->GetShowObject()->ChildIsHitWorld( ic, hitinfo, true );
01613
01614 if( hit && hit->GetDraggable() && hit->GetSelected() )
01615 {
01616 m_modehit = hit;
01617 if( event.ControlDown() )
01618 {
01619 GetCanvasView()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_Copy ) );
01620 m_mode = mode_copymulti;
01621 }
01622 else
01623 {
01624 GetCanvasView()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_Drag ) );
01625 m_mode = mode_dragmulti;
01626 }
01627 }
01628 event.Skip();
01629 }
01630 else if ( event.Moving() && !GetBusy() )
01631 {
01632 m_mode = mode_none;
01633 a2dCanvasObject* hit = GetCanvasView()->GetShowObject()->ChildIsHitWorld( ic, hitinfo, true );
01634 if ( hit )
01635 GetCanvasView()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_HAND ) );
01636 else
01637 GetCanvasView()->SetCursor( m_toolcursor );
01638 }
01639 else if( event.LeftDown() && !GetBusy() )
01640 {
01641 GetCanvasView()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_Select ) );
01642 m_modehit = 0;
01643 a2dCanvasObject* hit = GetCanvasView()->GetShowObject()->ChildIsHitWorld( ic, hitinfo, true );
01644 if( hit )
01645 m_modehit = hit;
01646
01647 m_dragStarted = false;
01648 m_xprev = m_x;
01649 m_yprev = m_y;
01650 m_dragstartx = m_x;
01651 m_dragstarty = m_y;
01652 m_toolBusy = true;
01653
01654 switch( m_mode )
01655 {
01656 case mode_dragmulti:
01657 PushDragMultiTool(m_modehit);
01658 event.Skip();
01659 break;
01660 case mode_copymulti:
01661 PushCopyMultiTool(m_modehit);
01662 event.Skip();
01663 break;
01664 case mode_vertex:
01665 PushEditVertexTool( m_modehit, m_modehitinfo.m_index );
01666 event.Skip();
01667 break;
01668 case mode_segment:
01669 PushEditSegmentTool( m_modehit, m_modehitinfo.m_index );
01670 event.Skip();
01671 break;
01672 default:
01673 m_mode = mode_none;
01674 event.Skip();
01675 }
01676 }
01677 else if( event.LeftUp() && GetBusy() && m_dragStarted )
01678 {
01679 m_toolBusy = false;
01680 m_dragStarted = false;
01681 switch( m_mode )
01682 {
01683 case mode_zoom:
01684 {
01685 a2dRect* rec = wxStaticCast( m_canvasobject.Get(), a2dRect );
01686
01687 double w = GetDrawer2D()->WorldToDeviceXRel( rec->GetWidth() );
01688 double h = GetDrawer2D()->WorldToDeviceYRel( rec->GetHeight() );
01689
01690 rec->Update( a2dCanvasObject::updatemask_force );
01691 double x1 = rec->GetBbox().GetMinX();
01692
01693 double y1 = rec->GetBbox().GetMinY();
01694
01695
01696 a2dBoundingBox* bbox = new a2dBoundingBox(GetDrawer2D()->GetVisibleMinX(),
01697 GetDrawer2D()->GetVisibleMinY(),
01698 GetDrawer2D()->GetVisibleMaxX(),
01699 GetDrawer2D()->GetVisibleMaxY()
01700 );
01701
01702 m_stcontroller->GetZoomList().Insert(bbox);
01703 GetDrawer2D()->SetMappingWidthHeight(x1,y1, fabs(rec->GetWidth()),fabs(rec->GetHeight()));
01704
01705 FinishBusyMode();
01706 GetCanvasView()->RemoveOverlayObject( rec );
01707
01708 event.Skip();
01709 break;
01710 }
01711 case mode_select:
01712 {
01713 SetIgnorePendingObjects( false );
01714
01715 a2dRect* rec = wxStaticCast( m_canvasobject.Get(), a2dRect );
01716 rec->Update( a2dCanvasObject::updatemask_force );
01717 GetCanvasView()->AddPendingUpdateArea(rec->GetBbox());
01718
01719 GetCanvasCommandProcessor()->Submit(
01720 new a2dCommand_Select( a2dCommand_Select::Args()
01721 .what(a2dCommand_Select::SelectRect)
01722 .x1( rec->GetBbox().GetMinX() )
01723 .y1( rec->GetBbox().GetMinY() )
01724 .x2( rec->GetBbox().GetMaxX() )
01725 .y2( rec->GetBbox().GetMaxY() )
01726 )
01727 );
01728 FinishBusyMode();
01729 GetCanvasView()->RemoveOverlayObject( rec );
01730 event.Skip();
01731 break;
01732 }
01733 case mode_cntrlselect:
01734 {
01735 DeselectAll();
01736 SetIgnorePendingObjects( false );
01737
01738 a2dRect* rec = wxStaticCast( m_canvasobject.Get(), a2dRect );
01739 rec->Update( a2dCanvasObject::updatemask_force );
01740 GetCanvasView()->AddPendingUpdateArea(rec->GetBbox());
01741
01742 GetCanvasCommandProcessor()->Submit(
01743 new a2dCommand_Select( a2dCommand_Select::Args()
01744 .what(a2dCommand_Select::SelectRect)
01745 .x1( rec->GetBbox().GetMinX() )
01746 .y1( rec->GetBbox().GetMinY() )
01747 .x2( rec->GetBbox().GetMaxX() )
01748 .y2( rec->GetBbox().GetMaxY() )
01749 )
01750 );
01751 FinishBusyMode();
01752 GetCanvasView()->RemoveOverlayObject( rec );
01753 event.Skip();
01754 break;
01755 }
01756 default:
01757 break;
01758 }
01759 GetCanvasView()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_Zoom ) );
01760 }
01761 else if( event.LeftUp() && m_toolBusy )
01762 {
01763 m_toolBusy = false;
01764
01765 m_modehitLastSelectState = false;
01766 if ( m_modehit )
01767 m_modehitLastSelectState = m_modehit->GetSelected();
01768
01769
01770 if ( event.ControlDown() )
01771 {
01772 DeselectAll();
01773 if ( m_modehit && m_modehit->GetSelectable() )
01774 m_modehit->SetSelected( true );
01775 }
01776 else if ( event.ShiftDown() )
01777 {
01778 if ( m_modehit && m_modehit->GetSelectable() )
01779 m_modehit->SetSelected( true );
01780 }
01781 else
01782 {
01783 if ( !m_modehit )
01784 DeselectAll();
01785 if ( m_modehit && m_modehit->GetSelectable() )
01786 m_modehit->SetSelected( ! m_modehit->GetSelected() );
01787 }
01788 GetCanvasView()->SetCursor( a2dCanvasGlobals->GetCursor( a2dCURSOR_Zoom ) );
01789 }
01790 else if( event.RightDown() && !GetBusy() )
01791 {
01792 PushZoomTool();
01793 event.Skip();
01794 }
01795 else
01796 {
01797 event.Skip();
01798 }
01799 }
01800
01801
01802
01803
01804
01805 IMPLEMENT_CLASS( a2dToolProperty, a2dDynamicEventProperty );
01806
01807
01808 #ifdef _MSC_VER
01809 #pragma warning(disable: 4660)
01810 #endif
01811
01812 template class a2dPropertyIdProp<class a2dToolProperty>;
01813
01814 #ifdef _MSC_VER
01815 #pragma warning(default: 4660)
01816 #endif
01817
01818 const long SUBMASTER_PUSHTOOL = wxNewId();
01819 const long SUBMASTER_MENUTOOL_DRAG = wxNewId();
01820 const long SUBMASTER_MENUTOOL_REC = wxNewId();
01821 const long SUBMASTER_MENUTOOL_EDIT = wxNewId();
01822
01823 const a2dPropertyIdDynamicEventProperty a2dSubDrawMasterTool::PROPID_toolMenu( wxT("PROPID_toolMenu"), a2dPropertyId::flag_multiple );
01824
01825 a2dToolProperty::a2dToolProperty(): a2dDynamicEventProperty()
01826 {
01827 m_tool = NULL;
01828 m_key = ' ';
01829 m_menuItem = NULL;
01830 }
01831
01832 a2dToolProperty::a2dToolProperty( const a2dPropertyIdDynamicEventProperty* id, a2dBaseTool* tool, wxMenuItem* menuItem, wxChar key )
01833 :a2dDynamicEventProperty( id, wxEVT_COMMAND_MENU_SELECTED, menuItem->GetId(),-1,
01834 (a2dObjectEventFunction) (a2dCommandEventFunction) (&a2dSubDrawMasterTool::PushToolFromMouseMenu ) )
01835 {
01836 m_tool = tool;
01837 m_menuItem = menuItem;
01838 m_key = key;
01839 }
01840
01841 a2dToolProperty::a2dToolProperty(const a2dToolProperty &other )
01842 :a2dDynamicEventProperty( other )
01843 {
01844 m_tool = other.m_tool;
01845 m_menuItem = other.m_menuItem;
01846 m_key = other.m_key;
01847 }
01848
01849 a2dToolProperty::~a2dToolProperty()
01850 {
01851 }
01852
01853 a2dNamedProperty* a2dToolProperty::Clone( a2dObject::CloneOptions WXUNUSED(options) ) const
01854 {
01855 return new a2dToolProperty( *this );
01856 };
01857
01858 void a2dToolProperty::Assign( const a2dNamedProperty &other )
01859 {
01860 a2dToolProperty *propcast = wxStaticCast( &other, a2dToolProperty);
01861 m_tool = propcast->m_tool;
01862 m_menuItem = propcast->m_menuItem;
01863 m_key = propcast->m_key;
01864 }
01865
01866 #if wxART2D_USE_CVGIO
01867
01868 void a2dToolProperty::DoSave( wxObject* WXUNUSED(parent), a2dIOHandlerXmlSerOut &WXUNUSED(out), a2dXmlSer_flag WXUNUSED(xmlparts) , a2dObjectList* WXUNUSED(towrite) )
01869 {
01870
01871 wxASSERT(0);
01872 }
01873
01874 #endif //wxART2D_USE_CVGIO
01875
01876 #if wxART2D_USE_CVGIO
01877
01878 void a2dToolProperty::DoLoad( wxObject* WXUNUSED(parent), a2dIOHandlerXmlSerIn& WXUNUSED(parser), a2dXmlSer_flag WXUNUSED(xmlparts) )
01879 {
01880
01881 wxASSERT(0);
01882 }
01883
01884 #endif //wxART2D_USE_CVGIO
01885
01886
01887
01888
01889
01890 IMPLEMENT_DYNAMIC_CLASS(a2dSubDrawMasterTool,a2dStTool)
01891
01892 A2D_BEGIN_EVENT_TABLE(a2dSubDrawMasterTool,a2dStTool)
01893 A2D_EVT_MOUSE_EVENTS(a2dSubDrawMasterTool::OnMouseEvent)
01894 A2D_EVT_CHAR(a2dSubDrawMasterTool::OnChar)
01895 A2D_END_EVENT_TABLE()
01896
01897 a2dSubDrawMasterTool::a2dSubDrawMasterTool(a2dStToolContr* controller):a2dStTool(controller)
01898 {
01899 m_toolcursor = a2dCanvasGlobals->GetCursor( a2dCURSOR_ARROW );
01900 m_mode = 0;
01901 m_canvasobject=0;
01902
01903 m_mousemenu = new wxMenu( _("Tool menu"),(long)0);
01904
01905 a2dDragTool *tool = new a2dDragTool( controller );
01906 tool->SetCursorType( a2dCanvasGlobals->GetCursor( a2dCURSOR_ARROW ) );
01907 tool->SetBusyCursorType( a2dCanvasGlobals->GetCursor( a2dCURSOR_HAND ) );
01908 tool->SetDeleteOnOutsideDrop( false );
01909 AppendTool( tool, new wxMenuItem( m_mousemenu, SUBMASTER_MENUTOOL_DRAG, _("drag"), _("pushes drag tool") ), 'd' );
01910
01911 a2dRecursiveEditTool* edit = new a2dRecursiveEditTool( controller );
01912 edit->SetCorridor( m_corridor );
01913 AppendTool( edit, new wxMenuItem( m_mousemenu, SUBMASTER_MENUTOOL_EDIT, _("edit"), _("pushes edit tool") ), 'e' );
01914
01915 a2dDrawRectangleTool* drawrec = new a2dDrawRectangleTool( controller );
01916 drawrec->SetEditAtEnd( true );
01917 AppendTool( drawrec, new wxMenuItem( m_mousemenu, SUBMASTER_MENUTOOL_REC, _("draw rectangle"), _("pushes draw rectangle tool") ), 'r' );
01918
01919 m_curTool = drawrec;
01920 }
01921
01922 a2dSubDrawMasterTool::~a2dSubDrawMasterTool()
01923 {
01924 }
01925
01926 void a2dSubDrawMasterTool::OnPostPushTool()
01927 {
01928 m_curTool->SetCorridor( m_corridor );
01929 m_controller->PushTool( m_curTool );
01930 }
01931
01932 void a2dSubDrawMasterTool::AppendTool( a2dBaseTool* tool, wxMenuItem* menuItem, wxChar key )
01933 {
01934
01935 m_mousemenu->Append( menuItem );
01936 }
01937
01938 bool a2dSubDrawMasterTool::ZoomSave()
01939 {
01940 return true;
01941 }
01942
01943 void a2dSubDrawMasterTool::DoStopTool( bool abort )
01944 {
01945 a2dStTool::DoStopTool( abort );
01946 }
01947
01948 void a2dSubDrawMasterTool::OnChar(wxKeyEvent& WXUNUSED(event) )
01949 {
01950
01951
01952
01953 }
01954
01955 void a2dSubDrawMasterTool::OnMouseEvent(wxMouseEvent& event)
01956 {
01957 if (!m_active)
01958 {
01959 event.Skip();
01960 return;
01961 }
01962 m_x = event.GetX();
01963 m_y = event.GetY();
01964
01965
01966 double xw;
01967 double yw;
01968
01969 xw = GetDrawer2D()->DeviceToWorldX(m_x);
01970 yw = GetDrawer2D()->DeviceToWorldY(m_y);
01971
01972 a2dHitEvent hitinfo( xw, yw, false, a2dCANOBJHITOPTION_LAYERS, true );
01973 a2dCanvasObject* hit = GetCanvasView()->IsHitWorld( hitinfo, wxLAYER_ALL );
01974
01975 if ( event.Moving() && !GetBusy() )
01976 {
01977 if( hit )
01978 {
01979 a2dHit how2;
01980 }
01981 }
01982 else if( event.LeftDown() && !GetBusy() )
01983 {
01984 }
01985 else
01986 {
01987 event.Skip();
01988 }
01989 }
01990
01991 void a2dSubDrawMasterTool::PushToolFromMouseMenu( wxCommandEvent& event )
01992 {
01993 a2dToolProperty *property = wxStaticCast( event.m_callbackUserData, a2dToolProperty );
01994 if ( property->GetMenuItem()->GetId() == event.GetId() )
01995 {
01996 a2dSmrtPtr< a2dBaseTool > tool;
01997 if ( m_controller->GetFirstTool() != this )
01998 m_controller->PopTool( tool );
01999
02000 property->GetToolObject()->SetCorridor( m_corridor );
02001 m_controller->PushTool( property->GetToolObject() );
02002 }
02003 }
02004