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 1222 : const char* getTypeName( sal_uInt16 nType )
33 : {
34 1222 : switch ( nType )
35 : {
36 0 : case POR_LIN: return "POR_LIN";
37 2 : case POR_FLYCNT: return "POR_FLYCNT";
38 :
39 6 : case POR_HOLE: return "POR_HOLE";
40 0 : case POR_TMPEND: return "POR_TMPEND";
41 2 : 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 204 : case POR_TXT: return "POR_TXT";
49 46 : case POR_LAY: return "POR_LAY";
50 726 : 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 2 : 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 20 : case POR_NUMBER: return "POR_NUMBER";
80 48 : 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 36 : case POR_MARGIN: return "POR_MARGIN";
86 :
87 0 : case POR_FIX: return "POR_FIX";
88 12 : case POR_FLY: return "POR_FLY";
89 :
90 0 : case POR_TAB: return "POR_TAB";
91 :
92 10 : case POR_TABRIGHT: return "POR_TABRIGHT";
93 0 : case POR_TABCENTER: return "POR_TABCENTER";
94 0 : case POR_TABDECIMAL: return "POR_TABDECIMAL";
95 :
96 108 : case POR_TABLEFT: return "POR_TABLEFT";
97 : default:
98 0 : return "Unknown";
99 : }
100 : }
101 :
102 : public:
103 :
104 1582 : XmlPortionDumper( xmlTextWriterPtr some_writer ):writer( some_writer ), ofs( 0 )
105 : {
106 1582 : }
107 :
108 1582 : virtual ~ XmlPortionDumper( )
109 1582 : {
110 1582 : }
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 1102 : virtual void Text( sal_Int32 nLength,
119 : sal_uInt16 nType,
120 : sal_Int32 nHeight,
121 : sal_Int32 nWidth) SAL_OVERRIDE
122 : {
123 1102 : ofs += nLength;
124 1102 : xmlTextWriterStartElement( writer, BAD_CAST( "Text" ) );
125 : xmlTextWriterWriteFormatAttribute( writer,
126 : BAD_CAST( "nLength" ),
127 1102 : "%i", ( int ) nLength );
128 : xmlTextWriterWriteFormatAttribute( writer,
129 : BAD_CAST( "nType" ),
130 1102 : "%s", getTypeName( nType ) );
131 1102 : if (nHeight > 0)
132 1086 : xmlTextWriterWriteFormatAttribute(writer, BAD_CAST("nHeight"), "%i", (int)nHeight);
133 1102 : if (nWidth > 0)
134 994 : xmlTextWriterWriteFormatAttribute(writer, BAD_CAST("nWidth"), "%i", (int)nWidth);
135 :
136 1102 : xmlTextWriterEndElement( writer );
137 1102 : }
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 120 : virtual void Special( sal_Int32 nLength,
150 : const OUString & rText,
151 : sal_uInt16 nType,
152 : sal_Int32 nHeight,
153 : sal_Int32 nWidth ) SAL_OVERRIDE
154 : {
155 120 : xmlTextWriterStartElement( writer, BAD_CAST( "Special" ) );
156 : xmlTextWriterWriteFormatAttribute( writer,
157 : BAD_CAST( "nLength" ),
158 120 : "%i", ( int ) nLength );
159 : xmlTextWriterWriteFormatAttribute( writer,
160 : BAD_CAST( "nType" ),
161 120 : "%s", getTypeName( nType ) );
162 120 : OUString sText( rText );
163 : OString sText8 =OUStringToOString( sText,
164 240 : RTL_TEXTENCODING_UTF8 );
165 : xmlTextWriterWriteFormatAttribute( writer, BAD_CAST( "rText" ),
166 120 : "%s", sText8.getStr( ) );
167 :
168 120 : if (nHeight > 0)
169 82 : xmlTextWriterWriteFormatAttribute(writer, BAD_CAST("nHeight"), "%i", (int)nHeight);
170 :
171 120 : if (nWidth > 0)
172 46 : xmlTextWriterWriteFormatAttribute(writer, BAD_CAST("nWidth"), "%i", (int)nWidth);
173 :
174 120 : xmlTextWriterEndElement( writer );
175 240 : ofs += nLength;
176 120 : }
177 :
178 910 : virtual void LineBreak( sal_Int32 nWidth ) SAL_OVERRIDE
179 : {
180 910 : xmlTextWriterStartElement( writer, BAD_CAST( "LineBreak" ) );
181 910 : if (nWidth > 0)
182 : xmlTextWriterWriteFormatAttribute( writer,
183 : BAD_CAST( "nWidth" ),
184 812 : "%i", ( int ) nWidth );
185 910 : xmlTextWriterEndElement( writer );
186 910 : }
187 :
188 : /**
189 : * @param nLength
190 : * number of 'model string' characters to be skipped
191 : */
192 0 : virtual void Skip( sal_Int32 nLength ) SAL_OVERRIDE
193 : {
194 0 : xmlTextWriterStartElement( writer, BAD_CAST( "Skip" ) );
195 : xmlTextWriterWriteFormatAttribute( writer,
196 : BAD_CAST( "nLength" ),
197 0 : "%i", ( int ) nLength );
198 0 : xmlTextWriterEndElement( writer );
199 0 : ofs += nLength;
200 0 : }
201 :
202 1582 : virtual void Finish( ) SAL_OVERRIDE
203 : {
204 1582 : xmlTextWriterStartElement( writer, BAD_CAST( "Finish" ) );
205 1582 : xmlTextWriterEndElement( writer );
206 1582 : }
207 :
208 : };
209 :
210 : namespace
211 : {
212 0 : xmlTextWriterPtr lcl_createDefaultWriter()
213 : {
214 0 : xmlTextWriterPtr writer = xmlNewTextWriterFilename( "layout.xml", 0 );
215 0 : xmlTextWriterStartDocument( writer, NULL, NULL, NULL );
216 0 : return writer;
217 : }
218 :
219 0 : void lcl_freeWriter( xmlTextWriterPtr writer )
220 : {
221 0 : xmlTextWriterEndDocument( writer );
222 0 : xmlFreeTextWriter( writer );
223 0 : }
224 : }
225 :
226 3084 : void SwFrm::dumpAsXml( xmlTextWriterPtr writer ) const
227 : {
228 3084 : bool bCreateWriter = ( NULL == writer );
229 3084 : if ( bCreateWriter )
230 0 : writer = lcl_createDefaultWriter();
231 :
232 3084 : const char *name = NULL;
233 :
234 3084 : switch ( GetType( ) )
235 : {
236 : case FRM_ROOT:
237 66 : name = "root";
238 66 : break;
239 : case FRM_PAGE:
240 166 : name = "page";
241 166 : break;
242 : case FRM_COLUMN:
243 16 : name = "column";
244 16 : break;
245 : case FRM_HEADER:
246 124 : name = "header";
247 124 : break;
248 : case FRM_FOOTER:
249 124 : name = "footer";
250 124 : break;
251 : case FRM_FTNCONT:
252 0 : name = "ftncont";
253 0 : break;
254 : case FRM_FTN:
255 0 : name = "ftn";
256 0 : break;
257 : case FRM_BODY:
258 182 : name = "body";
259 182 : break;
260 : case FRM_FLY:
261 34 : name = "fly";
262 34 : break;
263 : case FRM_SECTION:
264 10 : name = "section";
265 10 : break;
266 : case FRM_UNUSED:
267 0 : name = "unused";
268 0 : break;
269 : case FRM_TAB:
270 36 : name = "tab";
271 36 : break;
272 : case FRM_ROW:
273 156 : name = "row";
274 156 : break;
275 : case FRM_CELL:
276 586 : name = "cell";
277 586 : break;
278 : case FRM_TXT:
279 1582 : name = "txt";
280 1582 : break;
281 : case FRM_NOTXT:
282 2 : name = "notxt";
283 2 : break;
284 : };
285 :
286 3084 : if ( name != NULL )
287 : {
288 3084 : xmlTextWriterStartElement( writer, ( const xmlChar * ) name );
289 :
290 3084 : dumpAsXmlAttributes( writer );
291 :
292 3084 : if (IsRootFrm())
293 : {
294 : // Root frame has access to the edit shell, so dump the current selection ranges here.
295 66 : const SwRootFrm* const pRootFrm = static_cast<const SwRootFrm* const>(this);
296 66 : SwEditShell* pEditShell = pRootFrm->GetCurrShell()->GetDoc()->GetEditShell();
297 66 : xmlTextWriterStartElement(writer, BAD_CAST("shellCrsr"));
298 66 : SwPaM* pPaM = pEditShell->getShellCrsr(false);
299 66 : do
300 : {
301 66 : xmlTextWriterStartElement(writer, BAD_CAST("swpam"));
302 66 : xmlTextWriterWriteFormatAttribute(writer, BAD_CAST("pointNodeIndex"), "%ld", pPaM->GetPoint()->nNode.GetIndex());
303 66 : xmlTextWriterWriteFormatAttribute(writer, BAD_CAST("pointContentIndex"), "%" SAL_PRIdINT32, pPaM->GetPoint()->nContent.GetIndex());
304 :
305 66 : xmlTextWriterWriteFormatAttribute(writer, BAD_CAST("markNodeIndex"), "%ld", pPaM->GetMark()->nNode.GetIndex());
306 66 : xmlTextWriterWriteFormatAttribute(writer, BAD_CAST("markContentIndex"), "%" SAL_PRIdINT32, pPaM->GetMark()->nContent.GetIndex());
307 66 : xmlTextWriterEndElement(writer);
308 66 : pPaM = static_cast<SwPaM*>(pPaM->GetNext());
309 : }
310 66 : while (pPaM && pPaM != pEditShell->getShellCrsr(false));
311 66 : xmlTextWriterEndElement(writer);
312 : }
313 :
314 3084 : xmlTextWriterStartElement( writer, BAD_CAST( "infos" ) );
315 3084 : dumpInfosAsXml( writer );
316 3084 : xmlTextWriterEndElement( writer );
317 :
318 : // Dump Anchored objects if any
319 3084 : const SwSortedObjs* pAnchored = GetDrawObjs();
320 3084 : if ( pAnchored && pAnchored->size() > 0 )
321 : {
322 52 : xmlTextWriterStartElement( writer, BAD_CAST( "anchored" ) );
323 :
324 112 : for ( size_t i = 0, len = pAnchored->size(); i < len; ++i )
325 : {
326 60 : SwAnchoredObject* pObject = (*pAnchored)[i];
327 60 : pObject->dumpAsXml( writer );
328 : }
329 :
330 52 : xmlTextWriterEndElement( writer );
331 : }
332 :
333 : // Dump the children
334 3084 : if ( IsTxtFrm( ) )
335 : {
336 1582 : SwTxtFrm *pTxtFrm = ( SwTxtFrm * ) this;
337 1582 : OUString aTxt = pTxtFrm->GetTxt( );
338 52206 : for ( int i = 0; i < 32; i++ )
339 : {
340 50624 : aTxt = aTxt.replace( i, '*' );
341 : }
342 : OString aTxt8 =OUStringToOString( aTxt,
343 3164 : RTL_TEXTENCODING_UTF8 );
344 : xmlTextWriterWriteString( writer,
345 1582 : ( const xmlChar * ) aTxt8.getStr( ) );
346 3164 : XmlPortionDumper pdumper( writer );
347 3164 : pTxtFrm->VisitPortions( pdumper );
348 :
349 : }
350 : else
351 : {
352 1502 : dumpChildrenAsXml( writer );
353 : }
354 3084 : xmlTextWriterEndElement( writer );
355 : }
356 :
357 3084 : if ( bCreateWriter )
358 0 : lcl_freeWriter( writer );
359 3084 : }
360 :
361 3084 : void SwFrm::dumpInfosAsXml( xmlTextWriterPtr writer ) const
362 : {
363 : // output the Frm
364 3084 : xmlTextWriterStartElement( writer, BAD_CAST( "bounds" ) );
365 3084 : xmlTextWriterWriteFormatAttribute( writer, BAD_CAST( "left" ), "%ld", Frm().Left() );
366 3084 : xmlTextWriterWriteFormatAttribute( writer, BAD_CAST( "top" ), "%ld", Frm().Top() );
367 3084 : xmlTextWriterWriteFormatAttribute( writer, BAD_CAST( "width" ), "%ld", Frm().Width() );
368 3084 : xmlTextWriterWriteFormatAttribute( writer, BAD_CAST( "height" ), "%ld", Frm().Height() );
369 3084 : xmlTextWriterEndElement( writer );
370 3084 : }
371 :
372 : // Hack: somehow conversion from "..." to va_list does
373 : // bomb on two string litterals in the format.
374 : static const char* TMP_FORMAT = "%" SAL_PRIuUINTPTR;
375 :
376 3084 : void SwFrm::dumpAsXmlAttributes( xmlTextWriterPtr writer ) const
377 : {
378 3084 : xmlTextWriterWriteFormatAttribute( writer, BAD_CAST( "ptr" ), "%p", this );
379 3084 : xmlTextWriterWriteFormatAttribute( writer, BAD_CAST( "id" ), "%" SAL_PRIuUINT32, GetFrmId() );
380 3084 : xmlTextWriterWriteFormatAttribute( writer, BAD_CAST( "symbol" ), "%s", BAD_CAST( typeid( *this ).name( ) ) );
381 3084 : if ( GetNext( ) )
382 1488 : xmlTextWriterWriteFormatAttribute( writer, BAD_CAST( "next" ), "%" SAL_PRIuUINT32, GetNext()->GetFrmId() );
383 3084 : if ( GetPrev( ) )
384 1488 : xmlTextWriterWriteFormatAttribute( writer, BAD_CAST( "prev" ), "%" SAL_PRIuUINT32, GetPrev()->GetFrmId() );
385 3084 : if ( GetUpper( ) )
386 2984 : xmlTextWriterWriteFormatAttribute( writer, BAD_CAST( "upper" ), "%" SAL_PRIuUINT32, GetUpper()->GetFrmId() );
387 3084 : if ( GetLower( ) )
388 1496 : xmlTextWriterWriteFormatAttribute( writer, BAD_CAST( "lower" ), "%" SAL_PRIuUINT32, GetLower()->GetFrmId() );
389 3084 : if ( IsTxtFrm( ) )
390 : {
391 1582 : SwTxtFrm *pTxtFrm = ( SwTxtFrm * ) this;
392 1582 : SwTxtNode *pTxtNode = pTxtFrm->GetTxtNode();
393 1582 : xmlTextWriterWriteFormatAttribute( writer, BAD_CAST( "txtNodeIndex" ), TMP_FORMAT, pTxtNode->GetIndex() );
394 : }
395 3084 : if (IsHeaderFrm() || IsFooterFrm())
396 : {
397 248 : SwHeadFootFrm *pHeadFootFrm = (SwHeadFootFrm*)this;
398 248 : OUString aFmtName = pHeadFootFrm->GetFmt()->GetName();
399 248 : xmlTextWriterWriteFormatAttribute( writer, BAD_CAST( "fmtName" ), "%s", BAD_CAST(OUStringToOString(aFmtName, RTL_TEXTENCODING_UTF8).getStr()));
400 248 : xmlTextWriterWriteFormatAttribute( writer, BAD_CAST( "fmtPtr" ), "%p", pHeadFootFrm->GetFmt());
401 : }
402 3084 : }
403 :
404 1502 : void SwFrm::dumpChildrenAsXml( xmlTextWriterPtr writer ) const
405 : {
406 1502 : const SwFrm *pFrm = GetLower( );
407 4486 : for ( ; pFrm != NULL; pFrm = pFrm->GetNext( ) )
408 : {
409 2984 : pFrm->dumpAsXml( writer );
410 : }
411 1502 : }
412 :
413 26 : void SwAnchoredObject::dumpAsXml( xmlTextWriterPtr writer ) const
414 : {
415 26 : bool bCreateWriter = ( NULL == writer );
416 26 : if ( bCreateWriter )
417 0 : writer = lcl_createDefaultWriter();
418 :
419 26 : xmlTextWriterStartElement( writer, BAD_CAST( getElementName() ) );
420 26 : xmlTextWriterWriteFormatAttribute( writer, BAD_CAST( "ptr" ), "%p", this );
421 :
422 26 : xmlTextWriterStartElement( writer, BAD_CAST( "bounds" ) );
423 26 : xmlTextWriterWriteFormatAttribute( writer, BAD_CAST( "left" ), "%ld", GetObjBoundRect().Left() );
424 26 : xmlTextWriterWriteFormatAttribute( writer, BAD_CAST( "top" ), "%ld", GetObjBoundRect().Top() );
425 26 : xmlTextWriterWriteFormatAttribute( writer, BAD_CAST( "width" ), "%ld", GetObjBoundRect().Width() );
426 26 : xmlTextWriterWriteFormatAttribute( writer, BAD_CAST( "height" ), "%ld", GetObjBoundRect().Height() );
427 26 : xmlTextWriterEndElement( writer );
428 :
429 26 : xmlTextWriterEndElement( writer );
430 :
431 26 : if ( bCreateWriter )
432 0 : lcl_freeWriter( writer );
433 26 : }
434 :
435 1582 : void SwTxtFrm::dumpAsXmlAttributes( xmlTextWriterPtr writer ) const
436 : {
437 1582 : SwFrm::dumpAsXmlAttributes( writer );
438 1582 : if ( HasFollow() )
439 0 : xmlTextWriterWriteFormatAttribute( writer, BAD_CAST( "follow" ), "%" SAL_PRIuUINT32, GetFollow()->GetFrmId() );
440 :
441 1582 : if (m_pPrecede != NULL)
442 0 : xmlTextWriterWriteFormatAttribute( writer, BAD_CAST( "precede" ), "%" SAL_PRIuUINT32, static_cast<SwTxtFrm*>(m_pPrecede)->GetFrmId() );
443 1582 : }
444 :
445 10 : void SwSectionFrm::dumpAsXmlAttributes( xmlTextWriterPtr writer ) const
446 : {
447 10 : SwFrm::dumpAsXmlAttributes( writer );
448 10 : if ( HasFollow() )
449 0 : xmlTextWriterWriteFormatAttribute( writer, BAD_CAST( "follow" ), "%" SAL_PRIuUINT32, GetFollow()->GetFrmId() );
450 :
451 10 : if (m_pPrecede != NULL)
452 0 : xmlTextWriterWriteFormatAttribute( writer, BAD_CAST( "precede" ), "%" SAL_PRIuUINT32, static_cast<SwSectionFrm*>( m_pPrecede )->GetFrmId() );
453 10 : }
454 :
455 36 : void SwTabFrm::dumpAsXmlAttributes( xmlTextWriterPtr writer ) const
456 : {
457 36 : SwFrm::dumpAsXmlAttributes( writer );
458 36 : if ( HasFollow() )
459 0 : xmlTextWriterWriteFormatAttribute( writer, BAD_CAST( "follow" ), "%" SAL_PRIuUINT32, GetFollow()->GetFrmId() );
460 :
461 36 : if (m_pPrecede != NULL)
462 0 : xmlTextWriterWriteFormatAttribute( writer, BAD_CAST( "precede" ), "%" SAL_PRIuUINT32, static_cast<SwTabFrm*>( m_pPrecede )->GetFrmId() );
463 306 : }
464 :
465 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|