wxArt2D
xmlpars.cpp
Go to the documentation of this file.
1 /*!
2  \file canvas/src/xmlpars.cpp
3 
4  \brief a2dCanvasDocument - XML reader via Expat
5  \author Klaas Holwerda
6 
7  Copyright: 2001-2004 (C) Klaas Holwerda
8 
9  Licence: wxWidgets licence
10 
11  RCS-ID: $Id: xmlpars.cpp,v 1.70 2009/07/24 16:35:01 titato Exp $
12 */
13 
14 #include "a2dprec.h"
15 
16 #ifdef __BORLANDC__
17 #pragma hdrstop
18 #endif
19 
20 #ifndef WX_PRECOMP
21 #include "wx/wx.h"
22 #endif
23 
24 #include "a2dprivate.h"
25 
26 #if wxART2D_USE_CVGIO
27 
28 #include "wx/canvas/canglob.h"
29 #include "wx/canvas/algos.h"
30 #include "wx/canvas/xmlpars.h"
31 #include "wx/canvas/drawing.h"
32 
33 //----------------------------------------------------------------------------
34 // a2dIOHandlerCVGIn
35 //----------------------------------------------------------------------------
36 
38 {
39  // stay compatible for the moment
40  m_objectCreate[ wxT( "a2dOneColourFill" ) ] = wxT( "a2dFill" );
41  m_objectCreate[ wxT( "a2dLinearGradientFill" ) ] = wxT( "a2dFill" );
42  m_objectCreate[ wxT( "a2dRadialGradientFill" ) ] = wxT( "a2dFill" );
43  m_objectCreate[ wxT( "a2dOneColourStroke" ) ] = wxT( "a2dStroke" );
44  m_docClassInfo = &a2dDrawing::ms_classInfo;
45 }
46 
47 
49 {
50 }
51 
52 bool a2dIOHandlerCVGIn::CanLoad( a2dDocumentInputStream& stream, const wxObject* obj, wxClassInfo* docClassInfo )
53 {
54  if ( obj && !wxDynamicCast( obj, a2dDrawing ) && !wxDynamicCast( obj, a2dLayers ) )
55  return false;
56 
57  if ( docClassInfo && m_docClassInfo && !docClassInfo->IsKindOf( m_docClassInfo ) )
58  return false;
59 
60  m_streami = &stream;
61  SeekI( 0 );
62  char cheader[170];
63  cheader[169] = 0;
64 
65  Read( cheader, 169 );
66  SeekI( 0 );
67 
68  // XML header:
69  if ( memcmp( cheader, "<?xml ", 6 ) == 0 )
70  {
71  wxString buf = XmlDecodeStringToString( cheader, 169 );
72  // <cvg classname="a2dCanvasDocument">
73 
74  int pos;
75  pos = buf.Find( wxT( "<cvg" ) );
76  if ( pos == wxNOT_FOUND )
77  return false;
78 
79  pos = buf.Find( wxT( "classname" ) );
80  if ( pos == wxNOT_FOUND )
81  return false;
82 
83 #if wxUSE_STD_IOSTREAM
84  return ( m_streami->fail() || m_streami->bad() ) == 0;
85 #else
86  return true;
87 #endif
88  }
89 
90  return false;
91 }
92 
94 {
95  bool oke = true;
96 
97  m_streami = &stream;
98 
100 
101  try
102  {
103 
104  Next();
105  Require( START_TAG, wxT( "cvg" ) );
106  Next();
107  if ( GetTagName() == wxT( "title" ) )
108  {
109  Next();
110  Require( END_TAG, wxT( "title" ) );
111  Next();
112  }
113  if ( GetTagName() == wxT( "desc" ) )
114  {
115  Next();
116  Require( END_TAG, wxT( "desc" ) );
117  Next();
118  }
119 
120  if ( GetTagName() == wxT( "o" ) && GetAttributeValue( wxT( "classname" ) ) == wxT( "a2dLayers" ) )
121  {
122  //add ON top existing setup
123  layers->Load( NULL, *this );
124  }
125 
126  Require( END_TAG, wxT( "cvg" ) );
127  Next();
128 
129  //now resolve references on id.
130  //CVG links on Id's
131  LinkReferences();
132  layers->UpdateIndexes();
133  }
134  catch ( a2dIOHandlerXMLException& error ) // error from the parser: process here
135  {
136  a2dGeneralGlobals->ReportErrorF( a2dError_XMLparse, _( "CVG parsing error: '%s' at line %d column %d" ), error.getMessage().c_str(), error.getLineNumber(), error.getColumnNumber() );
137  oke = false;
138  }
139 
140  ResetLoad();
141  return oke;
142 }
143 
144 
145 
147 {
148  m_streami = &stream;
149  SeekI( 0 );
150 
151  bool oke = true;
152 
153  InitializeLoad();
154 
155  try
156  {
157  wxString version = wxT("");
158  SetFormatVersion( version );
159 
160  drawing->Load( NULL, *this );
161 /*
162  a2dCanvasObject* readobject;
163  Next();
164  Require( START_TAG, wxT( "cvg" ) );
165  Next();
166  if ( GetTagName() == wxT( "title" ) )
167  {
168  //doc->SetTitle( GetContent() );
169  Next();
170  Require( END_TAG, wxT( "title" ) );
171  Next();
172  }
173  if ( GetTagName() == wxT( "desc" ) )
174  {
175  //doc->SetDescription( GetContent() );
176  Next();
177  Require( END_TAG, wxT( "desc" ) );
178  Next();
179  }
180 
181  if ( GetTagName() == wxT( "a2dLayers" ) )
182  {
183  //add ON top existing setup
184  m_doc->GetLayerSetup()->Load( NULL, *this );
185  }
186 
187  //this way allows empty documents also
188  //Require( START_TAG, "canvasobject" );
189 
190  while( GetEventType() == START_TAG && GetTagName() == wxT( "o" ) )
191  {
192  wxString classname = GetAttributeValue( wxT( "classname" ) );
193  readobject = ( a2dCanvasObject* ) CreateObject( classname );
194  if ( !readobject )
195  {
196  a2dGeneralGlobals->ReportErrorF( a2dError_XMLparse, _( "could not create a2dCanvasObject %s, will be skipped line %d" ),
197  GetAttributeValue( wxT( "classname" ) ).c_str(), GetCurrentLineNumber() );
198  return false;
199  }
200  else
201  {
202  parent->Append( readobject );
203  readobject->Load( NULL, *this );
204  }
205  }
206 
207  Require( END_TAG, wxT( "cvg" ) );
208  Next();
209 */
210  //now resolve references on id.
211  //CVG links on Id's
212  LinkReferences();
213  }
214  catch ( a2dIOHandlerXMLException& error ) // error from the parser: process here
215  {
216  a2dGeneralGlobals->ReportErrorF( a2dError_XMLparse, _( "CVG parsing error: '%s' at line %d column %d" ), error.getMessage().c_str(), error.getLineNumber(), error.getColumnNumber() );
217  oke = false;
218  }
219 
220  ResetLoad();
221 
222  return oke;
223 }
224 
226 {
227  m_streami = &stream;
228 
229  bool oke = true;
230 
231  InitializeLoad();
232  SeekI( 0 );
233 
234  try
235  {
236  Next();
237  Require( START_TAG, wxT( "cvg" ) );
238  Next();
239  if ( GetTagName() == wxT( "title" ) )
240  {
241  //doc->SetTitle( GetContent() );
242  Next();
243  Require( END_TAG, wxT( "title" ) );
244  Next();
245  }
246  if ( GetTagName() == wxT( "desc" ) )
247  {
248  //doc->SetDescription( GetContent() );
249  Next();
250  Require( END_TAG, wxT( "desc" ) );
251  Next();
252  }
253 
254  Require( START_TAG, "o" );
255 
256  while( GetEventType() == START_TAG && GetTagName() == wxT( "o" ) )
257  {
258  wxString classname = GetAttributeValue( wxT( "classname" ) );
259  canvasobject = ( a2dCanvasObject* ) CreateObject( classname );
260  if ( !canvasobject )
261  {
262  a2dGeneralGlobals->ReportErrorF( a2dError_XMLparse, _( "could not create a2dCanvasObject %s, will be skipped line %d" ),
263  GetAttributeValue( wxT( "classname" ) ).c_str(), GetCurrentLineNumber() );
264  canvasobject = NULL;
265  return false;
266  }
267  else
268  {
269  canvasobject->Load( NULL, *this );
270  }
271  }
272 
273  Require( END_TAG, wxT( "cvg" ) );
274  Next();
275 
276  //now resolve references on id.
277  //CVG links on Id's
278  LinkReferences();
279  }
280  catch ( a2dIOHandlerXMLException& error ) // error from the parser: process here
281  {
282  a2dGeneralGlobals->ReportErrorF( a2dError_XMLparse, _( "CVG parsing error: '%s' at line %d column %d" ), error.getMessage().c_str(), error.getLineNumber(), error.getColumnNumber() );
283  oke = false;
284  }
285 
286  ResetLoad();
287 
288  return oke;
289 }
290 
291 //----------------------------------------------------------------------------
292 // a2dIOHandlerCVGOut
293 //----------------------------------------------------------------------------
294 
296 {
297 }
298 
299 
301 {
302 }
303 
305 {
306  m_streamo = &stream;
307 
308 #if wxUSE_STD_IOSTREAM
309  if ( stream.fail() || stream.bad() )
310  {
311 #else
312  if ( !stream.IsOk() )
313  {
314 #endif
315  a2dGeneralGlobals->ReportErrorF( a2dError_FileCouldNotOpen, _( "Sorry, could not open stream for saving" ) );
316  return false;
317  }
318  InitializeSave();
319 
320  //check flag is used for writing once an object which is referenced many times
321  a2dWalker_SetCheck setp( false );
322  setp.Start( layers );
323 
324  WriteStartDocument( wxT( "1.0" ), wxT( "UTF-8" ) , true );
325 
326  WriteStartElementAttributes( wxT( "cvg" ) );
327  WriteAttribute( wxT( "classname" ), GetClassInfo()->GetClassName() );
329 
330  WriteElement( wxT( "title" ), wxT( "layersettings" ) );
331  WriteElement( wxT( "desc" ), wxT( "description" ) );
332 
333  a2dObjectList towritelayer;
334  layers->Save( NULL, *this, &towritelayer );
335 
336  WriteEndElement();
338 
339  ResetSave();
340 
341  return true;
342 }
343 
345 {
346  m_streamo = &stream;
347 
348 #if wxUSE_STD_IOSTREAM
349  if ( stream.fail() || stream.bad() )
350  {
351 #else
352  if ( !stream.IsOk() )
353  {
354 #endif
355  a2dGeneralGlobals->ReportErrorF( a2dError_FileCouldNotOpen, _( "Sorry, could not open stream for saving" ) );
356  return false;
357  }
358 
359  InitializeSave();
360  a2dObjectList towrite;
361  const_cast<a2dDrawing*>( drawing )->Save( NULL, *this, &towrite, start );
362  ResetSave();
363 
364  return true;
365 }
366 
367 void a2dIOHandlerCVGOut::WriteCvgStartDocument( a2dDocumentOutputStream& stream )
368 {
369  m_streamo = &stream;
370 
371  InitializeSave();
372 
373  WriteStartDocument( wxT( "1.0" ), wxT( "UTF-8" ) , true );
374 
375  WriteStartElementAttributes( wxT( "cvg" ) );
376  WriteAttribute( wxT( "classname" ), GetClassInfo()->GetClassName() );
378 
379  WriteElement( wxT( "title" ), wxT( "" ) );
380  WriteElement( wxT( "desc" ), wxT( "" ) );
381 }
382 
383 void a2dIOHandlerCVGOut::WriteCvgEndDocument()
384 {
385  WriteEndElement();
387  ResetSave( );
388 }
389 
390 void a2dIOHandlerCVGOut::WriteObject( a2dCanvasObject* start )
391 {
392  //check flag is used for writing once an object which is referenced many times
393  a2dWalker_SetCheck setp( false );
394  setp.Start( start );
395 
396  a2dObjectList towrite;
397  towrite.push_back( start );
398 
399  a2dObjectList::iterator iter = towrite.begin();
400  while ( towrite.size() )
401  {
402  a2dObject* obj = *iter;
403  obj->Save( NULL, *this, &towrite );
404  towrite.erase( iter );
405  iter = towrite.begin();
406  }
407 }
408 
409 #endif /* wxART2D_USE_CVGIO */
set check on a2dObject flag false or true
Definition: algos.h:665
For exceptions thrown while parsing XML files.
Definition: genxmlpars.h:36
a2dHashMapCreateObject m_objectCreate
This is used to find a classname using a symbolic name.
Definition: gen.h:3549
#define wxDynamicCast(obj, className)
Define wxDynamicCast so that it will give a compiler error for unrelated types.
Definition: gen.h:75
bool SaveStartAt(a2dDocumentOutputStream &stream, const a2dDrawing *drawing, a2dCanvasObject *start)
saves as CVG starting at object start
Definition: xmlpars.cpp:344
void WriteElement(const wxString &name, const wxString &content=wxT(""), bool newLine=true)
Writes start and end tag.
Definition: genxmlpars.cpp:794
XMLeventType Next()
Walks to next element and returns event type.
Definition: genxmlpars.cpp:422
void WriteStartElementAttributes(const wxString &name, bool newLine=true)
Writes start tag which has attributes.
Definition: genxmlpars.cpp:757
Ref Counted base object.
Definition: gen.h:1045
a2dIOHandlerCVGIn and a2dIOHandlerCVGOut - XML I/O classes for the CVG format.
wxOutputStream a2dDocumentOutputStream
output stream based wxStreams
Definition: gen.h:3458
virtual int GetCurrentLineNumber()
where in the input was line the current tag
Definition: genxmlpars.cpp:349
a2dDocumentInputStream * m_streami
file or other string stream containing the format to parse.
Definition: gen.h:3734
const a2dError a2dError_FileCouldNotOpen
a2dCanvasObject is the base class for Canvas Objects.
Definition: canobj.h:371
virtual wxObject * CreateObject(const wxString &symbolicName)
Creates an specific object by name.
Definition: gen.cpp:4937
void WriteEndElement(bool newLine=true)
Writes correspondending end tag for the current start tag.
Definition: genxmlpars.cpp:862
virtual void ResetLoad()
Reset the object after loading.
Definition: genxmlpars.cpp:334
void WriteStartDocument(const wxString &version, const wxString &encoding, bool standalone)
Writes the XML header declaration.
Definition: genxmlpars.cpp:723
a2dIOHandlerStrIn & SeekI(wxFileOffset pos)
set stream at a position
Definition: gen.cpp:5021
virtual bool CanLoad(a2dDocumentInputStream &stream, const wxObject *obj=NULL, wxClassInfo *docClassInfo=NULL)
test header of the file to see if its CVG format
Definition: xmlpars.cpp:52
a2dIOHandlerCVGIn()
Constructor.
Definition: xmlpars.cpp:37
~a2dIOHandlerCVGOut()
Destructor.
Definition: xmlpars.cpp:300
const a2dError a2dError_XMLparse
virtual void InitializeSave()
Inits the IO handler for writing.
Definition: genxmlpars.cpp:695
virtual void ResetSave()
Reset the object after saving.
Definition: genxmlpars.cpp:703
bool SaveLayers(a2dDocumentOutputStream &stream, a2dLayers *layers)
save a layer definition to a CVG file.
Definition: xmlpars.cpp:304
A2DGENERALDLLEXP a2dSmrtPtr< a2dGeneralGlobal > a2dGeneralGlobals
a global pointer to get to global instance of important classes.
Definition: comevt.cpp:1148
wxStringInputStream a2dDocumentStringInputStream
string input stream based wxStreams
Definition: gen.h:3452
bool Load(a2dDocumentStringInputStream &stream, a2dDrawing *doc, a2dCanvasObject *parent)
reading a CVG document and add the contents as children to a given a2dCanvasObject parent...
Definition: xmlpars.cpp:146
virtual void InitializeLoad()
Inits the IO handler for reading.
Definition: genxmlpars.cpp:327
void UpdateIndexes()
all non defined layers until wxMAXLAYER will be added a new childs.
Definition: layerinf.cpp:695
bool LoadLayers(a2dDocumentInputStream &stream, a2dLayers *layers)
load a layer definition from a CVG file.
Definition: xmlpars.cpp:93
Contains a2dDrawing Class to hold a drawing.
void WriteEndAttributes(bool close=false)
&quot;Closes&quot; the start tag after writing all attributes (writes the &quot;&gt;&quot; or &quot;/&gt;&quot; bracket).
Definition: genxmlpars.cpp:837
wxClassInfo * m_docClassInfo
Run-time class information that allows document instances to be constructed dynamically.
Definition: gen.h:3737
a2dIOHandlerCVGOut()
Constructor.
Definition: xmlpars.cpp:295
wxInputStream a2dDocumentInputStream
input stream based wxStreams
Definition: gen.h:3456
a2dWalker based algorithms
virtual void Load(wxObject *parent, a2dIOHandlerXmlSerIn &parser)
load object from CVG file
Definition: gen.cpp:1396
wxString GetAttributeValue(const wxString &attrib, const wxString &defaultv=wxT(""))
Returns the value of an attribute.
Definition: genxmlpars.cpp:450
virtual void Load(wxObject *parent, a2dIOHandlerXmlSerIn &parser)
load object from CVG file
Definition: drawing.cpp:730
void WriteEndDocument()
Checks if all open tags are closed.
Definition: genxmlpars.cpp:730
XMLeventType GetEventType()
Returns the type of current event.
Definition: genxmlpars.cpp:606
void Require(const XMLeventType &type, wxString name)
Forces a special tag.
Definition: genxmlpars.cpp:390
virtual bool Save(a2dDocumentOutputStream &stream, const wxObject *doc)
save a2dCanvasDocument as CVG
wxString GetTagName()
Returns name of the current XML tag.
Definition: genxmlpars.cpp:565
virtual void Save(wxObject *parent, a2dIOHandlerXmlSerOut &out, a2dObjectList *towrite)
write all needed to an XML type of file called the CVG format
Definition: gen.cpp:1343
~a2dIOHandlerCVGIn()
Destructor.
Definition: xmlpars.cpp:48
list of a2dObject&#39;s
Definition: gen.h:3157
virtual bool LinkReferences(bool ignoreNonResolved=false)
link references to their destination
Definition: gen.cpp:4862
a2dDocumentOutputStream * m_streamo
file or other string stream containing the format to output to.
Definition: gen.h:3825
bool Start(a2dObject *object)
start removing properties from the object given, and down.
Definition: algos.h:634
void SetFormatVersion(wxString formatVersion)
set version of library or document being parsed for
Definition: genxmlpars.h:844
Contain one drawing as hierarchical tree of a2dCanvasObject&#39;s.
Definition: drawing.h:434
general canvas module declarations and classes
xmlpars.cpp Source File -- Sun Oct 12 2014 17:04:26 -- Sun Oct 12 2014 -- 1.8.5 -- wxArt2D -- . -- Main Page Reference Documentation