00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #include "docviewprec.h"
00014
00015 #ifdef __BORLANDC__
00016 #pragma hdrstop
00017 #endif
00018
00019 #ifndef WX_PRECOMP
00020 #include "wx/wx.h"
00021 #endif
00022
00023 #if defined(_DEBUG)
00024
00025 #endif
00026
00027
00028
00029
00030
00031 #ifndef WX_PRECOMP
00032 #include "wx/string.h"
00033 #include "wx/dc.h"
00034 #include "wx/list.h"
00035 #endif
00036
00037 #include "wx/general/comevt.h"
00038
00039 #include "wx/general/smrtptr.inl"
00040 #include <wx/general/id.inl>
00041
00042 #if defined(__WXMSW__) && defined(__MEMDEBUG__)
00043 #include <wx/msw/msvcrt.h>
00044 #endif
00045
00046
00047
00048
00049 IMPLEMENT_DYNAMIC_CLASS(a2dEvtHandler, a2dPropObject)
00050 IMPLEMENT_DYNAMIC_CLASS(a2dCommandProcessor, a2dEvtHandler)
00051 IMPLEMENT_DYNAMIC_CLASS( a2dCommand_SetProperty, a2dCommand )
00052 IMPLEMENT_DYNAMIC_CLASS(a2dCommand_SetVariable, a2dCommand )
00053 IMPLEMENT_DYNAMIC_CLASS(a2dCommand_SetEnvironmentVariable, a2dCommand )
00054 IMPLEMENT_DYNAMIC_CLASS(a2dCommand_GetVariable, a2dCommand )
00055 IMPLEMENT_DYNAMIC_CLASS(a2dCommand_GetEnvVariable, a2dCommand )
00056
00057 DEFINE_EVENT_TYPE(wxEVT_DO)
00058 DEFINE_EVENT_TYPE(wxEVT_UNDO)
00059 DEFINE_EVENT_TYPE(wxEVT_REDO)
00060 DEFINE_EVENT_TYPE(wxEVT_MENUSTRINGS)
00061 DEFINE_EVENT_TYPE(wxEVT_BEGINBUSY)
00062 DEFINE_EVENT_TYPE(wxEVT_ENDBUSY)
00063 DEFINE_EVENT_TYPE(a2dEVT_PROPOBJECT_EDITPROPERTIES_EVENT)
00064
00065
00066
00067
00068 #if (__GNUC__ < 3 || (__GNUC__ == 3 && __GNUC_MINOR__ < 4))
00069
00070
00071
00072 #endif // (__GNUC__ < 3 || (__GNUC__ == 3 && __GNUC_MINOR__ < 4))
00073
00074 IMPLEMENT_DYNAMIC_CLASS( a2dDynamicEventProperty, a2dNamedProperty );
00075
00076 a2dDynamicEventProperty::a2dDynamicEventProperty(): a2dNamedProperty()
00077 {
00078 m_eventType = -1;
00079 m_id = -1;
00080 m_lastId = -1;
00081 m_fn = NULL;
00082 }
00083
00084 a2dDynamicEventProperty::a2dDynamicEventProperty( const a2dPropertyIdDynamicEventProperty* propid,
00085 int evType, int id, int idLast, a2dObjectEventFunction fn )
00086 :a2dNamedProperty( propid )
00087 {
00088 m_eventType = evType;
00089 m_id = id;
00090 m_lastId = idLast;
00091 m_fn = fn;
00092 }
00093
00094 a2dDynamicEventProperty::a2dDynamicEventProperty(const a2dDynamicEventProperty &other )
00095 :a2dNamedProperty( other )
00096 {
00097 m_eventType = other.m_eventType;
00098 m_id = other.m_id;
00099 m_lastId = other.m_lastId;
00100 m_fn = other.m_fn;
00101 }
00102
00103 a2dDynamicEventProperty::~a2dDynamicEventProperty()
00104 {
00105 }
00106
00107 a2dNamedProperty* a2dDynamicEventProperty::Clone( a2dObject::CloneOptions WXUNUSED(options) ) const
00108 {
00109 return new a2dDynamicEventProperty( *this );
00110 }
00111
00112 void a2dDynamicEventProperty::Assign( const a2dNamedProperty &other )
00113 {
00114 a2dDynamicEventProperty *propcast = wxStaticCast( &other, a2dDynamicEventProperty);
00115 m_eventType = propcast->m_eventType;
00116 m_id = propcast->m_id;
00117 m_lastId = propcast->m_lastId;
00118 m_fn = propcast->m_fn;
00119 }
00120
00121 #if wxART2D_USE_CVGIO
00122
00123 void a2dDynamicEventProperty::DoSave( wxObject* WXUNUSED(parent), a2dIOHandlerXmlSerOut& WXUNUSED(out), a2dXmlSer_flag WXUNUSED(xmlparts), a2dObjectList* WXUNUSED(towrite) )
00124 {
00125 wxASSERT(0);
00126 }
00127
00128 #endif //wxART2D_USE_CVGIO
00129
00130 #if wxART2D_USE_CVGIO
00131
00132 void a2dDynamicEventProperty::DoLoad( wxObject* WXUNUSED(parent), a2dIOHandlerXmlSerIn& WXUNUSED(parser), a2dXmlSer_flag WXUNUSED(xmlparts) )
00133 {
00134 wxASSERT(0);
00135 }
00136
00137 #endif //wxART2D_USE_CVGIO
00138
00139
00140
00141
00142
00143
00144 long a2dEvent::ms_timestamp = 0;
00145
00146
00147 const a2dEventTable *a2dEvtHandler::GetEventTable() const
00148 { return &a2dEvtHandler::sm_eventTable; }
00149
00150
00151 const a2dEventTable a2dEvtHandler::sm_eventTable =
00152 { (const a2dEventTable *)NULL, &a2dEvtHandler::sm_eventTableEntries[0] };
00153
00154
00155 const a2dEventTableEntry a2dEvtHandler::sm_eventTableEntries[] =
00156 { A2D_DECLARE_EVENT_TABLE_ENTRY(wxEVT_NULL, 0, 0, (a2dObjectEventFunction)NULL, NULL) };
00157
00158
00159
00160
00161
00162
00163 a2dEvtHandler::a2dEvtHandler()
00164 {
00165 m_enabled = true;
00166 }
00167
00168 a2dEvtHandler::a2dEvtHandler( const a2dEvtHandler& other, CloneOptions options )
00169 :a2dPropObject( other, options )
00170 {
00171 m_enabled = true;
00172 }
00173
00174 a2dEvtHandler::~a2dEvtHandler()
00175 {
00176 }
00177
00178 a2dObject* a2dEvtHandler::Clone( CloneOptions options ) const
00179 {
00180 return new a2dEvtHandler( *this, options );
00181 }
00182
00183 a2dEvtHandler* a2dEvtHandler::GetEventHandler() const
00184 {
00185 return const_cast<a2dEvtHandler*> ( this );
00186 }
00187
00188
00189
00190
00191
00192 bool a2dEvtHandler::ProcessEvent(wxEvent& event)
00193 {
00194
00195 if ( GetEvtHandlerEnabled() )
00196 {
00197
00198 if ( HasDynamicProperties() )
00199 if ( SearchDynamicEventProperties( event ) )
00200 return true;
00201
00202
00203 const a2dEventTable *table = GetEventTable();
00204
00205
00206 while (table)
00207 {
00208 if ( SearchEventTable((a2dEventTable&)*table, event) )
00209 return true;
00210 table = table->baseTable;
00211 }
00212
00213 if ( event.IsCommandEvent() && GetParentEvtHandler() )
00214 {
00215 return GetParentEvtHandler()->GetEventHandler()->ProcessEvent(event);
00216 }
00217
00218 }
00219 return false;
00220 }
00221
00222 bool a2dEvtHandler::SearchEventTable(a2dEventTable& table, wxEvent& event)
00223 {
00224 wxEventType eventType = event.GetEventType();
00225 int eventId = event.GetId();
00226
00227
00228 for ( int i = 0; table.entries[i].m_fn != 0; i++ )
00229 {
00230
00231
00232
00233 #ifdef __GNUG__
00234 a2dEventTableEntry entry = table.entries[i];
00235 #else
00236 const a2dEventTableEntry& entry = table.entries[i];
00237 #endif
00238
00239
00240
00241
00242
00243 if ( eventType == entry.m_eventType )
00244 {
00245 int tableId1 = entry.m_id,
00246 tableId2 = entry.m_lastId;
00247
00248 if ( (tableId1 == -1) ||
00249 (tableId2 == -1 && eventId == tableId1) ||
00250 (tableId2 != -1 &&
00251 (eventId >= tableId1 && eventId <= tableId2)) )
00252 {
00253 event.Skip(false);
00254 event.m_callbackUserData = entry.m_callbackUserData;
00255
00256 (this->*((a2dEvtHandlerEventFunction) (entry.m_fn)))(event);
00257
00258 return !event.GetSkipped();
00259 }
00260 }
00261 }
00262
00263 return false;
00264 }
00265
00266 bool a2dEvtHandler::SearchDynamicEventProperties( wxEvent& event )
00267 {
00268 wxEventType eventType = event.GetEventType();
00269 int eventId = event.GetId();
00270
00271
00272 a2dNamedPropertyList::iterator iter;
00273 for( iter = m_propertylist.begin(); iter != m_propertylist.end(); ++iter )
00274 {
00275 a2dDynamicEventProperty *prop = wxDynamicCast( (*iter).Get(), a2dDynamicEventProperty );
00276 if( prop && eventType == prop->m_eventType && prop->m_fn != 0 )
00277 {
00278 int tableId1 = prop->m_id,
00279 tableId2 = prop->m_lastId;
00280
00281 if ( (tableId1 == -1) ||
00282 (tableId2 == -1 && eventId == tableId1) ||
00283 (tableId2 != -1 &&
00284 (eventId >= tableId1 && eventId <= tableId2)) )
00285 {
00286 event.Skip(false);
00287 event.m_callbackUserData = prop;
00288 (this->*((a2dEvtHandlerEventFunction) (prop->m_fn)))(event);
00289
00290 return !event.GetSkipped();
00291 }
00292 }
00293 }
00294 return false;
00295 }
00296
00297 #if wxART2D_USE_CVGIO
00298 void a2dEvtHandler::DoSave( wxObject* parent, a2dIOHandlerXmlSerOut &out, a2dXmlSer_flag xmlparts , a2dObjectList* towrite )
00299 {
00300 a2dPropObject::DoSave( parent, out, xmlparts, towrite );
00301 }
00302
00303 void a2dEvtHandler::DoLoad( wxObject* parent, a2dIOHandlerXmlSerIn& parser, a2dXmlSer_flag xmlparts )
00304 {
00305 a2dPropObject::DoLoad( parent, parser, xmlparts );
00306 }
00307 #endif //wxART2D_USE_CVGIO
00308
00309 a2dCommandId::a2dCommandId( const wxString& commandName )
00310 {
00311 m_name = commandName;
00312
00313
00314 for( int indx = 1; GetHashMap().find( commandName ) != GetHashMap().end(); indx++ )
00315 {
00316 wxASSERT_MSG( 0, _("The command id name '") + commandName + _("' already exists") );
00317 }
00318
00319 GetHashMap()[commandName] = this;
00320 }
00321
00322 const a2dCommandId& a2dCommandId::GetCommandByName(const wxString& commandName)
00323 {
00324 a2dHashMapCommandIds::iterator iterCommand = GetHashMap().find(commandName);
00325 return iterCommand != GetHashMap().end() ? *iterCommand->second : a2dCommand::sm_noCommandId;
00326 }
00327
00328 a2dHashMapCommandIds &a2dCommandId::GetHashMap()
00329 {
00330 static a2dMemoryCriticalSectionHelper helper;
00331 static a2dHashMapCommandIds namehash;
00332 return namehash;
00333 }
00334
00335
00336
00337
00338
00339 const a2dCommandId a2dCommand::sm_noCommandId = a2dCommandId( wxT("NoCommandId") );
00340 const a2dCommandId a2dCommand::sm_noCommandTypeId = a2dCommandId( wxT("NoCommandTypeId") );
00341 const a2dCommandId a2dCommand::sm_groupCommandId = a2dCommandId( wxT("GroupCommandId") );
00342
00343 a2dCommand::a2dCommand( bool canUndo,
00344 const a2dCommandId& commandId,
00345 const a2dCommandId& commandTypeId,
00346 const wxString& menuString )
00347 : a2dPropObject()
00348 {
00349 m_cmp = 0;
00350 m_canUndo = canUndo;
00351 m_commandId = &commandId;
00352 m_commandTypeId = &commandTypeId;
00353 m_menuString = menuString;
00354 #if defined(_DEBUG) && defined (SMART_POINTER_DEBUG)
00355 extern wxObject * CurrentSmartPointerOwner;
00356 CurrentSmartPointerOwner = this;
00357 #endif
00358 }
00359
00360 a2dCommand::a2dCommand( const a2dCommand &other )
00361 : a2dPropObject( other, a2dPropObject::clone_deep )
00362 {
00363 m_commandId = other.m_commandId;
00364 m_commandTypeId = other.m_commandTypeId;
00365 m_menuString = other.m_menuString;
00366 m_canUndo = other.m_canUndo;
00367 m_cmp = other.m_cmp;
00368 }
00369
00370 a2dObject* a2dCommand::Clone( CloneOptions options ) const
00371 {
00372 a2dGeneralGlobals->ReportErrorF( a2dError_CommandError, _T("%s"), _("clone not implemented for this command") );
00373 return NULL;
00374 }
00375
00376 wxString a2dCommand::GetName() const
00377 {
00378 if ( m_menuString.IsEmpty() )
00379 return m_commandId->GetName();
00380 return m_menuString;
00381 }
00382
00383 a2dCommand::~a2dCommand()
00384 {
00385 }
00386
00387 a2dCommand *a2dCommand::CloneAndBind( a2dPropObject* WXUNUSED(object) )
00388 {
00389 wxASSERT_MSG( 0 , wxT("a2dCommand::CloneAndBind not overloaded in derived class") );
00390 return 0;
00391 }
00392
00393 bool a2dCommand::Redo()
00394 {
00395 return Do();
00396 }
00397
00398 bool a2dCommand::ClearAfterCurrentCommand( a2dCommand *current )
00399 {
00400 return current == this;
00401 }
00402
00403 a2dCommand *a2dCommand::FindPrevious( a2dCommand* WXUNUSED(current) ) const
00404 {
00405 return 0;
00406 }
00407
00408 a2dCommand *a2dCommand::FindNext( a2dCommand* WXUNUSED(current) ) const
00409 {
00410 return 0;
00411 }
00412
00413 bool a2dCommand::Remove( a2dCommand* WXUNUSED(command) )
00414 {
00415 return false;
00416 }
00417
00418 bool a2dCommand::ContainsCommand( a2dCommand *command )
00419 {
00420 return command == this;
00421 }
00422
00423 void a2dCommand::DistributeEvent( wxEventType eventType )
00424 {
00425 if ( eventType == wxEVT_DO )
00426 {
00427 a2dCommandProcessorEvent event( wxEVT_DO, this );
00428 event.SetEventObject(this);
00429 a2dGeneralGlobals->GetEventDistributer()->ProcessEvent( event );
00430 }
00431 else if ( eventType == wxEVT_UNDO )
00432 {
00433 a2dCommandProcessorEvent event( wxEVT_UNDO, this );
00434 event.SetEventObject(this);
00435 a2dGeneralGlobals->GetEventDistributer()->ProcessEvent( event );
00436 }
00437 else if ( eventType == wxEVT_REDO )
00438 {
00439 a2dCommandProcessorEvent event( wxEVT_REDO, this );
00440 event.SetEventObject(this);
00441 a2dGeneralGlobals->GetEventDistributer()->ProcessEvent( event );
00442 }
00443 }
00444
00445
00446
00447
00448
00449 a2dCommandGroup::a2dCommandGroup( const wxString &name, a2dCommandGroup* parent )
00450 : a2dCommand( true, a2dCommand::sm_groupCommandId )
00451 {
00452
00453 wxString idName;
00454 idName.Printf( wxT("%s_%ld"), name.c_str(), wxGenNewId() );
00455
00456 m_commandId = new a2dCommandId( idName );
00457
00458 m_groupName = name;
00459 m_parentGroup = parent;
00460 m_active = true;
00461 }
00462
00463 a2dCommandGroup::~a2dCommandGroup(void)
00464 {
00465 m_subcommands.clear();
00466 delete m_commandId;
00467 }
00468
00469 a2dObject* a2dCommandGroup::Clone( CloneOptions options ) const
00470 {
00471 a2dCommandGroup* clgr = new a2dCommandGroup( m_groupName, m_parentGroup );
00472
00473 a2dCommandList::const_iterator iter = m_subcommands.begin();
00474 while( iter != m_subcommands.end() )
00475 {
00476 a2dCommand* obj = *iter;
00477 a2dCommand* clone = (a2dCommand*) obj->Clone( options );
00478 clgr->m_subcommands.push_back( clone );
00479 iter++;
00480 }
00481 return clgr;
00482 }
00483
00484 bool a2dCommandGroup::ClearAfterCurrentCommand( a2dCommand *current )
00485 {
00486 if( current == this )
00487 return true;
00488
00489 int i = 0;
00490 a2dCommandList::reverse_iterator iter = m_subcommands.rbegin();
00491 while( iter != m_subcommands.rend() )
00492 {
00493 a2dCommand *obj = *iter;
00494 if( obj->ClearAfterCurrentCommand( current ) )
00495 {
00496
00497 a2dCommandList::reverse_iterator iterr = m_subcommands.rbegin();
00498 while( i > 0 && iterr != m_subcommands.rend() )
00499 {
00500 m_subcommands.rerase( iterr ) ;
00501 i--;
00502 }
00503 return true;
00504 }
00505 iter++;
00506 i++;
00507 }
00508 return false;
00509 }
00510
00511 bool a2dCommandGroup::ClearCommandsById( const a2dCommandId& commandId, a2dCommand *fromcommand )
00512 {
00513 bool start = false;
00514 bool found = false;
00515 a2dCommandList::iterator iter = m_subcommands.begin();
00516 while( iter != m_subcommands.end() )
00517 {
00518 a2dCommand *command = *iter;
00519 if( ( fromcommand == NULL || fromcommand == command || start ) )
00520 {
00521 start = true;
00522 if ( command->GetCommandId() == &commandId )
00523 {
00524 iter = m_subcommands.erase( iter );
00525 found = true;
00526 }
00527 else
00528 iter++;
00529 }
00530 else
00531 iter++;
00532 }
00533 return found;
00534 }
00535
00536 a2dCommand *a2dCommandGroup::FindPrevious( a2dCommand *current ) const
00537 {
00538
00539 a2dCommandList::const_reverse_iterator iter = m_subcommands.rbegin();
00540 while( iter != m_subcommands.rend() )
00541 {
00542 a2dCommand *obj = *iter;
00543
00544 if( obj->ContainsCommand( current ) )
00545 {
00546
00547 a2dCommand *previous = obj->FindPrevious( current );
00548
00549
00550 if( previous )
00551 return previous;
00552
00553
00554 iter++;
00555 if( iter != m_subcommands.rend() )
00556 return *iter;
00557
00558 return 0;
00559 }
00560 iter++;
00561 }
00562
00563 return 0;
00564 }
00565
00566 a2dCommand *a2dCommandGroup::FindNext( a2dCommand *current ) const
00567 {
00568 a2dCommandList::const_reverse_iterator iter = m_subcommands.rbegin();
00569 while( iter != m_subcommands.rend() )
00570 {
00571 a2dCommand *obj = *iter;
00572
00573 if( obj->ContainsCommand( current ) )
00574 {
00575
00576 a2dCommand *next = obj->FindNext( current );
00577
00578
00579 if( next )
00580 return next;
00581
00582
00583 if( iter != m_subcommands.rbegin() )
00584 iter--;
00585 else
00586 return 0;
00587
00588 if( iter != m_subcommands.rend() )
00589 return *iter;
00590
00591 return 0;
00592 }
00593 iter++;
00594 }
00595
00596 return 0;
00597 }
00598
00599 bool a2dCommandGroup::Remove( a2dCommand *command )
00600 {
00601 a2dCommandList::reverse_iterator iter = m_subcommands.rbegin();
00602 while( iter != m_subcommands.rend() )
00603 {
00604 a2dCommand *obj = *iter;
00605 if ( command == obj )
00606 {
00607 iter = m_subcommands.rerase( iter );
00608 return true;
00609 }
00610
00611 if ( obj->Remove( command ) )
00612 {
00613 return true;
00614 }
00615 iter++;
00616 }
00617 return false;
00618 }
00619
00620 void a2dCommandGroup::Add( a2dCommand *command )
00621 {
00622 m_subcommands.push_back( command );
00623 }
00624
00625 bool a2dCommandGroup::ContainsCommand( a2dCommand *command )
00626 {
00627 if( command==this )
00628 return true;
00629
00630 a2dCommandList::reverse_iterator iter = m_subcommands.rbegin();
00631 while( iter != m_subcommands.rend() )
00632 {
00633 a2dCommand *obj = *iter;
00634 if ( obj->ContainsCommand( command ) )
00635 return true;
00636 iter++;
00637 }
00638 return false;
00639 }
00640
00641 bool a2dCommandGroup::Do()
00642 {
00643 m_active = true;
00644
00645 a2dCommandList::iterator iter = m_subcommands.begin();
00646 while( iter != m_subcommands.end() )
00647 {
00648 a2dCommand *obj = *iter;
00649 obj->SetCommandProcessor( m_cmp );
00650 if ( !obj->Do() )
00651 return false;
00652 iter++;
00653 }
00654 m_cmp->CommandGroupEnd( this );
00655 return true;
00656 }
00657
00658 bool a2dCommandGroup::Undo()
00659 {
00660
00661 a2dCommandList::reverse_iterator iter = m_subcommands.rbegin();
00662 while( iter != m_subcommands.rend() )
00663 {
00664 a2dCommand *obj = *iter;
00665 if ( !obj->Undo() )
00666 return false;
00667 iter++;
00668 }
00669 return true;
00670 }
00671
00672
00673
00674
00675
00676 DEFINE_EVENT_TYPE( wxEVT_PROPOBJECT_EDITPROPERTIES_EVENT )
00677
00678 a2dPropertyEditEvent::a2dPropertyEditEvent( a2dPropObject* object, a2dNamedPropertyList* properties )
00679 : a2dEvent( wxID_ANY, a2dEVT_PROPOBJECT_EDITPROPERTIES_EVENT )
00680 {
00681 SetEventObject( object );
00682 m_properties = properties;
00683 m_edited = false;
00684 }
00685
00686 a2dPropertyEditEvent::a2dPropertyEditEvent( const a2dPropertyEditEvent& other )
00687 : a2dEvent( other )
00688 {
00689 m_properties = other.m_properties;
00690 m_edited = other.m_edited;
00691 }
00692
00693
00694
00695
00696
00697 const a2dCommandId a2dCommand_SetProperty::Id = a2dCommandId( wxT("SetProperty") );
00698
00699 a2dCommand_SetProperty::a2dCommand_SetProperty():
00700 a2dCommand( true, Id )
00701 {
00702 m_propRefObject = NULL;
00703 }
00704
00705 a2dCommand_SetProperty::a2dCommand_SetProperty( a2dPropObject* object, const a2dPropertyId* id ):
00706 a2dCommand( true, Id )
00707 {
00708 m_propRefObject = object;
00709 m_id = id;
00710 }
00711
00712 a2dCommand_SetProperty::a2dCommand_SetProperty( a2dPropObject* object, a2dNamedProperty* property ):
00713 a2dCommand( true, Id )
00714 {
00715 m_property = property;
00716 m_propRefObject = object;
00717 m_id = property->GetId();
00718 }
00719
00720 a2dCommand_SetProperty::a2dCommand_SetProperty( a2dPropObject* object, const a2dPropertyIdRefObject* id, a2dObject* value ):
00721 a2dCommand( true, Id, sm_noCommandTypeId, id->GetName() )
00722 {
00723 a2dProperty* prop = new a2dProperty( id, value );
00724
00725 m_property = prop;
00726 m_propRefObject = object;
00727 m_id = id;
00728 }
00729
00730 a2dCommand_SetProperty::a2dCommand_SetProperty( a2dPropObject* object, const a2dPropertyIdObject* id, const wxObject& value ):
00731 a2dCommand( true, Id, sm_noCommandTypeId, id->GetName() )
00732 {
00733 a2dObjectProperty* prop = new a2dObjectProperty( id, value );
00734
00735 m_property = prop;
00736 m_propRefObject = object;
00737 m_id = id;
00738 }
00739
00740 a2dCommand_SetProperty::a2dCommand_SetProperty( a2dPropObject* object, const a2dPropertyIdString* id, const wxString& value ):
00741 a2dCommand( true, Id, sm_noCommandTypeId, id->GetName() )
00742 {
00743 a2dStringProperty* prop = new a2dStringProperty( id, value );
00744
00745 m_property = prop;
00746 m_propRefObject = object;
00747 m_id = id;
00748 }
00749
00750 a2dCommand_SetProperty::a2dCommand_SetProperty( a2dPropObject* object, const a2dPropertyIdBool* id, bool value ):
00751 a2dCommand( true, Id, sm_noCommandTypeId, id->GetName() )
00752 {
00753 a2dBoolProperty* prop = new a2dBoolProperty( id, value );
00754
00755 m_property = prop;
00756 m_propRefObject = object;
00757 m_id = id;
00758 }
00759
00760 a2dCommand_SetProperty::a2dCommand_SetProperty( a2dPropObject* object, const a2dPropertyIdBool* id, const wxString& value ):
00761 a2dCommand( true, Id, sm_noCommandTypeId, id->GetName() )
00762 {
00763 a2dNamedProperty *prop = id->CreatePropertyFromString( value );
00764
00765 m_property = prop;
00766 m_propRefObject = object;
00767 m_id = id;
00768 }
00769
00770 a2dCommand_SetProperty::a2dCommand_SetProperty( a2dPropObject* object, const a2dPropertyIdInt16* id, wxInt16 value ):
00771 a2dCommand( true, Id, sm_noCommandTypeId, id->GetName() )
00772 {
00773 a2dInt16Property* prop = new a2dInt16Property( id, value );
00774
00775 m_property = prop;
00776 m_propRefObject = object;
00777 m_id = id;
00778 }
00779
00780 a2dCommand_SetProperty::a2dCommand_SetProperty( a2dPropObject* object, const a2dPropertyIdUint16* id, wxUint16 value ):
00781 a2dCommand( true, Id, sm_noCommandTypeId, id->GetName() )
00782 {
00783 a2dUint16Property* prop = new a2dUint16Property( id, value );
00784
00785 m_property = prop;
00786 m_propRefObject = object;
00787 m_id = id;
00788 }
00789
00790 a2dCommand_SetProperty::a2dCommand_SetProperty( a2dPropObject* object, const a2dPropertyIdInt32* id, wxInt32 value ):
00791 a2dCommand( true, Id, sm_noCommandTypeId, id->GetName() )
00792 {
00793 a2dInt32Property* prop = new a2dInt32Property( id, value );
00794
00795 m_property = prop;
00796 m_propRefObject = object;
00797 m_id = id;
00798 }
00799
00800 a2dCommand_SetProperty::a2dCommand_SetProperty( a2dPropObject* object, const a2dPropertyIdUint32* id, wxUint32 value ):
00801 a2dCommand( true, Id, sm_noCommandTypeId, id->GetName() )
00802 {
00803 a2dUint32Property* prop = new a2dUint32Property( id, value );
00804
00805 m_property = prop;
00806 m_propRefObject = object;
00807 m_id = id;
00808 }
00809
00810 a2dCommand_SetProperty::a2dCommand_SetProperty( a2dPropObject* object, const a2dPropertyIdDouble* id, double value ):
00811 a2dCommand( true, Id, sm_noCommandTypeId, id->GetName() )
00812 {
00813 a2dDoubleProperty* prop = new a2dDoubleProperty( id, value );
00814
00815 m_property = prop;
00816 m_propRefObject = object;
00817 m_id = id;
00818 }
00819
00820 a2dCommand_SetProperty::a2dCommand_SetProperty( a2dPropObject* object, const a2dPropertyIdColour* id, const wxColour& colour ):
00821 a2dCommand( true, Id, sm_noCommandTypeId, id->GetName() )
00822 {
00823 a2dColourProperty* prop = new a2dColourProperty( id, colour );
00824
00825 m_property = prop;
00826 m_propRefObject = object;
00827 m_id = id;
00828 }
00829
00830
00831 a2dCommand_SetProperty::~a2dCommand_SetProperty(void)
00832 {
00833 m_propRefObject = NULL;
00834 }
00835
00836 a2dCommand_SetProperty::a2dCommand_SetProperty( const a2dCommand_SetProperty &other )
00837 : a2dCommand ( other )
00838 {
00839 m_propRefObject = other.m_propRefObject;
00840 m_property = other.m_property->Clone(a2dObject::clone_flat);
00841 m_id = other.m_id;
00842 }
00843
00844 bool a2dCommand_SetProperty::Do(void)
00845 {
00846 if ( m_propRefObject )
00847 {
00848 a2dNamedPropertyPtr propertyold = m_propRefObject->GetProperty( m_id );
00849 m_propRefObject->SetProperty( m_property );
00850 m_property = propertyold;
00851 }
00852
00853 return true;
00854 }
00855
00856 bool a2dCommand_SetProperty::Undo(void)
00857 {
00858 if ( m_propRefObject )
00859 {
00860 a2dNamedPropertyPtr propertyold = m_propRefObject->GetProperty( m_id );
00861
00862 if ( !m_property )
00863 {
00864
00865 m_propRefObject->RemoveProperty( m_id, true );
00866 }
00867 else
00868 {
00869 m_propRefObject->SetProperty( m_property );
00870 }
00871
00872 m_property = propertyold;
00873 }
00874
00875 return true;
00876 }
00877
00878
00879
00880
00881
00882 const a2dCommandId a2dCommand_SetVariable::Id( wxT("SetVariable") );
00883 const a2dCommandId a2dCommand_SetEnvironmentVariable::Id( wxT("SetEnv") );
00884 const a2dCommandId a2dCommand_GetVariable::Id( wxT("GetVariable") );
00885
00886 a2dCommandProcessor::a2dCommandProcessor(int maxCommands)
00887 {
00888 m_rootGroup = new a2dCommandGroup( _("Root"), NULL );
00889 m_currentGroup = m_rootGroup;
00890 m_maxNoCommands = maxCommands;
00891 m_currentCommand = NULL;
00892 m_undoAccelerator = wxT("\tCtrl+Z");
00893 m_redoAccelerator = wxT("\tCtrl+Y");
00894 }
00895
00896 a2dCommandProcessor::~a2dCommandProcessor()
00897 {
00898 ClearCommands();
00899 }
00900
00901 bool a2dCommandProcessor::SmrtPtrRelease()
00902 {
00903 static bool clearingCommands = false;
00904 if ( !clearingCommands )
00905 {
00906
00907 clearingCommands = true;
00908 ClearCommands();
00909 clearingCommands = false;
00910 }
00911
00912 m_refcount--;
00913 wxASSERT_MSG( m_refcount >= 0, wxT("a2dCommandProcessor Own/Release not matched (extra Release calls)") );
00914 if ( m_refcount <= 0 )
00915 {
00916 delete this;
00917 return true;
00918 }
00919 return false;
00920 }
00921
00922 a2dCommandGroup *a2dCommandProcessor::FindActiveGroup()
00923 {
00924 a2dCommandGroup *group = m_currentGroup;
00925
00926 for(;;)
00927 {
00928 if( group->m_subcommands.empty() )
00929 break;
00930
00931 a2dCommandGroup *next = group->m_subcommands.back()->IsCommandGroup();
00932 if( !next || !next->m_active )
00933 break;
00934
00935 group = next;
00936 }
00937
00938 return group;
00939 }
00940
00941 void a2dCommandProcessor::SetCurrentToLastActive()
00942 {
00943 a2dCommandGroup *group = m_currentGroup;
00944
00945 for(;;)
00946 {
00947 if( group->m_subcommands.empty() )
00948 break;
00949
00950 a2dCommandGroup *next = group->m_subcommands.back()->IsCommandGroup();
00951 if( !next || !next->m_active || next->m_subcommands.empty() )
00952 break;
00953
00954 group = next;
00955 }
00956
00957 m_currentCommand = ( group->m_subcommands.empty() ) ? 0 : group->m_subcommands.back();
00958 }
00959
00960 bool a2dCommandProcessor::DoCommand(a2dCommand& cmd)
00961 {
00962 #if defined(A2D_COMMAND_DEBUG)
00963 wxLogDebug( wxT( "Do name = %s 0x%p" ), cmd.GetName().c_str(), &cmd );
00964 #endif
00965 bool ret = cmd.Do();
00966
00967 if ( ret )
00968 cmd.DistributeEvent( wxEVT_DO );
00969 return ret;
00970 }
00971
00972 bool a2dCommandProcessor::UndoCommand(a2dCommand& cmd)
00973 {
00974 #if defined(A2D_COMMAND_DEBUG)
00975 wxLogDebug( wxT( "UnDo name = %s 0x%p" ), cmd.GetName().c_str(), &cmd );
00976 #endif
00977 bool ret = cmd.Undo();
00978
00979 if ( ret )
00980 cmd.DistributeEvent( wxEVT_UNDO );
00981 return ret;
00982 }
00983
00984 bool a2dCommandProcessor::RedoCommand(a2dCommand& cmd)
00985 {
00986 #if defined(A2D_COMMAND_DEBUG)
00987 wxLogDebug( wxT( "ReDo name = %s 0x%p" ), cmd.GetName().c_str(), &cmd );
00988 #endif
00989 bool ret = cmd.Redo();
00990
00991 if ( ret )
00992 cmd.DistributeEvent( wxEVT_REDO );
00993 return ret;
00994 }
00995
00996 void a2dCommandProcessor::SentBusyEvent( bool start, a2dCommand *command )
00997 {
00998 if ( start )
00999 {
01000 a2dCommandProcessorEvent event( wxEVT_BEGINBUSY, command );
01001 event.SetEventObject(this);
01002 this->ProcessEvent( event );
01003 }
01004 else
01005 {
01006 a2dCommandProcessorEvent event( wxEVT_ENDBUSY, command );
01007 event.SetEventObject(this);
01008 this->ProcessEvent( event );
01009 }
01010 }
01011
01012
01013
01014
01015 bool a2dCommandProcessor::Submit(a2dCommand *command, bool storeIt)
01016 {
01017 wxCHECK_MSG( command, false, _T("no command in a2dCommandProcessor::Submit") );
01018
01019 SentBusyEvent( true, command );
01020
01021
01022 a2dSmrtPtr<a2dCommand> lcommand = command;
01023
01024 command->SetCommandProcessor( this );
01025 if ( command->IsCommandGroup() )
01026 {
01027 wxStaticCast( command, a2dCommandGroup )->m_parentGroup = m_currentGroup;
01028 }
01029
01030
01031 if ( storeIt )
01032 Store(command);
01033
01034 bool oke = false;
01035 try
01036 {
01037 oke = DoCommand(*command);
01038 }
01039 catch (const a2dCommandException& e)
01040 {
01041 a2dGeneralGlobals->ReportErrorF( a2dError_CommandError, _T("%s"), e.getMessage().c_str() );
01042 oke = false;
01043 }
01044
01045
01046 if ( !oke )
01047 {
01048 if ( storeIt )
01049 {
01050 m_currentGroup->Remove( command );
01051 SetCurrentToLastActive();
01052 }
01053
01054 SentBusyEvent( false, command );
01055
01056 return false;
01057 }
01058
01059 SentBusyEvent( false, command );
01060 return true;
01061 }
01062
01063 void a2dCommandProcessor::Store(a2dCommand *command)
01064 {
01065 wxCHECK_RET( command, _T("no command in a2dCommandProcessor::Store") );
01066
01067
01068 if (m_currentGroup->m_subcommands.size() == m_maxNoCommands)
01069 m_currentGroup->m_subcommands.pop_front();
01070
01071
01072
01073
01074
01075 if( !m_currentCommand )
01076 ClearCommands();
01077 else
01078 m_currentGroup->ClearAfterCurrentCommand( m_currentCommand );
01079
01080 m_currentCommand = command;
01081 m_currentGroup->m_subcommands.push_back( command );
01082
01083 SetMenuStrings();
01084 }
01085
01086 bool a2dCommandProcessor::Undo()
01087 {
01088 if ( m_currentCommand && m_currentCommand->CanUndo() )
01089 {
01090 if ( UndoCommand(*m_currentCommand) )
01091 {
01092 m_currentCommand = m_currentGroup->FindPrevious( m_currentCommand );
01093 SetMenuStrings();
01094 return true;
01095 }
01096 }
01097
01098 return false;
01099 }
01100
01101 bool a2dCommandProcessor::Redo()
01102 {
01103 a2dCommand *redoCommand = (a2dCommand *) NULL;
01104
01105 if ( m_currentCommand )
01106 {
01107
01108 a2dCommand *next = m_currentGroup->FindNext( m_currentCommand );
01109 if ( next )
01110 {
01111 redoCommand = next;
01112 }
01113 }
01114 else
01115 {
01116
01117
01118 if ( !m_currentGroup->m_subcommands.empty() )
01119 redoCommand = m_currentGroup->m_subcommands.front();
01120 }
01121
01122 if (redoCommand)
01123 {
01124 bool success = RedoCommand(*redoCommand);
01125 if (success)
01126 {
01127 m_currentCommand = redoCommand;
01128 SetMenuStrings();
01129 return true;
01130 }
01131 }
01132 return false;
01133 }
01134
01135 bool a2dCommandProcessor::CanUndo() const
01136 {
01137 a2dCommand *command = GetCurrentCommand();
01138
01139 return command && command->CanUndo();
01140 }
01141
01142 bool a2dCommandProcessor::CanRedo() const
01143 {
01144 if( m_currentCommand )
01145 {
01146 a2dCommand *next = m_currentGroup->FindNext( m_currentCommand );
01147 return next != 0;
01148 }
01149 else
01150 {
01151 return m_currentGroup->m_subcommands.size() != 0;
01152 }
01153 }
01154
01155 void a2dCommandProcessor::Initialize()
01156 {
01157 SetCurrentToLastActive();
01158 SetMenuStrings();
01159 }
01160
01161 void a2dCommandProcessor::SetMenuStrings()
01162 {
01163
01164 a2dCommandProcessorEvent event(
01165 m_currentCommand,
01166 GetUndoMenuLabel(),
01167 CanUndo(),
01168 GetRedoMenuLabel(),
01169 CanRedo()
01170 );
01171 event.SetEventObject(this);
01172 a2dGeneralGlobals->GetEventDistributer()->ProcessEvent( event );
01173 }
01174
01175
01176 wxString a2dCommandProcessor::GetUndoMenuLabel() const
01177 {
01178 wxString buf;
01179 if (m_currentCommand)
01180 {
01181 wxString commandName(m_currentCommand->GetName());
01182 if (commandName == wxT("")) commandName = _("Unnamed command");
01183 bool canUndo = m_currentCommand->CanUndo();
01184 if (canUndo)
01185 buf = wxString(_("&Undo ")) + commandName + m_undoAccelerator;
01186 else
01187 buf = wxString(_("Can't &Undo ")) + commandName + m_undoAccelerator;
01188 }
01189 else
01190 {
01191 buf = _("&Undo") + m_undoAccelerator;
01192 }
01193
01194 return buf;
01195 }
01196
01197
01198 wxString a2dCommandProcessor::GetRedoMenuLabel() const
01199 {
01200 a2dCommand *redoCommand;
01201 wxString buf;
01202
01203 if (m_currentCommand)
01204 {
01205
01206 redoCommand = m_currentGroup->FindNext( m_currentCommand );
01207 }
01208 else
01209 {
01210 redoCommand = m_currentGroup->m_subcommands.empty() ? 0 : m_currentGroup->m_subcommands.front();
01211 }
01212 if ( redoCommand )
01213 {
01214 wxString redoCommandName(redoCommand->GetName());
01215 if (redoCommandName == wxT("")) redoCommandName = _("Unnamed command");
01216 buf = wxString(_("&Redo ")) + redoCommandName + m_redoAccelerator;
01217 }
01218 else
01219 {
01220 buf = _("&Redo") + m_redoAccelerator;
01221 }
01222 return buf;
01223 }
01224
01225 void a2dCommandProcessor::ClearCommands()
01226 {
01227 m_rootGroup->m_subcommands.clear();
01228
01229 m_currentCommand = 0;
01230 }
01231
01232 bool a2dCommandProcessor::SetOrAddPropertyToObject( a2dPropObject* propRefObject, const wxString& name, const wxString& value, bool withUndo )
01233 {
01234 wxASSERT_MSG( propRefObject != 0 , wxT("a2dPropObject not NULL") );
01235
01236
01237 a2dPropertyId *id = propRefObject->HasPropertyId( name );
01238 if( !id )
01239 return false;
01240
01241 a2dNamedProperty *prop = id->CreatePropertyFromString( value );
01242
01243 if( !prop )
01244 return false;
01245
01246 return Submit( new a2dCommand_SetProperty( propRefObject, prop ), withUndo );
01247 }
01248
01249 bool a2dCommandProcessor::SetOrAddPropertyToObject( a2dPropObject* propRefObject, a2dNamedProperty *property, bool withUndo )
01250 {
01251 wxASSERT_MSG( propRefObject != 0, wxT("a2dPropObject not NULL") );
01252
01253 return Submit( new a2dCommand_SetProperty( propRefObject, property ), withUndo );
01254 }
01255
01256 a2dCommandGroup *a2dCommandProcessor::CommandGroupBegin( const wxString &name )
01257 {
01258 a2dCommandGroup *group = new a2dCommandGroup( name, m_currentGroup );
01259 #if defined(A2D_COMMAND_DEBUG)
01260 wxLogDebug( wxT( "Open Group = %s 0x%p" ), name.c_str(), group );
01261 #endif
01262 group->SetCommandProcessor( this );
01263
01264 Store( group );
01265
01266 m_currentGroup = group;
01267 return group;
01268 }
01269
01270 void a2dCommandProcessor::CommandGroupEnd( a2dCommandGroup *group )
01271 {
01272 m_currentGroup = group->m_parentGroup;
01273 group->m_active = false;
01274 a2dCommandGroup* activeGroup = FindActiveGroup();
01275 #if defined(A2D_COMMAND_DEBUG)
01276 wxLogDebug( wxT( "End Group = %s 0x%p" ), group->GetGroupName().c_str(), group );
01277 #endif
01278 wxASSERT( activeGroup == m_currentGroup );
01279
01280 wxASSERT( m_currentGroup->m_active );
01281 SetCurrentToLastActive();
01282 SetMenuStrings();
01283 }
01284
01285
01286
01287
01288
01289 a2dEventDistributer::a2dEventDistributer()
01290 {
01291
01292 }
01293
01294 a2dEventDistributer::~a2dEventDistributer()
01295 {
01296 m_handlers.clear();
01297 }
01298
01299 bool a2dEventDistributer::ProcessEvent( wxEvent& event)
01300 {
01301 bool retCode = false;
01302 wxEventHandlersList::iterator iter;
01303 for( iter = m_handlers.begin(); iter != m_handlers.end(); ++iter )
01304 {
01305 a2dDistributedEventReceiver *wrappedhandler = *iter;
01306 if ( wrappedhandler->m_valid &&
01307 event.GetEventObject() != wrappedhandler->m_handler &&
01308 wrappedhandler->WantsType( event.GetEventType() )
01309 )
01310 {
01311 if ( wrappedhandler->m_type == a2dDistributedEventReceiver::a2dReceiverwxEvtHandler )
01312 retCode |= ((wxEvtHandler*)wrappedhandler->m_handler)->ProcessEvent( event );
01313 else if ( wrappedhandler->m_type == a2dDistributedEventReceiver::a2dReceivera2dObject )
01314
01315
01316 retCode |= ((a2dObject*)wrappedhandler->m_handler)->ProcessEvent( event );
01317 }
01318
01319
01320
01321 event.Skip( false );
01322 }
01323 event.Skip( true );
01324
01325
01326
01327
01328
01329
01330 iter = m_handlers.begin();
01331 while ( iter != m_handlers.end() )
01332 {
01333 a2dDistributedEventReceiver *wrappedhandler = *iter;
01334
01335 if ( ! wrappedhandler->m_valid )
01336 iter = m_handlers.erase( iter );
01337 else
01338 iter++;
01339 }
01340
01341 return retCode;
01342 }
01343
01344 a2dDistributedEventReceiver* a2dEventDistributer::Register( wxEvtHandler* handler )
01345 {
01346 bool found = false;
01347
01348 wxEventHandlersList::iterator iter = m_handlers.begin();
01349 while ( iter != m_handlers.end() && !found)
01350 {
01351 a2dDistributedEventReceiver *wrappedhandler = *iter;
01352
01353 if ( wrappedhandler->m_valid && wrappedhandler->m_handler == handler )
01354 {
01355 found = true;
01356 break;
01357 }
01358 iter++;
01359 }
01360
01361 if ( !found )
01362 {
01363 m_handlers.push_back( new a2dDistributedEventReceiver( handler ) );
01364 return m_handlers.back();
01365 }
01366 else
01367 return *iter;
01368 }
01369
01370 bool a2dEventDistributer::Unregister( wxEvtHandler* handler )
01371 {
01372 bool found = false;
01373
01374 forEachIn( wxEventHandlersList, &m_handlers )
01375 {
01376 a2dDistributedEventReceiver *wrappedhandler = *iter;
01377 if ( wrappedhandler->m_valid && wrappedhandler->m_handler == handler )
01378 {
01379 found = true;
01380 wrappedhandler->m_valid = false;
01381 }
01382 }
01383
01384 return found;
01385 }
01386
01387 a2dDistributedEventReceiver* a2dEventDistributer::Register( a2dObject* handler )
01388 {
01389 bool found = false;
01390
01391 wxEventHandlersList::iterator iter = m_handlers.begin();
01392 while ( iter != m_handlers.end() && !found)
01393 {
01394 a2dDistributedEventReceiver *wrappedhandler = *iter;
01395
01396 if ( wrappedhandler->m_valid && (wxObject*)wrappedhandler->m_handler == (wxObject*)handler )
01397 {
01398 found = true;
01399 break;
01400 }
01401 iter++;
01402 }
01403
01404 if ( !found )
01405 {
01406 m_handlers.push_back( new a2dDistributedEventReceiver( handler ) );
01407 return m_handlers.back();
01408 }
01409 else
01410 return *iter;
01411 }
01412
01413 bool a2dEventDistributer::Unregister( a2dObject* handler )
01414 {
01415 bool found = false;
01416
01417 wxEventHandlersList::iterator iter = m_handlers.begin();
01418 while ( iter != m_handlers.end() && !found)
01419 {
01420 a2dDistributedEventReceiver *wrappedhandler = *iter;
01421
01422 if ( wrappedhandler->m_valid && (wxObject*)wrappedhandler->m_handler == (wxObject*)handler )
01423 {
01424 found = true;
01425 wrappedhandler->m_valid = false;
01426 }
01427 iter++;
01428 }
01429
01430 return found;
01431 }
01432
01433
01434
01435
01436 IMPLEMENT_DYNAMIC_CLASS(a2dGeneralModule, wxModule)
01437
01438
01439 A2DGENERALDLLEXP a2dSmrtPtr<a2dGeneralGlobal> a2dGeneralGlobals = new a2dGeneralGlobal();
01440
01441
01442
01443 bool a2dGeneralModule::OnInit()
01444 {
01445 a2dGeneralGlobals = new a2dGeneralGlobal();
01446 return true;
01447 }
01448
01449 void a2dGeneralModule::OnExit()
01450 {
01451 a2dGeneralGlobals = NULL;
01452 }
01453
01454
01455
01456
01457
01458 a2dPathList a2dGeneralGlobal::m_configpath = a2dPathList();
01459 bool a2dGeneralGlobal::m_showlog = true;
01460 a2dErrorVector a2dGeneralGlobal::m_errors = a2dErrorVector();
01461 a2dEventDistributer* a2dGeneralGlobal::m_docviewEventDistributer = new a2dEventDistributer();
01462 wxArrayInt a2dGeneralGlobal::m_ignoredErrorIds = wxArrayInt();
01463 a2dVariablesHash a2dGeneralGlobal::m_variableList = a2dVariablesHash();
01464 a2dPropertyIdList a2dGeneralGlobal::m_dynamicIdList = a2dPropertyIdList();
01465
01466 IMPLEMENT_DYNAMIC_CLASS(a2dGeneralGlobal, a2dObject)
01467
01468 a2dGeneralGlobal::a2dGeneralGlobal()
01469 {
01470 m_showlog = true;
01471 }
01472
01473 a2dGeneralGlobal::~a2dGeneralGlobal()
01474 {
01475 m_errors.clear();
01476
01477
01478 if ( a2dGeneralGlobals == (a2dGeneralGlobal*)NULL )
01479 {
01480 if ( m_docviewEventDistributer )
01481 delete m_docviewEventDistributer;
01482 m_docviewEventDistributer = NULL;
01483 }
01484 m_dynamicIdList.DeleteObjects();
01485 }
01486
01487 a2dObject* a2dGeneralGlobal::Clone( CloneOptions WXUNUSED(options) ) const
01488 {
01489 wxLogMessage( _("Not implemented") );
01490 return NULL;
01491 }
01492
01493 #if wxART2D_USE_CVGIO
01494 void a2dGeneralGlobal::DoSave( wxObject* WXUNUSED(parent), a2dIOHandlerXmlSerOut &WXUNUSED(out), a2dXmlSer_flag WXUNUSED(xmlparts), a2dObjectList* WXUNUSED(towrite) )
01495 {
01496 wxLogMessage( _("Not implemented") );
01497 }
01498
01499 void a2dGeneralGlobal::DoLoad( wxObject* WXUNUSED(parent), a2dIOHandlerXmlSerIn& WXUNUSED(parser), a2dXmlSer_flag WXUNUSED(xmlparts) )
01500 {
01501 wxLogMessage( _("Not implemented") );
01502 }
01503
01504 #endif //wxART2D_USE_CVGIO
01505
01506 void a2dGeneralGlobal::SetEventDistributer( a2dEventDistributer* docviewEventDistributer )
01507 {
01508 if ( m_docviewEventDistributer )
01509 delete m_docviewEventDistributer;
01510 m_docviewEventDistributer = docviewEventDistributer;
01511 }
01512
01513 void a2dGeneralGlobal::ResetErrors()
01514 {
01515 m_errors.clear();
01516
01517
01518 }
01519
01520 void a2dGeneralGlobal::IgnoreError( unsigned int id )
01521 {
01522 if( m_ignoredErrorIds.Index( id ) == wxNOT_FOUND )
01523 {
01524 m_ignoredErrorIds.Add( id );
01525 }
01526 }
01527
01528 void a2dGeneralGlobal::ReportError( const a2dError& error, const wxString& errorstr )
01529 {
01530 if( m_ignoredErrorIds.Index( error.GetErrorCode() ) != wxNOT_FOUND )
01531 return;
01532
01533 a2dError errorc( error );
01534 if ( !errorstr.IsEmpty() )
01535 errorc.SetErrorMessage(errorstr);
01536
01537 m_errors.push_back( errorc );
01538
01539 if ( m_showlog )
01540 wxLogError( errorc.GetErrorMessage() );
01541 }
01542
01543
01544 #if wxCHECK_VERSION(2,9,0)
01545
01546 #if !wxUSE_UTF8_LOCALE_ONLY
01547 void a2dGeneralGlobal::DoPrintfWchar( const a2dError& error, const wxChar *format, ...)
01548 {
01549 va_list args;
01550 va_start(args, format);
01551 wxString out;
01552
01553 out.PrintfV(format, args);
01554 va_end(args);
01555
01556 ReportError( error, out );
01557 }
01558 #endif // !wxUSE_UTF8_LOCALE_ONLY
01559
01560 #if wxUSE_UNICODE_UTF8
01561 void a2dGeneralGlobal::DoPrintfUtf8( const a2dError& error, const char *format, ...)
01562 {
01563 va_list args;
01564 va_start(args, format);
01565 wxString out;
01566
01567 out.PrintfV(format, args);
01568 va_end(args);
01569
01570 ReportError( error, out );
01571 }
01572 #endif // wxUSE_UNICODE_UTF8
01573
01574 #else
01575
01576
01577
01578
01579
01580
01581
01582
01583
01584
01585
01586
01587
01588
01589
01590
01591
01592
01593 void a2dGeneralGlobal::ReportErrorF( const a2dError& error, const wxChar* Format, ... )
01594 {
01595 va_list ap;
01596
01597 wxString errorstr;
01598 va_start( ap, Format );
01599
01600 errorstr.PrintfV( Format, ap );
01601 va_end( ap );
01602
01603 ReportError( error, errorstr );
01604 }
01605
01606 void a2dGeneralGlobal::ReportWarningF( const a2dError& error, const wxChar* Format, ... )
01607 {
01608 va_list ap;
01609
01610 wxString errorstr;
01611 va_start( ap, Format );
01612
01613 errorstr.PrintfV( Format, ap );
01614 va_end( ap );
01615
01616 ReportWarning( error, errorstr );
01617 }
01618
01619 #endif //wxCHECK_VERSION(2,9,0)
01620
01621
01622 void a2dGeneralGlobal::ReportWarning( const a2dError& error, const wxString& errorstr )
01623 {
01624 if( m_ignoredErrorIds.Index( error.GetErrorCode() ) != wxNOT_FOUND )
01625 return;
01626
01627 wxString errorsmes = error.GetErrorMessage();
01628 if ( !errorstr.IsEmpty() )
01629 errorsmes = errorstr;
01630 m_errors.push_back( a2dError( error.GetIdName(), errorsmes, true ) );
01631
01632
01633 if ( m_showlog )
01634 wxLogError( errorsmes );
01635 }
01636
01637 wxString a2dGeneralGlobal::GetErrorsAsString()
01638 {
01639 wxString errors;
01640 forEachIn( a2dErrorVector, &m_errors )
01641 {
01642 a2dErrorVector::value_type errorRecord = *iter;
01643 errors += errorRecord.GetErrorMessage() + wxT(".\n");
01644 }
01645 return errors;
01646 }
01647
01648 void a2dGeneralGlobal::SendToLogTarget()
01649 {
01650 forEachIn( a2dErrorVector, &m_errors )
01651 {
01652 a2dErrorVector::value_type errorRecord = *iter;
01653 wxLogError( errorRecord.GetErrorMessage() );
01654 }
01655 ResetErrors();
01656 }
01657
01658 a2dErrorWarningCode a2dGeneralGlobal::GetLastErrorCode() const
01659 {
01660 if ( m_errors.size() )
01661 return m_errors.back().GetErrorCode();
01662 return a2dError_NoError.GetErrorCode();
01663 }
01664
01665 a2dError a2dGeneralGlobal::GetLastError() const
01666 {
01667 if ( m_errors.size() )
01668 return m_errors.back();
01669 return a2dError_NoError;
01670 }
01671
01672
01673 wxString* a2dGeneralGlobal::GetVariableString( const wxString& variablename )
01674 {
01675 wxString* prop = GetVariablesHash().GetVariableString( variablename );
01676
01677 if( !prop )
01678 {
01679 a2dGeneralGlobals->ReportError( a2dError_GetVar, _("wrong variable name, variable does not exist") );
01680 return NULL;
01681 }
01682
01683 return prop;
01684 }
01685
01686 wxString a2dGeneralGlobal::GetWxArt2DVar( bool withSep ) const
01687 {
01688 wxString art2Droot;
01689 wxGetEnv(_T("WXART2D"), &art2Droot );
01690 if( art2Droot.IsEmpty() )
01691 {
01692 #ifndef _GUNIX
01693 wxMessageBox(_T(" WXART2D variable not set\nPlease set the WXART2D environment string to the correct dir.\n\nExample : WXART2D=c:\\wxArt2D\n\n"),_T("environment error"), wxOK);
01694 #else
01695 wxMessageBox(_T(" WXART2D variable not set\nPlease set the WXART2D environment string to the correct dir.\n\nExample : WXART2D=/user/home/wxArt2D; export WXART2D \n\n"),_T("environment error"), wxOK);
01696 #endif
01697 }
01698 else
01699 {
01700 if ( withSep )
01701 return art2Droot + wxT("/");
01702 }
01703 return art2Droot;
01704 }
01705
01706 wxString a2dGeneralGlobal::GetWxArt2DArtVar( bool withSep ) const
01707 {
01708 wxString* artdir = a2dGeneralGlobals->GetVariablesHash().GetVariableString( wxT( "WXART2D_ART" ) );
01709 wxString artroot;
01710 if ( !artdir || artdir->IsEmpty() )
01711 {
01712 wxGetEnv(_T("WXART2D_ART"), &artroot );
01713 if( artroot.IsEmpty() )
01714 {
01715 wxGetEnv(_T("WXART2D"), &artroot );
01716 if( artroot.IsEmpty() )
01717 {
01718 #ifndef _GUNIX
01719 wxMessageBox(_T("WXART2D_ART or WXART2D variable not set\nPlease set the WXART2D environment string to the correct dir.\n\nExample : WXART2D=c:\\wxArt2D\n\n"),_T("environment error"), wxOK);
01720 #else
01721 wxMessageBox(_T("WXART2D_ART or WXART2D variable not set\nPlease set the WXART2D environment string to the correct dir.\n\nExample : WXART2D=/user/home/wxArt2D; export WXART2D \n\n"),_T("environment error"), wxOK);
01722 #endif
01723 return artroot;
01724 }
01725 artroot += wxT("/art");
01726 }
01727 }
01728 else
01729 artroot = *artdir;
01730 if ( withSep )
01731 return artroot + wxT("/");
01732 return artroot;
01733 }
01734
01735
01736
01737
01738
01739 DEFINE_EVENT_TYPE( a2dComEvent::sm_changedProperty )
01740 DEFINE_EVENT_TYPE( a2dComEvent::sm_changedRefObject )
01741 DEFINE_EVENT_TYPE( a2dComEvent::sm_non )
01742
01743 IMPLEMENT_DYNAMIC_CLASS( a2dComEvent, wxEvent )
01744
01745 DEFINE_EVENT_TYPE( a2dEVT_COM_EVENT )
01746
01747 a2dComEvent::a2dComEvent( wxObject* sender, const wxEventType* eventid )
01748 : wxEvent( wxID_ANY, a2dEVT_COM_EVENT )
01749 {
01750 SetEventObject( sender );
01751 m_handler = NULL;
01752 m_property = 0;
01753 m_ownProp = false;
01754 m_comid = eventid;
01755 m_comReturn = &sm_non;
01756 m_refcount = 0;
01757 }
01758
01759 a2dComEvent::a2dComEvent( a2dPropObject* sender, const a2dPropertyId* id, const wxEventType* eventid )
01760 : wxEvent( wxID_ANY, a2dEVT_COM_EVENT )
01761 {
01762 SetEventObject( sender );
01763 m_handler = NULL;
01764 m_property = sender->FindProperty( id );
01765 m_ownProp = false;
01766 m_comid = eventid;
01767 m_comReturn = &sm_non;
01768 m_refcount = 0;
01769 }
01770
01771 a2dComEvent::a2dComEvent( wxObject* sender, a2dNamedProperty* property, const wxEventType* eventid, bool ownProp )
01772 : wxEvent( wxID_ANY, a2dEVT_COM_EVENT )
01773 {
01774 SetEventObject( sender );
01775 m_handler = NULL;
01776 if ( ownProp )
01777 m_property = property->Clone( a2dObject::clone_flat );
01778 else
01779 m_property = property;
01780 m_ownProp = ownProp;
01781 m_comid = eventid;
01782 m_comReturn = &sm_non;
01783 m_refcount = 0;
01784 }
01785
01786 a2dComEvent::a2dComEvent( wxObject* sender, const a2dNamedProperty& property, const wxEventType* eventid )
01787 : wxEvent( wxID_ANY, a2dEVT_COM_EVENT )
01788 {
01789 SetEventObject( sender );
01790 m_handler = NULL;
01791 m_property = property.Clone( a2dObject::clone_flat );
01792 m_ownProp = true;
01793 m_comid = eventid;
01794 m_comReturn = &sm_non;
01795 m_refcount = 0;
01796 }
01797
01798 a2dComEvent::a2dComEvent( wxObject* sender, a2dObject* refObject, const wxEventType* eventid )
01799 : wxEvent( wxID_ANY, a2dEVT_COM_EVENT )
01800 {
01801 SetEventObject( sender );
01802 m_handler = NULL;
01803 m_property = new a2dProperty( a2dPropertyIdRefObject::GetDummy(), refObject );
01804 m_ownProp = true;
01805 m_comid = eventid;
01806 m_comReturn = &sm_non;
01807 m_refcount = 0;
01808 }
01809
01810 a2dComEvent::a2dComEvent( wxObject* sender, const a2dPropertyIdRefObject* id, a2dObject* refObject, const wxEventType* eventid )
01811 : wxEvent( wxID_ANY, a2dEVT_COM_EVENT )
01812 {
01813 SetEventObject( sender );
01814 m_handler = NULL;
01815 m_property = new a2dProperty( id, refObject );
01816 m_ownProp = true;
01817 m_comid = eventid;
01818 m_comReturn = &sm_non;
01819 m_refcount = 0;
01820 }
01821
01822 a2dComEvent::a2dComEvent( wxObject* sender, const a2dPropertyIdBool* id, bool propertyValue, const wxEventType* eventid )
01823 : wxEvent( wxID_ANY, a2dEVT_COM_EVENT )
01824 {
01825 SetEventObject( sender );
01826 m_handler = NULL;
01827 m_property = new a2dBoolProperty( id, propertyValue );
01828 m_ownProp = true;
01829 m_comid = eventid;
01830 m_comReturn = &sm_non;
01831 m_refcount = 0;
01832 }
01833
01834 a2dComEvent::a2dComEvent( wxObject* sender, const a2dPropertyIdUint16* id, wxUint16 propertyValue, const wxEventType* eventid )
01835 : wxEvent( wxID_ANY, a2dEVT_COM_EVENT )
01836 {
01837 SetEventObject( sender );
01838 m_handler = NULL;
01839 m_property = new a2dUint16Property( id, propertyValue );
01840 m_ownProp = true;
01841 m_comid = eventid;
01842 m_comReturn = &sm_non;
01843 m_refcount = 0;
01844 }
01845
01846 a2dComEvent::a2dComEvent( wxObject* sender, const a2dPropertyIdInt32* id, wxInt32 propertyValue, const wxEventType* eventid )
01847 : wxEvent( wxID_ANY, a2dEVT_COM_EVENT )
01848 {
01849 SetEventObject( sender );
01850 m_handler = NULL;
01851 m_property = new a2dInt32Property( id, propertyValue );
01852 m_ownProp = true;
01853 m_comid = eventid;
01854 m_comReturn = &sm_non;
01855 m_refcount = 0;
01856 }
01857
01858 a2dComEvent::a2dComEvent( wxObject* sender, const a2dPropertyIdDouble* id, double propertyValue, const wxEventType* eventid )
01859 : wxEvent( wxID_ANY, a2dEVT_COM_EVENT )
01860 {
01861 SetEventObject( sender );
01862 m_handler = NULL;
01863 m_property = new a2dDoubleProperty( id, propertyValue );
01864 m_ownProp = true;
01865 m_comid = eventid;
01866 m_comReturn = &sm_non;
01867 m_refcount = 0;
01868 }
01869
01870 a2dComEvent::a2dComEvent( wxObject* sender, const a2dPropertyIdString* id, const wxString& propertyValue, const wxEventType* eventid )
01871 : wxEvent( wxID_ANY, a2dEVT_COM_EVENT )
01872 {
01873 SetEventObject( sender );
01874 m_handler = NULL;
01875 m_property = new a2dStringProperty( id, propertyValue );
01876 m_ownProp = true;
01877 m_comid = eventid;
01878 m_comReturn = &sm_non;
01879 m_refcount = 0;
01880 }
01881
01882 a2dComEvent::a2dComEvent()
01883 : wxEvent( -1, a2dEVT_COM_EVENT )
01884 {
01885 SetEventObject( 0 );
01886 m_handler = NULL;
01887 m_ownProp = false;
01888 m_comid = &sm_non;
01889 m_comReturn = &sm_non;
01890 m_refcount = 0;
01891 }
01892
01893 a2dComEvent::~a2dComEvent()
01894 {
01895 wxASSERT_MSG( m_refcount == 0, wxT("deleting a2dComEvent while referenced") );
01896 if ( m_ownProp )
01897 delete m_property;
01898 }
01899
01900 a2dComEvent::a2dComEvent( const a2dComEvent& other )
01901 : wxEvent( other )
01902 {
01903 m_property = other.m_property ? other.m_property->Clone( a2dObject::clone_flat ) : 0;
01904 m_ownProp = true;
01905 m_comid = other.m_comid;
01906 m_comReturn = other.m_comReturn;
01907 m_handler = other.m_handler;
01908
01909 #if defined(_DEBUG) && defined (SMART_POINTER_DEBUG)
01910
01911 CurrentSmartPointerOwner = this;
01912 #endif
01913 m_refcount = 0;
01914 }
01915
01916 wxEvent* a2dComEvent::Clone(void) const
01917 {
01918 return new a2dComEvent( *this );
01919 }
01920