Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : */
9 :
10 : #include "frame.hxx"
11 : #include "frmfmt.hxx"
12 : #include "sectfrm.hxx"
13 : #include "tabfrm.hxx"
14 : #include "txtfrm.hxx"
15 : #include "hffrm.hxx"
16 : #include "rootfrm.hxx"
17 : #include "editsh.hxx"
18 : #include "porlin.hxx"
19 : #include "porlay.hxx"
20 : #include "portxt.hxx"
21 : #include "sortedobjs.hxx"
22 : #include <anchoredobject.hxx>
23 : #include <libxml/xmlwriter.h>
24 : #include <SwPortionHandler.hxx>
25 :
26 : class XmlPortionDumper:public SwPortionHandler
27 : {
28 : private:
29 : xmlTextWriterPtr writer;
30 : sal_Int32 ofs;
31 :
32 759 : static const char* getTypeName( sal_uInt16 nType )
33 : {
34 759 : switch ( nType )
35 : {
36 0 : case POR_LIN: return "POR_LIN";
37 1 : case POR_FLYCNT: return "POR_FLYCNT";
38 :
39 4 : case POR_HOLE: return "POR_HOLE";
40 0 : case POR_TMPEND: return "POR_TMPEND";
41 1 : case POR_BRK: return "POR_BRK";
42 0 : case POR_KERN: return "POR_KERN";
43 0 : case POR_ARROW: return "POR_ARROW";
44 0 : case POR_MULTI: return "POR_MULTI";
45 0 : case POR_HIDDEN_TXT: return "POR_HIDDEN_TXT";
46 0 : case POR_CONTROLCHAR: return "POR_CONTROLCHAR";
47 :
48 126 : case POR_TXT: return "POR_TXT";
49 29 : case POR_LAY: return "POR_LAY";
50 427 : case POR_PARA: return "POR_PARA";
51 0 : case POR_URL: return "POR_URL";
52 0 : case POR_HNG: return "POR_HNG";
53 :
54 0 : case POR_DROP: return "POR_DROP";
55 0 : case POR_TOX: return "POR_TOX";
56 0 : case POR_ISOTOX: return "POR_ISOTOX";
57 0 : case POR_REF: return "POR_REF";
58 0 : case POR_ISOREF: return "POR_ISOREF";
59 0 : case POR_META: return "POR_META";
60 :
61 0 : case POR_EXP: return "POR_EXP";
62 0 : case POR_BLANK: return "POR_BLANK";
63 0 : case POR_POSTITS: return "POR_POSTITS";
64 :
65 0 : case POR_HYPH: return "POR_HYPH";
66 0 : case POR_HYPHSTR: return "POR_HYPHSTR";
67 0 : case POR_SOFTHYPH: return "POR_SOFTHYPH";
68 0 : case POR_SOFTHYPHSTR: return "POR_SOFTHYPHSTR";
69 0 : case POR_SOFTHYPH_COMP: return "POR_SOFTHYPH_COMP";
70 :
71 36 : case POR_FLD: return "POR_FLD";
72 0 : case POR_HIDDEN: return "POR_HIDDEN";
73 0 : case POR_QUOVADIS: return "POR_QUOVADIS";
74 0 : case POR_ERGOSUM: return "POR_ERGOSUM";
75 0 : case POR_COMBINED: return "POR_COMBINED";
76 0 : case POR_FTN: return "POR_FTN";
77 :
78 0 : case POR_FTNNUM: return "POR_FTNNUM";
79 15 : case POR_NUMBER: return "POR_NUMBER";
80 24 : case POR_BULLET: return "POR_BULLET";
81 0 : case POR_GRFNUM: return "POR_GRFNUM";
82 :
83 0 : case POR_GLUE: return "POR_GLUE";
84 :
85 20 : case POR_MARGIN: return "POR_MARGIN";
86 :
87 0 : case POR_FIX: return "POR_FIX";
88 8 : case POR_FLY: return "POR_FLY";
89 :
90 0 : case POR_TAB: return "POR_TAB";
91 :
92 5 : case POR_TABRIGHT: return "POR_TABRIGHT";
93 0 : case POR_TABCENTER: return "POR_TABCENTER";
94 0 : case POR_TABDECIMAL: return "POR_TABDECIMAL";
95 :
96 63 : case POR_TABLEFT: return "POR_TABLEFT";
97 : default:
98 0 : return "Unknown";
99 : }
100 : }
101 :
102 : public:
103 :
104 952 : explicit XmlPortionDumper( xmlTextWriterPtr some_writer ):writer( some_writer ), ofs( 0 )
105 : {
106 952 : }
107 :
108 952 : virtual ~ XmlPortionDumper( )
109 952 : {
110 952 : }
111 :
112 : /**
113 : @param nLength
114 : length of this portion in the model string
115 : @param rText
116 : text which is painted on-screen
117 : */
118 655 : virtual void Text( sal_Int32 nLength,
119 : sal_uInt16 nType,
120 : sal_Int32 nHeight,
121 : sal_Int32 nWidth) SAL_OVERRIDE
122 : {
123 655 : ofs += nLength;
124 655 : xmlTextWriterStartElement( writer, BAD_CAST( "Text" ) );
125 : xmlTextWriterWriteFormatAttribute( writer,
126 : BAD_CAST( "nLength" ),
127 655 : "%i", ( int ) nLength );
128 : xmlTextWriterWriteFormatAttribute( writer,
129 : BAD_CAST( "nType" ),
130 655 : "%s", getTypeName( nType ) );
131 655 : if (nHeight > 0)
132 646 : xmlTextWriterWriteFormatAttribute(writer, BAD_CAST("nHeight"), "%i", (int)nHeight);
133 655 : if (nWidth > 0)
134 594 : xmlTextWriterWriteFormatAttribute(writer, BAD_CAST("nWidth"), "%i", (int)nWidth);
135 :
136 655 : xmlTextWriterEndElement( writer );
137 655 : }
138 :
139 : /**
140 : @param nLength
141 : length of this portion in the model string
142 : @param rText
143 : text which is painted on-screen
144 : @param nType
145 : type of this portion
146 : @param nHeight
147 : font size of the painted text
148 : */
149 104 : virtual void Special( sal_Int32 nLength,
150 : const OUString & rText,
151 : sal_uInt16 nType,
152 : sal_Int32 nHeight,
153 : sal_Int32 nWidth,
154 : const SwFont* pFont ) SAL_OVERRIDE
155 : {
156 104 : xmlTextWriterStartElement( writer, BAD_CAST( "Special" ) );
157 : xmlTextWriterWriteFormatAttribute( writer,
158 : BAD_CAST( "nLength" ),
159 104 : "%i", ( int ) nLength );
160 : xmlTextWriterWriteFormatAttribute( writer,
161 : BAD_CAST( "nType" ),
162 104 : "%s", getTypeName( nType ) );
163 104 : OUString sText( rText );
164 : OString sText8 =OUStringToOString( sText,
165 208 : RTL_TEXTENCODING_UTF8 );
166 : xmlTextWriterWriteFormatAttribute( writer, BAD_CAST( "rText" ),
167 104 : "%s", sText8.getStr( ) );
168 :
169 104 : if (nHeight > 0)
170 48 : xmlTextWriterWriteFormatAttribute(writer, BAD_CAST("nHeight"), "%i", (int)nHeight);
171 :
172 104 : if (nWidth > 0)
173 27 : xmlTextWriterWriteFormatAttribute(writer, BAD_CAST("nWidth"), "%i", (int)nWidth);
174 :
175 104 : if (pFont)
176 39 : pFont->dumpAsXml(writer);
177 :
178 104 : xmlTextWriterEndElement( writer );
179 208 : ofs += nLength;
180 104 : }
181 :
182 572 : virtual void LineBreak( sal_Int32 nWidth ) SAL_OVERRIDE
183 : {
184 572 : xmlTextWriterStartElement( writer, BAD_CAST( "LineBreak" ) );
185 572 : if (nWidth > 0)
186 : xmlTextWriterWriteFormatAttribute( writer,
187 : BAD_CAST( "nWidth" ),
188 519 : "%i", ( int ) nWidth );
189 572 : xmlTextWriterEndElement( writer );
190 572 : }
191 :
192 : /**
193 : * @param nLength
194 : * number of 'model string' characters to be skipped
195 : */
196 1 : virtual void Skip( sal_Int32 nLength ) SAL_OVERRIDE
197 : {
198 1 : xmlTextWriterStartElement( writer, BAD_CAST( "Skip" ) );
199 : xmlTextWriterWriteFormatAttribute( writer,
200 : BAD_CAST( "nLength" ),
201 1 : "%i", ( int ) nLength );
202 1 : xmlTextWriterEndElement( writer );
203 1 : ofs += nLength;
204 1 : }
205 :
206 952 : virtual void Finish( ) SAL_OVERRIDE
207 : {
208 952 : xmlTextWriterStartElement( writer, BAD_CAST( "Finish" ) );
209 952 : xmlTextWriterEndElement( writer );
210 952 : }
211 :
212 : };
213 :
214 : namespace
215 : {
216 0 : xmlTextWriterPtr lcl_createDefaultWriter()
217 : {
218 0 : xmlTextWriterPtr writer = xmlNewTextWriterFilename( "layout.xml", 0 );
219 0 : xmlTextWriterStartDocument( writer, NULL, NULL, NULL );
220 0 : return writer;
221 : }
222 :
223 0 : void lcl_freeWriter( xmlTextWriterPtr writer )
224 : {
225 0 : xmlTextWriterEndDocument( writer );
226 0 : xmlFreeTextWriter( writer );
227 0 : }
228 : }
229 :
230 1852 : void SwFrm::dumpAsXml( xmlTextWriterPtr writer ) const
231 : {
232 1852 : bool bCreateWriter = ( NULL == writer );
233 1852 : if ( bCreateWriter )
234 0 : writer = lcl_createDefaultWriter();
235 :
236 1852 : const char *name = NULL;
237 :
238 1852 : switch ( GetType( ) )
239 : {
240 : case FRM_ROOT:
241 52 : name = "root";
242 52 : break;
243 : case FRM_PAGE:
244 117 : name = "page";
245 117 : break;
246 : case FRM_COLUMN:
247 8 : name = "column";
248 8 : break;
249 : case FRM_HEADER:
250 67 : name = "header";
251 67 : break;
252 : case FRM_FOOTER:
253 62 : name = "footer";
254 62 : break;
255 : case FRM_FTNCONT:
256 0 : name = "ftncont";
257 0 : break;
258 : case FRM_FTN:
259 0 : name = "ftn";
260 0 : break;
261 : case FRM_BODY:
262 125 : name = "body";
263 125 : break;
264 : case FRM_FLY:
265 20 : name = "fly";
266 20 : break;
267 : case FRM_SECTION:
268 5 : name = "section";
269 5 : break;
270 : case FRM_UNUSED:
271 0 : name = "unused";
272 0 : break;
273 : case FRM_TAB:
274 24 : name = "tab";
275 24 : break;
276 : case FRM_ROW:
277 88 : name = "row";
278 88 : break;
279 : case FRM_CELL:
280 331 : name = "cell";
281 331 : break;
282 : case FRM_TXT:
283 952 : name = "txt";
284 952 : break;
285 : case FRM_NOTXT:
286 1 : name = "notxt";
287 1 : break;
288 : };
289 :
290 1852 : if ( name != NULL )
291 : {
292 1852 : xmlTextWriterStartElement( writer, reinterpret_cast<const xmlChar *>(name) );
293 :
294 1852 : dumpAsXmlAttributes( writer );
295 :
296 1852 : if (IsRootFrm())
297 : {
298 : // Root frame has access to the edit shell, so dump the current selection ranges here.
299 52 : const SwRootFrm* const pRootFrm = static_cast<const SwRootFrm* const>(this);
300 52 : SwEditShell* pEditShell = pRootFrm->GetCurrShell()->GetDoc()->GetEditShell();
301 52 : xmlTextWriterStartElement(writer, BAD_CAST("shellCrsr"));
302 104 : for (SwPaM& rPaM : pEditShell->getShellCrsr(false)->GetRingContainer())
303 52 : rPaM.dumpAsXml(writer);
304 52 : xmlTextWriterEndElement(writer);
305 : }
306 :
307 1852 : xmlTextWriterStartElement( writer, BAD_CAST( "infos" ) );
308 1852 : dumpInfosAsXml( writer );
309 1852 : xmlTextWriterEndElement( writer );
310 :
311 : // Dump Anchored objects if any
312 1852 : const SwSortedObjs* pAnchored = GetDrawObjs();
313 1852 : if ( pAnchored && pAnchored->size() > 0 )
314 : {
315 29 : xmlTextWriterStartElement( writer, BAD_CAST( "anchored" ) );
316 :
317 64 : for ( size_t i = 0, len = pAnchored->size(); i < len; ++i )
318 : {
319 35 : SwAnchoredObject* pObject = (*pAnchored)[i];
320 35 : pObject->dumpAsXml( writer );
321 : }
322 :
323 29 : xmlTextWriterEndElement( writer );
324 : }
325 :
326 : // Dump the children
327 1852 : if ( IsTextFrm( ) )
328 : {
329 952 : const SwTextFrm *pTextFrm = static_cast<const SwTextFrm *>(this);
330 952 : OUString aText = pTextFrm->GetText( );
331 31416 : for ( int i = 0; i < 32; i++ )
332 : {
333 30464 : aText = aText.replace( i, '*' );
334 : }
335 : OString aText8 =OUStringToOString( aText,
336 1904 : RTL_TEXTENCODING_UTF8 );
337 : xmlTextWriterWriteString( writer,
338 952 : reinterpret_cast<const xmlChar *>(aText8.getStr( )) );
339 1904 : XmlPortionDumper pdumper( writer );
340 1904 : pTextFrm->VisitPortions( pdumper );
341 :
342 : }
343 : else
344 : {
345 900 : dumpChildrenAsXml( writer );
346 : }
347 1852 : xmlTextWriterEndElement( writer );
348 : }
349 :
350 1852 : if ( bCreateWriter )
351 0 : lcl_freeWriter( writer );
352 1852 : }
353 :
354 1852 : void SwFrm::dumpInfosAsXml( xmlTextWriterPtr writer ) const
355 : {
356 : // output the Frm
357 1852 : xmlTextWriterStartElement( writer, BAD_CAST( "bounds" ) );
358 1852 : xmlTextWriterWriteFormatAttribute( writer, BAD_CAST( "left" ), "%ld", Frm().Left() );
359 1852 : xmlTextWriterWriteFormatAttribute( writer, BAD_CAST( "top" ), "%ld", Frm().Top() );
360 1852 : xmlTextWriterWriteFormatAttribute( writer, BAD_CAST( "width" ), "%ld", Frm().Width() );
361 1852 : xmlTextWriterWriteFormatAttribute( writer, BAD_CAST( "height" ), "%ld", Frm().Height() );
362 1852 : xmlTextWriterEndElement( writer );
363 1852 : }
364 :
365 : // Hack: somehow conversion from "..." to va_list does
366 : // bomb on two string litterals in the format.
367 : static const char* TMP_FORMAT = "%" SAL_PRIuUINTPTR;
368 :
369 1852 : void SwFrm::dumpAsXmlAttributes( xmlTextWriterPtr writer ) const
370 : {
371 1852 : xmlTextWriterWriteFormatAttribute( writer, BAD_CAST( "ptr" ), "%p", this );
372 1852 : xmlTextWriterWriteFormatAttribute( writer, BAD_CAST( "id" ), "%" SAL_PRIuUINT32, GetFrmId() );
373 1852 : xmlTextWriterWriteFormatAttribute( writer, BAD_CAST( "symbol" ), "%s", BAD_CAST( typeid( *this ).name( ) ) );
374 1852 : if ( GetNext( ) )
375 884 : xmlTextWriterWriteFormatAttribute( writer, BAD_CAST( "next" ), "%" SAL_PRIuUINT32, GetNext()->GetFrmId() );
376 1852 : if ( GetPrev( ) )
377 884 : xmlTextWriterWriteFormatAttribute( writer, BAD_CAST( "prev" ), "%" SAL_PRIuUINT32, GetPrev()->GetFrmId() );
378 1852 : if ( GetUpper( ) )
379 1780 : xmlTextWriterWriteFormatAttribute( writer, BAD_CAST( "upper" ), "%" SAL_PRIuUINT32, GetUpper()->GetFrmId() );
380 1852 : if ( GetLower( ) )
381 896 : xmlTextWriterWriteFormatAttribute( writer, BAD_CAST( "lower" ), "%" SAL_PRIuUINT32, GetLower()->GetFrmId() );
382 1852 : if ( IsTextFrm( ) )
383 : {
384 952 : const SwTextFrm *pTextFrm = static_cast<const SwTextFrm *>(this);
385 952 : const SwTextNode *pTextNode = pTextFrm->GetTextNode();
386 952 : xmlTextWriterWriteFormatAttribute( writer, BAD_CAST( "txtNodeIndex" ), TMP_FORMAT, pTextNode->GetIndex() );
387 : }
388 1852 : if (IsHeaderFrm() || IsFooterFrm())
389 : {
390 129 : const SwHeadFootFrm *pHeadFootFrm = static_cast<const SwHeadFootFrm*>(this);
391 129 : OUString aFormatName = pHeadFootFrm->GetFormat()->GetName();
392 129 : xmlTextWriterWriteFormatAttribute( writer, BAD_CAST( "fmtName" ), "%s", BAD_CAST(OUStringToOString(aFormatName, RTL_TEXTENCODING_UTF8).getStr()));
393 129 : xmlTextWriterWriteFormatAttribute( writer, BAD_CAST( "fmtPtr" ), "%p", pHeadFootFrm->GetFormat());
394 : }
395 1852 : }
396 :
397 900 : void SwFrm::dumpChildrenAsXml( xmlTextWriterPtr writer ) const
398 : {
399 900 : const SwFrm *pFrm = GetLower( );
400 2680 : for ( ; pFrm != NULL; pFrm = pFrm->GetNext( ) )
401 : {
402 1780 : pFrm->dumpAsXml( writer );
403 : }
404 900 : }
405 :
406 15 : void SwAnchoredObject::dumpAsXml( xmlTextWriterPtr writer ) const
407 : {
408 15 : bool bCreateWriter = ( NULL == writer );
409 15 : if ( bCreateWriter )
410 0 : writer = lcl_createDefaultWriter();
411 :
412 15 : xmlTextWriterStartElement( writer, BAD_CAST( getElementName() ) );
413 15 : xmlTextWriterWriteFormatAttribute( writer, BAD_CAST( "ptr" ), "%p", this );
414 :
415 15 : xmlTextWriterStartElement( writer, BAD_CAST( "bounds" ) );
416 15 : xmlTextWriterWriteFormatAttribute( writer, BAD_CAST( "left" ), "%ld", GetObjBoundRect().Left() );
417 15 : xmlTextWriterWriteFormatAttribute( writer, BAD_CAST( "top" ), "%ld", GetObjBoundRect().Top() );
418 15 : xmlTextWriterWriteFormatAttribute( writer, BAD_CAST( "width" ), "%ld", GetObjBoundRect().Width() );
419 15 : xmlTextWriterWriteFormatAttribute( writer, BAD_CAST( "height" ), "%ld", GetObjBoundRect().Height() );
420 15 : xmlTextWriterEndElement( writer );
421 :
422 15 : xmlTextWriterEndElement( writer );
423 :
424 15 : if ( bCreateWriter )
425 0 : lcl_freeWriter( writer );
426 15 : }
427 :
428 39 : void SwFont::dumpAsXml(xmlTextWriterPtr writer) const
429 : {
430 39 : xmlTextWriterStartElement(writer, BAD_CAST("pFont"));
431 39 : xmlTextWriterWriteFormatAttribute(writer, BAD_CAST("ptr"), "%p", this);
432 39 : xmlTextWriterWriteFormatAttribute(writer, BAD_CAST("color"), "%s", GetColor().AsRGBHexString().toUtf8().getStr());
433 39 : xmlTextWriterEndElement(writer);
434 39 : }
435 :
436 952 : void SwTextFrm::dumpAsXmlAttributes( xmlTextWriterPtr writer ) const
437 : {
438 952 : SwFrm::dumpAsXmlAttributes( writer );
439 952 : if ( HasFollow() )
440 1 : xmlTextWriterWriteFormatAttribute( writer, BAD_CAST( "follow" ), "%" SAL_PRIuUINT32, GetFollow()->GetFrmId() );
441 :
442 952 : if (m_pPrecede != NULL)
443 1 : xmlTextWriterWriteFormatAttribute( writer, BAD_CAST( "precede" ), "%" SAL_PRIuUINT32, static_cast<SwTextFrm*>(m_pPrecede)->GetFrmId() );
444 952 : }
445 :
446 5 : void SwSectionFrm::dumpAsXmlAttributes( xmlTextWriterPtr writer ) const
447 : {
448 5 : SwFrm::dumpAsXmlAttributes( writer );
449 5 : if ( HasFollow() )
450 0 : xmlTextWriterWriteFormatAttribute( writer, BAD_CAST( "follow" ), "%" SAL_PRIuUINT32, GetFollow()->GetFrmId() );
451 :
452 5 : if (m_pPrecede != NULL)
453 0 : xmlTextWriterWriteFormatAttribute( writer, BAD_CAST( "precede" ), "%" SAL_PRIuUINT32, static_cast<SwSectionFrm*>( m_pPrecede )->GetFrmId() );
454 5 : }
455 :
456 24 : void SwTabFrm::dumpAsXmlAttributes( xmlTextWriterPtr writer ) const
457 : {
458 24 : SwFrm::dumpAsXmlAttributes( writer );
459 24 : if ( HasFollow() )
460 1 : xmlTextWriterWriteFormatAttribute( writer, BAD_CAST( "follow" ), "%" SAL_PRIuUINT32, GetFollow()->GetFrmId() );
461 :
462 24 : if (m_pPrecede != NULL)
463 1 : xmlTextWriterWriteFormatAttribute( writer, BAD_CAST( "precede" ), "%" SAL_PRIuUINT32, static_cast<SwTabFrm*>( m_pPrecede )->GetFrmId() );
464 201 : }
465 :
466 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|