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 ///////////////////////////////////////////////////////////////////////////////
25 
26 #include "objectbase.h"
27 #include "wx/wx.h"
28 #include "utils/debug.h"
29 #include "utils/typeconv.h"
30 #include "utils/stringutils.h"
31 #include "rad/appdata.h"
32 #include <ticpp.h>
33 #include <wx/tokenzr.h>
34 
PropertyInfo(wxString name,PropertyType type,wxString def_value,wxString description,wxString customEditor,POptionList opt_list,const std::list<PropertyChild> & children)35 PropertyInfo::PropertyInfo(wxString name, PropertyType type, wxString def_value, wxString description, wxString customEditor,
36 						   POptionList opt_list, const std::list< PropertyChild >& children )
37 {
38 	m_name = name;
39 	m_type = type;
40 	m_def_value = def_value;
41 	m_opt_list = opt_list;
42 	m_description = description;
43 	m_children = children;
44 	m_customEditor = customEditor;
45 }
46 
~PropertyInfo()47 PropertyInfo::~PropertyInfo()
48 {
49 }
50 
EventInfo(const wxString & name,const wxString & eventClass,const wxString & defValue,const wxString & description)51 EventInfo::EventInfo(const wxString &name, const wxString &eventClass,
52   const wxString &defValue,  const wxString &description)
53   : m_name(name), m_eventClass(eventClass), m_defaultValue(defValue),
54     m_description(description)
55 {
56 }
57 
IsDefaultValue()58 bool Property::IsDefaultValue()
59 {
60 	return (m_info->GetDefaultValue() == m_value);
61 }
62 
IsNull()63 bool Property::IsNull()
64 {
65 	switch ( m_info->GetType() )
66 	{
67 		case PT_BITMAP:
68 		{
69 			wxString path;
70 			size_t semicolonIndex = m_value.find_first_of( wxT(";") );
71 			if ( semicolonIndex != m_value.npos )
72 			{
73 				path = m_value.substr( 0, semicolonIndex );
74 			}
75 			else
76 			{
77 				path = m_value;
78 			}
79 
80 			return path.empty();
81 		}
82 		case PT_WXSIZE:
83 		{
84 			return ( wxDefaultSize == TypeConv::StringToSize( m_value ) );
85 		}
86 		default:
87 		{
88 			return m_value.empty();
89 		}
90 	}
91 }
92 
SetDefaultValue()93 void Property::SetDefaultValue()
94 {
95 	m_value = m_info->GetDefaultValue();
96 }
97 
SetValue(const wxFontContainer & font)98 void Property::SetValue(const wxFontContainer &font)
99 {
100 	m_value = TypeConv::FontToString( font );
101 }
SetValue(const wxColour & colour)102 void Property::SetValue(const wxColour &colour)
103 {
104 	m_value = TypeConv::ColourToString( colour );
105 }
SetValue(const wxString & str,bool format)106 void Property::SetValue(const wxString &str, bool format)
107 {
108 	m_value = (format ? TypeConv::TextToString(str) : str );
109 }
110 
SetValue(const wxPoint & point)111 void Property::SetValue(const wxPoint &point)
112 {
113 	m_value = TypeConv::PointToString(point);
114 }
115 
SetValue(const wxSize & size)116 void Property::SetValue(const wxSize &size)
117 {
118 	m_value = TypeConv::SizeToString(size);
119 }
120 
SetValue(const int integer)121 void Property::SetValue(const int integer)
122 {
123 	m_value = StringUtils::IntToStr(integer);
124 }
125 
SetValue(const double val)126 void Property::SetValue(const double val )
127 {
128 	m_value = TypeConv::FloatToString( val );
129 }
130 
GetValueAsFont()131 wxFontContainer Property::GetValueAsFont()
132 {
133 	return TypeConv::StringToFont( m_value );
134 }
135 
GetValueAsColour()136 wxColour Property::GetValueAsColour()
137 {
138 	return TypeConv::StringToColour(m_value);
139 }
GetValueAsPoint()140 wxPoint Property::GetValueAsPoint()
141 {
142 	return TypeConv::StringToPoint(m_value);
143 }
GetValueAsSize()144 wxSize Property::GetValueAsSize()
145 {
146 	return TypeConv::StringToSize(m_value);
147 }
148 
GetValueAsBitmap()149 wxBitmap Property::GetValueAsBitmap()
150 {
151 	return TypeConv::StringToBitmap( m_value );
152 }
153 
GetValueAsInteger()154 int Property::GetValueAsInteger()
155 {
156 	int result = 0;
157 
158 	switch (GetType())
159 	{
160 	case PT_OPTION:
161 	case PT_MACRO:
162 		result = TypeConv::GetMacroValue(m_value);
163 		break;
164 	case PT_BITLIST:
165 		result = TypeConv::BitlistToInt(m_value);
166 		break;
167 	default:
168 		result = TypeConv::StringToInt(m_value);
169 		break;
170 	}
171 	return result;
172 }
173 
GetValueAsString()174 wxString Property::GetValueAsString()
175 {
176 	return m_value;
177 }
178 
GetValueAsText()179 wxString Property::GetValueAsText()
180 {
181 	return TypeConv::StringToText(m_value);
182 }
183 
GetValueAsArrayString()184 wxArrayString Property::GetValueAsArrayString()
185 {
186 	return TypeConv::StringToArrayString(m_value);
187 }
188 
GetValueAsFloat()189 double Property::GetValueAsFloat()
190 {
191 	return TypeConv::StringToFloat(m_value);
192 }
193 
SplitParentProperty(std::map<wxString,wxString> * children)194 void Property::SplitParentProperty( std::map< wxString, wxString >* children )
195 {
196 	children->clear();
197 	if ( m_info->GetType() != PT_PARENT )
198 	{
199 		return;
200 	}
201 
202 	std::list< PropertyChild >* myChildren = m_info->GetChildren();
203 	std::list< PropertyChild >::iterator it = myChildren->begin();
204 
205 	wxStringTokenizer tkz( m_value, wxT(";"), wxTOKEN_RET_EMPTY_ALL );
206 	while ( tkz.HasMoreTokens() )
207 	{
208 		if ( myChildren->end() == it )
209 		{
210 			return;
211 		}
212 		wxString child = tkz.GetNextToken();
213 		child.Trim( false );
214 		child.Trim( true );
215 		children->insert( std::map< wxString, wxString >::value_type( it->m_name, child ) );
216 		it++;
217 	}
218 }
219 
GetChildFromParent(const wxString & childName)220 wxString Property::GetChildFromParent( const wxString& childName )
221 {
222 	std::map< wxString, wxString > children;
223 	SplitParentProperty( &children );
224 
225 	std::map< wxString, wxString >::iterator child;
226 	child = children.find( childName );
227 
228 	if ( children.end() == child )
229 	{
230 		return wxEmptyString;
231 	}
232 	else
233 	{
234 		return child->second;
235 	}
236 }
237 
238 ///////////////////////////////////////////////////////////////////////////////
239 const int ObjectBase::INDENT = 2;
240 
ObjectBase(wxString class_name)241 ObjectBase::ObjectBase (wxString class_name)
242 :
243 m_expanded( true )
244 {
245 	m_class = class_name;
246 
247 	LogDebug(wxT("new ObjectBase"));
248 }
249 
~ObjectBase()250 ObjectBase::~ObjectBase()
251 {
252 	// remove the reference in the parent
253 	PObjectBase parent = m_parent.lock();
254 
255 	if (parent)
256 	{
257 		PObjectBase pobj(GetThis());
258 		parent->RemoveChild(pobj);
259 	}
260 
261 	LogDebug(wxT("delete ObjectBase"));
262 }
263 
GetIndentString(int indent)264 wxString ObjectBase::GetIndentString(int indent)
265 {
266 	int i;
267 	wxString s;
268 
269 	for (i=0;i<indent;i++)
270 		s += wxT(" ");
271 
272 	return s;
273 }
274 
275 
GetProperty(wxString name)276 PProperty ObjectBase::GetProperty (wxString name)
277 {
278 	PropertyMap::iterator it = m_properties.find( name );
279 	if ( it != m_properties.end() )
280 		return it->second;
281 
282   //LogDebug(wxT("[ObjectBase::GetProperty] Property %s not found!"),name.c_str());
283 	// este aserto falla siempre que se crea un sizeritem
284 	// assert(false);
285 	return PProperty();
286 }
287 
GetProperty(unsigned int idx)288 PProperty ObjectBase::GetProperty (unsigned int idx)
289 {
290 	assert (idx < m_properties.size());
291 
292 	PropertyMap::iterator it = m_properties.begin();
293 	unsigned int i = 0;
294 	while (i < idx && it != m_properties.end())
295 	{
296 		i++;
297 		it++;
298 	}
299 
300 	if (it != m_properties.end())
301 		return it->second;
302 
303 	return PProperty();
304 }
305 
GetEvent(wxString name)306 PEvent ObjectBase::GetEvent (wxString name)
307 {
308 	EventMap::iterator it = m_events.find( name );
309 	if ( it != m_events.end() )
310 		return it->second;
311 
312 #if wxVERSION_NUMBER < 2900
313 	LogDebug(wxT("[ObjectBase::GetEvent] Event %s not found!"),name.c_str());
314 #else
315     LogDebug("[ObjectBase::GetEvent] Event " + name + " not found!");
316 #endif
317 	return PEvent();
318 }
319 
GetEvent(unsigned int idx)320 PEvent ObjectBase::GetEvent (unsigned int idx)
321 {
322 	assert (idx < m_events.size());
323 
324 	EventMap::iterator it = m_events.begin();
325 	unsigned int i = 0;
326 	while (i < idx && it != m_events.end())
327 	{
328 		i++;
329 		it++;
330 	}
331 
332 	if (it != m_events.end())
333 		return it->second;
334 
335   return PEvent();
336 }
337 
AddProperty(PProperty prop)338 void ObjectBase::AddProperty (PProperty prop)
339 {
340 	m_properties.insert( PropertyMap::value_type( prop->GetName(), prop ) );
341 }
342 
AddEvent(PEvent event)343 void ObjectBase::AddEvent(PEvent event)
344 {
345 	m_events.insert( EventMap::value_type( event->GetName(), event ) );
346 }
347 
FindNearAncestor(wxString type)348 PObjectBase ObjectBase::FindNearAncestor(wxString type)
349 {
350 	PObjectBase result;
351 	PObjectBase parent = GetParent();
352 	if (parent)
353 	{
354 		if (parent->GetObjectTypeName() == type)
355 			result = parent;
356 		else
357 			result = parent->FindNearAncestor(type);
358 	}
359 
360 	return result;
361 }
362 
FindNearAncestorByBaseClass(wxString type)363 PObjectBase ObjectBase::FindNearAncestorByBaseClass(wxString type)
364 {
365 	PObjectBase result;
366 	PObjectBase parent = GetParent();
367 	if (parent)
368 	{
369 		if ( parent->GetObjectInfo()->IsSubclassOf( type ) )
370 			result = parent;
371 		else
372 			result = parent->FindNearAncestorByBaseClass( type );
373 	}
374 
375 	return result;
376 }
377 
FindParentForm()378 PObjectBase ObjectBase::FindParentForm()
379 {
380 	PObjectBase retObj = this->FindNearAncestor( wxT( "form" ) );
381 	if( retObj == NULL ) retObj = this->FindNearAncestor( wxT( "menubar_form" ) );
382 	if( retObj == NULL ) retObj = this->FindNearAncestor( wxT( "toolbar_form" ) );
383     if( retObj == NULL ) retObj = this->FindNearAncestor( wxT("wizard") );
384 
385 	return retObj;
386 }
387 
AddChild(PObjectBase obj)388 bool ObjectBase::AddChild (PObjectBase obj)
389 {
390 	bool result = false;
391 	if (ChildTypeOk(obj->GetObjectInfo()->GetObjectType()))
392 		//if (ChildTypeOk(obj->GetObjectTypeName()))
393 	{
394 		m_children.push_back(obj);
395 		result = true;
396 	}
397 
398 	return result;
399 }
400 
AddChild(unsigned int idx,PObjectBase obj)401 bool ObjectBase::AddChild (unsigned int idx, PObjectBase obj)
402 {
403 	bool result = false;
404 	if (ChildTypeOk(obj->GetObjectInfo()->GetObjectType()) && idx <= m_children.size())
405 		//if (ChildTypeOk(obj->GetObjectTypeName()) && idx <= m_children.size())
406 	{
407 		m_children.insert(m_children.begin() + idx,obj);
408 		result = true;
409 	}
410 
411 	return result;
412 }
413 
ChildTypeOk(PObjectType type)414 bool ObjectBase::ChildTypeOk (PObjectType type)
415 {
416 	// buscamos si puede haber objectos del tipo "type" como hijos
417 	// del actual objeto tipo.
418 
419 	int nmax = 0;
420 
421 	// check allowed child count
422 	if( GetObjectInfo()->GetObjectType()->GetName() == wxT("form") )
423 	{
424 		nmax = GetObjectInfo()->GetObjectType()->FindChildType(type, this->GetPropertyAsInteger(wxT("aui_managed")));
425 	}
426 	else
427 		nmax = GetObjectInfo()->GetObjectType()->FindChildType(type, false);
428 
429 	if (nmax == 0)
430 		return false;
431 
432 	if (nmax < 0)
433 		return true;
434 
435 	// llegados aquí hay que comprobar el número de hijos del tipo pasado
436 	int count = 0;
437 	for (unsigned int i=0; i < GetChildCount() && count <= nmax; i++)
438 	{
439 		if (GetChild(i)->GetObjectInfo()->GetObjectType() == type)
440 			count++;
441 	}
442 
443 	if (count > nmax)
444 		return false;
445 
446 	return true;
447 
448 }
449 
GetLayout()450 PObjectBase ObjectBase::GetLayout()
451 {
452 	PObjectBase result;
453 
454 	if (GetParent() && GetParent()->GetObjectInfo()->IsSubclassOf( wxT("sizeritembase") ))
455 		result = GetParent();
456 
457 	return result;
458 }
459 
RemoveChild(PObjectBase obj)460 void ObjectBase::RemoveChild (PObjectBase obj)
461 {
462 	std::vector< PObjectBase >::iterator it = m_children.begin();
463 	while (it != m_children.end() && *it != obj)
464 		it++;
465 
466 	if (it != m_children.end())
467 		m_children.erase(it);
468 }
469 
RemoveChild(unsigned int idx)470 void ObjectBase::RemoveChild (unsigned int idx)
471 {
472 	assert (idx < m_children.size());
473 
474 	std::vector< PObjectBase >::iterator it =  m_children.begin() + idx;
475 	m_children.erase(it);
476 }
477 
GetChild(unsigned int idx)478 PObjectBase ObjectBase::GetChild (unsigned int idx)
479 {
480 	assert (idx < m_children.size());
481 
482 	return m_children[idx];
483 }
484 
GetChild(unsigned int idx,const wxString & type)485 PObjectBase ObjectBase::GetChild (unsigned int idx, const wxString& type)
486 {
487 	assert (idx < m_children.size());
488 
489 	unsigned int cnt = 0;
490 
491 	for( std::vector< PObjectBase >::iterator it =  m_children.begin(); it != m_children.end(); ++it )
492 	{
493 		if( (*it)->GetObjectInfo()->GetObjectTypeName() == type && ++cnt == idx ) return *it;
494 	}
495 
496 	return PObjectBase();
497 }
498 
Deep()499 int ObjectBase::Deep()
500 {
501 	int deep = 0;
502 	PObjectBase obj(GetParent());
503 	while (obj)
504 	{
505 		obj = obj->GetParent();
506 		deep++;
507 
508 		if (deep > 1000)
509 			assert(false);
510 	}
511 	return deep;
512 }
513 
514 //void ObjectBase::PrintOut(ostream &s, int indent)
515 //{
516 //  wxString ind_str = GetIndentString(indent);
517 //
518 //  s << ind_str << "[ " << GetClassName() << " ] " << GetObjectType() << endl;
519 //  map< wxString, PProperty >::const_iterator it_prop;
520 //  for (it_prop = m_properties.begin(); it_prop!= m_properties.end(); it_prop++)
521 //  {
522 //    s << ind_str << "property '" << it_prop->first << "' = '" <<
523 //      it_prop->second->GetValue() << "'" << endl;
524 //  }
525 //
526 //  vector< PObjectBase >::const_iterator it_ch;
527 //  for (it_ch = m_children.begin() ; it_ch != m_children.end(); it_ch++)
528 //  {
529 //    (*it_ch)->PrintOut(s,INDENT + indent);
530 //  }
531 //}
532 //
533 //ostream& operator << (ostream &s, PObjectBase obj)
534 //{
535 //  obj->PrintOut(s,0);
536 //  return s;
537 //}
538 
SerializeObject(ticpp::Element * serializedElement)539 void ObjectBase::SerializeObject( ticpp::Element* serializedElement )
540 {
541 	ticpp::Element element( "object" );
542 	element.SetAttribute( "class", _STDSTR( GetClassName() ) );
543 	element.SetAttribute( "expanded", GetExpanded() );
544 
545 	for ( unsigned int i = 0; i < GetPropertyCount(); i++ )
546 	{
547 		PProperty prop = GetProperty( i );
548 		ticpp::Element prop_element( "property" );
549 		prop_element.SetAttribute( "name", _STDSTR( prop->GetName() ) );
550 		prop_element.SetText( _STDSTR( prop->GetValue() ) );
551 		element.LinkEndChild( &prop_element );
552 	}
553 
554 	for ( unsigned int i = 0; i < GetEventCount(); i++ )
555 	{
556 		PEvent event = GetEvent( i );
557 		ticpp::Element event_element( "event" );
558 		event_element.SetAttribute( "name", _STDSTR( event->GetName() ) );
559 		event_element.SetText( _STDSTR( event->GetValue() ) );
560 		element.LinkEndChild( &event_element );
561 	}
562 
563 	for ( unsigned int i = 0 ; i < GetChildCount(); i++ )
564 	{
565 		PObjectBase child = GetChild( i );
566 		ticpp::Element child_element;
567 		child->SerializeObject( &child_element );
568 		element.LinkEndChild( &child_element );
569 	}
570 
571 	*serializedElement = element;
572 }
573 
Serialize(ticpp::Document * serializedDocument)574 void ObjectBase::Serialize( ticpp::Document* serializedDocument )
575 {
576 	ticpp::Document document( "document" );
577 
578   #if wxUSE_UNICODE
579 	ticpp::Declaration dec( "1.0", "UTF-8", "yes" );
580 	#else
581 	ticpp::Declaration dec( "1.0", "ISO-8859-13", "yes" );
582 	#endif
583 	document.LinkEndChild( &dec );
584 
585 	ticpp::Element root( "wxFormBuilder_Project" );
586 
587 	ticpp::Element fileVersion( "FileVersion" );
588 	fileVersion.SetAttribute( "major", AppData()->m_fbpVerMajor );
589 	fileVersion.SetAttribute( "minor", AppData()->m_fbpVerMinor );
590 
591 	root.LinkEndChild( &fileVersion );
592 
593 	ticpp::Element element;
594 	SerializeObject( &element );
595 
596 	root.LinkEndChild( &element );
597 	document.LinkEndChild( &root );
598 
599 	*serializedDocument = document;
600 }
601 
GetChildPosition(PObjectBase obj)602 unsigned int ObjectBase::GetChildPosition(PObjectBase obj)
603 {
604 	unsigned int pos = 0;
605 	while (pos < GetChildCount() && m_children[pos] != obj)
606 		pos++;
607 
608 	return pos;
609 }
610 
ChangeChildPosition(PObjectBase obj,unsigned int pos)611 bool ObjectBase::ChangeChildPosition( PObjectBase obj, unsigned int pos)
612 {
613 	unsigned int obj_pos = GetChildPosition(obj);
614 
615 	if (obj_pos == GetChildCount() || pos >= GetChildCount())
616 		return false;
617 
618 	if (pos == obj_pos)
619 		return true;
620 
621 	// Procesamos el cambio de posición
622 	RemoveChild(obj);
623 	AddChild(pos,obj);
624 	return true;
625 }
626 
627 ///////////////////////////////////////////////////////////////////////////////
628 
IsNull(const wxString & pname)629 bool ObjectBase::IsNull (const wxString& pname)
630 {
631 	PProperty property = GetProperty( pname );
632 	if (property)
633 		return property->IsNull();
634 	else
635 		return true;
636 }
637 
GetPropertyAsInteger(const wxString & pname)638 int ObjectBase::GetPropertyAsInteger (const wxString& pname)
639 {
640 	PProperty property = GetProperty( pname );
641 	if (property)
642 		return property->GetValueAsInteger();
643 	else
644 		return 0;
645 }
646 
GetPropertyAsFont(const wxString & pname)647 wxFontContainer ObjectBase::GetPropertyAsFont(const wxString& pname)
648 {
649 	PProperty property = GetProperty( pname );
650 	if (property)
651 		return property->GetValueAsFont();
652 	else
653 		return wxFontContainer();
654 }
655 
GetPropertyAsColour(const wxString & pname)656 wxColour ObjectBase::GetPropertyAsColour  (const wxString& pname)
657 {
658 	PProperty property = GetProperty( pname );
659 	if (property)
660 		return property->GetValueAsColour();
661 	else
662 		return wxColour();
663 }
664 
GetPropertyAsString(const wxString & pname)665 wxString ObjectBase::GetPropertyAsString  (const wxString& pname)
666 {
667 	PProperty property = GetProperty( pname );
668 	if (property)
669 		return property->GetValueAsString();
670 	else
671 		return wxString();
672 }
673 
GetPropertyAsPoint(const wxString & pname)674 wxPoint  ObjectBase::GetPropertyAsPoint   (const wxString& pname)
675 {
676 	PProperty property = GetProperty( pname );
677 	if (property)
678 		return property->GetValueAsPoint();
679 	else
680 		return wxPoint();
681 }
682 
GetPropertyAsSize(const wxString & pname)683 wxSize   ObjectBase::GetPropertyAsSize    (const wxString& pname)
684 {
685 	PProperty property = GetProperty( pname );
686 	if (property)
687 		return property->GetValueAsSize();
688 	else
689 		return wxDefaultSize;
690 }
691 
GetPropertyAsBitmap(const wxString & pname)692 wxBitmap ObjectBase::GetPropertyAsBitmap  (const wxString& pname)
693 {
694 	PProperty property = GetProperty( pname );
695 	if (property)
696 		return property->GetValueAsBitmap();
697 	else
698 		return wxBitmap();
699 }
GetPropertyAsFloat(const wxString & pname)700 double ObjectBase::GetPropertyAsFloat( const wxString& pname )
701 {
702 	PProperty property = GetProperty( pname );
703 	if (property)
704 		return property->GetValueAsFloat();
705 	else
706 		return 0;
707 }
GetPropertyAsArrayInt(const wxString & pname)708 wxArrayInt ObjectBase::GetPropertyAsArrayInt(const wxString& pname)
709 {
710 	wxArrayInt array;
711 	PProperty property = GetProperty( pname );
712 	if (property)
713 	{
714 		IntList il( property->GetValue(), property->GetType() == PT_UINTLIST );
715 		for (unsigned int i=0; i < il.GetSize() ; i++)
716 			array.Add(il.GetValue(i));
717 	}
718 
719 	return array;
720 }
721 
GetPropertyAsArrayString(const wxString & pname)722 wxArrayString ObjectBase::GetPropertyAsArrayString(const wxString& pname)
723 {
724 	PProperty property = GetProperty( pname );
725 	if (property)
726 		return property->GetValueAsArrayString();
727 	else
728 		return wxArrayString();
729 }
730 
GetChildFromParentProperty(const wxString & parentName,const wxString & childName)731 wxString ObjectBase::GetChildFromParentProperty( const wxString& parentName, const wxString& childName )
732 {
733 	PProperty property = GetProperty( parentName );
734 	if (property)
735 		return property->GetChildFromParent( childName );
736 	else
737 		return wxEmptyString;
738 }
739 
740 ///////////////////////////////////////////////////////////////////////////////
741 
ObjectInfo(wxString class_name,PObjectType type,WPObjectPackage package,bool startGroup)742 ObjectInfo::ObjectInfo(wxString class_name, PObjectType type, WPObjectPackage package, bool startGroup )
743 {
744 	m_class = class_name;
745 	m_type = type;
746 	m_numIns = 0;
747 	m_component = NULL;
748 	m_package = package;
749 	m_category = PPropertyCategory( new PropertyCategory( m_class ) );
750 	m_startGroup = startGroup;
751 }
752 
GetPackage()753 PObjectPackage ObjectInfo::GetPackage()
754 {
755 	return m_package.lock();
756 }
757 
GetPropertyInfo(wxString name)758 PPropertyInfo ObjectInfo::GetPropertyInfo(wxString name)
759 {
760 	PPropertyInfo result;
761 
762 	std::map< wxString, PPropertyInfo >::iterator it = m_properties.find(name);
763 	if (it != m_properties.end())
764 		result = it->second;
765 
766 	return result;
767 }
768 
GetPropertyInfo(unsigned int idx)769 PPropertyInfo ObjectInfo::GetPropertyInfo(unsigned int idx)
770 {
771 	PPropertyInfo result;
772 
773 	assert (idx < m_properties.size());
774 
775 	std::map< wxString, PPropertyInfo >::iterator it = m_properties.begin();
776 	unsigned int i = 0;
777 	while (i < idx && it != m_properties.end())
778 	{
779 		i++;
780 		it++;
781 	}
782 
783 	if (it != m_properties.end())
784 		result = it->second;
785 
786 	return result;
787 }
788 
GetEventInfo(wxString name)789 PEventInfo ObjectInfo::GetEventInfo(wxString name)
790 {
791 	PEventInfo result;
792 
793 	EventInfoMap::iterator it = m_events.find(name);
794 	if (it != m_events.end())
795 		result = it->second;
796 
797 	return result;
798 }
799 
GetEventInfo(unsigned int idx)800 PEventInfo ObjectInfo::GetEventInfo(unsigned int idx)
801 {
802 	PEventInfo result;
803 
804 	assert (idx < m_events.size());
805 
806 	EventInfoMap::iterator it = m_events.begin();
807 	unsigned int i = 0;
808 	while (i < idx && it != m_events.end())
809 	{
810 		i++;
811 		it++;
812 	}
813 
814 	if (it != m_events.end())
815 		result = it->second;
816 
817 	return result;
818 }
819 
AddPropertyInfo(PPropertyInfo prop)820 void ObjectInfo::AddPropertyInfo( PPropertyInfo prop )
821 {
822 	m_properties.insert( PropertyInfoMap::value_type(prop->GetName(), prop) );
823 }
824 
AddEventInfo(PEventInfo evtInfo)825 void ObjectInfo::AddEventInfo(PEventInfo evtInfo)
826 {
827   m_events.insert( EventInfoMap::value_type(evtInfo->GetName(), evtInfo) );
828 }
829 
AddBaseClassDefaultPropertyValue(size_t baseIndex,const wxString & propertyName,const wxString & defaultValue)830 void ObjectInfo::AddBaseClassDefaultPropertyValue( size_t baseIndex, const wxString& propertyName, const wxString& defaultValue )
831 {
832 	std::map< size_t, std::map< wxString, wxString > >::iterator baseClassMap = m_baseClassDefaultPropertyValues.find( baseIndex );
833 	if ( baseClassMap != m_baseClassDefaultPropertyValues.end() )
834 	{
835 		baseClassMap->second.insert( std::map< wxString, wxString >::value_type( propertyName, defaultValue ) );
836 	}
837 	else
838 	{
839 		std::map< wxString, wxString > propertyDefaultValues;
840 		propertyDefaultValues[ propertyName ] = defaultValue;
841 		m_baseClassDefaultPropertyValues[ baseIndex ] = propertyDefaultValues;
842 	}
843 }
844 
GetBaseClassDefaultPropertyValue(size_t baseIndex,const wxString & propertyName)845 wxString ObjectInfo::GetBaseClassDefaultPropertyValue( size_t baseIndex, const wxString& propertyName )
846 {
847 	std::map< size_t, std::map< wxString, wxString > >::iterator baseClassMap = m_baseClassDefaultPropertyValues.find( baseIndex );
848 	if ( baseClassMap != m_baseClassDefaultPropertyValues.end() )
849 	{
850 		std::map< wxString, wxString >::iterator defaultValue = baseClassMap->second.find( propertyName );
851 		if ( defaultValue != baseClassMap->second.end() )
852 		{
853 			return defaultValue->second;
854 		}
855 	}
856 	return wxString();
857 }
858 
GetBaseClass(unsigned int idx,bool inherited)859 PObjectInfo ObjectInfo::GetBaseClass(unsigned int idx, bool inherited)
860 {
861 	if( inherited )
862 	{
863 		std::vector<PObjectInfo> classes;
864 		GetBaseClasses( classes );
865 
866 		assert (idx < classes.size());
867 		return classes[idx];
868 	}
869 	else
870 	{
871 		assert (idx < m_base.size());
872 		return m_base[idx];
873 	}
874 }
875 
GetBaseClassCount(bool inherited)876 unsigned int ObjectInfo::GetBaseClassCount(bool inherited)
877 {
878 	if( inherited )
879 	{
880 		std::vector<PObjectInfo> classes;
881 		GetBaseClasses( classes );
882 
883 		return (unsigned int)classes.size();
884 	}
885 	else
886 		return (unsigned int)m_base.size();
887 }
888 
GetBaseClasses(std::vector<PObjectInfo> & classes,bool inherited)889 void ObjectInfo::GetBaseClasses(std::vector<PObjectInfo> &classes, bool inherited)
890 {
891 	for ( std::vector<PObjectInfo>::iterator it = m_base.begin(); it != m_base.end(); ++it )
892 	{
893 		PObjectInfo base_info = *it;;
894 		classes.push_back( base_info );
895 
896 		if( inherited ) base_info->GetBaseClasses( classes );
897 	}
898 }
899 
IsSubclassOf(wxString classname)900 bool ObjectInfo::IsSubclassOf(wxString classname)
901 {
902 	bool found = false;
903 
904 	if (GetClassName() == classname)
905 		found = true;
906 	else
907 
908 		for (unsigned int i=0; !found && i < GetBaseClassCount() ; i++)
909 		{
910 			PObjectInfo base = GetBaseClass(i);
911 			found = base->IsSubclassOf(classname);
912 		}
913 
914 		return found;
915 }
916 
917 //
918 //void ObjectInfo::PrintOut(ostream &s, int indent)
919 //{
920 //  wxString ind_str = "";
921 //  for (int i=0;i<indent;i++)
922 //    ind_str = ind_str + " ";
923 //
924 //  s << ind_str << "[ " << GetClassName() << " ] " << GetObjectType() << endl;
925 //  map< wxString, PPropertyInfo >::const_iterator it_prop;
926 //  for (it_prop = m_properties.begin(); it_prop!= m_properties.end(); it_prop++)
927 //  {
928 //    s << ind_str << "property '" << it_prop->first << "' type = '" <<
929 //      it_prop->second->GetType() << "' with value = '" <<
930 //      it_prop->second->GetDefaultValue() << "' by default" << endl;
931 //  }
932 //}
933 
AddCodeInfo(wxString lang,PCodeInfo codeinfo)934 void ObjectInfo::AddCodeInfo(wxString lang, PCodeInfo codeinfo)
935 {
936 	std::map< wxString, PCodeInfo >::iterator templates = m_codeTemp.find( lang );
937 	if ( templates == m_codeTemp.end() )
938 	{
939 		// First code info is a clean copy
940 		m_codeTemp[ lang ] = PCodeInfo( new CodeInfo( *codeinfo ) );
941 	}
942 	else
943 	{
944 		// If code info already existed for the language, merge code info
945 		templates->second->Merge( codeinfo );
946 	}
947 }
948 
GetCodeInfo(wxString lang)949 PCodeInfo ObjectInfo::GetCodeInfo(wxString lang)
950 {
951 	PCodeInfo result;
952 	std::map< wxString, PCodeInfo >::iterator it = m_codeTemp.find(lang);
953 	if (it != m_codeTemp.end())
954 		result = it->second;
955 
956 	return result;
957 }
958 
959 //ostream& operator << (ostream &s, PObjectInfo obj)
960 //{
961 //  obj->PrintOut(s,0);
962 //  return s;
963 //}
964 
965 ///////////////////////////////////////////////////////////////////////////////
GetTemplate(wxString name)966 wxString CodeInfo::GetTemplate(wxString name)
967 {
968 	wxString result;
969 
970 	TemplateMap::iterator it = m_templates.find(name);
971 	if (it != m_templates.end())
972 		result = it->second;
973 
974 	return result;
975 }
976 
AddTemplate(wxString name,wxString _template)977 void CodeInfo::AddTemplate(wxString name, wxString _template)
978 {
979 	m_templates.insert(TemplateMap::value_type(name,_template));
980 }
981 
Merge(PCodeInfo merger)982 void CodeInfo::Merge( PCodeInfo merger )
983 {
984 	TemplateMap::iterator mergerTemplate;
985 	for ( mergerTemplate = merger->m_templates.begin(); mergerTemplate != merger->m_templates.end(); ++mergerTemplate )
986 	{
987 		std::pair< TemplateMap::iterator, bool > mine = m_templates.insert( TemplateMap::value_type( mergerTemplate->first, mergerTemplate->second ) );
988 		if ( !mine.second )
989 		{
990 			mine.first->second += mergerTemplate->second;
991 		}
992 	}
993 }
994