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