1 ///////////////////////////////////////////////////////////////////////////////
2 //
3 // wxFormBuilder - A Visual Dialog Editor for wxWidgets.
4 // Copyright (C) 2005 José Antonio Hurtado
5 //
6 // This program is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU General Public License
8 // as published by the Free Software Foundation; either version 2
9 // of the License, or (at your option) any later version.
10 //
11 // This program is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
15 //
16 // You should have received a copy of the GNU General Public License
17 // along with this program; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
19 //
20 // Written by
21 // José Antonio Hurtado - joseantonio.hurtado@gmail.com
22 // Juan Antonio Ortega - jortegalalmolda@gmail.com
23 //
24 // Modified by
25 // Andrea Zanellato - zanellato.andrea@gmail.com
26 //
27 ///////////////////////////////////////////////////////////////////////////////
28
29 #include <wx/wxprec.h>
30
31 #ifndef WX_PRECOMP
32 #include <wx/wx.h>
33 #endif
34
35 #include <wx/propgrid/propgrid.h>
36 #include <wx/propgrid/advprops.h>
37 #include <wx/propgrid/manager.h>
38
39 #include "objinspect.h"
40 #include "wxfbadvprops.h"
41
42 #include "model/objectbase.h"
43 #include "utils/debug.h"
44 #include "utils/typeconv.h"
45
46 #include "rad/appdata.h"
47 #include "rad/bitmaps.h"
48 #include "rad/wxfbevent.h"
49 #include "rad/auitabart.h"
50
51 #include <wx/tokenzr.h>
52 #include <wx/config.h>
53
54 static int wxEVT_FB_PROP_BITMAP_CHANGED = wxNewEventType();
55
56 #define WXFB_PROPERTY_GRID 1000
57 #define WXFB_EVENT_GRID 1001
58
59 // -----------------------------------------------------------------------
60 // ObjectInspector
61 // -----------------------------------------------------------------------
BEGIN_EVENT_TABLE(ObjectInspector,wxPanel)62 BEGIN_EVENT_TABLE(ObjectInspector, wxPanel)
63 EVT_PG_CHANGING(WXFB_PROPERTY_GRID, ObjectInspector::OnPropertyGridChanging)
64 EVT_PG_CHANGED(WXFB_PROPERTY_GRID, ObjectInspector::OnPropertyGridChanged)
65 EVT_PG_CHANGED(WXFB_EVENT_GRID, ObjectInspector::OnEventGridChanged)
66 EVT_PG_DOUBLE_CLICK(WXFB_EVENT_GRID, ObjectInspector::OnEventGridDblClick)
67 EVT_PG_DOUBLE_CLICK(WXFB_PROPERTY_GRID, ObjectInspector::OnPropertyGridDblClick)
68 EVT_PG_ITEM_COLLAPSED(WXFB_PROPERTY_GRID, ObjectInspector::OnPropertyGridExpand)
69 EVT_PG_ITEM_EXPANDED(WXFB_PROPERTY_GRID, ObjectInspector::OnPropertyGridExpand)
70 EVT_PG_ITEM_COLLAPSED(WXFB_EVENT_GRID, ObjectInspector::OnEventGridExpand)
71 EVT_PG_ITEM_EXPANDED(WXFB_EVENT_GRID, ObjectInspector::OnEventGridExpand)
72 EVT_PG_SELECTED(WXFB_PROPERTY_GRID, ObjectInspector::OnPropertyGridItemSelected)
73 EVT_PG_SELECTED(WXFB_EVENT_GRID, ObjectInspector::OnPropertyGridItemSelected)
74
75 EVT_FB_OBJECT_SELECTED( ObjectInspector::OnObjectSelected )
76 EVT_FB_PROJECT_REFRESH( ObjectInspector::OnProjectRefresh )
77 EVT_FB_PROPERTY_MODIFIED( ObjectInspector::OnPropertyModified )
78 EVT_FB_EVENT_HANDLER_MODIFIED( ObjectInspector::OnEventHandlerModified )
79 #if wxVERSION_NUMBER >= 2900
80 EVT_CHILD_FOCUS( ObjectInspector::OnChildFocus )
81 #endif
82 END_EVENT_TABLE()
83
84 ObjectInspector::ObjectInspector( wxWindow* parent, int id, int style )
85 : wxPanel(parent,id), m_style(style)
86 {
87 AppData()->AddHandler( this->GetEventHandler() );
88 m_currentSel = PObjectBase();
89
90 #ifdef USE_FLATNOTEBOOK
91 long nbStyle;
92 wxConfigBase* config = wxConfigBase::Get();
93 config->Read( wxT("/mainframe/objectInspector/notebook_style"), &nbStyle, wxFNB_NO_X_BUTTON | wxFNB_NO_NAV_BUTTONS | wxFNB_NODRAG | wxFNB_DROPDOWN_TABS_LIST | wxFNB_FF2 | wxFNB_CUSTOM_DLG );
94
95 m_nb = new wxFlatNotebook( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, FNB_STYLE_OVERRIDES( nbStyle ) );
96 m_nb->SetCustomizeOptions( wxFNB_CUSTOM_TAB_LOOK | wxFNB_CUSTOM_ORIENTATION | wxFNB_CUSTOM_LOCAL_DRAG );
97
98 m_icons.Add( AppBitmaps::GetBitmap( wxT("properties"), 16 ) );
99 m_icons.Add( AppBitmaps::GetBitmap( wxT("events"), 16 ) );
100 m_nb->SetImageList( &m_icons );
101 #else
102 m_nb = new wxAuiNotebook( this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxAUI_NB_TOP );
103 m_nb->SetArtProvider( new AuiTabArt() );
104 #endif
105
106 // The colour of property grid description looks ugly if we don't set this colour
107 m_nb->SetBackgroundColour(wxSystemSettings::GetColour(wxSYS_COLOUR_3DFACE));
108
109 // Register the slider editor
110 #if wxUSE_SLIDER
111 #if wxVERSION_NUMBER < 2900
112 wxPGEditor* sliderEditor = new wxPGSliderEditor();
113 wxPropertyGrid::RegisterEditorClass( sliderEditor, wxT("Slider") );
114 #else
115 // TODO
116 #endif
117 #endif
118 m_pg = CreatePropertyGridManager(m_nb, WXFB_PROPERTY_GRID);
119 m_eg = CreatePropertyGridManager(m_nb, WXFB_EVENT_GRID);
120
121 m_nb->AddPage( m_pg, _("Properties"), false, 0 );
122 m_nb->AddPage( m_eg, _("Events"), false, 1 );
123
124 #ifndef USE_FLATNOTEBOOK
125 m_nb->SetPageBitmap( 0, AppBitmaps::GetBitmap( wxT("properties"), 16 ) );
126 m_nb->SetPageBitmap( 1, AppBitmaps::GetBitmap( wxT("events"), 16 ) );
127 #endif
128
129 wxBoxSizer* topSizer = new wxBoxSizer( wxVERTICAL );
130 topSizer->Add( m_nb, 1, wxALL | wxEXPAND, 0 );
131 SetSizer( topSizer );
132
133 Connect( wxID_ANY, wxEVT_FB_PROP_BITMAP_CHANGED, wxCommandEventHandler( ObjectInspector::OnBitmapPropertyChanged) );
134 }
135
~ObjectInspector()136 ObjectInspector::~ObjectInspector()
137 {
138 Disconnect( wxID_ANY, wxEVT_FB_PROP_BITMAP_CHANGED, wxCommandEventHandler( ObjectInspector::OnBitmapPropertyChanged) );
139
140 AppData()->RemoveHandler( this->GetEventHandler() );
141 }
142
SavePosition()143 void ObjectInspector::SavePosition()
144 {
145 // Save Layout
146 wxConfigBase* config = wxConfigBase::Get();
147 config->Write( wxT("/mainframe/objectInspector/DescBoxHeight" ), m_pg->GetDescBoxHeight() );
148 #ifdef USE_FLATNOTEBOOK
149 config->Write( wxT("/mainframe/objectInspector/notebook_style"), m_nb->GetWindowStyleFlag() );
150 #endif
151 }
152
Create(bool force)153 void ObjectInspector::Create( bool force )
154 {
155 PObjectBase sel_obj = AppData()->GetSelectedObject();
156 if ( sel_obj && ( sel_obj != m_currentSel || force ) )
157 {
158 Freeze();
159
160 m_currentSel = sel_obj;
161
162 int pageNumber = m_pg->GetSelectedPage();
163 wxString pageName;
164 if ( pageNumber != wxNOT_FOUND )
165 {
166 pageName = m_pg->GetPageName( pageNumber );
167 }
168
169 // Clear Property Grid Manager
170 m_pg->Clear();
171
172 // Now we do the same thing for event grid...
173 m_eg->Clear();
174
175 m_propMap.clear();
176 m_eventMap.clear();
177
178 PObjectInfo obj_desc = sel_obj->GetObjectInfo();
179 if (obj_desc)
180 {
181 PropertyMap propMap, dummyPropMap;
182 EventMap eventMap, dummyEventMap;
183
184 // We create the categories with the properties of the object organized by "classes"
185 CreateCategory( obj_desc->GetClassName(), sel_obj, obj_desc, propMap, false );
186 CreateCategory( obj_desc->GetClassName(), sel_obj, obj_desc, eventMap, true );
187
188 for (unsigned int i=0; i<obj_desc->GetBaseClassCount() ; i++)
189 {
190 PObjectInfo info_base = obj_desc->GetBaseClass(i);
191 CreateCategory( info_base->GetClassName(), sel_obj, info_base, propMap, false );
192 CreateCategory( info_base->GetClassName(), sel_obj, info_base, eventMap, true );
193 }
194
195 PObjectBase parent = sel_obj->GetParent();
196 if ( parent )
197 {
198 PObjectInfo parent_desc = parent->GetObjectInfo();
199 if ( parent_desc->GetObjectType()->IsItem())
200 {
201 CreateCategory( parent_desc->GetClassName(), parent, parent_desc, dummyPropMap, false );
202 CreateCategory( parent_desc->GetClassName(), parent, parent_desc, dummyEventMap, true );
203
204 for (unsigned int i=0; i<parent_desc->GetBaseClassCount() ; i++)
205 {
206 PObjectInfo info_base = parent_desc->GetBaseClass(i);
207 CreateCategory( info_base->GetClassName(), parent, info_base, dummyPropMap, false );
208 CreateCategory( info_base->GetClassName(), parent, info_base, dummyEventMap, true );
209 }
210 }
211 }
212
213 // Select previously selected page, or first page
214 if ( m_pg->GetPageCount() > 0 )
215 {
216 int pageIndex = m_pg->GetPageByName( pageName );
217 if ( wxNOT_FOUND != pageIndex )
218 {
219 m_pg->SelectPage( pageIndex );
220 }
221 else
222 {
223 m_pg->SelectPage( 0 );
224 }
225 }
226 }
227
228 m_pg->Refresh();
229 m_pg->Update();
230 m_eg->Refresh();
231 m_eg->Update();
232 Thaw();
233
234 RestoreLastSelectedPropItem();
235 }
236 }
237
StringToBits(const wxString & strVal,wxPGChoices & constants)238 int ObjectInspector::StringToBits(const wxString& strVal, wxPGChoices& constants)
239 {
240 wxStringTokenizer strTok(strVal, wxT(" |"));
241 int val = 0;
242 while (strTok.HasMoreTokens())
243 {
244 wxString token = strTok.GetNextToken();
245 unsigned int i = 0;
246 bool done = false;
247 while (i < constants.GetCount() && !done)
248 {
249 if (constants.GetLabel(i) == token)
250 {
251 val |= constants.GetValue(i);
252 done = true;
253 }
254 i++;
255 }
256 }
257 return val;
258 }
259
GetProperty(PProperty prop)260 wxPGProperty* ObjectInspector::GetProperty( PProperty prop )
261 {
262 wxPGProperty *result = NULL;
263 PropertyType type = prop->GetType();
264 wxString name = prop->GetName();
265 wxVariant vTrue = wxVariant( true, wxT("true") );
266
267 if (type == PT_MACRO)
268 {
269 result = new wxStringProperty( name, wxPG_LABEL, prop->GetValueAsString() );
270 }
271 else if (type == PT_INT)
272 {
273 result = new wxIntProperty( name, wxPG_LABEL, prop->GetValueAsInteger() );
274 }
275 else if (type == PT_UINT)
276 {
277 result = new wxUIntProperty( name, wxPG_LABEL, (unsigned)prop->GetValueAsInteger() );
278 }
279 else if (type == PT_WXSTRING || type == PT_WXSTRING_I18N)
280 {
281 result = new wxLongStringProperty( name, wxPG_LABEL, prop->GetValueAsText() );
282 }
283 else if (type == PT_TEXT)
284 {
285 result = new wxLongStringProperty( name, wxPG_LABEL, prop->GetValueAsString() );
286 result->ChangeFlag( wxPG_PROP_NO_ESCAPE, true );
287 }
288 else if (type == PT_BOOL)
289 {
290 result = new wxBoolProperty( name, wxPG_LABEL, prop->GetValue() == wxT("1") );
291 }
292 else if (type == PT_BITLIST)
293 {
294 PPropertyInfo prop_desc = prop->GetPropertyInfo();
295 POptionList opt_list = prop_desc->GetOptionList();
296
297 assert(opt_list && opt_list->GetOptionCount() > 0);
298
299 wxPGChoices constants;
300 const std::map< wxString, wxString > options = opt_list->GetOptions();
301 std::map< wxString, wxString >::const_iterator it;
302 unsigned int i = 0;
303 for( it = options.begin(); it != options.end(); ++it )
304 {
305 constants.Add( it->first, 1 << i++ );
306 }
307
308 int val = StringToBits(prop->GetValueAsString(), constants);
309 result = new wxFlagsProperty(name, wxPG_LABEL, constants, val);
310
311 // Workaround to set the help strings for individual members of a wxFlagsProperty
312 wxFlagsProperty* flagsProp = dynamic_cast< wxFlagsProperty* >( result );
313 if ( NULL != flagsProp )
314 {
315 for ( size_t i = 0; i < flagsProp->GetItemCount(); i++ )
316 {
317 wxPGProperty* prop = flagsProp->Item( i );
318 std::map< wxString, wxString >::const_iterator option = options.find( prop->GetLabel() );
319 if ( option != options.end() )
320 {
321 m_pg->SetPropertyHelpString( prop, option->second );
322 }
323 }
324 }
325 }
326 else if (type == PT_INTLIST || type == PT_UINTLIST)
327 {
328 result = new wxStringProperty( name, wxPG_LABEL, IntList( prop->GetValueAsString(), type == PT_UINTLIST ).ToString() );
329 }
330 else if (type == PT_OPTION)
331 {
332 PPropertyInfo prop_desc = prop->GetPropertyInfo();
333 POptionList opt_list = prop_desc->GetOptionList();
334
335 assert(opt_list && opt_list->GetOptionCount() > 0);
336
337 wxString value = prop->GetValueAsString();
338 wxString help;
339
340 wxPGChoices constants;
341 const std::map< wxString, wxString > options = opt_list->GetOptions();
342 std::map< wxString, wxString >::const_iterator it;
343 unsigned int i = 0;
344 for( it = options.begin(); it != options.end(); ++it )
345 {
346 constants.Add( it->first, i++ );
347 if ( it->first == value )
348 {
349 // Save help
350 help = it->second;
351 }
352 }
353
354 result = new wxEnumProperty( name, wxPG_LABEL, constants );
355 result->SetValueFromString( value, 0 );
356 wxString desc = prop_desc->GetDescription();
357 if ( desc.empty() )
358 {
359 desc = value + wxT(":\n") + help;
360 }
361 else
362 {
363 desc += wxT("\n\n") + value + wxT(":\n") + help;
364 }
365 result->SetHelpString( wxGetTranslation( desc ) );
366
367 }
368 else if (type == PT_WXPOINT)
369 {
370 result = new wxFBPointProperty( name, wxPG_LABEL, prop->GetValueAsPoint() );
371 }
372 else if (type == PT_WXSIZE)
373 {
374 result = new wxFBSizeProperty( name, wxPG_LABEL, prop->GetValueAsSize() );
375 }
376 else if (type == PT_WXFONT)
377 {
378 result = new wxFBFontProperty( name, wxPG_LABEL, TypeConv::StringToFont( prop->GetValueAsString() ) );
379 }
380 else if (type == PT_WXCOLOUR)
381 {
382 wxString value = prop->GetValueAsString();
383 if ( value.empty() ) // Default Colour
384 {
385 wxColourPropertyValue colProp;
386 colProp.m_type = wxSYS_COLOUR_WINDOW;
387 colProp.m_colour = TypeConv::StringToSystemColour( wxT("wxSYS_COLOUR_WINDOW") );
388 result = new wxSystemColourProperty( name, wxPG_LABEL, colProp );
389 }
390 else
391 {
392 if ( value.find_first_of( wxT("wx") ) == 0 )
393 {
394 wxColourPropertyValue def; // System Colour
395 def.m_type = TypeConv::StringToSystemColour( value );
396 result = new wxSystemColourProperty( name, wxPG_LABEL, def );
397 }
398 else
399 {
400 result = new wxSystemColourProperty( name, wxPG_LABEL, prop->GetValueAsColour() );
401 }
402 }
403 }
404 else if (type == PT_PATH)
405 {
406 result = new wxDirProperty( name, wxPG_LABEL, prop->GetValueAsString() );
407 }
408 else if (type == PT_FILE)
409 {
410 result = new wxFileProperty( name, wxPG_LABEL, prop->GetValueAsString() );
411 }
412 else if (type == PT_BITMAP)
413 {
414 wxLogDebug( wxT("OI::GetProperty: prop:%s"), prop->GetValueAsString().c_str() );
415
416 result = new wxFBBitmapProperty( name, wxPG_LABEL, prop->GetValueAsString() );
417 }
418 else if (type == PT_STRINGLIST)
419 {
420 result = new wxArrayStringProperty( name, wxPG_LABEL,prop->GetValueAsArrayString() );
421 #if wxVERSION_NUMBER >= 2901
422 wxVariant v("\"");
423 result->DoSetAttribute(wxPG_ARRAY_DELIMITER, v);
424 #endif
425 }
426 else if (type == PT_FLOAT)
427 {
428 result = new wxFloatProperty( name, wxPG_LABEL, prop->GetValueAsFloat() );
429 }
430 else if ( type == PT_PARENT )
431 {
432 result = new wxPGProperty( name, wxPG_LABEL );
433
434 /*wxPGProperty* parent = new wxPGProperty( name, wxPG_LABEL );
435 parent->SetValueFromString( prop->GetValueAsString(), wxPG_FULL_VALUE );
436 //wxPGProperty* parent = new wxStringProperty( name, wxPG_LABEL, wxT("<composed>") );
437 //parent->SetValueFromString( prop->GetValueAsString() );
438
439 PPropertyInfo prop_desc = prop->GetPropertyInfo();
440 std::list< PropertyChild >* children = prop_desc->GetChildren();
441 std::list< PropertyChild >::iterator it;
442 for ( it = children->begin(); it != children->end(); ++it )
443 {
444 wxPGProperty* child = new wxStringProperty( it->m_name, wxPG_LABEL, wxEmptyString );
445 parent->AppendChild( child );
446 m_pg->SetPropertyHelpString( child, it->m_description );
447 }
448
449 result = parent;*/
450 }
451 else // Unknown property
452 {
453 result = new wxStringProperty( name, wxPG_LABEL, prop->GetValueAsString() );
454 result->SetAttribute( wxPG_BOOL_USE_DOUBLE_CLICK_CYCLING, vTrue );
455 wxLogError(_("Property type Unknown") );
456 }
457
458 return result;
459 }
460
AddItems(const wxString & name,PObjectBase obj,PObjectInfo obj_info,PPropertyCategory category,PropertyMap & properties)461 void ObjectInspector::AddItems( const wxString& name, PObjectBase obj,
462 PObjectInfo obj_info, PPropertyCategory category, PropertyMap &properties )
463 {
464 size_t propCount = category->GetPropertyCount();
465 for ( size_t i = 0; i < propCount; i++ )
466 {
467 wxString propName = category->GetPropertyName( i );
468 PProperty prop = obj->GetProperty( propName );
469
470 if ( !prop )
471 continue;
472
473 PPropertyInfo propInfo = prop->GetPropertyInfo();
474
475 // we do not want to duplicate inherited properties
476 if ( properties.find( propName ) == properties.end() )
477 {
478 wxPGProperty* id = m_pg->Append( GetProperty( prop ) );
479 int propType = prop->GetType();
480
481 if ( propType != PT_OPTION )
482 {
483 m_pg->SetPropertyHelpString( id, propInfo->GetDescription() );
484
485 if ( propType == PT_BITMAP )
486 {
487 wxFBBitmapProperty *bp = wxDynamicCast( id, wxFBBitmapProperty );
488 if ( bp )
489 {
490 bp->CreateChildren();
491
492 // perform delayed child properties update
493 wxCommandEvent e( wxEVT_FB_PROP_BITMAP_CHANGED );
494 e.SetString( bp->GetName() + wxT(":") + prop->GetValue() );
495 GetEventHandler()->AddPendingEvent( e );
496
497 //AppData()->ModifyProperty( prop, bp->GetValueAsString() );
498 }
499 }
500 else if( propType == PT_PARENT )
501 {
502 PPropertyInfo prop_desc = prop->GetPropertyInfo();
503 std::list< PropertyChild >* children = prop_desc->GetChildren();
504 std::list< PropertyChild >::iterator it;
505 wxArrayString values = wxStringTokenize( prop->GetValueAsString(), wxT(";"), wxTOKEN_RET_EMPTY_ALL );
506 size_t i = 0;
507 wxString value;
508
509 for ( it = children->begin(); it != children->end(); ++it )
510 {
511 if( values.GetCount() > i ) value = values[i++].Trim().Trim(false);
512 else value = wxT("");
513
514 wxPGProperty* child = new wxStringProperty( it->m_name, wxPG_LABEL, value );
515 id->AppendChild( child );
516 m_pg->SetPropertyHelpString( child, it->m_description );
517 }
518 }
519 }
520
521 wxString customEditor = propInfo->GetCustomEditor();
522 if ( !customEditor.empty() )
523 {
524 wxPGEditor* editor = m_pg->GetEditorByName( customEditor );
525 if ( editor )
526 {
527 m_pg->SetPropertyEditor( id, editor );
528 }
529 }
530
531 if (m_style != wxFB_OI_MULTIPAGE_STYLE)
532 {
533 // Most common classes will be showed with a slightly different colour.
534 if (name == wxT("wxWindow"))
535 m_pg->SetPropertyBackgroundColour(id,wxColour(255,255,205)); // yellow
536 else if (name == wxT("AUI"))
537 m_pg->SetPropertyBackgroundColour(id,wxColour(240,240,255)); // light blue
538 else if (name == wxT("sizeritem") || name == wxT("gbsizeritem") || name == wxT("sizeritembase") )
539 m_pg->SetPropertyBackgroundColour(id,wxColour(220,255,255)); // cyan
540 }
541
542 ExpandMap::iterator it = m_isExpanded.find( propName );
543 if ( it != m_isExpanded.end() )
544 {
545 if ( it->second )
546 {
547 m_pg->Expand( id );
548 }
549 else
550 {
551 m_pg->Collapse( id );
552 }
553 }
554
555 properties.insert( PropertyMap::value_type( propName, prop ) );
556 m_propMap.insert( ObjInspectorPropertyMap::value_type( id, prop ) );
557 }
558 }
559
560 size_t catCount = category->GetCategoryCount();
561 for ( size_t i = 0; i < catCount; i++ )
562 {
563 PPropertyCategory nextCat = category->GetCategory( i );
564 if ( 0 == nextCat->GetCategoryCount() && 0 == nextCat->GetPropertyCount() )
565 {
566 continue;
567 }
568 wxPGProperty* catId = m_pg->AppendIn( category->GetName() , new wxPropertyCategory( nextCat->GetName() ) );
569
570 AddItems( name, obj, obj_info, nextCat, properties );
571
572 ExpandMap::iterator it = m_isExpanded.find( nextCat->GetName() );
573 if ( it != m_isExpanded.end() )
574 {
575 if ( it->second )
576 {
577 m_pg->Expand( catId );
578 }
579 else
580 {
581 m_pg->Collapse( catId );
582 }
583 }
584 }
585 }
586
AddItems(const wxString & name,PObjectBase obj,PObjectInfo obj_info,PPropertyCategory category,EventMap & events)587 void ObjectInspector::AddItems( const wxString& name, PObjectBase obj,
588 PObjectInfo obj_info, PPropertyCategory category, EventMap &events )
589 {
590 size_t eventCount = category->GetEventCount();
591 for ( size_t i = 0; i < eventCount; i++ )
592 {
593 wxString eventName = category->GetEventName( i );
594 PEvent event = obj->GetEvent( eventName );
595
596 if ( !event )
597 continue;
598
599 PEventInfo eventInfo = event->GetEventInfo();
600
601 // We do not want to duplicate inherited events
602 if ( events.find( eventName ) == events.end() )
603 {
604 wxPGProperty* pgProp = new wxStringProperty( eventInfo->GetName(), wxPG_LABEL, event->GetValue() );
605 wxPGProperty* id = m_eg->Append( pgProp );
606
607 m_eg->SetPropertyHelpString( id, wxGetTranslation( eventInfo->GetDescription() ) );
608
609 if (m_style != wxFB_OI_MULTIPAGE_STYLE)
610 {
611 // Most common classes will be showed with a slightly different colour.
612 if (name == wxT("wxWindow"))
613 m_eg->SetPropertyBackgroundColour( id, wxColour( 255, 255, 205 ) ); // Yellow
614 else if (name == wxT("AUI Events"))
615 m_eg->SetPropertyBackgroundColour( id, wxColour(240,240,255) ); // light blue
616 else if (name == wxT("sizeritem") || name == wxT("gbsizeritem") || name == wxT("sizeritembase") )
617 m_eg->SetPropertyBackgroundColour( id, wxColour( 220, 255, 255 ) ); // Cyan
618 }
619
620 ExpandMap::iterator it = m_isExpanded.find(eventName);
621 if ( it != m_isExpanded.end() )
622 {
623 if ( it->second )
624 {
625 m_eg->Expand( id );
626 }
627 else
628 {
629 m_eg->Collapse( id );
630 }
631 }
632
633 events.insert( EventMap::value_type( eventName, event ) );
634 m_eventMap.insert( ObjInspectorEventMap::value_type( id, event ) );
635 }
636 }
637
638 size_t catCount = category->GetCategoryCount();
639 for ( size_t i = 0; i < catCount; i++ )
640 {
641 PPropertyCategory nextCat = category->GetCategory( i );
642 if ( 0 == nextCat->GetCategoryCount() && 0 == nextCat->GetEventCount() )
643 {
644 continue;
645 }
646 wxPGProperty* catId = m_eg->AppendIn( category->GetName(), new wxPropertyCategory( nextCat->GetName() ) );
647
648 AddItems( name, obj, obj_info, nextCat, events );
649
650 ExpandMap::iterator it = m_isExpanded.find( nextCat->GetName() );
651 if ( it != m_isExpanded.end() )
652 {
653 if ( it->second )
654 {
655 m_eg->Expand( catId );
656 }
657 else
658 {
659 m_eg->Collapse( catId );
660 }
661 }
662 }
663 }
664
OnPropertyGridChanging(wxPropertyGridEvent & event)665 void ObjectInspector::OnPropertyGridChanging( wxPropertyGridEvent& event )
666 {
667 wxImageFileProperty *imgFileProp = wxDynamicCast( event.GetProperty(), wxImageFileProperty );
668
669 if ( imgFileProp )
670 {
671 // GetValue() returns the pending value, but is only supported by wxEVT_PG_CHANGING.
672 wxFBBitmapProperty *bmpProp = wxDynamicCast( imgFileProp->GetParent(), wxFBBitmapProperty );
673
674 if ( bmpProp )
675 {
676 wxString img = bmpProp->SetupImage( event.GetValue().GetString() );
677 if ( img == wxEmptyString )
678 {
679 event.Veto();
680 return;
681 }
682 }
683 }
684 }
685
OnPropertyGridChanged(wxPropertyGridEvent & event)686 void ObjectInspector::OnPropertyGridChanged( wxPropertyGridEvent& event )
687 {
688 wxPGProperty* propPtr = event.GetProperty();
689
690 // wxPGProperty *parent = propPtr->GetParent();
691 // wxFBBitmapProperty *bp = wxDynamicCast( parent, wxFBBitmapProperty );
692 //
693 // // Handle the main bitmap property
694 // if ( bp )
695 // {
696 //#if wxVERSION_NUMBER >= 2900
697 // // GetValue() returns wxVariant, but it is converted transparently to wxAny
698 // wxAny
699 //#else
700 // wxVariant
701 //#endif
702 // childValue = propPtr->GetValue();
703 //
704 // // Also, handle the case where property value is unspecified
705 // if ( childValue.IsNull() )
706 // return;
707 //
708 // // bp->GetValue() have no updated value...
709 // wxString bmpVal = bp->GetValueAsString( wxPG_FULL_VALUE );
710 //
711 // // Handle changes in values, as needed
712 // wxVariant thisValue = WXVARIANT( bmpVal );
713 // unsigned int childIndex = propPtr->GetIndexInParent();
714 //
715 //wxLogDebug( wxT("OI::OnPGChanged: thisValue (AsString):%s"), bp->GetValueAsString().c_str() );
716 //wxLogDebug( wxT("OI::OnPGChanged: childValue (AsString):%s"), propPtr->GetValueAsString().c_str() );
717 //wxLogDebug( wxT("OI::OnPGChanged: thisValue:%s childIndex:%i childValue:%s" ),
718 // thisValue.GetString().c_str(), childIndex, childValue.GetString().c_str() );
719 //
720 // ObjInspectorPropertyMap::iterator itBmp = m_propMap.find( bp );
721 // PProperty bmpProp = itBmp->second;
722 //
723 //#if wxVERSION_NUMBER >= 2900
724 // wxVariant newVal =
725 //#endif
726 // bp->ChildChanged( thisValue, propPtr->GetIndexInParent(), childValue );
727 //
728 //#if wxVERSION_NUMBER >= 2900
729 // AppData()->ModifyProperty( bmpProp, newVal.GetString() );
730 //#else
731 // wxLogDebug( wxT("OI::OnPGChanged: Setting prop value to %s"), thisValue.GetString().c_str() );
732 // AppData()->ModifyProperty( bmpProp, thisValue.GetString() );
733 // wxLogDebug( wxT("OI::OnPGChanged: Changed prop value to %s"), bmpProp->GetValueAsString().c_str() );
734 //#endif
735 // }
736
737 ObjInspectorPropertyMap::iterator it = m_propMap.find( propPtr );
738
739 if ( m_propMap.end() == it )
740 {
741 // Could be a child property
742 propPtr = propPtr->GetParent();
743 it = m_propMap.find( propPtr );
744 }
745 if ( it != m_propMap.end() )
746 {
747 PProperty prop = it->second;
748 switch ( prop->GetType() )
749 {
750
751 case PT_FLOAT:
752 {
753 // Use typeconv to properly handle locale
754 double val = m_pg->GetPropertyValueAsDouble( propPtr );
755 ModifyProperty( prop, TypeConv::FloatToString( val ) );
756 break;
757 }
758 case PT_TEXT:
759 case PT_MACRO:
760 case PT_INT:
761 case PT_UINT:
762 {
763 ModifyProperty( prop, m_pg->GetPropertyValueAsString( propPtr ) );
764 break;
765 }
766 case PT_OPTION:
767 {
768 wxString value = m_pg->GetPropertyValueAsString( propPtr );
769 ModifyProperty( prop, value );
770
771 // Update displayed description for the new selection
772 PPropertyInfo prop_desc = prop->GetPropertyInfo();
773 POptionList opt_list = prop_desc->GetOptionList();
774
775 wxString helpString = prop_desc->GetDescription();
776 if ( opt_list && opt_list->GetOptionCount() > 0 )
777 {
778 const std::map< wxString, wxString > options = opt_list->GetOptions();
779 std::map< wxString, wxString >::const_iterator option = options.find( value );
780 if ( option != options.end() )
781 {
782 if ( helpString.empty() )
783 {
784 helpString = value + wxT(":\n") + option->second;
785 }
786 else
787 {
788 helpString += wxT("\n\n") + value + wxT(":\n") + option->second;
789 }
790 }
791 }
792 wxString localized = wxGetTranslation( helpString );
793 m_pg->SetPropertyHelpString( propPtr, localized );
794 m_pg->SetDescription( propPtr->GetLabel(), localized );
795 break;
796 }
797 case PT_PARENT:
798 {
799 #if wxVERSION_NUMBER >= 2900
800 ModifyProperty( prop, propPtr->GenerateComposedValue( ));
801 #else
802 ModifyProperty( prop, propPtr->GetValueAsString( wxPG_FULL_VALUE ) );
803 #endif
804 break;
805 }
806 case PT_WXSTRING:
807 case PT_WXSTRING_I18N:
808 {
809 // ObjectInspector's text strings are formatted.
810 wxString value = TypeConv::TextToString( m_pg->GetPropertyValueAsString( propPtr ) );
811 ModifyProperty( prop, value );
812 break;
813 }
814 case PT_BOOL:
815 {
816 if( prop->GetName() == wxT("aui_managed") )
817 {
818 PObjectBase propobj = prop->GetObject();
819 if( propobj->GetChildCount() )
820 {
821 wxMessageBox(_("You have to remove all child widgets first."));
822 #if wxVERSION_NUMBER < 2900
823 m_pg->SetPropertyValueBool( propPtr, !m_pg->GetPropertyValueAsBool( propPtr ) );
824 #else
825 m_pg->SetPropertyValue( propPtr, !m_pg->GetPropertyValueAsBool( propPtr ) );
826 #endif
827 }
828 else
829 ModifyProperty( prop, m_pg->GetPropertyValueAsBool( propPtr ) ? wxT("1") : wxT("0") );
830 }
831 else
832 ModifyProperty( prop, m_pg->GetPropertyValueAsBool( propPtr ) ? wxT("1") : wxT("0") );
833 break;
834 }
835 case PT_BITLIST:
836 {
837 wxString aux = m_pg->GetPropertyValueAsString( propPtr );
838 aux.Replace( wxT(" "), wxT("") );
839 aux.Replace( wxT(","), wxT("|") );
840 ModifyProperty( prop, aux );
841 break;
842 }
843 case PT_WXPOINT:
844 {
845 #if wxVERSION_NUMBER < 2900
846 wxPoint point = wxPointFromVariant( event.GetPropertyValue () );
847 #else
848 wxPoint point = wxPointRefFromVariant( event.GetPropertyValue () );
849 #endif
850 ModifyProperty( prop, wxString::Format( wxT("%i,%i"), point.x, point.y ) );
851 break;
852 }
853 case PT_WXSIZE:
854 {
855 #if wxVERSION_NUMBER < 2900
856 wxSize size = wxSizeFromVariant( event.GetPropertyValue() );
857 #else
858 wxSize size = wxSizeRefFromVariant( event.GetPropertyValue() );
859 #endif
860 ModifyProperty( prop, wxString::Format( wxT("%i,%i"), size.GetWidth(), size.GetHeight() ) );
861 break;
862 }
863 case PT_WXFONT:
864 {
865 ModifyProperty( prop, event.GetPropertyValue().GetString() );
866 break;
867 }
868 case PT_WXCOLOUR:
869 {
870 wxColourPropertyValue colour;
871 colour << event.GetPropertyValue();
872 switch ( colour.m_type ) {
873 case wxSYS_COLOUR_MAX:
874 ModifyProperty( prop, wxT("") );
875 break;
876 case wxPG_COLOUR_CUSTOM:
877 ModifyProperty( prop, TypeConv::ColourToString( colour.m_colour ) );
878 break;
879 default:
880 wxString sCol = TypeConv::SystemColourToString( colour.m_type );
881 ModifyProperty( prop, sCol );
882 }
883 break;
884 }
885 case PT_INTLIST:
886 case PT_UINTLIST:
887 {
888 IntList il( event.GetPropertyValue(), PT_UINTLIST == prop->GetType() );
889 ModifyProperty( prop, il.ToString() );
890 break;
891 }
892 case PT_BITMAP:
893 {
894 wxVariant childValue = event.GetProperty()->GetValue();
895
896 // Also, handle the case where property value is unspecified
897 if ( childValue.IsNull() )
898 return;
899
900 // bp->GetValue() have no updated value...
901 wxString bmpVal = propPtr->GetValueAsString( wxPG_FULL_VALUE );
902
903 // Handle changes in values, as needed
904 wxVariant thisValue = WXVARIANT(bmpVal);
905
906 #if wxVERSION_NUMBER >= 2900
907 wxVariant newVal =
908 propPtr->ChildChanged( thisValue, (int)event.GetProperty()->GetIndexInParent(), childValue );
909 #else
910 propPtr->ChildChanged( thisValue, event.GetProperty()->GetIndexInParent(), childValue );
911 #endif
912
913 #if wxVERSION_NUMBER >= 2900
914 ModifyProperty( prop, newVal.GetString() );
915 #else
916 ModifyProperty( prop, bmpVal);
917 #endif
918
919 if( event.GetProperty()->GetIndexInParent() > 0 )
920 {
921 // perform delayed child properties update
922 wxCommandEvent e( wxEVT_FB_PROP_BITMAP_CHANGED );
923 e.SetString( propPtr->GetName() + wxT(":") + bmpVal );
924 GetEventHandler()->AddPendingEvent( e );
925 }
926
927 break;
928 }
929
930 default:
931 //ModifyProperty( prop, event.GetPropertyValue() );
932 ModifyProperty( prop, propPtr->GetValueAsString() );
933 }
934 }
935 }
936
OnEventGridChanged(wxPropertyGridEvent & event)937 void ObjectInspector::OnEventGridChanged( wxPropertyGridEvent& event )
938 {
939 ObjInspectorEventMap::iterator it = m_eventMap.find( event.GetProperty() );
940
941 if ( it != m_eventMap.end() )
942 {
943 PEvent evt = it->second;
944 wxString handler = event.GetPropertyValue();
945 handler.Trim();
946 handler.Trim( false );
947 AppData()->ModifyEventHandler( evt, handler );
948 }
949 }
950
OnPropertyGridExpand(wxPropertyGridEvent & event)951 void ObjectInspector::OnPropertyGridExpand( wxPropertyGridEvent& event )
952 {
953 m_isExpanded[event.GetPropertyName()] = event.GetProperty()->IsExpanded();
954
955 wxPGProperty* egProp = m_eg->GetProperty( event.GetProperty()->GetName() );
956 if ( egProp )
957 {
958 if ( event.GetProperty()->IsExpanded() )
959 {
960 m_eg->Expand( egProp );
961 }
962 else
963 {
964 m_eg->Collapse( egProp );
965 }
966 }
967 }
968
OnEventGridExpand(wxPropertyGridEvent & event)969 void ObjectInspector::OnEventGridExpand( wxPropertyGridEvent& event )
970 {
971 m_isExpanded[event.GetPropertyName()] = event.GetProperty()->IsExpanded();
972
973 wxPGProperty* pgProp = m_pg->GetProperty( event.GetProperty()->GetName() );
974 if ( pgProp )
975 {
976 if ( event.GetProperty()->IsExpanded() )
977 {
978 m_pg->Expand( pgProp );
979 }
980 else
981 {
982 m_pg->Collapse( pgProp );
983 }
984 }
985 }
986
987 ///////////////////////////////////////////////////////////////////////////////
OnObjectSelected(wxFBObjectEvent & event)988 void ObjectInspector::OnObjectSelected( wxFBObjectEvent& event)
989 {
990 bool isForced = ( event.GetString() == wxT("force") );
991
992 Create( isForced );
993 }
994
OnProjectRefresh(wxFBEvent &)995 void ObjectInspector::OnProjectRefresh( wxFBEvent& )
996 {
997 Create( true );
998 }
999
OnEventHandlerModified(wxFBEventHandlerEvent & event)1000 void ObjectInspector::OnEventHandlerModified( wxFBEventHandlerEvent& event )
1001 {
1002 PEvent e = event.GetFBEventHandler();
1003 m_eg->SetPropertyValue( e->GetName(), e->GetValue() );
1004 m_eg->Refresh();
1005 }
1006
OnPropertyModified(wxFBPropertyEvent & event)1007 void ObjectInspector::OnPropertyModified( wxFBPropertyEvent& event )
1008 {
1009 LogDebug("");
1010 PProperty prop = event.GetFBProperty();
1011
1012 PObjectBase propobj = prop->GetObject();
1013 PObjectBase appobj = AppData()->GetSelectedObject();
1014
1015 bool shouldContinue = ( prop->GetObject() == AppData()->GetSelectedObject() );
1016 if ( !shouldContinue )
1017 {
1018 // Item objects cannot be selected - their children are selected instead
1019 if ( propobj->GetObjectInfo()->GetObjectType()->IsItem() )
1020 {
1021 if ( propobj->GetChildCount() > 0 )
1022 {
1023 shouldContinue = ( appobj == propobj->GetChild( 0 ) );
1024 }
1025 }
1026 }
1027 if ( !shouldContinue )
1028 {
1029 return;
1030 }
1031
1032 wxPGProperty* pgProp = m_pg->GetPropertyByLabel(prop->GetName() );
1033 if ( pgProp == NULL ) return; // Maybe now isn't showing this page
1034
1035
1036 switch (prop->GetType())
1037 {
1038 case PT_FLOAT:
1039 {
1040 // Use float instead of string -> typeconv handles locale
1041 pgProp->SetValue( WXVARIANT( prop->GetValueAsFloat() ) );
1042 break;
1043 }
1044 case PT_INT:
1045 case PT_UINT:
1046 {
1047 pgProp->SetValueFromString(prop->GetValueAsString(), 0);
1048 break;
1049 }
1050 case PT_TEXT:
1051 pgProp->SetValueFromString(prop->GetValueAsString(), 0);
1052 break;
1053 case PT_MACRO:
1054 case PT_OPTION:
1055 case PT_PARENT:
1056 case PT_WXSTRING:
1057 pgProp->SetValueFromString(prop->GetValueAsText(), 0);
1058 break;
1059 case PT_WXSTRING_I18N:
1060 pgProp->SetValueFromString(prop->GetValueAsText(), 0);
1061 break;
1062 case PT_BOOL:
1063 pgProp->SetValueFromInt(prop->GetValueAsString() == wxT("0") ? 0 : 1, 0);
1064 break;
1065 case PT_BITLIST:
1066 {
1067 wxString aux = prop->GetValueAsString();
1068 aux.Replace(wxT("|"), wxT(", "));
1069 if (aux == wxT("0")) aux = wxT("");
1070 pgProp->SetValueFromString(aux, 0);
1071 }
1072 break;
1073 case PT_WXPOINT:
1074 {
1075 //m_pg->SetPropertyValue( pgProp, prop->GetValue() );
1076 wxString aux = prop->GetValueAsString();
1077 aux.Replace(wxT(","), wxT(";"));
1078 pgProp->SetValueFromString(aux, 0);
1079 }
1080 break;
1081 case PT_WXSIZE:
1082 {
1083 //m_pg->SetPropertyValue( pgProp, prop->GetValue() );
1084 wxString aux = prop->GetValueAsString();
1085 aux.Replace(wxT(","), wxT(";"));
1086 pgProp->SetValueFromString(aux, 0);
1087 }
1088 break;
1089 case PT_WXFONT:
1090 pgProp->SetValue( WXVARIANT( prop->GetValueAsString() ) );
1091 break;
1092 case PT_WXCOLOUR:
1093 {
1094 wxString value = prop->GetValueAsString();
1095 if ( value.empty() ) // Default Colour
1096 {
1097 wxColourPropertyValue def;
1098 def.m_type = wxSYS_COLOUR_WINDOW;
1099 def.m_colour = TypeConv::StringToSystemColour( wxT("wxSYS_COLOUR_WINDOW") );
1100 m_pg->SetPropertyValue( pgProp, def );
1101 }
1102 else
1103 {
1104 if ( value.find_first_of( wxT("wx") ) == 0 )
1105 {
1106 // System Colour
1107 wxColourPropertyValue def;
1108 def.m_type = TypeConv::StringToSystemColour( value );
1109 def.m_colour = prop->GetValueAsColour();
1110 m_pg->SetPropertyValue( pgProp, WXVARIANT( def ) );
1111 }
1112 else
1113 {
1114 wxColourPropertyValue def( wxPG_COLOUR_CUSTOM, prop->GetValueAsColour() );
1115 m_pg->SetPropertyValue( pgProp, WXVARIANT( def ) );
1116 }
1117 }
1118 }
1119 break;
1120 case PT_BITMAP:
1121 // pgProp->SetValue( WXVARIANT( prop->GetValueAsString() ) );
1122 wxLogDebug( wxT("OI::OnPropertyModified: prop:%s"), prop->GetValueAsString().c_str() );
1123 break;
1124 default:
1125 pgProp->SetValueFromString(prop->GetValueAsString(), wxPG_FULL_VALUE);
1126 }
1127 AutoGenerateId(AppData()->GetSelectedObject(), event.GetFBProperty(), wxT("PropChange"));
1128 m_pg->Refresh();
1129 }
1130
CreatePropertyGridManager(wxWindow * parent,wxWindowID id)1131 wxPropertyGridManager* ObjectInspector::CreatePropertyGridManager(wxWindow *parent, wxWindowID id)
1132 {
1133 int pgStyle;
1134 int defaultDescBoxHeight;
1135
1136 switch (m_style)
1137 {
1138 case wxFB_OI_MULTIPAGE_STYLE:
1139 pgStyle = wxPG_BOLD_MODIFIED | wxPG_SPLITTER_AUTO_CENTER | wxPG_TOOLBAR | wxPG_DESCRIPTION | wxPGMAN_DEFAULT_STYLE;
1140 defaultDescBoxHeight = 50;
1141 break;
1142
1143 case wxFB_OI_DEFAULT_STYLE:
1144 case wxFB_OI_SINGLE_PAGE_STYLE:
1145 default:
1146 pgStyle = wxPG_BOLD_MODIFIED | wxPG_SPLITTER_AUTO_CENTER | wxPG_DESCRIPTION | wxPGMAN_DEFAULT_STYLE;
1147 defaultDescBoxHeight = 150;
1148 break;
1149 }
1150
1151 int descBoxHeight;
1152 wxConfigBase* config = wxConfigBase::Get();
1153 config->Read( wxT( "/mainframe/objectInspector/DescBoxHeight" ), &descBoxHeight, defaultDescBoxHeight );
1154 if ( -1 == descBoxHeight )
1155 {
1156 descBoxHeight = defaultDescBoxHeight;
1157 }
1158
1159 wxPropertyGridManager* pg;
1160 pg = new wxPropertyGridManager( parent, id, wxDefaultPosition, wxDefaultSize, pgStyle );
1161 pg->SetDescBoxHeight( descBoxHeight );
1162 // pg->SetExtraStyle( wxPG_EX_NATIVE_DOUBLE_BUFFERING ); Both seems to no more needed.
1163 // pg->SetExtraStyle( wxPG_EX_PROCESS_EVENTS_IMMEDIATELY );
1164
1165 return pg;
1166 }
1167
OnPropertyGridDblClick(wxPropertyGridEvent & event)1168 void ObjectInspector::OnPropertyGridDblClick(wxPropertyGridEvent& event)
1169 {
1170 PObjectBase obj = AppData()->GetSelectedObject();
1171 if( obj )
1172 {
1173 #if wxVERSION_NUMBER < 2900
1174 wxString propName = event.GetPropertyPtr()->GetLabel();
1175 #else
1176 wxString propName = event.GetProperty()->GetLabel();
1177 #endif
1178 AutoGenerateId(obj, obj->GetProperty(propName), wxT("DblClk"));
1179 m_pg->Refresh();
1180 }
1181 }
1182
OnEventGridDblClick(wxPropertyGridEvent & event)1183 void ObjectInspector::OnEventGridDblClick(wxPropertyGridEvent& event)
1184 {
1185 wxPGProperty *pgProp = m_pg->GetPropertyByLabel( wxT("name") );
1186 if ( !pgProp ) return;
1187
1188 #if wxVERSION_NUMBER < 2900
1189 wxPGProperty *p = event.GetPropertyPtr();
1190 p->SetValueFromString( pgProp->GetDisplayedString() + event.GetPropertyLabel() );
1191 #else
1192 wxPGProperty *p = event.GetProperty();
1193 p->SetValueFromString( pgProp->GetDisplayedString() + event.GetProperty()->GetLabel() );
1194 #endif
1195 ObjInspectorEventMap::iterator it = m_eventMap.find( p );
1196 if ( it != m_eventMap.end() )
1197 {
1198 PEvent evt = it->second;
1199 #if wxVERSION_NUMBER < 2900
1200 wxString handler = event.GetPropertyValueAsString();
1201 #else
1202 wxString handler = p->GetValueAsString();
1203 #endif
1204 handler.Trim();
1205 handler.Trim( false );
1206 AppData()->ModifyEventHandler( evt, handler );
1207 };
1208 }
1209
AutoGenerateId(PObjectBase objectChanged,PProperty propChanged,wxString reason)1210 void ObjectInspector::AutoGenerateId(PObjectBase objectChanged, PProperty propChanged, wxString reason)
1211 {
1212 if(objectChanged && propChanged)
1213 {
1214 PProperty prop;
1215 if((propChanged->GetName() == wxT("name") && reason == wxT("PropChange")) ||
1216 (propChanged->GetName() == wxT("id") && reason == wxT("DblClk")))
1217 {
1218 //wxPGId pgid = m_pg->GetPropertyByLabel(wxT(""));
1219 prop = AppData()->GetProjectData()->GetProperty( wxT("event_generation") );
1220 if ( prop )
1221 {
1222 if(prop->GetValueAsString() == wxT("table"))
1223 {
1224 prop = objectChanged->GetProperty(wxT("id"));
1225 if ( prop )
1226 {
1227 if(prop->GetValueAsString() == wxT("wxID_ANY") || reason == wxT("DblClk"))
1228 {
1229 PProperty name(objectChanged->GetProperty(wxT("name")));
1230 wxString idString;
1231 idString << wxT("ID_");
1232 idString << name->GetValueAsString().Upper();
1233 ModifyProperty( prop, idString);
1234
1235 wxPGProperty *pgid = m_pg->GetPropertyByLabel(wxT("id"));
1236 if ( !pgid ) return;
1237 m_pg->SetPropertyValue( pgid, idString );
1238 }
1239 }
1240 }
1241 else
1242 {
1243 prop = objectChanged->GetProperty(wxT("id"));
1244 if ( prop )
1245 {
1246 ModifyProperty( prop, wxT("wxID_ANY"));
1247 wxPGProperty *pgid = m_pg->GetPropertyByLabel(wxT("id"));
1248 if ( !pgid ) return;
1249 m_pg->SetPropertyValue( pgid, wxT("wxID_ANY") );
1250 }
1251 }
1252 }
1253 }
1254 }
1255 m_pg->Update();
1256 }
1257
OnBitmapPropertyChanged(wxCommandEvent & event)1258 void ObjectInspector::OnBitmapPropertyChanged( wxCommandEvent& event )
1259 {
1260 wxLogDebug( wxT("OI::BitmapPropertyChanged: %s"), event.GetString().c_str() );
1261
1262 wxString propName = event.GetString().BeforeFirst( ':' );
1263 wxString propVal = event.GetString().AfterFirst( ':' );
1264
1265 if( !propVal.IsEmpty() )
1266 {
1267 wxFBBitmapProperty *bp = wxDynamicCast( m_pg->GetPropertyByLabel( propName ), wxFBBitmapProperty );
1268 if( bp )
1269 {
1270 bp->UpdateChildValues( propVal );
1271 }
1272 }
1273 }
1274
ModifyProperty(PProperty prop,const wxString & str)1275 void ObjectInspector::ModifyProperty( PProperty prop, const wxString& str )
1276 {
1277 AppData()->RemoveHandler( this->GetEventHandler() );
1278 AppData()->ModifyProperty( prop, str );
1279 AppData()->AddHandler( this->GetEventHandler() );
1280 }
1281
1282 #if wxVERSION_NUMBER >= 2900
OnChildFocus(wxChildFocusEvent & event)1283 void ObjectInspector::OnChildFocus( wxChildFocusEvent& event )
1284 {
1285 // do nothing to avoid "scrollbar jump" if wx2.9 is used
1286 }
1287 #endif
1288
OnPropertyGridItemSelected(wxPropertyGridEvent & event)1289 void ObjectInspector::OnPropertyGridItemSelected( wxPropertyGridEvent& event )
1290 {
1291 wxPGProperty *p = event.GetProperty();
1292 if( p )
1293 {
1294 if( m_nb->GetSelection() == 0 )
1295 {
1296 m_strSelPropItem = m_pg->GetPropertyLabel( p );
1297 m_pageName = wxT("Properties");
1298 }
1299 else
1300 {
1301 m_strSelPropItem = m_eg->GetPropertyLabel( p );
1302 m_pageName = wxT("Events");
1303 }
1304 }
1305 }
1306
RestoreLastSelectedPropItem()1307 void ObjectInspector::RestoreLastSelectedPropItem()
1308 {
1309 if( m_pageName == wxT("Properties") )
1310 {
1311 wxPGProperty* p = m_pg->GetPropertyByLabel( m_strSelPropItem );
1312 if( p )
1313 {
1314 m_pg->SelectProperty(p, true);
1315 m_pg->SetFocus();
1316 }
1317 }
1318 else if( m_pageName == wxT("Events") )
1319 {
1320 wxPGProperty* p = m_eg->GetPropertyByLabel(m_strSelPropItem);
1321 if( p )
1322 {
1323 m_eg->SelectProperty(p, true);
1324 m_eg->SetFocus();
1325 }
1326 }
1327 }