1 /** \file wxseditenumproperty.cpp
2 *
3 * This file is part of wxSmith plugin for Code::Blocks Studio
4 * Copyright (C) 2010  Gary Harris.
5 *
6 * wxSmith is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation; either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * wxSmith 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 wxSmith. If not, see <http://www.gnu.org/licenses/>.
18 *
19 * This code was taken from the wxSmithImage plug-in, copyright Ron Collins
20 * and released under the GPL.
21 */
22 
23 #include "wxseditenumproperty.h"
24 
25 #include <globals.h>
26 #include <prep.h>
27 
28 // Helper macro for fetching variable
29 #define VALUE   wxsVARIABLE(Object,Offset,wxString)
30 
wxsEditEnumProperty(const wxString & PGName,const wxString & DataName,long _Offset,const wxChar ** _Names,bool _UpdateEntries,const wxString & _Default,bool _XmlStoreEmpty,bool _UseNamesInXml,int Priority)31 wxsEditEnumProperty::wxsEditEnumProperty(const wxString &PGName,
32         const wxString &DataName,
33         long _Offset,
34         const wxChar **_Names,
35         bool _UpdateEntries,
36         const wxString &_Default,
37         bool _XmlStoreEmpty,
38         bool _UseNamesInXml,
39         int Priority):
40     wxsProperty(PGName, DataName, Priority),
41     Offset(_Offset),
42     Default(_Default),
43     XmlStoreEmpty(_XmlStoreEmpty),
44     UpdateEntries(_UpdateEntries),
45     Names(_Names),
46     UseNamesInXml(_UseNamesInXml)
47 {
48     int     i;
49 
50     // the calling routine only needs the returned value as a string
51     // the list of long Values[] is useless to the calling routine
52     // so, let us hope that we have enough Values[] here
53 
54     for(i = 0; i < 512; i++) Values[i] = i;
55 }
56 
57 /*! \brief Register the control with a property grid.
58  *
59  * \param Object wxsPropertyContainer*
60  * \param Grid wxPropertyGridManager*
61  * \param Parent wxPGId
62  * \return void
63  *
64  */
PGCreate(wxsPropertyContainer * Object,wxPropertyGridManager * Grid,wxPGId Parent)65 void wxsEditEnumProperty::PGCreate(wxsPropertyContainer *Object, wxPropertyGridManager *Grid, wxPGId Parent)
66 {
67     wxPGChoices PGC(Names, Values);
68 
69     PGRegister(Object, Grid, Grid->AppendIn(Parent, NEW_IN_WXPG14X wxEditEnumProperty(GetPGName(), wxPG_LABEL, PGC, VALUE)));
70 }
71 
72 /*! \brief Read a property value.
73  *
74  * \param Object wxsPropertyContainer*
75  * \param Grid wxPropertyGridManager*
76  * \param Id wxPGId
77  * \param Index long
78  * \return bool
79  *
80  * \date 27/8/10
81  * Updated by Cryogen to use the item name rather than the enumerator value under wxPropertyGrid 1.4.
82  */
PGRead(cb_unused wxsPropertyContainer * Object,wxPropertyGridManager * Grid,wxPGId Id,cb_unused long Index)83 bool wxsEditEnumProperty::PGRead(cb_unused wxsPropertyContainer *Object,
84                                  wxPropertyGridManager *Grid, wxPGId Id,
85                                  cb_unused long Index)
86 {
87     VALUE = Grid->GetPropertyValueAsString(Id);
88     VALUE.Replace(_T("\\n"), _T("\n"));
89 
90     return true;
91 }
92 
93 /*! \brief Write a property value.
94  *
95  * \param Object wxsPropertyContainer*
96  * \param Grid wxPropertyGridManager*
97  * \param Id wxPGId
98  * \param Index long
99  * \return bool
100  *
101  */
PGWrite(cb_unused wxsPropertyContainer * Object,wxPropertyGridManager * Grid,wxPGId Id,cb_unused long Index)102 bool wxsEditEnumProperty::PGWrite(cb_unused wxsPropertyContainer *Object,
103                                   wxPropertyGridManager *Grid, wxPGId Id,
104                                   cb_unused long Index)
105 {
106     wxString Fixed = VALUE;
107 
108     Fixed.Replace(_T("\n"), _T("\\n"));
109    if ( UpdateEntries )
110     {
111         #if wxCHECK_VERSION(3, 0, 0)
112         wxPGChoices(Id->GetChoices()).Set(Names,Values);
113         #else
114         Grid->GetPropertyChoices(Id).Set(Names,Values);
115         #endif
116     }
117     Grid->SetPropertyValue(Id, Fixed);
118     return true;
119 }
120 
121 /*! \brief Read XML data.
122  *
123  * \param Object wxsPropertyContainer*
124  * \param Element TiXmlElement*
125  * \return bool
126  *
127  */
XmlRead(cb_unused wxsPropertyContainer * Object,TiXmlElement * Element)128 bool wxsEditEnumProperty::XmlRead(cb_unused wxsPropertyContainer *Object,
129                                   TiXmlElement *Element)
130 {
131     if(!Element)
132     {
133         VALUE.Clear();
134         return false;
135     }
136     // TODO: Use proper encoding
137     wxString Base = cbC2U(Element->GetText());
138     wxString Result;
139     for(const wxChar *Ch = Base.c_str(); *Ch; Ch++)
140     {
141         if(*Ch == _T('_'))
142         {
143             if(*++Ch == _T('_'))
144             {
145                 Result << _T('_');
146             }
147             else
148             {
149                 Result << _T('&') << *Ch;
150             }
151         }
152         else if(*Ch == _T('\\'))
153         {
154             switch(*++Ch)
155             {
156                 case _T('n'):
157                     Result << _T('\n');
158                     break;
159                 case _T('r'):
160                     Result << _T('\r');
161                     break;
162                 case _T('t'):
163                     Result << _T('\t');
164                     break;
165                 case _T('\\'):
166                     Result << _T('\\');
167                     break;
168                 default:
169                     Result << _T('\\') << *Ch;
170                     break;
171             }
172         }
173         else
174         {
175             Result << *Ch;
176         }
177     }
178     VALUE = Result;
179     return true;
180 }
181 
182 /*! \brief Write XML data.
183  *
184  * \param Object wxsPropertyContainer*
185  * \param Element TiXmlElement*
186  * \return bool
187  *
188  */
XmlWrite(cb_unused wxsPropertyContainer * Object,TiXmlElement * Element)189 bool wxsEditEnumProperty::XmlWrite(cb_unused wxsPropertyContainer *Object,
190                                    TiXmlElement *Element)
191 {
192     if(XmlStoreEmpty || (VALUE != Default))
193     {
194         wxString Base = VALUE;
195         wxString Result;
196         for(const wxChar *Ch = Base.c_str(); *Ch; Ch++)
197         {
198             switch(*Ch)
199             {
200                 case _T('_'):
201                     Result << _T("__");
202                     break;       // TODO: This is NOT compatible with xrc file when there's no version entry or version is less than 2.3.0.1
203                     //case _T('&'):  Result << _T('_');  break;     // We could leave this to be translated into &amp; but this looks nicer ;)
204                 case _T('\\'):
205                     Result << _T("\\\\");
206                     break;
207                     // We could handle \n and \r here too but this is not necessary since XRC loading
208                     // routines also handle \n and \r chars
209                 default:
210                     Result << *Ch;
211             }
212         }
213         // TODO: Use proper encoding
214         Element->InsertEndChild(TiXmlText(cbU2C(Result)));
215         return true;
216     }
217     return false;
218 }
219 
220 /*! \brief Read from a property stream.
221  *
222  * \param Object wxsPropertyContainer*
223  * \param Stream wxsPropertyStream*
224  * \return bool
225  *
226  */
PropStreamRead(cb_unused wxsPropertyContainer * Object,wxsPropertyStream * Stream)227 bool wxsEditEnumProperty::PropStreamRead(cb_unused wxsPropertyContainer *Object,
228                                          wxsPropertyStream *Stream)
229 {
230     return Stream->GetString(GetDataName(), VALUE, Default);
231 }
232 
233 /*! \brief Write to a property stream.
234  *
235  * \param Object wxsPropertyContainer*
236  * \param Stream wxsPropertyStream*
237  * \return bool
238  *
239  */
PropStreamWrite(cb_unused wxsPropertyContainer * Object,wxsPropertyStream * Stream)240 bool wxsEditEnumProperty::PropStreamWrite(cb_unused wxsPropertyContainer *Object,
241                                           wxsPropertyStream *Stream)
242 {
243     return Stream->PutString(GetDataName(), VALUE, Default);
244 }
245