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 // Atencion!!!!!! 27 // ObjectBase::GetPropertyCount() != ObjectInfo::GetPropertyCount() 28 // 29 // En el primer caso devolverá el numero total de propiedades del objeto. 30 // En el segundo caso sólo devolverá el número de propiedades definidas 31 // para esa clase. 32 33 #ifndef __OBJ__ 34 #define __OBJ__ 35 36 #include <iostream> 37 #include <wx/string.h> 38 #include <list> 39 40 #include "types.h" 41 #include "ticpp.h" 42 43 #include "wx/wx.h" 44 #include <component.h> 45 46 #include "utils/wxfbdefs.h" 47 48 /////////////////////////////////////////////////////////////////////////////// 49 50 class OptionList 51 { 52 private: 53 54 std::map< wxString, wxString > m_options; 55 56 public: 57 58 void AddOption( wxString option, wxString description = wxString() ) 59 { 60 m_options[option] = description; 61 } GetOptionCount()62 unsigned int GetOptionCount() 63 { 64 return (unsigned int)m_options.size(); 65 } GetOptions()66 const std::map< wxString, wxString >& GetOptions() 67 { 68 return m_options; 69 } 70 }; 71 72 /////////////////////////////////////////////////////////////////////////////// 73 74 /** 75 @internal 76 Data Container for children of a Parent property 77 */ 78 class PropertyChild 79 { 80 public: 81 wxString m_name; 82 wxString m_defaultValue; 83 wxString m_description; 84 }; 85 86 /////////////////////////////////////////////////////////////////////////////// 87 88 class PropertyInfo 89 { 90 friend class Property; 91 92 private: 93 wxString m_name; 94 PropertyType m_type; 95 wxString m_def_value; 96 POptionList m_opt_list; 97 std::list< PropertyChild > m_children; // Only used for parent properties 98 bool m_hidden; // Juan. Determina si la propiedad aparece o no en XRC 99 wxString m_description; 100 wxString m_customEditor; // an optional custom editor for the property grid 101 102 public: 103 104 PropertyInfo(wxString name, PropertyType type, wxString def_value, wxString description, wxString customEditor, 105 POptionList opt_list, const std::list< PropertyChild >& children ); 106 107 ~PropertyInfo(); 108 GetDefaultValue()109 wxString GetDefaultValue() { return m_def_value; } GetType()110 PropertyType GetType() { return m_type; } GetName()111 wxString GetName() { return m_name; } GetOptionList()112 POptionList GetOptionList () { return m_opt_list; } GetChildren()113 std::list< PropertyChild >* GetChildren(){ return &m_children; } GetDescription()114 wxString GetDescription () { return m_description;} GetCustomEditor()115 wxString GetCustomEditor() { return m_customEditor; } 116 }; 117 118 class EventInfo 119 { 120 private: 121 wxString m_name; 122 wxString m_eventClass; 123 wxString m_defaultValue; 124 wxString m_description; 125 126 public: 127 EventInfo(const wxString &name, 128 const wxString &eventClass, 129 const wxString &defValue, 130 const wxString &description); 131 GetName()132 wxString GetName() { return m_name; } GetEventClassName()133 wxString GetEventClassName() { return m_eventClass; } GetDefaultValue()134 wxString GetDefaultValue() { return m_defaultValue; } GetDescription()135 wxString GetDescription() { return m_description; } 136 }; 137 138 /////////////////////////////////////////////////////////////////////////////// 139 140 class Property 141 { 142 private: 143 PPropertyInfo m_info; // pointer to its descriptor 144 WPObjectBase m_object; // pointer to the owner object 145 146 wxString m_value; 147 148 public: 149 Property(PPropertyInfo info, PObjectBase obj = PObjectBase()) 150 { 151 m_object = obj; 152 m_info = info; 153 } 154 GetObject()155 PObjectBase GetObject() { return m_object.lock(); } GetName()156 wxString GetName() { return m_info->GetName(); } GetValue()157 wxString GetValue() { return m_value; } SetValue(wxString & val)158 void SetValue( wxString& val ) { m_value = val; } SetValue(const wxChar * val)159 void SetValue( const wxChar* val ) { m_value = val; } 160 GetPropertyInfo()161 PPropertyInfo GetPropertyInfo() { return m_info; } GetType()162 PropertyType GetType() { return m_info->GetType(); } 163 164 bool IsDefaultValue(); 165 bool IsNull(); 166 void SetDefaultValue(); ChangeDefaultValue(const wxString & value)167 void ChangeDefaultValue( const wxString& value ) 168 { 169 m_info->m_def_value = value; 170 } 171 172 //////////////////// 173 void SetValue(const wxFontContainer &font); 174 void SetValue(const wxColour &colour); 175 void SetValue(const wxString &str, bool format = false); 176 void SetValue(const wxPoint &point); 177 void SetValue(const wxSize &size); 178 void SetValue(const int integer); 179 void SetValue(const double val ); 180 181 wxFontContainer GetValueAsFont(); 182 wxColour GetValueAsColour(); 183 wxPoint GetValueAsPoint(); 184 wxSize GetValueAsSize(); 185 int GetValueAsInteger(); 186 wxString GetValueAsString(); 187 wxBitmap GetValueAsBitmap(); 188 wxString GetValueAsText(); // sustituye los ('\n',...) por ("\\n",...) 189 190 wxArrayString GetValueAsArrayString(); 191 double GetValueAsFloat(); 192 void SplitParentProperty( std::map< wxString, wxString >* children ); 193 wxString GetChildFromParent( const wxString& childName ); 194 }; 195 196 class Event 197 { 198 private: 199 PEventInfo m_info; // pointer to its descriptor 200 WPObjectBase m_object; // pointer to the owner object 201 wxString m_value; // handler function name 202 203 public: Event(PEventInfo info,PObjectBase obj)204 Event (PEventInfo info, PObjectBase obj) 205 : m_info(info), m_object(obj) 206 {} 207 SetValue(const wxString & value)208 void SetValue(const wxString &value) { m_value = value; } GetValue()209 wxString GetValue() { return m_value; } GetName()210 wxString GetName() { return m_info->GetName(); } GetObject()211 PObjectBase GetObject() { return m_object.lock(); } GetEventInfo()212 PEventInfo GetEventInfo() { return m_info; } 213 }; 214 215 class PropertyCategory 216 { 217 private: 218 wxString m_name; 219 std::vector< wxString > m_properties; 220 std::vector< wxString > m_events; 221 std::vector< PPropertyCategory > m_categories; 222 223 public: 224 PropertyCategory(wxString name)225 PropertyCategory( wxString name ) : m_name( name ){} AddProperty(wxString name)226 void AddProperty( wxString name ){ m_properties.push_back( name ); } AddEvent(wxString name)227 void AddEvent( wxString name ){ m_events.push_back( name ); } AddCategory(PPropertyCategory category)228 void AddCategory( PPropertyCategory category ){ m_categories.push_back( category ); } GetName()229 wxString GetName(){ return m_name; } GetPropertyName(size_t index)230 wxString GetPropertyName( size_t index ) 231 { 232 if ( index < m_properties.size() ) 233 { 234 return m_properties[ index ]; 235 } 236 else 237 { 238 return wxEmptyString; 239 } 240 } 241 GetEventName(size_t index)242 wxString GetEventName( size_t index ) 243 { 244 if ( index < m_events.size() ) 245 { 246 return m_events[ index ]; 247 } 248 else 249 { 250 return wxEmptyString; 251 } 252 } 253 GetCategory(size_t index)254 PPropertyCategory GetCategory( size_t index ) 255 { 256 if ( index < m_categories.size() ) 257 { 258 return m_categories[ index ]; 259 } 260 else 261 { 262 return PPropertyCategory(); 263 } 264 } 265 GetPropertyCount()266 size_t GetPropertyCount() { return m_properties.size(); } GetEventCount()267 size_t GetEventCount() { return m_events.size(); } GetCategoryCount()268 size_t GetCategoryCount() { return m_categories.size(); } 269 }; 270 271 /////////////////////////////////////////////////////////////////////////////// 272 namespace ticpp 273 { 274 class Document; 275 class Element; 276 } 277 278 class ObjectBase : public IObject, public boost::enable_shared_from_this<ObjectBase> 279 { 280 friend class wxFBDataObject; 281 private: 282 wxString m_class; // class name 283 wxString m_type; // type of object 284 WPObjectBase m_parent; // weak pointer, no reference loops please! 285 286 ObjectBaseVector m_children; 287 PropertyMap m_properties; 288 EventMap m_events; 289 PObjectInfo m_info; 290 bool m_expanded; // is expanded in the object tree, allows for saving to file 291 292 protected: 293 // utilites for implementing the tree 294 static const int INDENT; // size of indent 295 wxString GetIndentString(int indent); // obtiene la cadena con el indentado 296 GetChildren()297 ObjectBaseVector& GetChildren() { return m_children; }; GetProperties()298 PropertyMap& GetProperties() { return m_properties; }; 299 300 // Crea un elemento del objeto 301 void SerializeObject( ticpp::Element* serializedElement ); 302 303 // devuelve el puntero "this" GetThis()304 PObjectBase GetThis() { return shared_from_this(); } 305 306 public: 307 308 /// Constructor. 309 ObjectBase (wxString class_name); 310 311 /// Destructor. 312 virtual ~ObjectBase(); 313 314 /** 315 Sets whether the object is expanded in the object tree or not. 316 */ SetExpanded(bool expanded)317 void SetExpanded( bool expanded ){ m_expanded = expanded; } 318 319 /** 320 Gets whether the object is expanded in the object tree or not. 321 */ GetExpanded()322 bool GetExpanded(){ return m_expanded; } 323 324 /** 325 * Obtiene el nombre del objeto. 326 * 327 * @note No confundir con la propiedad nombre que tienen algunos objetos. 328 * Cada objeto tiene un nombre, el cual será el mismo que el usado 329 * como clave en el registro de descriptores. 330 */ GetClassName()331 wxString GetClassName () { return m_class; } 332 333 /// Gets the parent object GetParent()334 PObjectBase GetParent () { return m_parent.lock(); } 335 336 /// Links the object to a parent SetParent(PObjectBase parent)337 void SetParent(PObjectBase parent) { m_parent = parent; } 338 339 /** 340 * Obtiene la propiedad identificada por el nombre. 341 * 342 * @note Notar que no existe el método SetProperty, ya que la modificación 343 * se hace a través de la referencia. 344 */ 345 PProperty GetProperty (wxString name); 346 347 PEvent GetEvent(wxString name); 348 349 /** 350 * Añade una propiedad al objeto. 351 * 352 * Este método será usado por el registro de descriptores para crear la 353 * instancia del objeto. 354 * Los objetos siempre se crearán a través del registro de descriptores. 355 */ 356 void AddProperty (PProperty value); 357 358 void AddEvent(PEvent event); 359 360 /** 361 * Obtiene el número de propiedades del objeto. 362 */ GetPropertyCount()363 unsigned int GetPropertyCount() { return (unsigned int)m_properties.size(); } 364 GetEventCount()365 unsigned int GetEventCount() { return m_events.size(); } 366 367 /** 368 * Obtiene una propiedad del objeto. 369 * @todo esta función deberá lanzar una excepción en caso de no encontrarse 370 * dicha propiedad, así se simplifica el código al no tener que hacer 371 * tantas comprobaciones. 372 * Por ejemplo, el código sin excepciones sería algo así: 373 * 374 * @code 375 * 376 * PProperty plabel = obj->GetProperty("label"); 377 * PProperty ppos = obj->GetProperty("pos"); 378 * PProperty psize = obj->GetProperty("size"); 379 * PProperty pstyle = obj->GetProperty("style"); 380 * 381 * if (plabel && ppos && psize && pstyle) 382 * { 383 * wxButton *button = new wxButton(parent,-1, 384 * plabel->GetValueAsString(), 385 * ppos->GetValueAsPoint(), 386 * psize->GetValueAsSize(), 387 * pstyle->GetValueAsInteger()); 388 * } 389 * else 390 * { 391 * // manejo del error 392 * } 393 * 394 * @endcode 395 * 396 * y con excepciones: 397 * 398 * @code 399 * 400 * try 401 * { 402 * wxButton *button = new wxButton(parent,-1, 403 * obj->GetProperty("label")->GetValueAsString(), 404 * obj->GetProperty("pos")->GetValueAsPoint(), 405 * obj->GetProperty("size")->GetValueAsSize(), 406 * obj->GetProperty("style")->GetValueAsInteger()); 407 * } 408 * catch (...) 409 * { 410 * // manejo del error 411 * } 412 * 413 * @endcode 414 * 415 */ 416 PProperty GetProperty (unsigned int idx); // throws ...; 417 418 PEvent GetEvent (unsigned int idx); // throws ...; 419 420 /** 421 * Devuelve el primer antecesor cuyo tipo coincida con el que se pasa 422 * como parámetro. 423 * 424 * Será útil para encontrar el widget padre. 425 */ 426 PObjectBase FindNearAncestor(wxString type); 427 PObjectBase FindNearAncestorByBaseClass(wxString type); 428 PObjectBase FindParentForm(); 429 430 /** 431 * Obtiene el documento xml del arbol tomando como raíz el nodo actual. 432 */ 433 void Serialize( ticpp::Document* serializedDocument ); 434 435 /** 436 * Añade un hijo al objeto. 437 * Esta función es virtual, debido a que puede variar el comportamiento 438 * según el tipo de objeto. 439 * 440 * @return true si se añadió el hijo con éxito y false en caso contrario. 441 */ 442 virtual bool AddChild (PObjectBase); 443 virtual bool AddChild (unsigned int idx, PObjectBase obj); 444 445 /** 446 * Devuelve la posicion del hijo o GetChildCount() en caso de no encontrarlo 447 */ 448 unsigned int GetChildPosition(PObjectBase obj); 449 bool ChangeChildPosition(PObjectBase obj, unsigned int pos); 450 451 /** 452 * devuelve la posición entre sus hermanos 453 */ 454 /* unsigned int GetPosition(); 455 bool ChangePosition(unsigned int pos);*/ 456 457 458 /** 459 * Elimina un hijo del objeto. 460 */ 461 void RemoveChild (PObjectBase obj); 462 void RemoveChild (unsigned int idx); RemoveAllChildren()463 void RemoveAllChildren(){ m_children.clear(); } 464 465 /** 466 * Obtiene un hijo del objeto. 467 */ 468 PObjectBase GetChild (unsigned int idx); 469 470 PObjectBase GetChild (unsigned int idx, const wxString& type); 471 472 /** 473 * Obtiene el número de hijos del objeto. 474 */ GetChildCount()475 unsigned int GetChildCount() { return (unsigned int)m_children.size(); } 476 477 /** 478 * Comprueba si el tipo de objeto pasado es válido como hijo del objeto. 479 * Esta rutina es importante, ya que define las restricciónes de ubicación. 480 */ 481 //bool ChildTypeOk (wxString type); 482 bool ChildTypeOk (PObjectType type); 483 IsContainer()484 bool IsContainer() { return (GetObjectTypeName() == wxT("container") ); } 485 486 PObjectBase GetLayout(); 487 488 /** 489 * Devuelve el tipo de objeto. 490 * 491 * Deberá ser redefinida en cada clase derivada. 492 */ GetObjectTypeName()493 wxString GetObjectTypeName() { return m_type; } SetObjectTypeName(wxString type)494 void SetObjectTypeName(wxString type) { m_type = type; } 495 496 /** 497 * Devuelve el descriptor del objeto. 498 */ GetObjectInfo()499 PObjectInfo GetObjectInfo() { return m_info; }; SetObjectInfo(PObjectInfo info)500 void SetObjectInfo(PObjectInfo info) { m_info = info; }; 501 502 /** 503 * Devuelve la profundidad del objeto en el arbol. 504 */ 505 int Deep(); 506 507 /** 508 * Imprime el arbol en un stream. 509 */ 510 //virtual void PrintOut(ostream &s, int indent); 511 512 /** 513 * Sobrecarga del operador inserción. 514 */ 515 friend std::ostream& operator << (std::ostream &s, PObjectBase obj); 516 517 ///////////////////////// 518 // Implementación de la interfaz IObject para su uso dentro de los 519 // plugins 520 bool IsNull (const wxString& pname); 521 int GetPropertyAsInteger (const wxString& pname); 522 wxFontContainer GetPropertyAsFont (const wxString& pname); 523 wxColour GetPropertyAsColour (const wxString& pname); 524 wxString GetPropertyAsString (const wxString& pname); 525 wxPoint GetPropertyAsPoint (const wxString& pname); 526 wxSize GetPropertyAsSize (const wxString& pname); 527 wxBitmap GetPropertyAsBitmap (const wxString& pname); 528 double GetPropertyAsFloat (const wxString& pname); 529 530 wxArrayInt GetPropertyAsArrayInt (const wxString& pname); 531 wxArrayString GetPropertyAsArrayString (const wxString& pname); 532 wxString GetChildFromParentProperty( const wxString& parentName, const wxString& childName ); 533 GetChildPtr(unsigned int idx)534 IObject* GetChildPtr (unsigned int idx) { return GetChild(idx).get(); } 535 }; 536 537 /////////////////////////////////////////////////////////////////////////////// 538 539 /** 540 * Clase que guarda un conjunto de plantillas de código. 541 */ 542 class CodeInfo 543 { 544 private: 545 typedef std::map<wxString,wxString> TemplateMap; 546 TemplateMap m_templates; 547 public: 548 wxString GetTemplate(wxString name); 549 void AddTemplate(wxString name, wxString _template); 550 void Merge( PCodeInfo merger ); 551 }; 552 553 /////////////////////////////////////////////////////////////////////////////// 554 555 /** 556 * Información de objeto o MetaObjeto. 557 */ 558 class ObjectInfo 559 { 560 public: 561 /** 562 * Constructor. 563 */ 564 ObjectInfo(wxString class_name, PObjectType type, WPObjectPackage package, bool startGroup = false ); 565 ~ObjectInfo()566 virtual ~ObjectInfo() {}; 567 GetCategory()568 PPropertyCategory GetCategory(){ return m_category; } 569 GetPropertyCount()570 unsigned int GetPropertyCount() { return (unsigned int)m_properties.size(); } GetEventCount()571 unsigned int GetEventCount() { return (unsigned int)m_events.size(); } 572 573 /** 574 * Obtiene el descriptor de la propiedad. 575 */ 576 PPropertyInfo GetPropertyInfo(wxString name); 577 PPropertyInfo GetPropertyInfo(unsigned int idx); 578 579 PEventInfo GetEventInfo(wxString name); 580 PEventInfo GetEventInfo(unsigned int idx); 581 582 /** 583 * Añade un descriptor de propiedad al descriptor de objeto. 584 */ 585 void AddPropertyInfo(PPropertyInfo pinfo); 586 587 /** 588 * Adds a event descriptor. 589 */ 590 void AddEventInfo(PEventInfo evtInfo); 591 592 /** 593 * Add a default value for an inherited property. 594 * @param baseIndex Index of base class returned from AddBaseClass. 595 * @param propertyName Property of base class to assign a default value to. 596 * @param defaultValue Default value of the inherited property. 597 */ 598 void AddBaseClassDefaultPropertyValue( size_t baseIndex, const wxString& propertyName, const wxString& defaultValue ); 599 600 /** 601 * Get a default value for an inherited property. 602 * @param baseIndex Index of base class in the base class vector 603 * @param propertName Name of the property to get the default value for 604 * @return The default value for the property 605 */ 606 wxString GetBaseClassDefaultPropertyValue( size_t baseIndex, const wxString& propertyName ); 607 608 /** 609 * Devuelve el tipo de objeto, será util para que el constructor de objetos 610 * sepa la clase derivada de ObjectBase que ha de crear a partir del 611 * descriptor. 612 */ GetObjectTypeName()613 wxString GetObjectTypeName() { return m_type->GetName(); } 614 GetObjectType()615 PObjectType GetObjectType() { return m_type; } 616 GetClassName()617 wxString GetClassName () { return m_class; } 618 619 /** 620 * Imprime el descriptor en un stream. 621 */ 622 //virtual void PrintOut(ostream &s, int indent); 623 624 625 /** 626 * Sobrecarga del operador inserción. 627 */ 628 friend std::ostream& operator << (std::ostream &s, PObjectInfo obj); 629 630 // nos serán utiles para generar el nombre del objeto GetInstanceCount()631 unsigned int GetInstanceCount() { return m_numIns; } IncrementInstanceCount()632 void IncrementInstanceCount() { m_numIns++; } ResetInstanceCount()633 void ResetInstanceCount() { m_numIns = 0; } 634 635 /** 636 * Añade la información de un objeto al conjunto de clases base. 637 */ AddBaseClass(PObjectInfo base)638 size_t AddBaseClass(PObjectInfo base) 639 { 640 m_base.push_back(base); 641 return m_base.size() - 1; 642 } 643 644 /** 645 * Comprueba si el tipo es derivado del que se pasa como parámetro. 646 */ 647 bool IsSubclassOf(wxString classname); 648 649 PObjectInfo GetBaseClass(unsigned int idx, bool inherited = true); 650 void GetBaseClasses(std::vector<PObjectInfo> &classes, bool inherited = true); 651 unsigned int GetBaseClassCount(bool inherited = true); 652 SetIconFile(wxBitmap icon)653 void SetIconFile(wxBitmap icon) { m_icon = icon; }; GetIconFile()654 wxBitmap GetIconFile() { return m_icon; } 655 SetSmallIconFile(wxBitmap icon)656 void SetSmallIconFile(wxBitmap icon) { m_smallIcon = icon; }; GetSmallIconFile()657 wxBitmap GetSmallIconFile() { return m_smallIcon; } 658 659 void AddCodeInfo(wxString lang, PCodeInfo codeinfo); 660 PCodeInfo GetCodeInfo(wxString lang); 661 662 PObjectPackage GetPackage(); 663 IsStartOfGroup()664 bool IsStartOfGroup() { return m_startGroup; } 665 666 /** 667 * Le asigna un componente a la clase. 668 */ SetComponent(IComponent * c)669 void SetComponent(IComponent *c) { m_component = c; }; GetComponent()670 IComponent* GetComponent() { return m_component; }; 671 672 private: 673 wxString m_class; // nombre de la clase (tipo de objeto) 674 675 PObjectType m_type; // tipo del objeto 676 WPObjectPackage m_package; // Package that the object comes from 677 678 PPropertyCategory m_category; 679 680 wxBitmap m_icon; 681 wxBitmap m_smallIcon; // The icon for the property grid toolbar 682 bool m_startGroup; // Place a separator in the palette toolbar just before this widget 683 684 std::map< wxString, PCodeInfo > m_codeTemp; // plantillas de codigo K=language_name T=PCodeInfo 685 686 unsigned int m_numIns; // número de instancias del objeto 687 688 std::map< wxString, PPropertyInfo > m_properties; 689 std::map< wxString, PEventInfo > m_events; 690 691 std::vector< PObjectInfo > m_base; // base classes 692 std::map< size_t, std::map< wxString, wxString > > m_baseClassDefaultPropertyValues; 693 IComponent* m_component; // componente asociado a la clase los objetos del 694 // designer 695 }; 696 697 #endif 698