wxArt2D
comevt.cpp
Go to the documentation of this file.
1 /*! \file general/src/comevt.cpp
2  \brief Document/view classes
3  \author Klaas Holwerda
4  \date Created 05/07/2003
5 
6  Copyright: 2001-2004 (C) Klaas Holwerda
7 
8  Licence: wxWidgets licence
9 
10  RCS-ID: $Id: comevt.cpp,v 1.113 2009/08/23 19:49:38 titato Exp $
11 */
12 
13 #include "wxartbaseprec.h"
14 
15 #ifdef __BORLANDC__
16 #pragma hdrstop
17 #endif
18 
19 #ifndef WX_PRECOMP
20 #include "wx/wx.h"
21 #endif
22 
23 #if defined(_DEBUG)
24 // #define A2D_COMMAND_DEBUG
25 #endif
26 
27 // ----------------------------------------------------------------------------
28 // headers
29 // ----------------------------------------------------------------------------
30 
31 #ifndef WX_PRECOMP
32 #include "wx/string.h"
33 #include "wx/dc.h"
34 #include "wx/list.h"
35 #endif
36 
37 #include "wx/general/comevt.h"
38 
39 #include "wx/general/smrtptr.inl"
40 #include <wx/general/id.inl>
41 
42 #if defined(__WXMSW__) && defined(__MEMDEBUG__)
43 #include <wx/msw/msvcrt.h>
44 #endif
45 
46 // ----------------------------------------------------------------------------
47 // wxWindows macros
48 // ----------------------------------------------------------------------------
49 IMPLEMENT_DYNAMIC_CLASS( a2dCommandProcessor, a2dObject )
50 IMPLEMENT_DYNAMIC_CLASS( a2dCommand_SetProperty, a2dCommand )
51 IMPLEMENT_DYNAMIC_CLASS( a2dCommand_SetVariable, a2dCommand )
52 IMPLEMENT_DYNAMIC_CLASS( a2dCommand_SetEnvironmentVariable, a2dCommand )
53 IMPLEMENT_DYNAMIC_CLASS( a2dCommand_GetVariable, a2dCommand )
54 IMPLEMENT_DYNAMIC_CLASS( a2dCommand_GetEnvVariable, a2dCommand )
55 
56 DEFINE_EVENT_TYPE( wxEVT_DO )
57 DEFINE_EVENT_TYPE( wxEVT_UNDO )
58 DEFINE_EVENT_TYPE( wxEVT_REDO )
59 DEFINE_EVENT_TYPE( wxEVT_MENUSTRINGS )
60 DEFINE_EVENT_TYPE( wxEVT_BEGINBUSY )
61 DEFINE_EVENT_TYPE( wxEVT_ENDBUSY )
62 DEFINE_EVENT_TYPE( a2dEVT_PROPOBJECT_EDITPROPERTIES_EVENT )
63 DEFINE_EVENT_TYPE( wxEVT_RECORD )
64 
65 // ----------------------------------------------------------------------------
66 // a2dCommandId
67 // ----------------------------------------------------------------------------
68 
69 a2dCommandId::a2dCommandId( const wxString& commandName )
70 {
71  m_name = commandName;
72 
73  // check if name is unique
74  for( int indx = 1; GetHashMap().find( commandName ) != GetHashMap().end(); indx++ )
75  {
76  wxASSERT_MSG( 0, _( "The command id name '" ) + commandName + _( "' already exists" ) );
77  }
78 
79  GetHashMap()[commandName] = this;
80 }
81 
82 const a2dCommandId& a2dCommandId::GetCommandByName( const wxString& commandName )
83 {
84  a2dHashMapCommandIds::iterator iterCommand = GetHashMap().find( commandName );
85  return iterCommand != GetHashMap().end() ? *iterCommand->second : a2dCommand::sm_noCommandId;
86 }
87 
88 a2dHashMapCommandIds& a2dCommandId::GetHashMap()
89 {
90  static a2dMemoryCriticalSectionHelper helper;
91  static a2dHashMapCommandIds namehash;
92  return namehash;
93 }
94 
95 // ----------------------------------------------------------------------------
96 // base docview command
97 // ----------------------------------------------------------------------------
98 
99 const a2dCommandId a2dCommand::sm_noCommandId = a2dCommandId( wxT( "NoCommandId" ) );
100 const a2dCommandId a2dCommand::sm_noCommandTypeId = a2dCommandId( wxT( "NoCommandTypeId" ) );
101 const a2dCommandId a2dCommand::sm_groupCommandId = a2dCommandId( wxT( "GroupCommandId" ) );
102 
104  const a2dCommandId& commandId,
105  const a2dCommandId& commandTypeId,
106  const wxString& menuString )
107  : a2dObject(),
108  m_modifies( true )
109 {
110  m_cmp = 0;
111  m_canUndo = canUndo;
112  m_commandId = &commandId;
113  m_commandTypeId = &commandTypeId;
114  m_menuString = menuString;
115 #if defined(_DEBUG) && defined (SMART_POINTER_DEBUG)
116  extern wxObject* CurrentSmartPointerOwner;
117  CurrentSmartPointerOwner = this;
118 #endif
119 }
120 
122  : a2dObject( other, a2dObject::clone_deep, NULL )
123 {
124  m_commandId = other.m_commandId;
126  m_menuString = other.m_menuString;
127  m_canUndo = other.m_canUndo;
128  m_cmp = other.m_cmp;
129  m_modifies = other.m_modifies;
130 }
131 
132 a2dObject* a2dCommand::DoClone( CloneOptions WXUNUSED( options ), a2dRefMap* refs ) const
133 {
134  a2dGeneralGlobals->ReportErrorF( a2dError_CommandError, wxT( "%s" ), _( "clone not implemented for this command" ) );
135  return NULL;
136 }
137 
138 wxString a2dCommand::GetName() const
139 {
140  if ( m_menuString.IsEmpty() )
141  return m_commandId->GetName();
142  return m_menuString;
143 }
144 
146 {
147 }
148 
150 {
151  wxASSERT_MSG( 0 , _( "a2dCommand::CloneAndBind not overloaded in derived class" ) );
152  return 0;
153 }
154 
156 {
157  return Do();
158 }
159 
161 {
162  return current == this;
163 }
164 
165 a2dCommand* a2dCommand::FindPrevious( a2dCommand* WXUNUSED( current ) ) const
166 {
167  return 0;
168 }
169 
170 a2dCommand* a2dCommand::FindNext( a2dCommand* WXUNUSED( current ) ) const
171 {
172  return 0;
173 }
174 
175 bool a2dCommand::Remove( a2dCommand* WXUNUSED( command ) )
176 {
177  return false;
178 }
179 
181 {
182  return command == this;
183 }
184 
185 void a2dCommand::DistributeEvent( wxEventType eventType )
186 {
187  if ( eventType == wxEVT_DO )
188  {
189  a2dCommandProcessorEvent event( wxEVT_DO, this );
190  event.SetEventObject( GetCommandProcessor() );
191  GetCommandProcessor()->ProcessEvent( event );
192  }
193  else if ( eventType == wxEVT_UNDO )
194  {
195  a2dCommandProcessorEvent event( wxEVT_UNDO, this );
196  event.SetEventObject( GetCommandProcessor() );
197  GetCommandProcessor()->ProcessEvent( event );
198  }
199  else if ( eventType == wxEVT_REDO )
200  {
201  a2dCommandProcessorEvent event( wxEVT_REDO, this );
202  event.SetEventObject( GetCommandProcessor() );
203  GetCommandProcessor()->ProcessEvent( event );
204  }
205 }
206 
207 //----------------------------------------------------------------------------
208 // a2dCommandGroup
209 //----------------------------------------------------------------------------
210 
211 a2dCommandGroup::a2dCommandGroup( const wxString& name, a2dCommandGroup* parent )
212  : a2dCommand( true, a2dCommand::sm_groupCommandId )
213 {
214  m_modifies = false; // assume a group on it self does nothing, only its sub commands
215  wxString idName;
216  idName.Printf( wxT( "%s_%ld" ), name.c_str(), wxGenNewId() );
217 
218  m_commandId = new a2dCommandId( idName );
219  m_ownId = true;
220 
221  m_groupName = name;
222  m_parentGroup = parent;
223  m_active = true;
224 }
225 
227  a2dCommandGroup* parent,
228  const a2dCommandId& commandId,
229  const a2dCommandId& commandTypeId,
230  const wxString& menuString
231  )
232  : a2dCommand( true, commandId, commandTypeId, menuString )
233 {
234  m_modifies = false; // assume a group on it self does nothing, only its sub commands
235  m_ownId = false;
236 
238  m_parentGroup = parent;
239  m_active = true;
240 }
241 
243 {
244  m_subcommands.clear();
245  if ( m_ownId )
246  delete m_commandId;
247 }
248 
250 {
252 
253  a2dCommandList::const_iterator iter = m_subcommands.begin();
254  while( iter != m_subcommands.end() )
255  {
256  a2dCommand* obj = *iter;
257  a2dCommand* clone = ( a2dCommand* ) obj->Clone( options, refs );
258  clgr->m_subcommands.push_back( clone );
259  iter++;
260  }
261  return clgr;
262 }
263 
265 {
266  if( current == this )
267  return true;
268 
269  int i = 0;
270  a2dCommandList::reverse_iterator iter = m_subcommands.rbegin();
271  while( iter != m_subcommands.rend() )
272  {
273  a2dCommand* obj = *iter;
274  if( obj->ClearAfterCurrentCommand( current ) )
275  {
276  // Everything after this command must be removed.
277  a2dCommandList::reverse_iterator iterr = m_subcommands.rbegin();
278  while( i > 0 && iterr != m_subcommands.rend() )
279  {
280  m_subcommands.rerase( iterr ) ;
281  i--;
282  }
283  return true;
284  }
285  iter++;
286  i++;
287  }
288  return false;
289 }
290 
291 bool a2dCommandGroup::ClearCommandsById( const a2dCommandId& commandId, a2dCommand* fromcommand )
292 {
293  bool start = false;
294  bool found = false;
295  a2dCommandList::iterator iter = m_subcommands.begin();
296  while( iter != m_subcommands.end() )
297  {
298  a2dCommand* command = *iter;
299  if( ( fromcommand == NULL || fromcommand == command || start ) )
300  {
301  start = true;
302  if ( command->GetCommandId() == &commandId )
303  {
304  iter = m_subcommands.erase( iter );
305  found = true;
306  }
307  else
308  iter++;
309  }
310  else
311  iter++;
312  }
313  return found;
314 }
315 
317 {
318 
319  a2dCommandList::const_reverse_iterator iter = m_subcommands.rbegin();
320  while( iter != m_subcommands.rend() )
321  {
322  a2dCommand* obj = *iter;
323  // Check if this command/group contains the current command
324  if( obj->ContainsCommand( current ) )
325  {
326  // Check if this command/group also has a previous command
327  a2dCommand* previous = obj->FindPrevious( current );
328 
329  // If yes, this is what we want
330  if( previous )
331  return previous;
332 
333  // Else find a command previous from our list
334  iter++;
335  if( iter != m_subcommands.rend() )
336  return *iter;
337 
338  return 0;
339  }
340  iter++;
341  }
342 
343  return 0;
344 }
345 
347 {
348  a2dCommandList::const_reverse_iterator iter = m_subcommands.rbegin();
349  while( iter != m_subcommands.rend() )
350  {
351  a2dCommand* obj = *iter;
352  // Check if this command/group contains the current command
353  if( obj->ContainsCommand( current ) )
354  {
355  // Check if this command/group also has a next command
356  a2dCommand* next = obj->FindNext( current );
357 
358  // If yes, this is what we want
359  if( next )
360  return next;
361 
362  // Else find a command next from our list
363  if( iter != m_subcommands.rbegin() )
364  iter--;
365  else
366  return 0;
367 
368  if( iter != m_subcommands.rend() )
369  return *iter;
370 
371  return 0;
372  }
373  iter++;
374  }
375 
376  return 0;
377 }
378 
380 {
381  a2dCommandList::reverse_iterator iter = m_subcommands.rbegin();
382  while( iter != m_subcommands.rend() )
383  {
384  a2dCommand* obj = *iter;
385  if ( command == obj )
386  {
387  iter = m_subcommands.rerase( iter );
388  return true;
389  }
390  //check recursive/nested groups
391  if ( obj->Remove( command ) )
392  {
393  return true;
394  }
395  iter++;
396  }
397  return false;
398 }
399 
401 {
402  m_subcommands.push_back( command );
403 }
404 
406 {
407  if( command == this )
408  return true;
409 
410  a2dCommandList::reverse_iterator iter = m_subcommands.rbegin();
411  while( iter != m_subcommands.rend() )
412  {
413  a2dCommand* obj = *iter;
414  if ( obj->ContainsCommand( command ) )
415  return true;
416  iter++;
417  }
418  return false;
419 }
420 
422 {
423  /*
424  m_cmp->SetCurrentGroup( this );
425  m_active = true;
426  // Redo is forward
427  a2dCommandList::iterator iter = m_subcommands.begin();
428  while( iter != m_subcommands.end() )
429  {
430  a2dCommand* obj = *iter;
431  obj->SetCommandProcessor( m_cmp );
432  if ( !obj->Do() )
433  return false;
434  else
435  obj->DistributeEvent( wxEVT_DO );
436 
437  iter++;
438  }
439  m_cmp->CommandGroupEnd( this );
440  */
441  return true;
442 }
443 
445 {
446  m_cmp->SetCurrentGroup( this );
447  m_active = true;
448  // Redo is forward
449  a2dCommandList::iterator iter = m_subcommands.begin();
450  while( iter != m_subcommands.end() )
451  {
452  a2dCommand* obj = *iter;
453  obj->SetCommandProcessor( m_cmp );
454  if ( !obj->Redo() )
455  return false;
456  else
457  obj->DistributeEvent( wxEVT_REDO );
458 
459  iter++;
460  }
461  m_cmp->CommandGroupEnd( this );
462  return true;
463 }
464 
466 {
467  //NO group set here
468 
469  // Undo is backward
470  a2dCommandList::reverse_iterator iter = m_subcommands.rbegin();
471  while( iter != m_subcommands.rend() )
472  {
473  a2dCommand* obj = *iter;
474  if ( !obj->Undo() )
475  return false;
476  else
477  obj->DistributeEvent( wxEVT_UNDO );
478  iter++;
479  }
480  return true;
481 }
482 
483 
484 //----------------------------------------------------------------------------
485 // a2dPropertyEditEvent
486 //----------------------------------------------------------------------------
487 DEFINE_EVENT_TYPE( wxEVT_PROPOBJECT_EDITPROPERTIES_EVENT )
488 
490  : a2dEvent( wxID_ANY, a2dEVT_PROPOBJECT_EDITPROPERTIES_EVENT )
491 {
492  SetEventObject( object );
493  m_properties = properties;
494  m_edited = false;
495 }
496 
498  : a2dEvent( other )
499 {
500  m_properties = other.m_properties;
501  m_edited = other.m_edited;
502 }
503 
504 //----------------------------------------------------------------------------
505 // a2dCommand_SetProperty
506 //----------------------------------------------------------------------------
507 
508 const a2dCommandId a2dCommand_SetProperty::Id = a2dCommandId( wxT( "SetProperty" ) );
509 
511  a2dCommand( true, Id )
512 {
513  m_propRefObject = NULL;
514 }
515 
517  a2dCommand( true, Id )
518 {
519  m_propRefObject = object;
520  m_id = id;
521 }
522 
524  a2dCommand( true, Id )
525 {
526  m_property = property;
527  m_propRefObject = object;
528  m_id = property->GetId();
529 }
530 
532  a2dCommand( true, Id, sm_noCommandTypeId, id->GetName() )
533 {
534  a2dProperty* prop = new a2dProperty( id, value );
535 
536  m_property = prop;
537  m_propRefObject = object;
538  m_id = id;
539 }
540 
542  a2dCommand( true, Id, sm_noCommandTypeId, id->GetName() )
543 {
544  a2dObjectProperty* prop = new a2dObjectProperty( id, value );
545 
546  m_property = prop;
547  m_propRefObject = object;
548  m_id = id;
549 }
550 
552  a2dCommand( true, Id, sm_noCommandTypeId, id->GetName() )
553 {
554  a2dStringProperty* prop = new a2dStringProperty( id, value );
555 
556  m_property = prop;
557  m_propRefObject = object;
558  m_id = id;
559 }
560 
562  a2dCommand( true, Id, sm_noCommandTypeId, id->GetName() )
563 {
564  a2dBoolProperty* prop = new a2dBoolProperty( id, value );
565 
566  m_property = prop;
567  m_propRefObject = object;
568  m_id = id;
569 }
570 
571 a2dCommand_SetProperty::a2dCommand_SetProperty( a2dObject* object, const a2dPropertyIdBool* id, const wxString& value ):
572  a2dCommand( true, Id, sm_noCommandTypeId, id->GetName() )
573 {
574  a2dNamedProperty* prop = id->CreatePropertyFromString( value );
575 
576  m_property = prop;
577  m_propRefObject = object;
578  m_id = id;
579 }
580 
582  a2dCommand( true, Id, sm_noCommandTypeId, id->GetName() )
583 {
584  a2dInt16Property* prop = new a2dInt16Property( id, value );
585 
586  m_property = prop;
587  m_propRefObject = object;
588  m_id = id;
589 }
590 
592  a2dCommand( true, Id, sm_noCommandTypeId, id->GetName() )
593 {
594  a2dUint16Property* prop = new a2dUint16Property( id, value );
595 
596  m_property = prop;
597  m_propRefObject = object;
598  m_id = id;
599 }
600 
602  a2dCommand( true, Id, sm_noCommandTypeId, id->GetName() )
603 {
604  a2dInt32Property* prop = new a2dInt32Property( id, value );
605 
606  m_property = prop;
607  m_propRefObject = object;
608  m_id = id;
609 }
610 
612  a2dCommand( true, Id, sm_noCommandTypeId, id->GetName() )
613 {
614  a2dUint32Property* prop = new a2dUint32Property( id, value );
615 
616  m_property = prop;
617  m_propRefObject = object;
618  m_id = id;
619 }
620 
622  a2dCommand( true, Id, sm_noCommandTypeId, id->GetName() )
623 {
624  a2dDoubleProperty* prop = new a2dDoubleProperty( id, value );
625 
626  m_property = prop;
627  m_propRefObject = object;
628  m_id = id;
629 }
630 
632  a2dCommand( true, Id, sm_noCommandTypeId, id->GetName() )
633 {
634  a2dColourProperty* prop = new a2dColourProperty( id, colour );
635 
636  m_property = prop;
637  m_propRefObject = object;
638  m_id = id;
639 }
640 
641 
642 a2dCommand_SetProperty::~a2dCommand_SetProperty( void )
643 {
644  m_propRefObject = NULL;
645 }
646 
648  : a2dCommand ( other )
649 {
651  m_property = other.m_property->Clone( a2dObject::clone_flat );
652  m_id = other.m_id;
653 }
654 
656 {
657  if ( m_propRefObject )
658  {
661  m_property = propertyold;
662  }
663 
664  return true;
665 }
666 
668 {
669  if ( m_propRefObject )
670  {
672 
673  if ( !m_property )
674  {
675  //the property did not exist before, so we need to remove the one that was added.
677  }
678  else
679  {
681  }
682 
683  m_property = propertyold;
684  }
685 
686  return true;
687 }
688 
689 // ----------------------------------------------------------------------------
690 // a2dCommandProcessor
691 // ----------------------------------------------------------------------------
692 
693 const a2dCommandId a2dCommand_SetVariable::Id( wxT( "SetVariable" ) );
694 const a2dCommandId a2dCommand_SetEnvironmentVariable::Id( wxT( "SetEnv" ) );
695 const a2dCommandId a2dCommand_GetVariable::Id( wxT( "GetVariable" ) );
696 
698 {
699  m_rootGroup = new a2dCommandGroup( _( "Root" ), NULL );
701  m_maxNoCommands = maxCommands;
702  m_currentCommand = NULL;
703  m_undoAccelerator = _( "\tCtrl+Z" );
704  m_redoAccelerator = _( "\tCtrl+Y" );
705 }
706 
708 {
710  ClearCommands();
711 }
712 
713 a2dObject* a2dCommandProcessor::DoClone( CloneOptions WXUNUSED( options ), a2dRefMap* refs ) const
714 {
715  wxFAIL_MSG( wxT( "cannot clone a2dIOHandler" ) );
716  return NULL;
717 }
718 
720 {
721  m_refcount--;
722  wxASSERT_MSG( m_refcount >= 0, wxT( "a2dCommandProcessor Own/Release not matched (extra Release calls)" ) );
723  if ( m_refcount <= 0 )
724  {
725  delete this;
726  return true;
727  }
728  return false;
729 }
730 
732 {
734 
735  for( ;; )
736  {
737  if( group->m_subcommands.empty() )
738  break;
739 
740  a2dCommandGroup* next = group->m_subcommands.back()->IsCommandGroup();
741  if( !next || !next->m_active )
742  break;
743 
744  group = next;
745  }
746 
747  return group;
748 }
749 
751 {
753 
754  for( ;; )
755  {
756  if( group->m_subcommands.empty() )
757  break;
758 
759  a2dCommandGroup* next = group->m_subcommands.back()->IsCommandGroup();
760  if( !next || !next->m_active || next->m_subcommands.empty() )
761  break;
762 
763  group = next;
764  }
765 
766  m_currentCommand = ( group->m_subcommands.empty() ) ? 0 : group->m_subcommands.back();
767 }
768 
770 {
771 #if defined(A2D_COMMAND_DEBUG)
772  wxLogDebug( wxT( "Pre Do name = %s 0x%p" ), cmd.GetName().c_str(), &cmd );
773 #endif
774  bool ret = cmd.PreDo();
775  return ret;
776 }
777 
779 {
780 #if defined(A2D_COMMAND_DEBUG)
781  wxLogDebug( wxT( "Post Do name = %s 0x%p" ), cmd.GetName().c_str(), &cmd );
782 #endif
783  bool ret = cmd.PostDo();
784  return ret;
785 }
786 
788 {
789 #if defined(A2D_COMMAND_DEBUG)
790  wxLogDebug( wxT( "Do name = %s 0x%p" ), cmd.GetName().c_str(), &cmd );
791 #endif
792  bool ret = cmd.Do();
793 
794  if ( ret )
795  cmd.DistributeEvent( wxEVT_DO );
796  return ret;
797 }
798 
800 {
801 #if defined(A2D_COMMAND_DEBUG)
802  wxLogDebug( wxT( "UnDo name = %s 0x%p" ), cmd.GetName().c_str(), &cmd );
803 #endif
804  bool ret = cmd.Undo();
805 
806  if ( ret )
807  cmd.DistributeEvent( wxEVT_UNDO );
808  return ret;
809 }
810 
812 {
813 #if defined(A2D_COMMAND_DEBUG)
814  wxLogDebug( wxT( "ReDo name = %s 0x%p" ), cmd.GetName().c_str(), &cmd );
815 #endif
816  bool ret = cmd.Redo();
817 
818  if ( ret )
819  cmd.DistributeEvent( wxEVT_REDO );
820  return ret;
821 }
822 
823 void a2dCommandProcessor::SentBusyEvent( bool start, a2dCommand* command )
824 {
825  if ( start )
826  {
827  a2dCommandProcessorEvent event( wxEVT_BEGINBUSY, command );
828  event.SetEventObject( this );
829  this->ProcessEvent( event );
830  }
831  else
832  {
833  a2dCommandProcessorEvent event( wxEVT_ENDBUSY, command );
834  event.SetEventObject( this );
835  this->ProcessEvent( event );
836  }
837 }
838 
839 // Pass a command to the processor. The processor calls Do();
840 // if successful, is appended to the command history unless
841 // storeIt is false.
842 bool a2dCommandProcessor::Submit( a2dCommand* command, bool storeIt )
843 {
844  wxCHECK_MSG( command, false, _( "no command in a2dCommandProcessor::Submit" ) );
845 
846  SentBusyEvent( true, command );
847 
848  // to properly delete it if needed
849  a2dSmrtPtr<a2dCommand> lcommand = command;
850 
851  command->SetCommandProcessor( this );
852  if ( command->IsCommandGroup() )
853  {
854  wxStaticCast( command, a2dCommandGroup )->m_parentGroup = m_currentGroup;
855  }
856 
857  bool oke = false;
858  try
859  {
860  //commands in here will be stored before the actual one.
861  oke = DoPreCommand( *command );
862 
863  //first store, and if not right command, remove it again.
864  if ( storeIt )
865  Store( command );
866 
867  oke |= DoCommand( *command );
868 
869  //commands in here will be stored after the actual one.
870  oke |= DoPostCommand( *command );
871  }
872  catch ( const a2dCommandException& e )
873  {
874  a2dGeneralGlobals->ReportErrorF( a2dError_CommandError, wxT( "%s" ), e.getMessage().c_str() );
875  oke = false;
876  }
877 
878  if ( !oke )
879  {
880  if ( storeIt )
881  {
882  m_currentGroup->Remove( command );
884  }
885 
886  SentBusyEvent( false, command );
887  // the user code expects the command to be released/deleted
888  return false;
889  }
890 
891  SentBusyEvent( false, command );
892  return true;
893 }
894 
896 {
897  wxCHECK_RET( command, _( "no command in a2dCommandProcessor::Store" ) );
898 
899  // If there are too many command in the command list, delete one
901  m_currentGroup->m_subcommands.pop_front();
902 
903  // If the complete command list in currentgroup was undone, m_currentCommand will be 0
904  // In this case, all commands in current group must be cleared.
905  // This also happens if no commands have been added yet, but in this case
906  // it doesn't hurt to clear the list.
907  if( !m_currentCommand )
908  ClearCommands();
909  else
911 
912  m_currentCommand = command;
913  m_currentGroup->m_subcommands.push_back( command );
914  //FindActiveGroup()->m_subcommands.push_back( command );
915  SetMenuStrings();
916 }
917 
919 {
920  if ( m_currentCommand && m_currentCommand->CanUndo() )
921  {
922  if ( UndoCommand( *m_currentCommand ) )
923  {
925  SetMenuStrings();
926  return true;
927  }
928  }
929 
930  return false;
931 }
932 
934 {
935  a2dCommand* redoCommand = ( a2dCommand* ) NULL;
936 
937  if ( m_currentCommand )
938  {
939  // is there anything to redo?
941  if ( next )
942  {
943  redoCommand = next;
944  }
945  }
946  else // no current command, redo the first one
947  {
948  // m_currentCommand is 0 is all commands have been undone
949  // OR if no command was inserted yet
950  if ( !m_currentGroup->m_subcommands.empty() )
951  redoCommand = m_currentGroup->m_subcommands.front();
952  }
953 
954  if ( redoCommand )
955  {
956  bool success = RedoCommand( *redoCommand );
957  if ( success )
958  {
959  m_currentCommand = redoCommand;
960  SetMenuStrings();
961  return true;
962  }
963  }
964  return false;
965 }
966 
968 {
969  a2dCommand* command = GetCurrentCommand();
970 
971  return command && command->CanUndo();
972 }
973 
975 {
976  if( m_currentCommand )
977  {
979  if ( next )
980  return next->CanUndo();
981  return false;
982  }
983  else
984  {
985  return m_currentGroup->m_subcommands.size() != 0;
986  }
987 }
988 
990 {
992  SetMenuStrings();
993 }
994 
996 {
997  // sent event wxEVT_MENUSTRINGS
1000  GetUndoMenuLabel(),
1001  CanUndo(),
1002  GetRedoMenuLabel(),
1003  CanRedo()
1004  );
1005  event.SetEventObject( this );
1006  ProcessEvent( event );
1007 }
1008 
1009 // Gets the current Undo menu label.
1011 {
1012  wxString buf;
1013  if ( m_currentCommand )
1014  {
1015  wxString commandName( m_currentCommand->GetName() );
1016  if ( commandName.IsEmpty() ) commandName = _( "Unnamed command" );
1017  bool canUndo = m_currentCommand->CanUndo();
1018  if ( canUndo )
1019  buf = wxString( _( "&Undo" ) ) + wxT( " " ) + commandName + m_undoAccelerator;
1020  else
1021  buf = wxString( _( "Can't &Undo" ) ) + wxT( " " ) + commandName + m_undoAccelerator;
1022  }
1023  else
1024  {
1025  buf = _( "&Undo" ) + m_undoAccelerator;
1026  }
1027 
1028  return buf;
1029 }
1030 
1031 // Gets the current Undo menu label.
1033 {
1034  a2dCommand* redoCommand;
1035  wxString buf;
1036 
1037  if ( m_currentCommand )
1038  {
1039  // We can redo, if we're not at the end of the history.
1040  redoCommand = m_currentGroup->FindNext( m_currentCommand );
1041  }
1042  else
1043  {
1044  redoCommand = m_currentGroup->m_subcommands.empty() ? 0 : m_currentGroup->m_subcommands.front();
1045  }
1046  if ( redoCommand )
1047  {
1048  wxString redoCommandName( redoCommand->GetName() );
1049  if ( redoCommandName.IsEmpty() ) redoCommandName = _( "Unnamed command" );
1050  buf = wxString( _( "&Redo" ) ) + wxT( " " ) + redoCommandName + m_redoAccelerator;
1051  }
1052  else
1053  {
1054  buf = _( "&Redo" ) + m_redoAccelerator;
1055  }
1056  return buf;
1057 }
1058 
1060 {
1061  m_currentGroup->m_subcommands.clear();
1062 
1063  m_currentCommand = 0;
1064 }
1065 
1066 bool a2dCommandProcessor::SetOrAddPropertyToObject( a2dObject* propRefObject, const wxString& name, const wxString& value, bool withUndo )
1067 {
1068  wxASSERT_MSG( propRefObject != 0 , _( "a2dObject not NULL" ) );
1069 
1070  // get the id object from the id hash table
1071  a2dPropertyId* id = propRefObject->HasPropertyId( name );
1072  if( !id )
1073  return false;
1074 
1075  a2dNamedProperty* prop = id->CreatePropertyFromString( value );
1076 
1077  if( !prop )
1078  return false;
1079 
1080  return Submit( new a2dCommand_SetProperty( propRefObject, prop ), withUndo );
1081 }
1082 
1083 bool a2dCommandProcessor::SetOrAddPropertyToObject( a2dObject* propRefObject, a2dNamedProperty* property, bool withUndo )
1084 {
1085  wxASSERT_MSG( propRefObject != 0, _( "a2dObject not NULL" ) );
1086 
1087  return Submit( new a2dCommand_SetProperty( propRefObject, property ), withUndo );
1088 }
1089 
1091 {
1092  group->m_active = true;
1093  m_currentGroup = group;
1094 }
1095 
1097 {
1098  a2dCommandGroup* group = new a2dCommandGroup( name, m_currentGroup );
1099 #if defined(A2D_COMMAND_DEBUG)
1100  wxLogDebug( wxT( "Open Group = %s 0x%p" ), name.c_str(), group );
1101 #endif
1102  group->SetCommandProcessor( this );
1103  //store in the group m_currentGroup!!
1104  Store( group );
1105  //now change to the new group
1106  m_currentGroup = group;
1107  return group;
1108 }
1109 
1111 {
1112  group->SetParentGroup( m_currentGroup );
1113  group->m_active = true;
1114 
1115 #if defined(A2D_COMMAND_DEBUG)
1116  wxLogDebug( wxT( "Open Group = %s 0x%p" ), name.c_str(), group );
1117 #endif
1118  group->SetCommandProcessor( this );
1119  //store in the group m_currentGroup!!
1120  Store( group );
1121  //now change to the new group
1122  m_currentGroup = group;
1123 }
1124 
1126 {
1127  m_currentGroup = group->m_parentGroup;
1128  group->m_active = false;
1129  /*
1130  a2dCommandGroup* activeGroup = FindActiveGroup();
1131  wxASSERT( activeGroup == m_currentGroup );
1132  */
1133 #if defined(A2D_COMMAND_DEBUG)
1134  wxLogDebug( wxT( "End Group = %s 0x%p" ), group->GetGroupName().c_str(), group );
1135 #endif
1136  //parent group must be active
1137  wxASSERT( m_currentGroup->m_active );
1139  SetMenuStrings();
1140 }
1141 
1142 // ----------------------------------------------------------------------------
1143 // a2dGeneralModule
1144 // ----------------------------------------------------------------------------
1145 IMPLEMENT_DYNAMIC_CLASS( a2dGeneralModule, wxModule )
1146 
1147 //! a global pointer to get to global instance of important classes.
1149 //a2dGeneralGlobal* a2dGeneralGlobals = NULL;
1150 
1151 
1152 bool a2dGeneralModule::OnInit()
1153 {
1154  a2dGeneralGlobals = new a2dGeneralGlobal();
1155  return true;
1156 }
1157 
1158 void a2dGeneralModule::OnExit()
1159 {
1160  a2dGeneralGlobals = NULL;
1161 }
1162 
1163 // ----------------------------------------------------------------------------
1164 // a2dGeneralGlobal
1165 // ----------------------------------------------------------------------------
1166 
1168 bool a2dGeneralGlobal::m_directlog = true;
1169 a2dErrorVector a2dGeneralGlobal::m_errors = a2dErrorVector();
1170 wxArrayInt a2dGeneralGlobal::m_ignoredErrorIds = wxArrayInt();
1172 a2dPropertyIdList a2dGeneralGlobal::m_dynamicIdList = a2dPropertyIdList();
1173 
1174 IMPLEMENT_CLASS( a2dGeneralGlobal, a2dObject )
1175 
1177 {
1178  m_logConnectedEvents = false;
1179  m_directlog = true;
1180 }
1181 
1182 a2dGeneralGlobal::~a2dGeneralGlobal()
1183 {
1184  m_errors.clear();
1185 }
1186 
1187 a2dObject* a2dGeneralGlobal::DoClone( CloneOptions WXUNUSED( options ), a2dRefMap* refs ) const
1188 {
1189  wxLogMessage( _( "Not implemented" ) );
1190  return NULL;
1191 }
1192 
1193 #if wxART2D_USE_CVGIO
1194 void a2dGeneralGlobal::DoSave( wxObject* WXUNUSED( parent ), a2dIOHandlerXmlSerOut& WXUNUSED( out ), a2dXmlSer_flag WXUNUSED( xmlparts ), a2dObjectList* WXUNUSED( towrite ) )
1195 {
1196  wxLogMessage( _( "Not implemented" ) );
1197 }
1198 
1199 void a2dGeneralGlobal::DoLoad( wxObject* WXUNUSED( parent ), a2dIOHandlerXmlSerIn& WXUNUSED( parser ), a2dXmlSer_flag WXUNUSED( xmlparts ) )
1200 {
1201  wxLogMessage( _( "Not implemented" ) );
1202 }
1203 
1204 #endif //wxART2D_USE_CVGIO
1205 
1207 {
1208  m_errors.clear();
1209  //wxLog* target = wxLog::GetActiveTarget();
1210  //target->Flush();
1211 }
1212 
1213 void a2dGeneralGlobal::IgnoreError( unsigned int id )
1214 {
1215  if( m_ignoredErrorIds.Index( id ) == wxNOT_FOUND )
1216  {
1217  m_ignoredErrorIds.Add( id );
1218  }
1219 }
1220 
1221 void a2dGeneralGlobal::ReportError( const a2dError& error, const wxString& errorstr )
1222 {
1223  if( m_ignoredErrorIds.Index( error.GetErrorCode() ) != wxNOT_FOUND )
1224  return;
1225 
1226  a2dError errorc( error );
1227  if ( !errorstr.IsEmpty() )
1228  errorc.SetErrorMessage( errorstr );
1229 
1230  m_errors.push_back( errorc );
1231 
1232  if ( m_directlog )
1233  wxLogError( errorc.GetErrorMessage() );
1234 }
1235 
1236 
1237 #if wxCHECK_VERSION(2,9,0)
1238 
1239 #if !wxUSE_UTF8_LOCALE_ONLY
1240 void a2dGeneralGlobal::DoPrintfWchar( const a2dError& error, const wxChar* format, ... )
1241 {
1242  va_list args;
1243  va_start( args, format );
1244  wxString out;
1245 
1246  out.PrintfV( format, args );
1247  va_end( args );
1248 
1249  ReportError( error, out );
1250 }
1251 
1252 void a2dGeneralGlobal::DoPrintfWcharWarn( const a2dError& error, const wxChar* format, ... )
1253 {
1254  va_list args;
1255  va_start( args, format );
1256  wxString out;
1257 
1258  out.PrintfV( format, args );
1259  va_end( args );
1260 
1261  ReportWarning( error, out );
1262 }
1263 
1264 #endif // !wxUSE_UTF8_LOCALE_ONLY
1265 
1266 #if wxUSE_UNICODE_UTF8
1267 void a2dGeneralGlobal::DoPrintfUtf8( const a2dError& error, const char* format, ... )
1268 {
1269  va_list args;
1270  va_start( args, format );
1271  wxString out;
1272 
1273  out.PrintfV( format, args );
1274  va_end( args );
1275 
1276  ReportError( error, out );
1277 }
1278 
1279 void a2dGeneralGlobal::DoPrintfUtf8Warn( const a2dError& error, const char* format, ... )
1280 {
1281  va_list args;
1282  va_start( args, format );
1283  wxString out;
1284 
1285  out.PrintfV( format, args );
1286  va_end( args );
1287 
1288  ReportError( error, out );
1289 }
1290 
1291 #endif // wxUSE_UNICODE_UTF8
1292 
1293 #else
1294 /*
1295 void a2dGeneralGlobal::ReportErrorFF( const a2dError& error, ... )
1296 {
1297  wxString errorformat = error.GetErrorMessage();
1298  if ( errorformat.IsEmpty() )
1299  errorformat = wxT("%s");
1300 
1301  va_list ap;
1302 
1303  wxString errorstr;
1304  va_start( ap, errorformat );
1305 
1306  errorstr.PrintfV( errorformat, ap );
1307  va_end( ap );
1308 
1309  ReportError( error, errorstr );
1310 }
1311 */
1312 void a2dGeneralGlobal::ReportErrorF( const a2dError& error, const wxChar* Format, ... )
1313 {
1314  va_list ap;
1315 
1316  wxString errorstr;
1317  va_start( ap, Format );
1318 
1319  errorstr.PrintfV( Format, ap );
1320  va_end( ap );
1321 
1322  ReportError( error, errorstr );
1323 }
1324 
1325 void a2dGeneralGlobal::ReportWarningF( const a2dError& error, const wxChar* Format, ... )
1326 {
1327  va_list ap;
1328 
1329  wxString errorstr;
1330  va_start( ap, Format );
1331 
1332  errorstr.PrintfV( Format, ap );
1333  va_end( ap );
1334 
1335  ReportWarning( error, errorstr );
1336 }
1337 
1338 #endif //wxCHECK_VERSION(2,9,0)
1339 
1340 
1341 void a2dGeneralGlobal::ReportWarning( const a2dError& error, const wxString& errorstr )
1342 {
1343  if( m_ignoredErrorIds.Index( error.GetErrorCode() ) != wxNOT_FOUND )
1344  return;
1345 
1346  wxString errorsmes = error.GetErrorMessage();
1347  if ( !errorstr.IsEmpty() )
1348  errorsmes = errorstr;
1349  m_errors.push_back( a2dError( error.GetIdName(), errorsmes, true ) );
1350 
1351 
1352  if ( m_directlog )
1353  wxLogWarning( errorsmes );
1354 }
1355 
1357 {
1358  wxString errors;
1359  forEachIn( a2dErrorVector, &m_errors )
1360  {
1361  a2dErrorVector::value_type errorRecord = *iter;
1362  errors += errorRecord.GetErrorMessage() + wxT( ".\n" );
1363  }
1364  return errors;
1365 }
1366 
1368 {
1369  if ( !m_directlog )
1370  {
1371  forEachIn( a2dErrorVector, &m_errors )
1372  {
1373  a2dErrorVector::value_type errorRecord = *iter;
1374  wxLogError( errorRecord.GetErrorMessage() );
1375  }
1376  }
1377  ResetErrors();
1378 }
1379 
1381 {
1382  if ( m_errors.size() )
1383  return m_errors.back().GetErrorCode();
1384  return a2dError_NoError.GetErrorCode();
1385 }
1386 
1387 a2dError a2dGeneralGlobal::GetLastError() const
1388 {
1389  if ( m_errors.size() )
1390  return m_errors.back();
1391  return a2dError_NoError;
1392 }
1393 
1394 void a2dGeneralGlobal::RecordF( wxObject* sender, const wxChar* Format, ... )
1395 {
1396  va_list ap;
1397 
1398  wxString recordstring;
1399  va_start( ap, Format );
1400 
1401  //Format.Replace( wxT("%f"), wxT("%6.3f") );
1402 
1403  recordstring.PrintfV( Format, ap );
1404  va_end( ap );
1405 
1406  a2dCommandProcessorEvent event( wxEVT_RECORD, NULL );//recordstring );
1407  event.SetEventObject( sender );
1408 
1409  ProcessEvent( event );
1410 }
1411 
1412 void a2dGeneralGlobal::RecordF( const wxChar* Format, ... )
1413 {
1414  va_list ap;
1415 
1416  wxString recordstring;
1417  va_start( ap, Format );
1418 
1419  //Format.Replace( wxT("%f"), wxT("%6.3f") );
1420 
1421  recordstring.PrintfV( Format, ap );
1422  va_end( ap );
1423 
1424  a2dCommandProcessorEvent event( wxEVT_RECORD, NULL );//recordstring );
1425  event.SetEventObject( this );
1426 
1427  ProcessEvent( event );
1428 }
1429 
1430 wxString* a2dGeneralGlobal::GetVariableString( const wxString& variablename )
1431 {
1432  wxString* prop = GetVariablesHash().GetVariableString( variablename );
1433 
1434  if( !prop )
1435  {
1436  a2dGeneralGlobals->ReportError( a2dError_GetVar, _( "wrong variable name, variable does not exist" ) );
1437  return NULL;// error, variable does not exist
1438  }
1439 
1440  return prop;
1441 }
1442 
1443 wxString a2dGeneralGlobal::GetWxArt2DVar( bool withSep ) const
1444 {
1445  wxString art2Droot;
1446  wxGetEnv( wxT( "WXART2D" ), &art2Droot );
1447  wxFileName artdir = wxFileName( art2Droot, wxEmptyString );
1448  art2Droot = artdir.GetVolume() + artdir.GetVolumeSeparator() + artdir.GetPath(0, wxPATH_UNIX);
1449 
1450  if( art2Droot.IsEmpty() )
1451  {
1452 #ifndef _GUNIX
1453  wxMessageBox( _( " WXART2D variable not set\nPlease set the WXART2D environment string to the correct dir.\n\nExample : WXART2D=c:\\wxArt2D\n\n" ), _( "environment error" ), wxOK );
1454 #else
1455  wxMessageBox( _( " WXART2D variable not set\nPlease set the WXART2D environment string to the correct dir.\n\nExample : WXART2D=/user/home/wxArt2D; export WXART2D \n\n" ), _( "environment error" ), wxOK );
1456 #endif
1457  }
1458  else
1459  {
1460  if ( withSep )
1461  return art2Droot + wxFileName::GetPathSeparator(wxPATH_UNIX);
1462  }
1463  return art2Droot;
1464 }
1465 
1466 wxString a2dGeneralGlobal::GetWxArt2DArtVar( bool withSep, bool silent ) const
1467 {
1468  wxString* artdir = a2dGeneralGlobals->GetVariablesHash().GetVariableString( wxT( "WXART2D_ART" ) );
1469  wxString artroot;
1470  if ( !artdir || artdir->IsEmpty() )
1471  {
1472  wxGetEnv( wxT( "WXART2D_ART" ), &artroot );
1473  if( artroot.IsEmpty() )
1474  {
1475  wxGetEnv( wxT( "WXART2D" ), &artroot );
1476  if( artroot.IsEmpty() )
1477  {
1478  if ( !silent )
1479  {
1480 #ifndef _GUNIX
1481  wxMessageBox( _( "WXART2D_ART or WXART2D variable not set\nPlease set the WXART2D environment string to the correct dir.\n\nExample : WXART2D=c:\\wxArt2D\n\n" ), _( "environment error" ), wxOK );
1482 #else
1483  wxMessageBox( _( "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" ), _( "environment error" ), wxOK );
1484 #endif
1485  }
1486  return artroot;
1487  }
1488  artroot = artroot + wxFileName::GetPathSeparator(wxPATH_UNIX) + wxT( "art" );
1489  }
1490  }
1491  else
1492  artroot = *artdir;
1493  if ( withSep )
1494  return artroot + wxFileName::GetPathSeparator(wxPATH_UNIX);
1495  return artroot;
1496 }
1497 
1498 
1499 // ----------------------------------------------------------------------------
1500 // class a2dMenuIdItem
1501 // ----------------------------------------------------------------------------
1502 
1503 IMPLEMENT_CLASS( a2dMenuIdItem, wxMenuItem )
1504 
1505 const a2dMenuIdItem a2dMenuIdItem::sm_noCmdMenuId = a2dMenuIdItem( wxT( "NoCommandId" ) );
1506 bool a2dMenuIdItem::m_bitmapinitialized = false;
1507 
1508 a2dMenuIdItemMap& a2dMenuIdItem::GetHashMap()
1509 {
1510  static a2dMemoryCriticalSectionHelper helper;
1511  static a2dMenuIdItemMap ms_Name2Id;
1512  return ms_Name2Id;
1513 }
1514 
1515 a2dMenuIdItem::a2dMenuIdItem( const wxString& menuIdName, const wxString& text, const wxString& help, wxItemKind kind )
1516 {
1517  m_isEnabled = true;
1518  m_isChecked = false;
1519  m_id = wxXmlResource::GetXRCID( menuIdName );
1520  m_kind = kind;
1521  if ( m_id == wxID_ANY )
1522  m_id = wxNewId();
1523  if ( m_id == wxID_SEPARATOR )
1524  m_kind = wxITEM_SEPARATOR;
1525 
1526  SetText( text );
1527  SetHelp( help );
1528 
1529  m_name = menuIdName;
1530  if ( GetHashMap().find( m_name ) == GetHashMap().end() )
1531  {
1532  GetHashMap()[ m_name ] = this;
1533  }
1534  else
1535  wxFAIL_MSG( wxT( "duplicate id" ) );
1536 }
1537 
1539 {
1540  a2dMenuIdItemMap::iterator iter;
1541  for( iter = GetHashMap().begin(); iter != GetHashMap().end(); ++iter )
1542  {
1543  a2dMenuIdItem& item = *( iter->second );
1544  //wxLogDebug( "%s", item.m_name );
1545  //if ( item.m_name == "CmdMenu_Selected_RotateObject90Right" )
1546  // wxLogDebug( "%s", item.m_name );
1547 
1548  wxString art2d = a2dGeneralGlobals->GetWxArt2DArtVar();
1549  art2d += wxT( "resources/" ) ;
1550 
1551  wxImage image;
1552  if ( wxFileExists( art2d + item.m_name + wxT( ".ico" ) ) )
1553  {
1554  if ( image.LoadFile( art2d + item.m_name + wxT( ".ico" ), wxBITMAP_TYPE_ICO ) )
1555  {
1556  item.m_bmpChecked = wxBitmap( image );
1557  wxASSERT_MSG( item.m_bmpChecked.Ok(),
1558  _( "Bitmap for a2dMenuIdItem wrong" ) );
1559  }
1560  item.m_bmpUnchecked = item.m_bmpChecked;
1561  }
1562  if ( wxFileExists( art2d + item.m_name + wxT( ".bmp" ) ) )
1563  {
1564  if ( image.LoadFile( art2d + item.m_name + wxT( ".bmp" ), wxBITMAP_TYPE_BMP ) )
1565  {
1566  item.m_bmpChecked = wxBitmap( image );
1567  wxASSERT_MSG( item.m_bmpChecked.Ok(),
1568  _( "Bitmap for a2dMenuIdItem wrong" ) );
1569  }
1570  item.m_bmpUnchecked = item.m_bmpChecked;
1571  }
1572  if ( wxFileExists( art2d + item.m_name + wxT( ".png" ) ) )
1573  {
1574  if ( image.LoadFile( art2d + item.m_name + wxT( ".png" ), wxBITMAP_TYPE_PNG ) )
1575  {
1576  item.m_bmpChecked = wxBitmap( image );
1577  wxASSERT_MSG( item.m_bmpChecked.Ok(),
1578  _( "Bitmap for a2dMenuIdItem wrong" ) );
1579 
1580  }
1581  item.m_bmpUnchecked = item.m_bmpChecked;
1582  }
1583  if ( wxFileExists( art2d + item.m_name + wxT( "_Un.ico" ) ) )
1584  {
1585  if ( image.LoadFile( art2d + item.m_name + wxT( "_Un.ico" ), wxBITMAP_TYPE_ICO ) )
1586  {
1587  item.m_bmpUnchecked = wxBitmap( image );
1588  wxASSERT_MSG( item.m_bmpUnchecked.Ok(),
1589  _( "Bitmap for a2dMenuIdItem wrong" ) );
1590  }
1591  }
1592  if ( wxFileExists( art2d + item.m_name + wxT( "_Un.bmp" ) ) )
1593  {
1594  if ( image.LoadFile( art2d + item.m_name + wxT( "_Un.bmp" ), wxBITMAP_TYPE_BMP ) )
1595  {
1596  item.m_bmpUnchecked = wxBitmap( image );
1597  wxASSERT_MSG( item.m_bmpUnchecked.Ok(),
1598  _( "Bitmap for a2dMenuIdItem wrong" ) );
1599  }
1600  }
1601  if ( wxFileExists( art2d + item.m_name + wxT( "_Un.png" ) ) )
1602  {
1603  if ( image.LoadFile( art2d + item.m_name + wxT( "_Un.png" ), wxBITMAP_TYPE_PNG ) )
1604  {
1605  item.m_bmpUnchecked = wxBitmap( image );
1606  wxASSERT_MSG( item.m_bmpUnchecked.Ok(),
1607  _( "Bitmap for a2dMenuIdItem wrong" ) );
1608  }
1609  }
1610 
1611 
1612  }
1613  m_bitmapinitialized = true;
1614 }
1615 
1616 const a2dMenuIdItem& a2dMenuIdItem::GetItemByName( const wxString& menuIdName )
1617 {
1618  a2dMenuIdItemMap::iterator iterCommand = GetHashMap().find( menuIdName );
1619  return iterCommand != GetHashMap().end() ? *iterCommand->second : a2dMenuIdItem::sm_noCmdMenuId;
1620 }
1621 
1622 #if wxUSE_ACCEL
1623 
1624 wxAcceleratorEntry* a2dMenuIdItem::GetAccel() const
1625 {
1626  return wxAcceleratorEntry::Create( GetText() );
1627 }
1628 
1629 void a2dMenuIdItem::SetAccel( wxAcceleratorEntry* accel )
1630 {
1631  wxString text = m_text.BeforeFirst( wxT( '\t' ) );
1632  if ( accel )
1633  {
1634  text += wxT( '\t' );
1635  text += accel->ToString();
1636  }
1637 
1638  SetText( text );
1639 }
1640 
1641 #endif // wxUSE_ACCEL
1642 
1643 void a2dMenuIdItem::SetText( const wxString& str )
1644 {
1645  m_text = str;
1646 }
1647 
1648 void a2dMenuIdItem::SetHelp( const wxString& str )
1649 {
1650  m_help = str;
1651 }
1652 
1653 wxString a2dMenuIdItem::GetLabelText( const wxString& label )
1654 {
1655  return wxStripMenuCodes( label );
1656 }
1657 
1658 void a2dMenuIdItem::SetBitmaps( const wxBitmap& bmpChecked, const wxBitmap& bmpUnchecked )
1659 {
1660  m_bmpChecked = bmpChecked;
1661  m_bmpUnchecked = bmpUnchecked;
1662 }
virtual bool ContainsCommand(a2dCommand *command)
return true if this command/group are nested group contains the given command
Definition: comevt.cpp:180
wxString m_menuString
if set this will be used for menu Undo/Redo labels, else the m_commandId its name is used...
Definition: comevt.h:282
void SetCommandProcessor(a2dCommandProcessor *cmp)
set when submitting this command via a2dCommandProcessor
Definition: comevt.h:217
virtual a2dObject * DoClone(CloneOptions options, a2dRefMap *refs) const
Clone this object and return a pointer to the new object.
Definition: comevt.cpp:249
virtual bool Undo()=0
Override this to undo a command.
virtual ~a2dCommandProcessor()
destructor
Definition: comevt.cpp:707
property to hold an unsigned 4 byte integer type variable to be associated with a a2dObject ...
Definition: gen.h:2453
(In) Visible property that can be added to Docview Objects.
Definition: gen.h:1785
static const a2dCommandId Id
Set a string environment variable.
Definition: comevt.h:1349
A2DGENERALDLLEXP long wxGenNewId()
This function is like wxNewId, but it has its own ID set.
Definition: gen.cpp:92
static a2dVariablesHash m_variableList
aliaslist containing internal variables
Definition: comevt.h:1213
virtual bool RedoCommand(a2dCommand &cmd)
sents a a2dCommandProcessorEvent with id ::wxEVT_REDO
Definition: comevt.cpp:811
bool Undo()
Override this to undo a command.
Definition: comevt.cpp:667
virtual bool Undo()
Undo one command or command group.
Definition: comevt.cpp:918
wxString GetIdName() const
name of the name of this error id
Definition: gen.h:672
virtual bool ContainsCommand(a2dCommand *command)
return true if this command/group are nested group contains the given command
Definition: comevt.cpp:405
virtual bool PostDo()
Override this to perform a dependency action after command is done.
Definition: comevt.h:203
virtual wxString GetGroupName() const
return command name
Definition: comevt.h:384
const a2dError a2dError_CommandError
virtual bool Redo()
Redo one command or command group.
Definition: comevt.cpp:933
static a2dPathList m_configpath
Path(s) for configuration file(s) in an application.
Definition: comevt.h:1201
void IgnoreError(unsigned int id)
Add an error to the list of ignored errors.
Definition: comevt.cpp:1213
virtual bool CanUndo() const
Are there commands to undo and can they be undone ?
Definition: comevt.cpp:967
virtual bool DoCommand(a2dCommand &cmd)
sents a a2dCommandProcessorEvent with id ::wxEVT_DO
Definition: comevt.cpp:787
virtual bool ClearAfterCurrentCommand(a2dCommand *current)
Hierarchically clear all commands after current command.
Definition: comevt.cpp:160
const a2dError a2dError_GetVar
class to map references to objects stored in XML, in order to make the connection later on...
Definition: gen.h:3462
static const a2dMenuIdItem sm_noCmdMenuId
constant to defined non valid id.
Definition: comevt.h:1570
see a2dCommandProcessorEvent
Definition: comevt.h:649
wxString GetUndoMenuLabel() const
Gets the current Undo menu label.
Definition: comevt.cpp:1010
~a2dCommandGroup(void)
destructor
Definition: comevt.cpp:242
a2dAutoZeroPtr< a2dObject > m_propRefObject
all property references will be set NULL when this object, having the property, will be deleted...
Definition: comevt.h:607
virtual bool Do()=0
Override this to perform a command.
bool Do()
Override this to perform a command.
Definition: comevt.cpp:655
One Global instance of this class exists, in order to get to global needed objects.
Definition: comevt.h:1099
virtual a2dCommand * CloneAndBind(a2dObject *object)
Copy and instantiate the command.
Definition: comevt.cpp:149
virtual a2dCommand * FindNext(a2dCommand *current) const
Find the next command of the given command.
Definition: comevt.cpp:346
Ref Counted base object.
Definition: gen.h:1045
virtual bool Redo()
Definition: comevt.cpp:155
const a2dError a2dError_NoError
int a2dErrorWarningCode
error codes generated in docview framework.
Definition: gen.h:259
a2dObject * Clone(CloneOptions options, a2dRefMap *refs=NULL) const
create an exact copy of this property
Definition: gen.cpp:1199
store a menu Id generated by XRCID( menuIdString ) plus a menustring and helpstring ...
Definition: comevt.h:1563
property to hold a double type variable to be associated with a a2dObject
Definition: gen.h:2503
a2dErrorWarningCode GetLastErrorCode() const
code of the last warning or error
Definition: comevt.cpp:1380
property to hold a bool type variable to be associated with a a2dObject
Definition: gen.h:2004
Input and output handler for the XmlSer format.
Definition: genxmlpars.h:819
Path searching.
Definition: gen.h:2926
static const a2dCommandId Id
Set a string environment variable.
Definition: comevt.h:1421
const wxString & GetText() const
get plain text for menu
Definition: comevt.h:1599
wxString m_redoAccelerator
associated redo accelerator
Definition: comevt.h:1033
a2dNamedProperty * GetProperty(const a2dPropertyId *propertyId, a2dPropertyId::Flags flags=a2dPropertyId::flag_none) const
get property on this object
Definition: gen.cpp:1590
bool m_canUndo
can this command be undone
Definition: comevt.h:268
a2dCommandProcessor * m_cmp
allows commands to get to the command processor that submitted the command.
Definition: comevt.h:279
wxString m_groupName
name of group of commands
Definition: comevt.h:431
virtual a2dObject * DoClone(CloneOptions options, a2dRefMap *refs) const
Clone this object and return a pointer to the new object.
Definition: comevt.cpp:132
list of a2dNamedProperty objects
Definition: gen.h:804
see wx/general/smrtptr.h
const a2dCommandId * m_commandId
can be used to identify the command
Definition: comevt.h:273
virtual void Initialize()
Initialises the current command and menu strings.
Definition: comevt.cpp:989
property to hold a FileName type variable to be associated with a a2dObject
Definition: gen.h:3035
property to hold a a2dObjectPtr smart pointer type variable to be associated with a a2dObject ...
Definition: gen.h:2199
void SetParentGroup(a2dCommandGroup *parent)
set the parent group of this group
Definition: comevt.h:414
Definition: gen.h:276
static const a2dCommandId sm_groupCommandId
property for group command id
Definition: comevt.h:150
~a2dCommand(void)
destructor
Definition: comevt.cpp:145
property to hold a 2 byte integer type variable to be associated with a a2dObject ...
Definition: gen.h:2301
virtual bool UndoCommand(a2dCommand &cmd)
sents a a2dCommandProcessorEvent with id ::wxEVT_UNDO
Definition: comevt.cpp:799
wxString GetRedoMenuLabel() const
Gets the current Undo menu label.
Definition: comevt.cpp:1032
base command processor
Definition: comevt.h:829
void SetProperty(a2dNamedProperty *propertyHolder, a2dPropertyId::SetFlags flags=a2dPropertyId::set_none)
Set the property to the this object.
Definition: gen.cpp:1605
a2dCommandPtr m_currentCommand
this is the tree-trace to the currently active command
Definition: comevt.h:1028
a2dCommandGroup * FindActiveGroup()
find the currently active command group
Definition: comevt.cpp:731
Set a environment variable.
Definition: comevt.h:1340
a group of commands, used to group commands together for undo/redo
Definition: comevt.h:360
property to hold a 2 byte integer type variable to be associated with a a2dObject ...
Definition: gen.h:2401
const a2dPropertyId * m_id
id of the property that is set.
Definition: comevt.h:613
a2dMenuIdItem(const wxString &menuIdName=wxEmptyString, const wxString &text=wxEmptyString, const wxString &help=wxEmptyString, wxItemKind kind=wxITEM_NORMAL)
constructor
Definition: comevt.cpp:1515
bool m_active
If true, this command group is not yet closed and may still receive commands.
Definition: comevt.h:436
virtual a2dCommand * FindNext(a2dCommand *current) const
Find the next command of the given command.
Definition: comevt.cpp:170
a2dCommandGroup * m_parentGroup
this is the parent group of this group
Definition: comevt.h:428
virtual bool DoPreCommand(a2dCommand &cmd)
Called before doing the actual command.
Definition: comevt.cpp:769
virtual bool Remove(a2dCommand *command)
Remove the given command in this group or a subgroup.
Definition: comevt.cpp:379
a2dCommandGroup(const wxString &name, a2dCommandGroup *parent=NULL)
constructor
Definition: comevt.cpp:211
virtual class a2dCommandGroup * IsCommandGroup()
This is like a wxDynamicCast, but much faster.
Definition: comevt.h:232
static const a2dCommandId sm_noCommandTypeId
property for type of command id
Definition: comevt.h:148
#define forEachIn(listtype, list)
easy iteration for a2dlist
Definition: a2dlist.h:111
virtual void ReportError(const a2dError &error, const wxString &errorstr=wxEmptyString)
concatenate to the the error report the given error.
Definition: comevt.cpp:1221
void CommandGroupEnd(a2dCommandGroup *group)
End a command group.
Definition: comevt.cpp:1125
wxUint32 m_maxNoCommands
maximum number of commands to store
Definition: comevt.h:1020
a2dCommandGroup * CommandGroupBegin(const wxString &name)
Start a new command group.
Definition: comevt.cpp:1096
a2dSmrtPtr< a2dCommandGroup > m_currentGroup
this is the parent group of the current command ( which may be a group itself )
Definition: comevt.h:1025
virtual bool CanRedo() const
Are there commands to redo and can they be redone ?
Definition: comevt.cpp:974
const a2dCommandId * GetCommandId()
a specific id for this command.
Definition: comevt.h:179
#define wxStaticCast(obj, className)
The wxWindows 2.4.2 wxStaticCast is buggy. It evaluates its argument twice.
Definition: gen.h:123
wxString m_undoAccelerator
associated undo accelerator attached to menu
Definition: comevt.h:1031
wxString * GetVariableString(const wxString &variablename)
get a variable from the internal aliases list
Definition: comevt.cpp:1430
A2DGENERALDLLEXP a2dSmrtPtr< a2dGeneralGlobal > a2dGeneralGlobals
a global pointer to get to global instance of important classes.
Definition: comevt.cpp:1148
Set a string variable inside wxDocview.
Definition: comevt.h:1277
a2dNamedProperty * Clone(a2dObject::CloneOptions options, a2dRefMap *refs=NULL) const
Virtual copy constructor.
Definition: gen.cpp:1820
static const a2dCommandId & GetCommandByName(const wxString &commandName)
search Id given the name of the command
Definition: comevt.cpp:82
Holds internal variables to be used whereever needed.
Definition: gen.h:3223
virtual bool Undo()
Override this to undo a command.
Definition: comevt.cpp:465
static const a2dCommandId Id
Set a string variable inside wxDocview.
Definition: comevt.h:1286
virtual bool ClearAfterCurrentCommand(a2dCommand *current)
Hierarchically clear all commands after current.
Definition: comevt.cpp:264
a2dCommand * GetCurrentCommand() const
command list access
Definition: comevt.h:916
Input and output handler for the XmlSer format.
Definition: genxmlpars.h:862
virtual bool PreDo()
Override this to perform a dependency action before command is done.
Definition: comevt.h:200
a2dVariablesHash & GetVariablesHash()
aliases list for setting internal variables
Definition: comevt.h:1168
virtual void ReportWarning(const a2dError &error, const wxString &errorstr)
concatenate to the error report the given warning.
Definition: comevt.cpp:1341
a2dCommandList m_subcommands
the list of subcommands
Definition: comevt.h:438
virtual void ClearCommands()
remove all commands stored
Definition: comevt.cpp:1059
void SentBusyEvent(bool start, a2dCommand *command)
Definition: comevt.cpp:823
virtual bool Redo()
Definition: comevt.cpp:444
Each a2dCommand is given a command id at construction.
Definition: comevt.h:99
wxString * GetVariableString(const wxString &variableName)
get an existing wxString variable
Definition: gen.cpp:4321
virtual bool Submit(a2dCommand *command, bool storeIt=true)
next to the base class submit, it sets a2DocumentCommandProcessor for a2dCommand
Definition: comevt.cpp:842
int m_refcount
how many references to this object do exist
Definition: gen.h:1564
property to hold a wxString type variable to be associated with a a2dObject
Definition: gen.h:2066
a2dSmrtPtr< a2dCommandGroup > m_rootGroup
this is the root of the command group tree
Definition: comevt.h:1022
a2dCommand(bool canUndo=false, const a2dCommandId &commandId=sm_noCommandId, const a2dCommandId &commandTypeId=sm_noCommandTypeId, const wxString &menuString=wxEmptyString)
constructor
Definition: comevt.cpp:103
static a2dErrorVector m_errors
list of all possible errors
Definition: comevt.h:1207
a2dPropertyEditEvent(a2dObject *object, a2dNamedPropertyList *properties=NULL)
constructor
Definition: comevt.cpp:489
virtual bool Remove(a2dCommand *command)
Remove the given command.
Definition: comevt.cpp:175
static wxArrayInt m_ignoredErrorIds
list of error id&#39;s to be ignored.
Definition: comevt.h:1210
virtual wxString GetName() const
Definition: comevt.cpp:138
void SetCurrentGroup(a2dCommandGroup *group)
set current group
Definition: comevt.cpp:1090
virtual bool DoPostCommand(a2dCommand &cmd)
Called after doing the actual command.
Definition: comevt.cpp:778
bool ClearCommandsById(const a2dCommandId &commandId, a2dCommand *fromcommand=NULL)
erase commands with a certain id, starting at fromcommand
Definition: comevt.cpp:291
static const a2dMenuIdItem & GetItemByName(const wxString &menuIdName)
search Id given the name of the command
Definition: comevt.cpp:1616
virtual bool SetOrAddPropertyToObject(a2dObject *propRefObject, const wxString &name, const wxString &value=wxT(""), bool withUndo=true)
set a named property to the given object
Definition: comevt.cpp:1066
virtual a2dCommand * FindPrevious(a2dCommand *current) const
Find the previous command of the given command.
Definition: comevt.cpp:165
wxString GetErrorsAsString()
concatenate all errors found into one string.
Definition: comevt.cpp:1356
const a2dCommandId * m_commandTypeId
if set can be used to identify groups of commands
Definition: comevt.h:276
void SetCurrentToLastActive()
Set the current command to the last command in the active group.
Definition: comevt.cpp:750
This is the base class for all kinds of property id&#39;s for a2dObject.
Definition: id.h:154
virtual void SetMenuStrings()
does sent an event to update menu strings after a command
Definition: comevt.cpp:995
static bool m_directlog
logging to wxLog target on or off
Definition: comevt.h:1204
void SetErrorMessage(const wxString &error)
set error message
Definition: gen.h:680
a2dErrorWarningCode GetErrorCode() const
get error code
Definition: gen.h:677
bool SmrtPtrRelease()
Definition: comevt.cpp:719
wxString GetErrorMessage() const
get error string
Definition: gen.h:675
a2dNamedPropertyPtr m_property
property set to the object.
Definition: comevt.h:610
virtual void ReportErrorF(const a2dError &error, const wxChar *Format,...)
concatenate to the the error report the given error.
Definition: comevt.cpp:1312
property to hold a wxObject variable to be associated with a a2dObject
Definition: gen.h:2164
command processor and intializing and event handling classes specific for wxDocview.
Event sent to a2dCommandProcessor.
Definition: comevt.h:701
static a2dHashMapCommandIds & GetHashMap()
return hash of commands
Definition: comevt.cpp:88
Get internal variable.
Definition: comevt.h:1412
void SendToLogTarget()
all stored errors and warning are sent to log target using wxLogError()
Definition: comevt.cpp:1367
static wxString GetLabelText(const wxString &text)
get the label from text (implemented in platform-specific code)
Definition: comevt.cpp:1653
virtual bool RemoveProperty(const a2dPropertyId *id, bool all=true)
This function is called by a2dPropertyId to remove a property from the list.
Definition: gen.cpp:1573
virtual void ReportWarningF(const a2dError &error, const wxChar *Format,...)
concatenate to the error report the given warning.
Definition: comevt.cpp:1325
static void InitializeBitmaps()
initialize bitmaps associated with found a2dMenuIdItem&#39;s from files
Definition: comevt.cpp:1538
virtual void Store(a2dCommand *command)
just store the command without executing it
Definition: comevt.cpp:895
virtual void ResetErrors()
reset the error report to empty.
Definition: comevt.cpp:1206
This template class is for property ids with a known data type.
Definition: id.h:477
initializes the general module
Definition: comevt.h:1238
holds one error report.
Definition: gen.h:623
virtual bool Do()
Override this to perform a command.
Definition: comevt.cpp:421
a2dCommandProcessor(int maxCommands=-1)
Constructor.
Definition: comevt.cpp:697
static a2dMenuIdItemMap & GetHashMap()
stored map of names to get id
Definition: comevt.cpp:1508
list of a2dObject&#39;s
Definition: gen.h:3157
wxString GetName() const
get name
Definition: comevt.h:113
CloneOptions
options for cloning
Definition: gen.h:1200
a2dCommand_SetProperty()
for dynamic creation
Definition: comevt.cpp:510
void Add(a2dCommand *command)
add a command to the group
Definition: comevt.cpp:400
static const a2dCommandId sm_noCommandId
property for command id
Definition: comevt.h:146
For exceptions thrown from commands.
Definition: comevt.h:294
used to change a property on objects
Definition: comevt.h:460
virtual a2dCommand * FindPrevious(a2dCommand *current) const
Find the previous command of the given command.
Definition: comevt.cpp:316
property to hold an unsigned 2 byte integer type variable to be associated with a a2dObject ...
Definition: gen.h:2351
Get internal variable.
Definition: comevt.h:1484
a base command for the a2dCommandProcessor
Definition: comevt.h:140
a2dSmrtPtrList< a2dPropertyId > a2dPropertyIdList
list to hold a set of property id objects pointers
Definition: id.h:373
comevt.cpp Source File -- Sun Oct 12 2014 17:04:15 -- Sun Oct 12 2014 -- 1.8.5 -- wxArt2D -- . -- Main Page Reference Documentation