]> git.saurik.com Git - wxWidgets.git/blame - src/xrc/xmlwrite.cpp
New Refresh()/Update() behaviour. As expected, scrolling
[wxWidgets.git] / src / xrc / xmlwrite.cpp
CommitLineData
78d14f80
VS
1/////////////////////////////////////////////////////////////////////////////
2// Name: xmlwrite.cpp
3// Purpose: wxXmlDocument - XML text writer
4// Author: Vaclav Slavik
5// Created: 2001/04/30
6// RCS-ID: $Id$
7// Copyright: (c) 2001 Vaclav Slavik
8// Licence: wxWindows licence
9/////////////////////////////////////////////////////////////////////////////
10
11#ifdef __GNUG__
12// nothing - already in xml.cpp
13#endif
14
15// For compilers that support precompilation, includes "wx.h".
16#include "wx/wxprec.h"
17
18#ifdef __BORLANDC__
19 #pragma hdrstop
20#endif
21
22#include "wx/wfstream.h"
23#include "wx/intl.h"
24#include "wx/log.h"
25#include "wx/strconv.h"
26#include "wx/xrc/xml.h"
27#include "wx/xrc/xmlio.h"
28
29// write string to output:
1419ea47
VS
30inline static void OutputString(wxOutputStream& stream, const wxString& str,
31 wxMBConv *convMem, wxMBConv *convFile)
78d14f80
VS
32{
33 if (str.IsEmpty()) return;
34#if wxUSE_UNICODE
1419ea47
VS
35 const wxW2MBbuf *buf = str.mb_str(convFile ? *convFile : wxConvUTF8);
36 stream.Write((const char*)buf, strlen((const char*)buf));
78d14f80 37#else
1419ea47
VS
38 if ( convFile == NULL )
39 stream.Write(str.mb_str(), str.Len());
40 else
41 {
42 wxString str2(str.wc_str(*convMem), *convFile);
43 stream.Write(str2.mb_str(), str2.Len());
44 }
78d14f80
VS
45#endif
46}
47
48// Same as above, but create entities first.
49// Translates '<' to "&lt;", '>' to "&gt;" and '&' to "&amp;"
1419ea47
VS
50static void OutputStringEnt(wxOutputStream& stream, const wxString& str,
51 wxMBConv *convMem, wxMBConv *convFile)
78d14f80
VS
52{
53 wxString buf;
54 size_t i, last, len;
480505bc 55 wxChar c;
78d14f80
VS
56
57 len = str.Len();
58 last = 0;
59 for (i = 0; i < len; i++)
60 {
61 c = str.GetChar(i);
480505bc
VS
62 if (c == wxT('<') || c == wxT('>') ||
63 (c == wxT('&') && str.Mid(i+1, 4) != wxT("amp;")))
78d14f80 64 {
1419ea47 65 OutputString(stream, str.Mid(last, i - last), convMem, convFile);
78d14f80
VS
66 switch (c)
67 {
1419ea47
VS
68 case wxT('<'):
69 OutputString(stream, wxT("&lt;"), NULL, NULL);
70 break;
71 case wxT('>'):
72 OutputString(stream, wxT("&gt;"), NULL, NULL);
73 break;
74 case wxT('&'):
75 OutputString(stream, wxT("&amp;"), NULL, NULL);
76 break;
78d14f80
VS
77 default: break;
78 }
79 last = i + 1;
80 }
81 }
1419ea47 82 OutputString(stream, str.Mid(last, i - last), convMem, convFile);
78d14f80
VS
83}
84
85inline static void OutputIndentation(wxOutputStream& stream, int indent)
86{
87 wxString str = wxT("\n");
88 for (int i = 0; i < indent; i++)
89 str << wxT(' ') << wxT(' ');
1419ea47 90 OutputString(stream, str, NULL, NULL);
78d14f80
VS
91}
92
1419ea47
VS
93static void OutputNode(wxOutputStream& stream, wxXmlNode *node, int indent,
94 wxMBConv *convMem, wxMBConv *convFile)
78d14f80
VS
95{
96 wxXmlNode *n, *prev;
97 wxXmlProperty *prop;
98
99 switch (node->GetType())
100 {
101 case wxXML_TEXT_NODE:
1419ea47 102 OutputStringEnt(stream, node->GetContent(), convMem, convFile);
78d14f80
VS
103 break;
104
105 case wxXML_ELEMENT_NODE:
1419ea47
VS
106 OutputString(stream, wxT("<"), NULL, NULL);
107 OutputString(stream, node->GetName(), NULL, NULL);
78d14f80
VS
108
109 prop = node->GetProperties();
110 while (prop)
111 {
112 OutputString(stream, wxT(" ") + prop->GetName() +
1419ea47
VS
113 wxT("=\"") + prop->GetValue() + wxT("\""),
114 NULL, NULL);
78d14f80
VS
115 // FIXME - what if prop contains '"'?
116 prop = prop->GetNext();
117 }
118
119 if (node->GetChildren())
120 {
1419ea47 121 OutputString(stream, wxT(">"), NULL, NULL);
78d14f80
VS
122 prev = NULL;
123 n = node->GetChildren();
124 while (n)
125 {
126 if (n && n->GetType() != wxXML_TEXT_NODE)
127 OutputIndentation(stream, indent + 1);
1419ea47 128 OutputNode(stream, n, indent + 1, convMem, convFile);
78d14f80
VS
129 prev = n;
130 n = n->GetNext();
131 }
132 if (prev && prev->GetType() != wxXML_TEXT_NODE)
133 OutputIndentation(stream, indent);
1419ea47
VS
134 OutputString(stream, wxT("</"), NULL, NULL);
135 OutputString(stream, node->GetName(), NULL, NULL);
136 OutputString(stream, wxT(">"), NULL, NULL);
78d14f80
VS
137 }
138 else
1419ea47 139 OutputString(stream, wxT("/>"), NULL, NULL);
78d14f80
VS
140 break;
141
142 case wxXML_COMMENT_NODE:
1419ea47
VS
143 OutputString(stream, wxT("<!--"), NULL, NULL);
144 OutputString(stream, node->GetContent(), convMem, convFile);
145 OutputString(stream, wxT("-->"), NULL, NULL);
78d14f80
VS
146 break;
147
148 default:
149 wxFAIL_MSG(wxT("unsupported node type"));
150 }
151}
152
153bool wxXmlIOHandlerWriter::Save(wxOutputStream& stream, const wxXmlDocument& doc)
154{
155 if (!doc.IsOk())
156 return FALSE;
157
158 wxString s;
159
1419ea47
VS
160 wxMBConv *convMem = NULL, *convFile = NULL;
161#if wxUSE_UNICODE
162 convFile = new wxCSConv(doc.GetFileEncoding());
163#else
164 if ( doc.GetFileEncoding() != doc.GetEncoding() )
165 {
166 convFile = new wxCSConv(doc.GetFileEncoding());
167 convMem = new wxCSConv(doc.GetEncoding());
168 }
169#endif
170
171 s.Printf(wxT("<?xml version=\"%s\" encoding=\"%s\"?>\n"),
172 doc.GetVersion().c_str(), doc.GetFileEncoding().c_str());
173 OutputString(stream, s, NULL, NULL);
174
175 OutputNode(stream, doc.GetRoot(), 0, convMem, convFile);
176 OutputString(stream, wxT("\n"), NULL, NULL);
78d14f80 177
1419ea47
VS
178 if ( convFile )
179 delete convFile;
180 if ( convMem )
181 delete convMem;
78d14f80
VS
182
183 return TRUE;
184}