xref: /aoo41x/main/sw/source/filter/ww8/wrtw8nds.cxx (revision 12ad4c42)
1efeef26fSAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3efeef26fSAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4efeef26fSAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5efeef26fSAndrew Rist  * distributed with this work for additional information
6efeef26fSAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7efeef26fSAndrew Rist  * to you under the Apache License, Version 2.0 (the
8efeef26fSAndrew Rist  * "License"); you may not use this file except in compliance
9efeef26fSAndrew Rist  * with the License.  You may obtain a copy of the License at
10efeef26fSAndrew Rist  *
11efeef26fSAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12efeef26fSAndrew Rist  *
13efeef26fSAndrew Rist  * Unless required by applicable law or agreed to in writing,
14efeef26fSAndrew Rist  * software distributed under the License is distributed on an
15efeef26fSAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16efeef26fSAndrew Rist  * KIND, either express or implied.  See the License for the
17efeef26fSAndrew Rist  * specific language governing permissions and limitations
18efeef26fSAndrew Rist  * under the License.
19efeef26fSAndrew Rist  *
20efeef26fSAndrew Rist  *************************************************************/
21efeef26fSAndrew Rist 
22efeef26fSAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_sw.hxx"
26cdf0e10cSrcweir /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil -*- */
27cdf0e10cSrcweir 
28cdf0e10cSrcweir #include <vector>
29cdf0e10cSrcweir #include <list>
30cdf0e10cSrcweir #include <utility>
31cdf0e10cSrcweir #include <algorithm>
32cdf0e10cSrcweir #include <functional>
33cdf0e10cSrcweir #include <iostream>
34cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 0
35cdf0e10cSrcweir #   include <cstdio>
36cdf0e10cSrcweir #endif
37cdf0e10cSrcweir 
38cdf0e10cSrcweir #include <hintids.hxx>
39cdf0e10cSrcweir #include <tools/urlobj.hxx>
40cdf0e10cSrcweir #include <editeng/boxitem.hxx>
41cdf0e10cSrcweir #include <editeng/cmapitem.hxx>
42cdf0e10cSrcweir #include <editeng/langitem.hxx>
43cdf0e10cSrcweir #include <editeng/svxfont.hxx>
44cdf0e10cSrcweir #include <editeng/lrspitem.hxx>
45cdf0e10cSrcweir #include <editeng/brshitem.hxx>
46cdf0e10cSrcweir #include <editeng/fontitem.hxx>
47cdf0e10cSrcweir #include <editeng/keepitem.hxx>
48cdf0e10cSrcweir #include <editeng/fhgtitem.hxx>
49cdf0e10cSrcweir #include <editeng/ulspitem.hxx>
50cdf0e10cSrcweir #include <editeng/brkitem.hxx>
51cdf0e10cSrcweir #include <editeng/frmdiritem.hxx>
52cdf0e10cSrcweir #include <editeng/tstpitem.hxx>
53cdf0e10cSrcweir #include "svl/urihelper.hxx"
54cdf0e10cSrcweir #include <svl/whiter.hxx>
55cdf0e10cSrcweir #include <fmtpdsc.hxx>
56cdf0e10cSrcweir #include <fmtfsize.hxx>
57cdf0e10cSrcweir #include <fmtornt.hxx>
58cdf0e10cSrcweir #include <fmtlsplt.hxx>
59cdf0e10cSrcweir #include <fmtflcnt.hxx>
60cdf0e10cSrcweir #include <fmtanchr.hxx>
61cdf0e10cSrcweir #include <fmtcntnt.hxx>
62cdf0e10cSrcweir #include <frmatr.hxx>
63cdf0e10cSrcweir #include <paratr.hxx>
64cdf0e10cSrcweir #include <txatbase.hxx>
65cdf0e10cSrcweir #include <fmtinfmt.hxx>
66cdf0e10cSrcweir #include <fmtrfmrk.hxx>
67cdf0e10cSrcweir #include <fchrfmt.hxx>
68cdf0e10cSrcweir #include <fmtautofmt.hxx>
69cdf0e10cSrcweir #include <charfmt.hxx>
70cdf0e10cSrcweir #include <tox.hxx>
71cdf0e10cSrcweir #include <ndtxt.hxx>
72cdf0e10cSrcweir #include <pam.hxx>
73cdf0e10cSrcweir #include <doc.hxx>
74cdf0e10cSrcweir #include <docary.hxx>
75cdf0e10cSrcweir #include <swtable.hxx>
76cdf0e10cSrcweir #include <swtblfmt.hxx>
77cdf0e10cSrcweir #include <section.hxx>
78cdf0e10cSrcweir #include <pagedesc.hxx>
79cdf0e10cSrcweir #include <swrect.hxx>
80cdf0e10cSrcweir #include <reffld.hxx>
81cdf0e10cSrcweir #include <redline.hxx>
82cdf0e10cSrcweir #include <wrtswtbl.hxx>
83cdf0e10cSrcweir #include <htmltbl.hxx>
84cdf0e10cSrcweir #include <txttxmrk.hxx>
85cdf0e10cSrcweir #include <fmtline.hxx>
86cdf0e10cSrcweir #include <fmtruby.hxx>
87cdf0e10cSrcweir #include <breakit.hxx>
88cdf0e10cSrcweir #include <txtatr.hxx>
89cdf0e10cSrcweir #include <fmtsrnd.hxx>
90cdf0e10cSrcweir #include <fmtrowsplt.hxx>
91cdf0e10cSrcweir #include <com/sun/star/i18n/ScriptType.hdl>
92cdf0e10cSrcweir #include <com/sun/star/i18n/WordType.hpp>
93cdf0e10cSrcweir 
94cdf0e10cSrcweir #include <writerfilter/doctok/sprmids.hxx>
95cdf0e10cSrcweir 
96cdf0e10cSrcweir #include "writerhelper.hxx"
97cdf0e10cSrcweir #include "writerwordglue.hxx"
98cdf0e10cSrcweir #include <numrule.hxx>
99cdf0e10cSrcweir #include "wrtww8.hxx"
100cdf0e10cSrcweir #include "ww8par.hxx"
101cdf0e10cSrcweir #include <IMark.hxx>
102cdf0e10cSrcweir #include "ww8attributeoutput.hxx"
103cdf0e10cSrcweir 
104cdf0e10cSrcweir #include <ndgrf.hxx>
105cdf0e10cSrcweir #include <ndole.hxx>
106cdf0e10cSrcweir 
107cdf0e10cSrcweir #include <cstdio>
108cdf0e10cSrcweir 
109cdf0e10cSrcweir using namespace ::com::sun::star;
110cdf0e10cSrcweir using namespace ::com::sun::star::i18n;
111cdf0e10cSrcweir using namespace sw::util;
112cdf0e10cSrcweir using namespace sw::types;
113cdf0e10cSrcweir using namespace sw::mark;
114cdf0e10cSrcweir using namespace nsFieldFlags;
115cdf0e10cSrcweir 
116cdf0e10cSrcweir 
lcl_getFieldCode(const IFieldmark * pFieldmark)117cdf0e10cSrcweir static String lcl_getFieldCode( const IFieldmark* pFieldmark ) {
118cdf0e10cSrcweir     ASSERT(pFieldmark!=NULL, "where is my fieldmark???");
119cdf0e10cSrcweir     if ( pFieldmark->GetFieldname( ).equalsAscii( ODF_FORMTEXT ) ) {
120cdf0e10cSrcweir         return String::CreateFromAscii(" FORMTEXT ");
121cdf0e10cSrcweir     } else if ( pFieldmark->GetFieldname( ).equalsAscii( ODF_FORMDROPDOWN ) ) {
122cdf0e10cSrcweir         return String::CreateFromAscii(" FORMDROPDOWN ");
123cdf0e10cSrcweir     } else if ( pFieldmark->GetFieldname( ).equalsAscii( ODF_FORMCHECKBOX ) ) {
124cdf0e10cSrcweir         return String::CreateFromAscii(" FORMCHECKBOX ");
125cdf0e10cSrcweir     } else if ( pFieldmark->GetFieldname( ).equalsAscii( ODF_TOC ) ) {
126cdf0e10cSrcweir         return String::CreateFromAscii(" TOC ");
127cdf0e10cSrcweir     } else if ( pFieldmark->GetFieldname( ).equalsAscii( ODF_HYPERLINK ) ) {
128cdf0e10cSrcweir         return String::CreateFromAscii(" HYPERLINK ");
129cdf0e10cSrcweir     } else if ( pFieldmark->GetFieldname( ).equalsAscii( ODF_PAGEREF ) ) {
130cdf0e10cSrcweir         return String::CreateFromAscii(" PAGEREF ");
131cdf0e10cSrcweir     } else {
132cdf0e10cSrcweir         return pFieldmark->GetFieldname();
133cdf0e10cSrcweir     }
134cdf0e10cSrcweir }
135cdf0e10cSrcweir 
lcl_getFieldId(const IFieldmark * pFieldmark)136cdf0e10cSrcweir ww::eField lcl_getFieldId( const IFieldmark* pFieldmark ) {
137cdf0e10cSrcweir     ASSERT(pFieldmark!=NULL, "where is my fieldmark???");
138cdf0e10cSrcweir     if ( pFieldmark->GetFieldname( ).equalsAscii( ODF_FORMTEXT ) ) {
139cdf0e10cSrcweir         return ww::eFORMTEXT;
140cdf0e10cSrcweir     } else if ( pFieldmark->GetFieldname( ).equalsAscii( ODF_FORMDROPDOWN ) ) {
141cdf0e10cSrcweir         return ww::eFORMDROPDOWN;
142cdf0e10cSrcweir     } else if ( pFieldmark->GetFieldname( ).equalsAscii( ODF_FORMCHECKBOX ) ) {
143cdf0e10cSrcweir         return ww::eFORMCHECKBOX;
144cdf0e10cSrcweir     } else if ( pFieldmark->GetFieldname( ).equalsAscii( ODF_TOC ) ) {
145cdf0e10cSrcweir         return ww::eTOC;
146cdf0e10cSrcweir     } else if ( pFieldmark->GetFieldname( ).equalsAscii( ODF_HYPERLINK ) ) {
147cdf0e10cSrcweir         return ww::eHYPERLINK;
148cdf0e10cSrcweir     } else if ( pFieldmark->GetFieldname( ).equalsAscii( ODF_PAGEREF ) ) {
149cdf0e10cSrcweir         return ww::ePAGEREF;
150cdf0e10cSrcweir     } else {
151cdf0e10cSrcweir         return ww::eUNKNOWN;
152cdf0e10cSrcweir     }
153cdf0e10cSrcweir }
154cdf0e10cSrcweir 
155cdf0e10cSrcweir /*  */
156cdf0e10cSrcweir 
MSWordAttrIter(MSWordExportBase & rExport)157cdf0e10cSrcweir MSWordAttrIter::MSWordAttrIter( MSWordExportBase& rExport )
158cdf0e10cSrcweir     : pOld( rExport.pChpIter ), m_rExport( rExport )
159cdf0e10cSrcweir {
160cdf0e10cSrcweir     m_rExport.pChpIter = this;
161cdf0e10cSrcweir }
162cdf0e10cSrcweir 
~MSWordAttrIter()163cdf0e10cSrcweir MSWordAttrIter::~MSWordAttrIter()
164cdf0e10cSrcweir {
165cdf0e10cSrcweir     m_rExport.pChpIter = pOld;
166cdf0e10cSrcweir }
167cdf0e10cSrcweir 
168cdf0e10cSrcweir // Die Klasse SwAttrIter ist eine Hilfe zum Aufbauen der Fkp.chpx.
169cdf0e10cSrcweir // Dabei werden nur Zeichen-Attribute beachtet; Absatz-Attribute brauchen
170cdf0e10cSrcweir // diese Behandlung nicht.
171cdf0e10cSrcweir // Die Absatz- und Textattribute des Writers kommen rein, und es wird
172cdf0e10cSrcweir // mit Where() die naechste Position geliefert, an der sich die Attribute
173cdf0e10cSrcweir // aendern. IsTxtAtr() sagt, ob sich an der mit Where() gelieferten Position
174cdf0e10cSrcweir // ein Attribut ohne Ende und mit \xff im Text befindet.
175cdf0e10cSrcweir // Mit OutAttr() werden die Attribute an der angegebenen SwPos
176cdf0e10cSrcweir // ausgegeben.
177cdf0e10cSrcweir 
178cdf0e10cSrcweir class WW8SwAttrIter : public MSWordAttrIter
179cdf0e10cSrcweir {
180cdf0e10cSrcweir private:
181cdf0e10cSrcweir     const SwTxtNode& rNd;
182cdf0e10cSrcweir 
183cdf0e10cSrcweir     CharRuns maCharRuns;
184cdf0e10cSrcweir     cCharRunIter maCharRunIter;
185cdf0e10cSrcweir 
186cdf0e10cSrcweir     rtl_TextEncoding meChrSet;
187cdf0e10cSrcweir     sal_uInt16 mnScript;
188cdf0e10cSrcweir     bool mbCharIsRTL;
189cdf0e10cSrcweir 
190cdf0e10cSrcweir     const SwRedline* pCurRedline;
191cdf0e10cSrcweir     xub_StrLen nAktSwPos;
192cdf0e10cSrcweir     sal_uInt16 nCurRedlinePos;
193cdf0e10cSrcweir 
194cdf0e10cSrcweir     bool mbParaIsRTL;
195cdf0e10cSrcweir 
196cdf0e10cSrcweir     const SwFmtDrop &mrSwFmtDrop;
197cdf0e10cSrcweir 
198cdf0e10cSrcweir     sw::Frames maFlyFrms;     // #i2916#
199cdf0e10cSrcweir     sw::FrameIter maFlyIter;
200cdf0e10cSrcweir 
201cdf0e10cSrcweir     xub_StrLen SearchNext( xub_StrLen nStartPos );
202cdf0e10cSrcweir     void FieldVanish( const String& rTxt );
203cdf0e10cSrcweir 
204cdf0e10cSrcweir     void OutSwFmtRefMark(const SwFmtRefMark& rAttr, bool bStart);
205cdf0e10cSrcweir 
206cdf0e10cSrcweir     void IterToCurrent();
207cdf0e10cSrcweir 
208cdf0e10cSrcweir     //No copying
209cdf0e10cSrcweir     WW8SwAttrIter(const WW8SwAttrIter&);
210cdf0e10cSrcweir     WW8SwAttrIter& operator=(const WW8SwAttrIter&);
211cdf0e10cSrcweir public:
212cdf0e10cSrcweir     WW8SwAttrIter( MSWordExportBase& rWr, const SwTxtNode& rNd );
213cdf0e10cSrcweir 
214cdf0e10cSrcweir     bool IsTxtAttr( xub_StrLen nSwPos );
215cdf0e10cSrcweir     bool IsRedlineAtEnd( xub_StrLen nPos ) const;
216cdf0e10cSrcweir     bool IsDropCap( int nSwPos );
217cdf0e10cSrcweir     bool RequiresImplicitBookmark();
218cdf0e10cSrcweir 
NextPos()219cdf0e10cSrcweir     void NextPos() { nAktSwPos = SearchNext( nAktSwPos + 1 ); }
220cdf0e10cSrcweir 
221cdf0e10cSrcweir     void OutAttr( xub_StrLen nSwPos );
222cdf0e10cSrcweir     virtual const SfxPoolItem* HasTextItem( sal_uInt16 nWhich ) const;
223cdf0e10cSrcweir     virtual const SfxPoolItem& GetItem( sal_uInt16 nWhich ) const;
224cdf0e10cSrcweir     int OutAttrWithRange(xub_StrLen nPos);
225cdf0e10cSrcweir     const SwRedlineData* GetRedline( xub_StrLen nPos );
226cdf0e10cSrcweir     void OutFlys(xub_StrLen nSwPos);
227cdf0e10cSrcweir 
WhereNext() const228cdf0e10cSrcweir     xub_StrLen WhereNext() const    { return nAktSwPos; }
GetScript() const229cdf0e10cSrcweir     sal_uInt16 GetScript() const { return mnScript; }
IsCharRTL() const230cdf0e10cSrcweir     bool IsCharRTL() const { return mbCharIsRTL; }
IsParaRTL() const231cdf0e10cSrcweir     bool IsParaRTL() const { return mbParaIsRTL; }
GetCharSet() const232cdf0e10cSrcweir     rtl_TextEncoding GetCharSet() const { return meChrSet; }
233cdf0e10cSrcweir     String GetSnippet(const String &rStr, xub_StrLen nAktPos,
234cdf0e10cSrcweir         xub_StrLen nLen) const;
GetSwFmtDrop() const235cdf0e10cSrcweir     const SwFmtDrop& GetSwFmtDrop() const { return mrSwFmtDrop; }
236cdf0e10cSrcweir };
237cdf0e10cSrcweir 
238cdf0e10cSrcweir class sortswflys :
239cdf0e10cSrcweir     public std::binary_function<const sw::Frame&, const sw::Frame&, bool>
240cdf0e10cSrcweir {
241cdf0e10cSrcweir public:
operator ()(const sw::Frame & rOne,const sw::Frame & rTwo) const242cdf0e10cSrcweir     bool operator()(const sw::Frame &rOne, const sw::Frame &rTwo) const
243cdf0e10cSrcweir     {
244cdf0e10cSrcweir         return rOne.GetPosition() < rTwo.GetPosition();
245cdf0e10cSrcweir     }
246cdf0e10cSrcweir };
247cdf0e10cSrcweir 
IterToCurrent()248cdf0e10cSrcweir void WW8SwAttrIter::IterToCurrent()
249cdf0e10cSrcweir {
250cdf0e10cSrcweir     ASSERT(maCharRuns.begin() != maCharRuns.end(), "Impossible");
251cdf0e10cSrcweir     mnScript = maCharRunIter->mnScript;
252cdf0e10cSrcweir     meChrSet = maCharRunIter->meCharSet;
253cdf0e10cSrcweir     mbCharIsRTL = maCharRunIter->mbRTL;
254cdf0e10cSrcweir }
255cdf0e10cSrcweir 
WW8SwAttrIter(MSWordExportBase & rWr,const SwTxtNode & rTxtNd)256cdf0e10cSrcweir WW8SwAttrIter::WW8SwAttrIter(MSWordExportBase& rWr, const SwTxtNode& rTxtNd) :
257cdf0e10cSrcweir     MSWordAttrIter(rWr),
258cdf0e10cSrcweir     rNd(rTxtNd),
259cdf0e10cSrcweir     maCharRuns(GetPseudoCharRuns(rTxtNd, 0, !rWr.HackIsWW8OrHigher())),
260cdf0e10cSrcweir     pCurRedline(0),
261cdf0e10cSrcweir     nAktSwPos(0),
262cdf0e10cSrcweir     nCurRedlinePos(USHRT_MAX),
263cdf0e10cSrcweir     mrSwFmtDrop(rTxtNd.GetSwAttrSet().GetDrop())
264cdf0e10cSrcweir {
265cdf0e10cSrcweir 
266cdf0e10cSrcweir     SwPosition aPos(rTxtNd);
267cdf0e10cSrcweir     if (FRMDIR_HORI_RIGHT_TOP == rWr.pDoc->GetTextDirection(aPos))
268cdf0e10cSrcweir         mbParaIsRTL = true;
269cdf0e10cSrcweir     else
270cdf0e10cSrcweir         mbParaIsRTL = false;
271cdf0e10cSrcweir 
272cdf0e10cSrcweir     maCharRunIter = maCharRuns.begin();
273cdf0e10cSrcweir     IterToCurrent();
274cdf0e10cSrcweir 
275cdf0e10cSrcweir     /*
276cdf0e10cSrcweir      #i2916#
277cdf0e10cSrcweir      Get list of any graphics which may be anchored from this paragraph.
278cdf0e10cSrcweir     */
279cdf0e10cSrcweir     maFlyFrms = GetFramesInNode(rWr.maFrames, rNd);
280cdf0e10cSrcweir     std::sort(maFlyFrms.begin(), maFlyFrms.end(), sortswflys());
281cdf0e10cSrcweir 
282cdf0e10cSrcweir     /*
283cdf0e10cSrcweir      #i18480#
284cdf0e10cSrcweir      If we are inside a frame then anything anchored inside this frame can
285cdf0e10cSrcweir      only be supported by word anchored inline ("as character"), so force
286cdf0e10cSrcweir      this in the supportable case.
287cdf0e10cSrcweir     */
288cdf0e10cSrcweir     if (rWr.HackIsWW8OrHigher() && rWr.bInWriteEscher)
289cdf0e10cSrcweir     {
290cdf0e10cSrcweir         std::for_each(maFlyFrms.begin(), maFlyFrms.end(),
291cdf0e10cSrcweir             std::mem_fun_ref(&sw::Frame::ForceTreatAsInline));
292cdf0e10cSrcweir     }
293cdf0e10cSrcweir 
294cdf0e10cSrcweir     maFlyIter = maFlyFrms.begin();
295cdf0e10cSrcweir 
296cdf0e10cSrcweir     if ( m_rExport.pDoc->GetRedlineTbl().Count() )
297cdf0e10cSrcweir     {
298cdf0e10cSrcweir         SwPosition aPosition( rNd, SwIndex( (SwTxtNode*)&rNd ) );
299cdf0e10cSrcweir         pCurRedline = m_rExport.pDoc->GetRedline( aPosition, &nCurRedlinePos );
300cdf0e10cSrcweir     }
301cdf0e10cSrcweir 
302cdf0e10cSrcweir     nAktSwPos = SearchNext(1);
303cdf0e10cSrcweir }
304cdf0e10cSrcweir 
lcl_getMinPos(xub_StrLen pos1,xub_StrLen pos2)305cdf0e10cSrcweir xub_StrLen lcl_getMinPos( xub_StrLen pos1, xub_StrLen pos2 )
306cdf0e10cSrcweir {
307cdf0e10cSrcweir     xub_StrLen min = STRING_NOTFOUND;
308cdf0e10cSrcweir     if ( pos1 == STRING_NOTFOUND && pos2 != STRING_NOTFOUND )
309cdf0e10cSrcweir         min = pos2;
310cdf0e10cSrcweir     else if ( pos2 == STRING_NOTFOUND && pos1 != STRING_NOTFOUND )
311cdf0e10cSrcweir         min = pos1;
312cdf0e10cSrcweir     else if ( pos2 != STRING_NOTFOUND && pos2 != STRING_NOTFOUND )
313cdf0e10cSrcweir     {
314cdf0e10cSrcweir         if ( pos1 < pos2 )
315cdf0e10cSrcweir             min = pos1;
316cdf0e10cSrcweir         else
317cdf0e10cSrcweir             min = pos2;
318cdf0e10cSrcweir     }
319cdf0e10cSrcweir 
320cdf0e10cSrcweir     return min;
321cdf0e10cSrcweir }
322cdf0e10cSrcweir 
SearchNext(xub_StrLen nStartPos)323cdf0e10cSrcweir xub_StrLen WW8SwAttrIter::SearchNext( xub_StrLen nStartPos )
324cdf0e10cSrcweir {
325cdf0e10cSrcweir     xub_StrLen nPos;
326cdf0e10cSrcweir     xub_StrLen nMinPos = STRING_MAXLEN;
327cdf0e10cSrcweir     xub_StrLen i=0;
328cdf0e10cSrcweir 
329cdf0e10cSrcweir 	const String aTxt = rNd.GetTxt();
330cdf0e10cSrcweir     xub_StrLen fieldEndPos = aTxt.Search(CH_TXT_ATR_FIELDEND, nStartPos);
331cdf0e10cSrcweir     xub_StrLen fieldStartPos = aTxt.Search(CH_TXT_ATR_FIELDSTART, nStartPos);
332cdf0e10cSrcweir     xub_StrLen formElementPos = aTxt.Search(CH_TXT_ATR_FORMELEMENT, nStartPos);
333cdf0e10cSrcweir 
334cdf0e10cSrcweir     xub_StrLen pos = lcl_getMinPos( fieldEndPos, fieldStartPos );
335cdf0e10cSrcweir     pos = lcl_getMinPos( pos, formElementPos );
336cdf0e10cSrcweir 
337cdf0e10cSrcweir 	if (pos!=STRING_NOTFOUND)
338cdf0e10cSrcweir         nMinPos=pos;
339cdf0e10cSrcweir 
340cdf0e10cSrcweir     // first the redline, then the attributes
341cdf0e10cSrcweir     if( pCurRedline )
342cdf0e10cSrcweir     {
343cdf0e10cSrcweir         const SwPosition* pEnd = pCurRedline->End();
344cdf0e10cSrcweir         if (pEnd->nNode == rNd && ((i = pEnd->nContent.GetIndex()) >= nStartPos) && i < nMinPos )
345cdf0e10cSrcweir 				nMinPos = i;
346cdf0e10cSrcweir     }
347cdf0e10cSrcweir 
348cdf0e10cSrcweir     if ( nCurRedlinePos < m_rExport.pDoc->GetRedlineTbl().Count() )
349cdf0e10cSrcweir     {
350cdf0e10cSrcweir         // nCurRedlinePos point to the next redline
351cdf0e10cSrcweir         nPos = nCurRedlinePos;
352cdf0e10cSrcweir         if( pCurRedline )
353cdf0e10cSrcweir             ++nPos;
354cdf0e10cSrcweir 
355cdf0e10cSrcweir         for ( ; nPos < m_rExport.pDoc->GetRedlineTbl().Count(); ++nPos )
356cdf0e10cSrcweir         {
357cdf0e10cSrcweir             const SwRedline* pRedl = m_rExport.pDoc->GetRedlineTbl()[ nPos ];
358cdf0e10cSrcweir 
359cdf0e10cSrcweir             const SwPosition* pStt = pRedl->Start();
360cdf0e10cSrcweir             const SwPosition* pEnd = pStt == pRedl->GetPoint()
361cdf0e10cSrcweir                                         ? pRedl->GetMark()
362cdf0e10cSrcweir                                         : pRedl->GetPoint();
363cdf0e10cSrcweir 
364cdf0e10cSrcweir             if( pStt->nNode == rNd )
365cdf0e10cSrcweir             {
366cdf0e10cSrcweir                 if( ( i = pStt->nContent.GetIndex() ) >= nStartPos &&
367cdf0e10cSrcweir                     i < nMinPos )
368cdf0e10cSrcweir                     nMinPos = i;
369cdf0e10cSrcweir             }
370cdf0e10cSrcweir             else
371cdf0e10cSrcweir                 break;
372cdf0e10cSrcweir 
373cdf0e10cSrcweir             if( pEnd->nNode == rNd &&
374cdf0e10cSrcweir                 ( i = pEnd->nContent.GetIndex() ) < nMinPos &&
375cdf0e10cSrcweir                 i >= nStartPos )
376cdf0e10cSrcweir                     nMinPos = i;
377cdf0e10cSrcweir         }
378cdf0e10cSrcweir     }
379cdf0e10cSrcweir 
380cdf0e10cSrcweir 
381cdf0e10cSrcweir     if (mrSwFmtDrop.GetWholeWord() && nStartPos <= rNd.GetDropLen(0))
382cdf0e10cSrcweir         nMinPos = rNd.GetDropLen(0);
383cdf0e10cSrcweir     else if(nStartPos <= mrSwFmtDrop.GetChars())
384cdf0e10cSrcweir         nMinPos = mrSwFmtDrop.GetChars();
385cdf0e10cSrcweir 
386cdf0e10cSrcweir     if(const SwpHints* pTxtAttrs = rNd.GetpSwpHints())
387cdf0e10cSrcweir     {
388cdf0e10cSrcweir 
389cdf0e10cSrcweir // kann noch optimiert werden, wenn ausgenutzt wird, dass die TxtAttrs
390cdf0e10cSrcweir // nach der Anfangsposition geordnet sind. Dann muessten
391cdf0e10cSrcweir // allerdings noch 2 Indices gemerkt werden
392cdf0e10cSrcweir         for( i = 0; i < pTxtAttrs->Count(); i++ )
393cdf0e10cSrcweir         {
394cdf0e10cSrcweir             const SwTxtAttr* pHt = (*pTxtAttrs)[i];
395cdf0e10cSrcweir             nPos = *pHt->GetStart();    // gibt erstes Attr-Zeichen
396cdf0e10cSrcweir             if( nPos >= nStartPos && nPos <= nMinPos )
397cdf0e10cSrcweir                 nMinPos = nPos;
398cdf0e10cSrcweir 
39969a74367SOliver-Rainer Wittmann             if( pHt->End() )         // Attr mit Ende
400cdf0e10cSrcweir             {
40169a74367SOliver-Rainer Wittmann                 nPos = *pHt->End();      // gibt letztes Attr-Zeichen + 1
402cdf0e10cSrcweir                 if( nPos >= nStartPos && nPos <= nMinPos )
403cdf0e10cSrcweir                     nMinPos = nPos;
404cdf0e10cSrcweir             }
405cdf0e10cSrcweir             if (pHt->HasDummyChar())
406cdf0e10cSrcweir             {
407cdf0e10cSrcweir                 // pos + 1 because of CH_TXTATR in Text
408cdf0e10cSrcweir                 nPos = *pHt->GetStart() + 1;
409cdf0e10cSrcweir                 if( nPos >= nStartPos && nPos <= nMinPos )
410cdf0e10cSrcweir                     nMinPos = nPos;
411cdf0e10cSrcweir             }
412cdf0e10cSrcweir         }
413cdf0e10cSrcweir     }
414cdf0e10cSrcweir 
415cdf0e10cSrcweir     if (maCharRunIter != maCharRuns.end())
416cdf0e10cSrcweir     {
417cdf0e10cSrcweir         if (maCharRunIter->mnEndPos < nMinPos)
418cdf0e10cSrcweir             nMinPos = maCharRunIter->mnEndPos;
419cdf0e10cSrcweir         IterToCurrent();
420cdf0e10cSrcweir     }
421cdf0e10cSrcweir 
422cdf0e10cSrcweir     /*
423cdf0e10cSrcweir      #i2916#
424cdf0e10cSrcweir      Check to see if there are any graphics anchored to characters in this
425cdf0e10cSrcweir      paragraph's text.  Set nMinPos to 1 past the placement for anchored to
426cdf0e10cSrcweir      character because anchors in Word appear after the character they are
427cdf0e10cSrcweir      anchored to.
428cdf0e10cSrcweir     */
429cdf0e10cSrcweir     if (maFlyIter != maFlyFrms.end())
430cdf0e10cSrcweir     {
431cdf0e10cSrcweir         const SwPosition &rAnchor = maFlyIter->GetPosition();
432cdf0e10cSrcweir 
433cdf0e10cSrcweir         nPos = rAnchor.nContent.GetIndex();
434cdf0e10cSrcweir         if (nPos >= nStartPos && nPos <= nMinPos)
435cdf0e10cSrcweir             nMinPos = nPos;
436cdf0e10cSrcweir 
437cdf0e10cSrcweir         if (maFlyIter->GetFrmFmt().GetAnchor().GetAnchorId() == FLY_AT_CHAR)
438cdf0e10cSrcweir         {
439cdf0e10cSrcweir             ++nPos;
440cdf0e10cSrcweir             if (nPos >= nStartPos && nPos <= nMinPos)
441cdf0e10cSrcweir                 nMinPos = nPos;
442cdf0e10cSrcweir         }
443cdf0e10cSrcweir     }
444cdf0e10cSrcweir 
445cdf0e10cSrcweir     //nMinPos found and not going to change at this point
446cdf0e10cSrcweir 
447cdf0e10cSrcweir     if (maCharRunIter != maCharRuns.end())
448cdf0e10cSrcweir     {
449cdf0e10cSrcweir         if (maCharRunIter->mnEndPos == nMinPos)
450cdf0e10cSrcweir             ++maCharRunIter;
451cdf0e10cSrcweir     }
452cdf0e10cSrcweir 
453cdf0e10cSrcweir     return nMinPos;
454cdf0e10cSrcweir }
455cdf0e10cSrcweir 
OutAttr(xub_StrLen nSwPos)456cdf0e10cSrcweir void WW8SwAttrIter::OutAttr( xub_StrLen nSwPos )
457cdf0e10cSrcweir {
458cdf0e10cSrcweir     m_rExport.AttrOutput().RTLAndCJKState( IsCharRTL(), GetScript() );
459cdf0e10cSrcweir 
460cdf0e10cSrcweir     /*
461cdf0e10cSrcweir      Depending on whether text is in CTL/CJK or Western, get the id of that
462cdf0e10cSrcweir      script, the idea is that the font that is actually in use to render this
463cdf0e10cSrcweir      range of text ends up in pFont
464cdf0e10cSrcweir     */
465cdf0e10cSrcweir     sal_uInt16 nFontId = GetWhichOfScript( RES_CHRATR_FONT, GetScript() );
466cdf0e10cSrcweir 
467cdf0e10cSrcweir     const SvxFontItem &rParentFont = ItemGet<SvxFontItem>(
468cdf0e10cSrcweir         (const SwTxtFmtColl&)rNd.GetAnyFmtColl(), nFontId);
469cdf0e10cSrcweir     const SvxFontItem *pFont = &rParentFont;
470cdf0e10cSrcweir 
471cdf0e10cSrcweir     SfxItemSet aExportSet(*rNd.GetSwAttrSet().GetPool(),
472cdf0e10cSrcweir         RES_CHRATR_BEGIN, RES_TXTATR_END - 1);
473cdf0e10cSrcweir 
474cdf0e10cSrcweir     //The hard formatting properties that affect the entire paragraph
475cdf0e10cSrcweir     if (rNd.HasSwAttrSet())
476cdf0e10cSrcweir     {
477cdf0e10cSrcweir         sal_Bool bDeep = sal_False;
478cdf0e10cSrcweir         // only copy hard attributes - bDeep = false
479cdf0e10cSrcweir         aExportSet.Set(rNd.GetSwAttrSet(), bDeep);
480cdf0e10cSrcweir         // get the current font item. Use rNd.GetSwAttrSet instead of aExportSet:
481cdf0e10cSrcweir         const SvxFontItem &rNdFont = ItemGet<SvxFontItem>(rNd.GetSwAttrSet(), nFontId);
482cdf0e10cSrcweir         pFont = &rNdFont;
483cdf0e10cSrcweir         aExportSet.ClearItem(nFontId);
484cdf0e10cSrcweir     }
485cdf0e10cSrcweir 
486cdf0e10cSrcweir     //The additional hard formatting properties that affect this range in the
487cdf0e10cSrcweir     //paragraph
488cdf0e10cSrcweir     sw::PoolItems aRangeItems;
489cdf0e10cSrcweir     if (const SwpHints* pTxtAttrs = rNd.GetpSwpHints())
490cdf0e10cSrcweir     {
491cdf0e10cSrcweir         for (xub_StrLen i = 0; i < pTxtAttrs->Count(); ++i)
492cdf0e10cSrcweir         {
493cdf0e10cSrcweir             const SwTxtAttr* pHt = (*pTxtAttrs)[i];
49469a74367SOliver-Rainer Wittmann             const xub_StrLen* pEnd = pHt->End();
495cdf0e10cSrcweir 
496cdf0e10cSrcweir             if (pEnd ? ( nSwPos >= *pHt->GetStart() && nSwPos < *pEnd)
497cdf0e10cSrcweir                         : nSwPos == *pHt->GetStart() )
498cdf0e10cSrcweir             {
499cdf0e10cSrcweir                 sal_uInt16 nWhich = pHt->GetAttr().Which();
500cdf0e10cSrcweir                 if (nWhich == RES_TXTATR_AUTOFMT)
501cdf0e10cSrcweir                 {
502cdf0e10cSrcweir                     const SwFmtAutoFmt& rAutoFmt = static_cast<const SwFmtAutoFmt&>(pHt->GetAttr());
503cdf0e10cSrcweir                     const boost::shared_ptr<SfxItemSet> pSet = rAutoFmt.GetStyleHandle();
504cdf0e10cSrcweir                     SfxWhichIter aIter( *pSet );
505cdf0e10cSrcweir                     const SfxPoolItem* pItem;
506cdf0e10cSrcweir                     sal_uInt16 nWhichId = aIter.FirstWhich();
507cdf0e10cSrcweir                     while( nWhichId )
508cdf0e10cSrcweir                     {
509cdf0e10cSrcweir                         if( SFX_ITEM_SET == pSet->GetItemState( nWhichId, sal_False, &pItem ))
510cdf0e10cSrcweir                         {
511cdf0e10cSrcweir                             if (nWhichId == nFontId)
512cdf0e10cSrcweir                                 pFont = &(item_cast<SvxFontItem>(*pItem));
513cdf0e10cSrcweir                             else
514cdf0e10cSrcweir                                 aRangeItems[nWhichId] = pItem;
515cdf0e10cSrcweir                         }
516cdf0e10cSrcweir                         nWhichId = aIter.NextWhich();
517cdf0e10cSrcweir                     }
518cdf0e10cSrcweir                 }
519cdf0e10cSrcweir                 else
520cdf0e10cSrcweir                     aRangeItems[nWhich] = (&(pHt->GetAttr()));
521cdf0e10cSrcweir             }
522cdf0e10cSrcweir             else if (nSwPos < *pHt->GetStart())
523cdf0e10cSrcweir                 break;
524cdf0e10cSrcweir         }
525cdf0e10cSrcweir     }
526cdf0e10cSrcweir 
527cdf0e10cSrcweir     /*
528cdf0e10cSrcweir      For #i24291# we need to explictly remove any properties from the
529cdf0e10cSrcweir      aExportSet which a SwCharFmt would override, we can't rely on word doing
530cdf0e10cSrcweir      this for us like writer does
531cdf0e10cSrcweir     */
532cdf0e10cSrcweir     const SwFmtCharFmt *pCharFmtItem =
533cdf0e10cSrcweir         HasItem< SwFmtCharFmt >( aRangeItems, RES_TXTATR_CHARFMT );
534cdf0e10cSrcweir     if ( pCharFmtItem )
535cdf0e10cSrcweir         ClearOverridesFromSet( *pCharFmtItem, aExportSet );
536cdf0e10cSrcweir 
537cdf0e10cSrcweir     sw::PoolItems aExportItems;
538cdf0e10cSrcweir     GetPoolItems( aExportSet, aExportItems, false );
539cdf0e10cSrcweir 
540cdf0e10cSrcweir     sw::cPoolItemIter aEnd = aRangeItems.end();
541cdf0e10cSrcweir     for ( sw::cPoolItemIter aI = aRangeItems.begin(); aI != aEnd; ++aI )
542cdf0e10cSrcweir         aExportItems[aI->first] = aI->second;
543cdf0e10cSrcweir 
544cdf0e10cSrcweir     if ( !aExportItems.empty() )
545cdf0e10cSrcweir     {
546cdf0e10cSrcweir         const SwModify* pOldMod = m_rExport.pOutFmtNode;
547cdf0e10cSrcweir         m_rExport.pOutFmtNode = &rNd;
548cdf0e10cSrcweir         m_rExport.m_aCurrentCharPropStarts.push( nSwPos );
549cdf0e10cSrcweir 
550cdf0e10cSrcweir         m_rExport.ExportPoolItemsToCHP( aExportItems, GetScript() );
551cdf0e10cSrcweir 
552cdf0e10cSrcweir         // HasTextItem nur in dem obigen Bereich erlaubt
553cdf0e10cSrcweir         m_rExport.m_aCurrentCharPropStarts.pop();
554cdf0e10cSrcweir         m_rExport.pOutFmtNode = pOldMod;
555cdf0e10cSrcweir     }
556cdf0e10cSrcweir 
557cdf0e10cSrcweir     ASSERT( pFont, "must be *some* font associated with this txtnode" );
558cdf0e10cSrcweir     if ( pFont )
559cdf0e10cSrcweir     {
560cdf0e10cSrcweir         SvxFontItem aFont( *pFont );
561cdf0e10cSrcweir 
562cdf0e10cSrcweir         /*
563cdf0e10cSrcweir          If we are a nonunicode aware format then we set the charset we want to
564cdf0e10cSrcweir          use for export of this range. If necessary this will generate a pseudo
565cdf0e10cSrcweir          font to use for this range.
566cdf0e10cSrcweir 
567cdf0e10cSrcweir          So now we are guaranteed to have a font with the correct charset set
568cdf0e10cSrcweir          for WW6/95 which will match the script we have exported this range in,
569cdf0e10cSrcweir          this makes older nonunicode aware versions of word display the correct
570cdf0e10cSrcweir          characters.
571cdf0e10cSrcweir         */
572cdf0e10cSrcweir         if ( !m_rExport.HackIsWW8OrHigher() )
573cdf0e10cSrcweir             aFont.SetCharSet( GetCharSet() );
574cdf0e10cSrcweir 
575cdf0e10cSrcweir         if ( rParentFont != aFont )
576cdf0e10cSrcweir             m_rExport.AttrOutput().OutputItem( aFont );
577cdf0e10cSrcweir     }
578cdf0e10cSrcweir }
579cdf0e10cSrcweir 
OutFlys(xub_StrLen nSwPos)580cdf0e10cSrcweir void WW8SwAttrIter::OutFlys(xub_StrLen nSwPos)
581cdf0e10cSrcweir {
582cdf0e10cSrcweir     /*
583cdf0e10cSrcweir      #i2916#
584cdf0e10cSrcweir      May have an anchored graphic to be placed, loop through sorted array
585cdf0e10cSrcweir      and output all at this position
586cdf0e10cSrcweir     */
587cdf0e10cSrcweir     while ( maFlyIter != maFlyFrms.end() )
588cdf0e10cSrcweir     {
589cdf0e10cSrcweir         const SwPosition &rAnchor = maFlyIter->GetPosition();
590cdf0e10cSrcweir         xub_StrLen nPos = rAnchor.nContent.GetIndex();
591cdf0e10cSrcweir 
592cdf0e10cSrcweir         if ( nPos != nSwPos )
593cdf0e10cSrcweir             break;
594cdf0e10cSrcweir         else
595cdf0e10cSrcweir         {
596cdf0e10cSrcweir             m_rExport.AttrOutput().OutputFlyFrame( *maFlyIter );
597cdf0e10cSrcweir             ++maFlyIter;
598cdf0e10cSrcweir         }
599cdf0e10cSrcweir     }
600cdf0e10cSrcweir }
601cdf0e10cSrcweir 
IsTxtAttr(xub_StrLen nSwPos)602cdf0e10cSrcweir bool WW8SwAttrIter::IsTxtAttr( xub_StrLen nSwPos )
603cdf0e10cSrcweir {
60469a74367SOliver-Rainer Wittmann     // search for attrs with dummy character or content
605cdf0e10cSrcweir     if (const SwpHints* pTxtAttrs = rNd.GetpSwpHints())
606cdf0e10cSrcweir     {
607cdf0e10cSrcweir         for (sal_uInt16 i = 0; i < pTxtAttrs->Count(); ++i)
608cdf0e10cSrcweir         {
609cdf0e10cSrcweir             const SwTxtAttr* pHt = (*pTxtAttrs)[i];
61069a74367SOliver-Rainer Wittmann             if ( ( pHt->HasDummyChar() || pHt->HasContent() )
61169a74367SOliver-Rainer Wittmann                  && (*pHt->GetStart() == nSwPos) )
61269a74367SOliver-Rainer Wittmann             {
613cdf0e10cSrcweir                 return true;
61469a74367SOliver-Rainer Wittmann             }
615cdf0e10cSrcweir         }
616cdf0e10cSrcweir     }
617cdf0e10cSrcweir 
618cdf0e10cSrcweir     return false;
619cdf0e10cSrcweir }
620cdf0e10cSrcweir 
IsDropCap(int nSwPos)621cdf0e10cSrcweir bool WW8SwAttrIter::IsDropCap( int nSwPos )
622cdf0e10cSrcweir {
623cdf0e10cSrcweir     // see if the current position falls on a DropCap
624cdf0e10cSrcweir     int nDropChars = mrSwFmtDrop.GetChars();
625cdf0e10cSrcweir     bool bWholeWord = mrSwFmtDrop.GetWholeWord();
626cdf0e10cSrcweir     if (bWholeWord)
627cdf0e10cSrcweir     {
628cdf0e10cSrcweir         short nWordLen = rNd.GetDropLen(0);
629cdf0e10cSrcweir         if(nSwPos == nWordLen && nSwPos != 0)
630cdf0e10cSrcweir             return true;
631cdf0e10cSrcweir     }
632cdf0e10cSrcweir     else
633cdf0e10cSrcweir     {
634cdf0e10cSrcweir         if (nSwPos == nDropChars && nSwPos != 0)
635cdf0e10cSrcweir             return true;
636cdf0e10cSrcweir     }
637cdf0e10cSrcweir     return false;
638cdf0e10cSrcweir }
639cdf0e10cSrcweir 
RequiresImplicitBookmark()640cdf0e10cSrcweir bool WW8SwAttrIter::RequiresImplicitBookmark()
641cdf0e10cSrcweir {
642cdf0e10cSrcweir     SwImplBookmarksIter bkmkIterEnd = m_rExport.maImplicitBookmarks.end();
643cdf0e10cSrcweir     for ( SwImplBookmarksIter aIter = m_rExport.maImplicitBookmarks.begin(); aIter != bkmkIterEnd; ++aIter )
644cdf0e10cSrcweir     {
645cdf0e10cSrcweir         sal_uLong sample  = aIter->second;
646cdf0e10cSrcweir 
647cdf0e10cSrcweir         if ( sample == rNd.GetIndex() )
648cdf0e10cSrcweir             return true;
649cdf0e10cSrcweir     }
650cdf0e10cSrcweir     return false;
651cdf0e10cSrcweir }
652cdf0e10cSrcweir 
653cdf0e10cSrcweir // HasItem ist fuer die Zusammenfassung des Doppel-Attributes Underline
654cdf0e10cSrcweir // und WordLineMode als TextItems. OutAttr() ruft die Ausgabefunktion,
655cdf0e10cSrcweir // die dann ueber HasItem() nach anderen Items an der
656cdf0e10cSrcweir // Attribut-Anfangposition fragen kann.
657cdf0e10cSrcweir // Es koennen nur Attribute mit Ende abgefragt werden.
658cdf0e10cSrcweir // Es wird mit bDeep gesucht
HasTextItem(sal_uInt16 nWhich) const659cdf0e10cSrcweir const SfxPoolItem* WW8SwAttrIter::HasTextItem( sal_uInt16 nWhich ) const
660cdf0e10cSrcweir {
661cdf0e10cSrcweir     const SfxPoolItem* pRet = 0;
662cdf0e10cSrcweir     const SwpHints* pTxtAttrs = rNd.GetpSwpHints();
663cdf0e10cSrcweir     if (pTxtAttrs)
664cdf0e10cSrcweir     {
66593996bb7SArmin Le Grand         xub_StrLen nTmpSwPos = m_rExport.m_aCurrentCharPropStarts.size() ?
66693996bb7SArmin Le Grand             m_rExport.m_aCurrentCharPropStarts.top() : 0;
667cdf0e10cSrcweir         for (sal_uInt16 i = 0; i < pTxtAttrs->Count(); ++i)
668cdf0e10cSrcweir         {
669cdf0e10cSrcweir             const SwTxtAttr* pHt = (*pTxtAttrs)[i];
670cdf0e10cSrcweir             const SfxPoolItem* pItem = &pHt->GetAttr();
671cdf0e10cSrcweir             const xub_StrLen* pAtrEnd = 0;
67269a74367SOliver-Rainer Wittmann             if( 0 != ( pAtrEnd = pHt->End() ) &&     // nur Attr mit Ende
673cdf0e10cSrcweir                 nWhich == pItem->Which() &&             //
674cdf0e10cSrcweir                 nTmpSwPos >= *pHt->GetStart() && nTmpSwPos < *pAtrEnd )
675cdf0e10cSrcweir             {
676cdf0e10cSrcweir                 pRet = pItem;       // gefunden
677cdf0e10cSrcweir                 break;
678cdf0e10cSrcweir             }
679cdf0e10cSrcweir             else if (nTmpSwPos < *pHt->GetStart())
680cdf0e10cSrcweir                 break;              // dann kommt da nichts mehr
681cdf0e10cSrcweir         }
682cdf0e10cSrcweir     }
683cdf0e10cSrcweir     return pRet;
684cdf0e10cSrcweir }
685cdf0e10cSrcweir 
GetCurrentItems(WW8Bytes & rItems) const686cdf0e10cSrcweir void WW8Export::GetCurrentItems(WW8Bytes& rItems) const
687cdf0e10cSrcweir {
688cdf0e10cSrcweir     sal_uInt16 nEnd = pO ? pO->Count() : 0;
689cdf0e10cSrcweir     for (sal_uInt16 nI = 0; nI < nEnd; ++nI)
690cdf0e10cSrcweir         rItems.Insert((*pO)[nI], rItems.Count());
691cdf0e10cSrcweir }
692cdf0e10cSrcweir 
GetItem(sal_uInt16 nWhich) const693cdf0e10cSrcweir const SfxPoolItem& WW8SwAttrIter::GetItem(sal_uInt16 nWhich) const
694cdf0e10cSrcweir {
695cdf0e10cSrcweir     const SfxPoolItem* pRet = HasTextItem(nWhich);
696cdf0e10cSrcweir     return pRet ? *pRet : rNd.SwCntntNode::GetAttr(nWhich);
697cdf0e10cSrcweir }
698cdf0e10cSrcweir 
StartRuby(const SwTxtNode & rNode,const SwFmtRuby & rRuby)699cdf0e10cSrcweir void WW8AttributeOutput::StartRuby( const SwTxtNode& rNode, const SwFmtRuby& rRuby )
700cdf0e10cSrcweir {
701cdf0e10cSrcweir     String aStr( FieldString( ww::eEQ ) );
702cdf0e10cSrcweir     aStr.APPEND_CONST_ASC( "\\* jc" );
703cdf0e10cSrcweir     sal_Int32 nJC = 0;
704cdf0e10cSrcweir     sal_Char cDirective = 0;
705cdf0e10cSrcweir     switch ( rRuby.GetAdjustment() )
706cdf0e10cSrcweir     {
707cdf0e10cSrcweir         case 0:
708cdf0e10cSrcweir             nJC = 3;
709cdf0e10cSrcweir             cDirective = 'l';
710cdf0e10cSrcweir             break;
711cdf0e10cSrcweir         case 1:
712cdf0e10cSrcweir             //defaults to 0
713cdf0e10cSrcweir             break;
714cdf0e10cSrcweir         case 2:
715cdf0e10cSrcweir             nJC = 4;
716cdf0e10cSrcweir             cDirective = 'r';
717cdf0e10cSrcweir             break;
718cdf0e10cSrcweir         case 3:
719cdf0e10cSrcweir             nJC = 1;
720cdf0e10cSrcweir             cDirective = 'd';
721cdf0e10cSrcweir             break;
722cdf0e10cSrcweir         case 4:
723cdf0e10cSrcweir             nJC = 2;
724cdf0e10cSrcweir             cDirective = 'd';
725cdf0e10cSrcweir             break;
726cdf0e10cSrcweir         default:
727cdf0e10cSrcweir             ASSERT( !this,"Unhandled Ruby justication code" );
728cdf0e10cSrcweir             break;
729cdf0e10cSrcweir     }
730cdf0e10cSrcweir     aStr += String::CreateFromInt32( nJC );
731cdf0e10cSrcweir 
732cdf0e10cSrcweir     /*
733cdf0e10cSrcweir      MS needs to know the name and size of the font used in the ruby item,
734cdf0e10cSrcweir      but we coud have written it in a mixture of asian and western
735cdf0e10cSrcweir      scripts, and each of these can be a different font and size than the
736cdf0e10cSrcweir      other, so we make a guess based upon the first character of the text,
737cdf0e10cSrcweir      defaulting to asian.
738cdf0e10cSrcweir      */
739cdf0e10cSrcweir     sal_uInt16 nRubyScript;
740cdf0e10cSrcweir     if( pBreakIt->GetBreakIter().is() )
741cdf0e10cSrcweir         nRubyScript = pBreakIt->GetBreakIter()->getScriptType( rRuby.GetText(), 0);
742cdf0e10cSrcweir     else
743cdf0e10cSrcweir         nRubyScript = i18n::ScriptType::ASIAN;
744cdf0e10cSrcweir 
745cdf0e10cSrcweir     const SwTxtRuby* pRubyTxt = rRuby.GetTxtRuby();
746cdf0e10cSrcweir     const SwCharFmt* pFmt = pRubyTxt ? pRubyTxt->GetCharFmt() : 0;
747cdf0e10cSrcweir     String sFamilyName;
748cdf0e10cSrcweir     long nHeight;
749cdf0e10cSrcweir     if ( pFmt )
750cdf0e10cSrcweir     {
751cdf0e10cSrcweir         const SvxFontItem &rFont = ItemGet< SvxFontItem >( *pFmt,
752cdf0e10cSrcweir                 GetWhichOfScript(RES_CHRATR_FONT,nRubyScript) );
753cdf0e10cSrcweir         sFamilyName = rFont.GetFamilyName();
754cdf0e10cSrcweir 
755cdf0e10cSrcweir         const SvxFontHeightItem &rHeight = ItemGet< SvxFontHeightItem >( *pFmt,
756cdf0e10cSrcweir                 GetWhichOfScript( RES_CHRATR_FONTSIZE, nRubyScript ) );
757cdf0e10cSrcweir         nHeight = rHeight.GetHeight();
758cdf0e10cSrcweir     }
759cdf0e10cSrcweir     else
760cdf0e10cSrcweir     {
761cdf0e10cSrcweir         /*Get defaults if no formatting on ruby text*/
762cdf0e10cSrcweir 
763cdf0e10cSrcweir         const SfxItemPool *pPool = rNode.GetSwAttrSet().GetPool();
764cdf0e10cSrcweir         const SfxItemPool &rPool = pPool ? *pPool : m_rWW8Export.pDoc->GetAttrPool();
765cdf0e10cSrcweir 
766cdf0e10cSrcweir         const SvxFontItem &rFont  = DefaultItemGet< SvxFontItem >( rPool,
767cdf0e10cSrcweir                 GetWhichOfScript( RES_CHRATR_FONT,nRubyScript ) );
768cdf0e10cSrcweir         sFamilyName = rFont.GetFamilyName();
769cdf0e10cSrcweir 
770cdf0e10cSrcweir         const SvxFontHeightItem &rHeight = DefaultItemGet< SvxFontHeightItem >
771cdf0e10cSrcweir             ( rPool, GetWhichOfScript( RES_CHRATR_FONTSIZE, nRubyScript ) );
772cdf0e10cSrcweir         nHeight = rHeight.GetHeight();
773cdf0e10cSrcweir     }
774cdf0e10cSrcweir     nHeight = (nHeight + 5)/10;
775cdf0e10cSrcweir 
776cdf0e10cSrcweir     aStr.APPEND_CONST_ASC( " \\* \"Font:" );
777cdf0e10cSrcweir     aStr.Append( sFamilyName );
778cdf0e10cSrcweir     aStr.APPEND_CONST_ASC( "\" \\* hps" );
779cdf0e10cSrcweir     aStr += String::CreateFromInt32( nHeight );
780cdf0e10cSrcweir     aStr.APPEND_CONST_ASC( " \\o" );
781cdf0e10cSrcweir     if ( cDirective )
782cdf0e10cSrcweir     {
783cdf0e10cSrcweir         aStr.APPEND_CONST_ASC( "\\a" );
784cdf0e10cSrcweir         aStr.Append( cDirective );
785cdf0e10cSrcweir     }
786cdf0e10cSrcweir     aStr.APPEND_CONST_ASC( "(\\s\\up " );
787cdf0e10cSrcweir 
788cdf0e10cSrcweir 
789cdf0e10cSrcweir     if ( pBreakIt->GetBreakIter().is() )
790cdf0e10cSrcweir         nRubyScript = pBreakIt->GetBreakIter()->getScriptType( rNode.GetTxt(),
791cdf0e10cSrcweir                 *( pRubyTxt->GetStart() ) );
792cdf0e10cSrcweir     else
793cdf0e10cSrcweir         nRubyScript = i18n::ScriptType::ASIAN;
794cdf0e10cSrcweir 
795cdf0e10cSrcweir     const SwAttrSet& rSet = rNode.GetSwAttrSet();
796cdf0e10cSrcweir     const SvxFontHeightItem &rHeightItem  =
797cdf0e10cSrcweir         ( const SvxFontHeightItem& )rSet.Get(
798cdf0e10cSrcweir                                              GetWhichOfScript( RES_CHRATR_FONTSIZE, nRubyScript ) );
799cdf0e10cSrcweir     nHeight = (rHeightItem.GetHeight() + 10)/20-1;
800cdf0e10cSrcweir     aStr += String::CreateFromInt32(nHeight);
801cdf0e10cSrcweir     aStr += '(';
802cdf0e10cSrcweir     aStr += rRuby.GetText();
803cdf0e10cSrcweir     aStr.APPEND_CONST_ASC( ");" );
804cdf0e10cSrcweir     m_rWW8Export.OutputField( 0, ww::eEQ, aStr,
805cdf0e10cSrcweir             WRITEFIELD_START | WRITEFIELD_CMD_START );
806cdf0e10cSrcweir }
807cdf0e10cSrcweir 
EndRuby()808cdf0e10cSrcweir void WW8AttributeOutput::EndRuby()
809cdf0e10cSrcweir {
810cdf0e10cSrcweir     m_rWW8Export.WriteChar( ')' );
811cdf0e10cSrcweir     m_rWW8Export.OutputField( 0, ww::eEQ, aEmptyStr, WRITEFIELD_END | WRITEFIELD_CLOSE );
812cdf0e10cSrcweir }
813cdf0e10cSrcweir 
814cdf0e10cSrcweir /*#i15387# Better ideas welcome*/
TruncateBookmark(String & rRet)815cdf0e10cSrcweir String &TruncateBookmark( String &rRet )
816cdf0e10cSrcweir {
817cdf0e10cSrcweir     if ( rRet.Len() > 40 )
818cdf0e10cSrcweir         rRet.Erase( 40 );
819cdf0e10cSrcweir     ASSERT( rRet.Len() <= 40, "Word cannot have bookmarks longer than 40 chars" );
820cdf0e10cSrcweir     return rRet;
821cdf0e10cSrcweir }
822cdf0e10cSrcweir 
AnalyzeURL(const String & rUrl,const String &,String * pLinkURL,String * pMark)823cdf0e10cSrcweir bool AttributeOutputBase::AnalyzeURL( const String& rUrl, const String& /*rTarget*/, String* pLinkURL, String* pMark )
824cdf0e10cSrcweir {
825cdf0e10cSrcweir     bool bBookMarkOnly = false;
826cdf0e10cSrcweir 
827cdf0e10cSrcweir     INetURLObject aURL( rUrl );
828cdf0e10cSrcweir     String sMark;
829cdf0e10cSrcweir     String sURL;
830cdf0e10cSrcweir 
831cdf0e10cSrcweir     if ( rUrl.Len() > 1 && rUrl.GetChar(0) == INET_MARK_TOKEN )
832cdf0e10cSrcweir     {
833cdf0e10cSrcweir         sMark = BookmarkToWriter( rUrl.Copy(1) );
834cdf0e10cSrcweir 
835cdf0e10cSrcweir         xub_StrLen nPos = sMark.SearchBackward( cMarkSeperator );
836cdf0e10cSrcweir 
837cdf0e10cSrcweir         String sRefType( sMark.Copy( nPos+1 ) );
838cdf0e10cSrcweir         sRefType.EraseAllChars();
839cdf0e10cSrcweir 
840cdf0e10cSrcweir         // i21465 Only interested in outline references
841cdf0e10cSrcweir         if ( sRefType.EqualsAscii( pMarkToOutline ) )
842cdf0e10cSrcweir         {
843cdf0e10cSrcweir             String sLink = sMark.Copy(0, nPos);
844cdf0e10cSrcweir             SwImplBookmarksIter bkmkIterEnd = GetExport().maImplicitBookmarks.end();
845cdf0e10cSrcweir             for ( SwImplBookmarksIter aIter = GetExport().maImplicitBookmarks.begin(); aIter != bkmkIterEnd; ++aIter )
846cdf0e10cSrcweir             {
847cdf0e10cSrcweir                 String bkmkName  = aIter->first;
848cdf0e10cSrcweir 
849cdf0e10cSrcweir                 if ( bkmkName == sLink )
850cdf0e10cSrcweir                 {
851cdf0e10cSrcweir                     sMark = String( RTL_CONSTASCII_STRINGPARAM( "_toc" ) );
852cdf0e10cSrcweir                     sMark += String::CreateFromInt32( aIter->second );
853cdf0e10cSrcweir                 }
854cdf0e10cSrcweir             }
855cdf0e10cSrcweir         }
856cdf0e10cSrcweir     }
857cdf0e10cSrcweir     else
858cdf0e10cSrcweir     {
859cdf0e10cSrcweir         sURL = aURL.GetURLNoMark( INetURLObject::DECODE_UNAMBIGUOUS );
860cdf0e10cSrcweir         sMark = aURL.GetMark( INetURLObject::DECODE_UNAMBIGUOUS );
861cdf0e10cSrcweir 
862cdf0e10cSrcweir     }
863cdf0e10cSrcweir 
864cdf0e10cSrcweir     if ( sMark.Len() && !sURL.Len() )
865cdf0e10cSrcweir         bBookMarkOnly = true;
866cdf0e10cSrcweir 
867cdf0e10cSrcweir 
868cdf0e10cSrcweir 
869cdf0e10cSrcweir     *pMark = sMark;
870cdf0e10cSrcweir     *pLinkURL = sURL;
871cdf0e10cSrcweir     return bBookMarkOnly;
872cdf0e10cSrcweir }
873cdf0e10cSrcweir 
AnalyzeURL(const String & rUrl,const String & rTarget,String * pLinkURL,String * pMark)874cdf0e10cSrcweir bool WW8AttributeOutput::AnalyzeURL( const String& rUrl, const String& rTarget, String* pLinkURL, String* pMark )
875cdf0e10cSrcweir {
876cdf0e10cSrcweir     bool bBookMarkOnly = AttributeOutputBase::AnalyzeURL( rUrl, rTarget, pLinkURL, pMark );
877cdf0e10cSrcweir 
878cdf0e10cSrcweir     String sURL = *pLinkURL;
879cdf0e10cSrcweir     String sMark = *pMark;
880cdf0e10cSrcweir 
881cdf0e10cSrcweir     if ( sURL.Len() )
882cdf0e10cSrcweir         sURL = URIHelper::simpleNormalizedMakeRelative( m_rWW8Export.GetWriter().GetBaseURL(), sURL );
883cdf0e10cSrcweir 
884cdf0e10cSrcweir     if ( bBookMarkOnly )
885cdf0e10cSrcweir         sURL = FieldString( ww::eHYPERLINK );
886cdf0e10cSrcweir     else
887cdf0e10cSrcweir     {
888cdf0e10cSrcweir         String sFld( FieldString( ww::eHYPERLINK ) );
889cdf0e10cSrcweir         sFld.APPEND_CONST_ASC( "\"" );
890cdf0e10cSrcweir         sURL.Insert( sFld, 0 );
891cdf0e10cSrcweir         sURL += '\"';
892cdf0e10cSrcweir     }
893cdf0e10cSrcweir 
894cdf0e10cSrcweir     if ( sMark.Len() )
895cdf0e10cSrcweir         ( ( sURL.APPEND_CONST_ASC( " \\l \"" ) ) += sMark ) += '\"';
896cdf0e10cSrcweir 
897cdf0e10cSrcweir     if ( rTarget.Len() )
898cdf0e10cSrcweir         ( sURL.APPEND_CONST_ASC( " \\n " ) ) += rTarget;
899cdf0e10cSrcweir 
900cdf0e10cSrcweir     *pLinkURL = sURL;
901cdf0e10cSrcweir     *pMark = sMark;
902cdf0e10cSrcweir 
903cdf0e10cSrcweir     return bBookMarkOnly;
904cdf0e10cSrcweir }
905cdf0e10cSrcweir 
StartURL(const String & rUrl,const String & rTarget)906cdf0e10cSrcweir bool WW8AttributeOutput::StartURL( const String &rUrl, const String &rTarget )
907cdf0e10cSrcweir {
908cdf0e10cSrcweir     // hyperlinks only in WW8
909cdf0e10cSrcweir     if ( !m_rWW8Export.bWrtWW8 )
910cdf0e10cSrcweir         return false;
911cdf0e10cSrcweir 
912cdf0e10cSrcweir     INetURLObject aURL( rUrl );
913cdf0e10cSrcweir     String sURL;
914cdf0e10cSrcweir     String sMark;
915cdf0e10cSrcweir 
916cdf0e10cSrcweir     bool bBookMarkOnly = AnalyzeURL( rUrl, rTarget, &sURL, &sMark );
917cdf0e10cSrcweir 
918cdf0e10cSrcweir 
919cdf0e10cSrcweir     m_rWW8Export.OutputField( 0, ww::eHYPERLINK, sURL, WRITEFIELD_START | WRITEFIELD_CMD_START );
920cdf0e10cSrcweir 
921cdf0e10cSrcweir     // write the refence to the "picture" structure
922cdf0e10cSrcweir     sal_uLong nDataStt = m_rWW8Export.pDataStrm->Tell();
923cdf0e10cSrcweir     m_rWW8Export.pChpPlc->AppendFkpEntry( m_rWW8Export.Strm().Tell() );
924cdf0e10cSrcweir 
925cdf0e10cSrcweir //  WinWord 2000 doesn't write this - so its a temp solution by W97 ?
926cdf0e10cSrcweir     m_rWW8Export.WriteChar( 0x01 );
927cdf0e10cSrcweir 
928cdf0e10cSrcweir     static sal_uInt8 aArr1[] = {
929cdf0e10cSrcweir         0x03, 0x6a, 0,0,0,0,    // sprmCPicLocation
930cdf0e10cSrcweir 
931cdf0e10cSrcweir         0x06, 0x08, 0x01,       // sprmCFData
932cdf0e10cSrcweir         0x55, 0x08, 0x01,       // sprmCFSpec
933cdf0e10cSrcweir         0x02, 0x08, 0x01        // sprmCFFldVanish
934cdf0e10cSrcweir     };
935cdf0e10cSrcweir     sal_uInt8* pDataAdr = aArr1 + 2;
936cdf0e10cSrcweir     Set_UInt32( pDataAdr, nDataStt );
937cdf0e10cSrcweir 
938cdf0e10cSrcweir     m_rWW8Export.pChpPlc->AppendFkpEntry( m_rWW8Export.Strm().Tell(), sizeof( aArr1 ), aArr1 );
939cdf0e10cSrcweir 
940cdf0e10cSrcweir     m_rWW8Export.OutputField( 0, ww::eHYPERLINK, sURL, WRITEFIELD_CMD_END );
941cdf0e10cSrcweir 
942cdf0e10cSrcweir     // now write the picture structur
943cdf0e10cSrcweir     sURL = aURL.GetURLNoMark();
944cdf0e10cSrcweir 
945cdf0e10cSrcweir     //all links end up in the data stream as absolute references.
946cdf0e10cSrcweir     bool bAbsolute = !bBookMarkOnly;
947cdf0e10cSrcweir 
948cdf0e10cSrcweir     static sal_uInt8 __READONLY_DATA aURLData1[] = {
949cdf0e10cSrcweir         0,0,0,0,        // len of struct
950cdf0e10cSrcweir         0x44,0,         // the start of "next" data
951cdf0e10cSrcweir         0,0,0,0,0,0,0,0,0,0,                // PIC-Structure!
952cdf0e10cSrcweir         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,    //  |
953cdf0e10cSrcweir         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,    //  |
954cdf0e10cSrcweir         0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,    //  |
955cdf0e10cSrcweir         0,0,0,0,                            // /
956cdf0e10cSrcweir     };
957cdf0e10cSrcweir     static sal_uInt8 __READONLY_DATA MAGIC_A[] = {
958cdf0e10cSrcweir         // start of "next" data
959cdf0e10cSrcweir         0xD0,0xC9,0xEA,0x79,0xF9,0xBA,0xCE,0x11,
960cdf0e10cSrcweir         0x8C,0x82,0x00,0xAA,0x00,0x4B,0xA9,0x0B
961cdf0e10cSrcweir     };
962cdf0e10cSrcweir 
963cdf0e10cSrcweir     m_rWW8Export.pDataStrm->Write( aURLData1, sizeof( aURLData1 ) );
964cdf0e10cSrcweir     sal_uInt8 nAnchor = 0x00;
965cdf0e10cSrcweir     if ( sMark.Len() )
966cdf0e10cSrcweir         nAnchor = 0x08;
967cdf0e10cSrcweir     m_rWW8Export.pDataStrm->Write( &nAnchor, 1 );
968cdf0e10cSrcweir     m_rWW8Export.pDataStrm->Write( MAGIC_A, sizeof(MAGIC_A) );
969cdf0e10cSrcweir     SwWW8Writer::WriteLong( *m_rWW8Export.pDataStrm, 0x00000002);
970cdf0e10cSrcweir     sal_uInt32 nFlag = bBookMarkOnly ? 0 : 0x01;
971cdf0e10cSrcweir     if ( bAbsolute )
972cdf0e10cSrcweir         nFlag |= 0x02;
973cdf0e10cSrcweir     if ( sMark.Len() )
974cdf0e10cSrcweir         nFlag |= 0x08;
975cdf0e10cSrcweir     SwWW8Writer::WriteLong( *m_rWW8Export.pDataStrm, nFlag );
976cdf0e10cSrcweir 
977cdf0e10cSrcweir     INetProtocol eProto = aURL.GetProtocol();
978cdf0e10cSrcweir     if ( eProto == INET_PROT_FILE )
979cdf0e10cSrcweir     {
980cdf0e10cSrcweir         // version 1 (for a document)
981cdf0e10cSrcweir 
982cdf0e10cSrcweir         static sal_uInt8 __READONLY_DATA MAGIC_C[] = {
983cdf0e10cSrcweir             0x03, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
984cdf0e10cSrcweir             0xC0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46,
985cdf0e10cSrcweir             0x00, 0x00
986cdf0e10cSrcweir         };
987cdf0e10cSrcweir 
988cdf0e10cSrcweir         static sal_uInt8 __READONLY_DATA MAGIC_D[] = {
989cdf0e10cSrcweir             0xFF, 0xFF, 0xAD, 0xDE, 0x00, 0x00, 0x00, 0x00,
990cdf0e10cSrcweir             0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
991cdf0e10cSrcweir             0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
992cdf0e10cSrcweir         };
993cdf0e10cSrcweir 
994cdf0e10cSrcweir         // save the links to files as relative
995cdf0e10cSrcweir         sURL = URIHelper::simpleNormalizedMakeRelative( m_rWW8Export.GetWriter().GetBaseURL(), sURL );
996cdf0e10cSrcweir         if ( sURL.EqualsAscii( "/", 0, 1 ) )
997cdf0e10cSrcweir             sURL = aURL.PathToFileName();
998cdf0e10cSrcweir 
999cdf0e10cSrcweir         // special case for the absolute windows names
1000cdf0e10cSrcweir         // (convert '/c:/foo/bar.doc' into 'c:\foo\bar.doc')
1001cdf0e10cSrcweir         sal_Unicode aDrive = ( sURL.Len() > 1 )? sURL.GetChar( 1 ): 0;
1002cdf0e10cSrcweir         if ( sURL.EqualsAscii( "/", 0, 1 ) &&
1003cdf0e10cSrcweir              ( ( aDrive >= 'A' && aDrive <= 'Z' ) || ( aDrive >= 'a' && aDrive <= 'z' ) ) &&
1004cdf0e10cSrcweir              sURL.EqualsAscii( ":", 2, 1 ) )
1005cdf0e10cSrcweir         {
1006cdf0e10cSrcweir             sURL.Erase( 0, 1 );
1007cdf0e10cSrcweir             sURL.SearchAndReplaceAll( '/', '\\' );
1008cdf0e10cSrcweir         }
1009cdf0e10cSrcweir 
1010cdf0e10cSrcweir         m_rWW8Export.pDataStrm->Write( MAGIC_C, sizeof(MAGIC_C) );
1011cdf0e10cSrcweir         SwWW8Writer::WriteLong( *m_rWW8Export.pDataStrm, sURL.Len()+1 );
1012cdf0e10cSrcweir         SwWW8Writer::WriteString8( *m_rWW8Export.pDataStrm, sURL, true,
1013cdf0e10cSrcweir                                     RTL_TEXTENCODING_MS_1252 );
1014cdf0e10cSrcweir         m_rWW8Export.pDataStrm->Write( MAGIC_D, sizeof( MAGIC_D ) );
1015cdf0e10cSrcweir 
1016cdf0e10cSrcweir         SwWW8Writer::WriteLong( *m_rWW8Export.pDataStrm, 2*sURL.Len() + 6 );
1017cdf0e10cSrcweir         SwWW8Writer::WriteLong( *m_rWW8Export.pDataStrm, 2*sURL.Len() );
1018cdf0e10cSrcweir         SwWW8Writer::WriteShort( *m_rWW8Export.pDataStrm, 3 );
1019cdf0e10cSrcweir         SwWW8Writer::WriteString16( *m_rWW8Export.pDataStrm, sURL, false );
1020cdf0e10cSrcweir     }
1021cdf0e10cSrcweir     else if ( eProto != INET_PROT_NOT_VALID )
1022cdf0e10cSrcweir     {
1023cdf0e10cSrcweir         // version 2 (simple url)
1024cdf0e10cSrcweir         // an write some data to the data stream, but dont ask
1025cdf0e10cSrcweir         // what the data mean, except for the URL.
1026cdf0e10cSrcweir         // The First piece is the WW8_PIC structure.
1027cdf0e10cSrcweir         //
1028cdf0e10cSrcweir         static sal_uInt8 __READONLY_DATA MAGIC_B[] = {
1029cdf0e10cSrcweir             0xE0,0xC9,0xEA,0x79,0xF9,0xBA,0xCE,0x11,
1030cdf0e10cSrcweir             0x8C,0x82,0x00,0xAA,0x00,0x4B,0xA9,0x0B
1031cdf0e10cSrcweir         };
1032cdf0e10cSrcweir 
1033cdf0e10cSrcweir         m_rWW8Export.pDataStrm->Write( MAGIC_B, sizeof(MAGIC_B) );
1034cdf0e10cSrcweir         SwWW8Writer::WriteLong( *m_rWW8Export.pDataStrm, 2 * ( sURL.Len() + 1 ) );
1035cdf0e10cSrcweir         SwWW8Writer::WriteString16( *m_rWW8Export.pDataStrm, sURL, true );
1036cdf0e10cSrcweir     }
1037cdf0e10cSrcweir 
1038cdf0e10cSrcweir     if ( sMark.Len() )
1039cdf0e10cSrcweir     {
1040cdf0e10cSrcweir         SwWW8Writer::WriteLong( *m_rWW8Export.pDataStrm, sMark.Len()+1 );
1041cdf0e10cSrcweir         SwWW8Writer::WriteString16( *m_rWW8Export.pDataStrm, sMark, true );
1042cdf0e10cSrcweir     }
1043cdf0e10cSrcweir     SwWW8Writer::WriteLong( *m_rWW8Export.pDataStrm, nDataStt,
1044cdf0e10cSrcweir         m_rWW8Export.pDataStrm->Tell() - nDataStt );
1045cdf0e10cSrcweir 
1046cdf0e10cSrcweir     return true;
1047cdf0e10cSrcweir }
1048cdf0e10cSrcweir 
EndURL()1049cdf0e10cSrcweir bool WW8AttributeOutput::EndURL()
1050cdf0e10cSrcweir {
1051cdf0e10cSrcweir     // hyperlinks only in WW8
1052cdf0e10cSrcweir     if ( !m_rWW8Export.bWrtWW8 )
1053cdf0e10cSrcweir         return false;
1054cdf0e10cSrcweir 
1055cdf0e10cSrcweir     m_rWW8Export.OutputField( 0, ww::eHYPERLINK, aEmptyStr, WRITEFIELD_CLOSE );
1056cdf0e10cSrcweir 
1057cdf0e10cSrcweir     return true;
1058cdf0e10cSrcweir }
1059cdf0e10cSrcweir 
BookmarkToWord(const String & rBookmark)1060cdf0e10cSrcweir String BookmarkToWord(const String &rBookmark)
1061cdf0e10cSrcweir {
1062cdf0e10cSrcweir     String sRet(INetURLObject::encode(rBookmark,
1063cdf0e10cSrcweir         INetURLObject::PART_REL_SEGMENT_EXTRA, '%',
1064cdf0e10cSrcweir         INetURLObject::ENCODE_ALL, RTL_TEXTENCODING_ASCII_US));
1065cdf0e10cSrcweir     return TruncateBookmark(sRet);
1066cdf0e10cSrcweir }
1067cdf0e10cSrcweir 
BookmarkToWriter(const String & rBookmark)1068cdf0e10cSrcweir String BookmarkToWriter(const String &rBookmark)
1069cdf0e10cSrcweir {
1070cdf0e10cSrcweir     return INetURLObject::decode(rBookmark, '%',
1071cdf0e10cSrcweir         INetURLObject::DECODE_UNAMBIGUOUS, RTL_TEXTENCODING_ASCII_US);
1072cdf0e10cSrcweir }
1073cdf0e10cSrcweir 
OutSwFmtRefMark(const SwFmtRefMark & rAttr,bool)1074cdf0e10cSrcweir void WW8SwAttrIter::OutSwFmtRefMark(const SwFmtRefMark& rAttr, bool)
1075cdf0e10cSrcweir {
1076cdf0e10cSrcweir     if ( m_rExport.HasRefToObject( REF_SETREFATTR, &rAttr.GetRefName(), 0 ) )
1077cdf0e10cSrcweir         m_rExport.AppendBookmark( m_rExport.GetBookmarkName( REF_SETREFATTR,
1078cdf0e10cSrcweir                                             &rAttr.GetRefName(), 0 ));
1079cdf0e10cSrcweir }
1080cdf0e10cSrcweir 
FieldVanish(const String & rTxt,ww::eField)1081cdf0e10cSrcweir void WW8AttributeOutput::FieldVanish( const String& rTxt, ww::eField /*eType*/ )
1082cdf0e10cSrcweir {
1083cdf0e10cSrcweir     WW8Bytes aItems;
1084cdf0e10cSrcweir     m_rWW8Export.GetCurrentItems( aItems );
1085cdf0e10cSrcweir 
1086cdf0e10cSrcweir     // sprmCFFldVanish
1087cdf0e10cSrcweir     if ( m_rWW8Export.bWrtWW8 )
1088cdf0e10cSrcweir         SwWW8Writer::InsUInt16( aItems, NS_sprm::LN_CFFldVanish );
1089cdf0e10cSrcweir     else
1090cdf0e10cSrcweir         aItems.Insert( 67, aItems.Count() );
1091cdf0e10cSrcweir     aItems.Insert( 1, aItems.Count() );
1092cdf0e10cSrcweir 
1093cdf0e10cSrcweir     sal_uInt16 nStt_sprmCFSpec = aItems.Count();
1094cdf0e10cSrcweir 
1095cdf0e10cSrcweir     // sprmCFSpec --  fSpec-Attribut true
1096cdf0e10cSrcweir     if ( m_rWW8Export.bWrtWW8 )
1097cdf0e10cSrcweir         SwWW8Writer::InsUInt16( aItems, 0x855 );
1098cdf0e10cSrcweir     else
1099cdf0e10cSrcweir         aItems.Insert( 117, aItems.Count() );
1100cdf0e10cSrcweir     aItems.Insert( 1, aItems.Count() );
1101cdf0e10cSrcweir 
1102cdf0e10cSrcweir     m_rWW8Export.WriteChar( '\x13' );
1103cdf0e10cSrcweir     m_rWW8Export.pChpPlc->AppendFkpEntry( m_rWW8Export.Strm().Tell(), aItems.Count(),
1104cdf0e10cSrcweir                                     aItems.GetData() );
1105cdf0e10cSrcweir     m_rWW8Export.OutSwString( rTxt, 0, rTxt.Len(), m_rWW8Export.IsUnicode(),
1106cdf0e10cSrcweir                         RTL_TEXTENCODING_MS_1252 );
1107cdf0e10cSrcweir     m_rWW8Export.pChpPlc->AppendFkpEntry( m_rWW8Export.Strm().Tell(), nStt_sprmCFSpec,
1108cdf0e10cSrcweir                                     aItems.GetData() );
1109cdf0e10cSrcweir     m_rWW8Export.WriteChar( '\x15' );
1110cdf0e10cSrcweir     m_rWW8Export.pChpPlc->AppendFkpEntry( m_rWW8Export.Strm().Tell(), aItems.Count(),
1111cdf0e10cSrcweir                                     aItems.GetData() );
1112cdf0e10cSrcweir }
1113cdf0e10cSrcweir 
TOXMark(const SwTxtNode & rNode,const SwTOXMark & rAttr)1114cdf0e10cSrcweir void AttributeOutputBase::TOXMark( const SwTxtNode& rNode, const SwTOXMark& rAttr )
1115cdf0e10cSrcweir {
1116cdf0e10cSrcweir     // its a field; so get the Text form the Node and build the field
1117cdf0e10cSrcweir     String sTxt;
1118cdf0e10cSrcweir     ww::eField eType = ww::eNONE;
1119cdf0e10cSrcweir 
1120cdf0e10cSrcweir     const SwTxtTOXMark& rTxtTOXMark = *rAttr.GetTxtTOXMark();
112169a74367SOliver-Rainer Wittmann     const xub_StrLen* pTxtEnd = rTxtTOXMark.End();
1122cdf0e10cSrcweir     if ( pTxtEnd ) // has range?
1123cdf0e10cSrcweir     {
1124cdf0e10cSrcweir         sTxt = rNode.GetExpandTxt( *rTxtTOXMark.GetStart(),
1125cdf0e10cSrcweir                                    *pTxtEnd - *rTxtTOXMark.GetStart() );
1126cdf0e10cSrcweir     }
1127cdf0e10cSrcweir     else
1128cdf0e10cSrcweir         sTxt = rAttr.GetAlternativeText();
1129cdf0e10cSrcweir 
1130cdf0e10cSrcweir     switch ( rAttr.GetTOXType()->GetType() )
1131cdf0e10cSrcweir     {
1132cdf0e10cSrcweir         case TOX_INDEX:
1133cdf0e10cSrcweir             eType = ww::eXE;
1134cdf0e10cSrcweir             if ( rAttr.GetPrimaryKey().Len() )
1135cdf0e10cSrcweir             {
1136cdf0e10cSrcweir                 if ( rAttr.GetSecondaryKey().Len() )
1137cdf0e10cSrcweir                 {
1138cdf0e10cSrcweir                     sTxt.Insert( ':', 0 );
1139cdf0e10cSrcweir                     sTxt.Insert( rAttr.GetSecondaryKey(), 0 );
1140cdf0e10cSrcweir                 }
1141cdf0e10cSrcweir 
1142cdf0e10cSrcweir                 sTxt.Insert( ':', 0 );
1143cdf0e10cSrcweir                 sTxt.Insert( rAttr.GetPrimaryKey(), 0 );
1144cdf0e10cSrcweir             }
1145cdf0e10cSrcweir             sTxt.InsertAscii( " XE \"", 0 );
1146cdf0e10cSrcweir             sTxt.InsertAscii( "\" " );
1147cdf0e10cSrcweir             break;
1148cdf0e10cSrcweir 
1149cdf0e10cSrcweir         case TOX_USER:
1150cdf0e10cSrcweir             ( sTxt.APPEND_CONST_ASC( "\" \\f \"" ) )
1151cdf0e10cSrcweir                 += (sal_Char)( 'A' + GetExport( ).GetId( *rAttr.GetTOXType() ) );
1152cdf0e10cSrcweir             // fall through - no break;
1153cdf0e10cSrcweir         case TOX_CONTENT:
1154cdf0e10cSrcweir             {
1155cdf0e10cSrcweir                 eType = ww::eTC;
1156cdf0e10cSrcweir                 sTxt.InsertAscii( " TC \"", 0 );
1157cdf0e10cSrcweir                 sal_uInt16 nLvl = rAttr.GetLevel();
1158cdf0e10cSrcweir                 if (nLvl > WW8ListManager::nMaxLevel)
1159cdf0e10cSrcweir                     nLvl = WW8ListManager::nMaxLevel;
1160cdf0e10cSrcweir 
1161cdf0e10cSrcweir                 ((sTxt.APPEND_CONST_ASC( "\" \\l " ))
1162cdf0e10cSrcweir                  += String::CreateFromInt32( nLvl )) += ' ';
1163cdf0e10cSrcweir             }
1164cdf0e10cSrcweir             break;
1165cdf0e10cSrcweir         default:
1166cdf0e10cSrcweir             ASSERT( !this, "Unhandled option for toc export" );
1167cdf0e10cSrcweir             break;
1168cdf0e10cSrcweir     }
1169cdf0e10cSrcweir 
1170cdf0e10cSrcweir     if ( sTxt.Len() )
1171cdf0e10cSrcweir         FieldVanish( sTxt, eType );
1172cdf0e10cSrcweir }
1173cdf0e10cSrcweir 
OutAttrWithRange(xub_StrLen nPos)1174cdf0e10cSrcweir int WW8SwAttrIter::OutAttrWithRange(xub_StrLen nPos)
1175cdf0e10cSrcweir {
1176cdf0e10cSrcweir     int nRet = 0;
1177cdf0e10cSrcweir     if ( const SwpHints* pTxtAttrs = rNd.GetpSwpHints() )
1178cdf0e10cSrcweir     {
1179cdf0e10cSrcweir         m_rExport.m_aCurrentCharPropStarts.push( nPos );
1180cdf0e10cSrcweir         const xub_StrLen* pEnd;
1181cdf0e10cSrcweir         for ( sal_uInt16 i = 0; i < pTxtAttrs->Count(); ++i )
1182cdf0e10cSrcweir         {
1183cdf0e10cSrcweir             const SwTxtAttr* pHt = (*pTxtAttrs)[i];
1184cdf0e10cSrcweir             const SfxPoolItem* pItem = &pHt->GetAttr();
1185cdf0e10cSrcweir             switch ( pItem->Which() )
1186cdf0e10cSrcweir             {
1187cdf0e10cSrcweir                 case RES_TXTATR_INETFMT:
1188cdf0e10cSrcweir                     if ( nPos == *pHt->GetStart() )
1189cdf0e10cSrcweir                     {
1190cdf0e10cSrcweir                         const SwFmtINetFmt *rINet = static_cast< const SwFmtINetFmt* >( pItem );
1191cdf0e10cSrcweir                         if ( m_rExport.AttrOutput().StartURL( rINet->GetValue(), rINet->GetTargetFrame() ) )
1192cdf0e10cSrcweir                             ++nRet;
1193cdf0e10cSrcweir                     }
119469a74367SOliver-Rainer Wittmann                     if ( 0 != ( pEnd = pHt->End() ) && nPos == *pEnd )
1195cdf0e10cSrcweir                     {
1196cdf0e10cSrcweir                         if ( m_rExport.AttrOutput().EndURL() )
1197cdf0e10cSrcweir                             --nRet;
1198cdf0e10cSrcweir                     }
1199cdf0e10cSrcweir                     break;
1200cdf0e10cSrcweir                 case RES_TXTATR_REFMARK:
1201cdf0e10cSrcweir                     if ( nPos == *pHt->GetStart() )
1202cdf0e10cSrcweir                     {
1203cdf0e10cSrcweir                         OutSwFmtRefMark( *static_cast< const SwFmtRefMark* >( pItem ), true );
1204cdf0e10cSrcweir                         ++nRet;
1205cdf0e10cSrcweir                     }
120669a74367SOliver-Rainer Wittmann                     if ( 0 != ( pEnd = pHt->End() ) && nPos == *pEnd )
1207cdf0e10cSrcweir                     {
1208cdf0e10cSrcweir                         OutSwFmtRefMark( *static_cast< const SwFmtRefMark* >( pItem ), false );
1209cdf0e10cSrcweir                         --nRet;
1210cdf0e10cSrcweir                     }
1211cdf0e10cSrcweir                     break;
1212cdf0e10cSrcweir                 case RES_TXTATR_TOXMARK:
1213cdf0e10cSrcweir                     if ( nPos == *pHt->GetStart() )
1214cdf0e10cSrcweir                         m_rExport.AttrOutput().TOXMark( rNd, *static_cast< const SwTOXMark* >( pItem ) );
1215cdf0e10cSrcweir                     break;
1216cdf0e10cSrcweir                 case RES_TXTATR_CJK_RUBY:
1217cdf0e10cSrcweir                     if ( nPos == *pHt->GetStart() )
1218cdf0e10cSrcweir                     {
1219cdf0e10cSrcweir                         m_rExport.AttrOutput().StartRuby( rNd, *static_cast< const SwFmtRuby* >( pItem ) );
1220cdf0e10cSrcweir                         ++nRet;
1221cdf0e10cSrcweir                     }
122269a74367SOliver-Rainer Wittmann                     if ( 0 != ( pEnd = pHt->End() ) && nPos == *pEnd )
1223cdf0e10cSrcweir                     {
1224cdf0e10cSrcweir                         m_rExport.AttrOutput().EndRuby();
1225cdf0e10cSrcweir                         --nRet;
1226cdf0e10cSrcweir                     }
1227cdf0e10cSrcweir                     break;
1228cdf0e10cSrcweir             }
1229cdf0e10cSrcweir         }
1230cdf0e10cSrcweir         m_rExport.m_aCurrentCharPropStarts.pop(); // HasTextItem nur in dem obigen Bereich erlaubt
1231cdf0e10cSrcweir     }
1232cdf0e10cSrcweir     return nRet;
1233cdf0e10cSrcweir }
1234cdf0e10cSrcweir 
IsRedlineAtEnd(xub_StrLen nEnd) const1235cdf0e10cSrcweir bool WW8SwAttrIter::IsRedlineAtEnd( xub_StrLen nEnd ) const
1236cdf0e10cSrcweir {
1237cdf0e10cSrcweir     bool bRet = false;
1238cdf0e10cSrcweir     // search next Redline
1239cdf0e10cSrcweir     for( sal_uInt16 nPos = nCurRedlinePos;
1240cdf0e10cSrcweir         nPos < m_rExport.pDoc->GetRedlineTbl().Count(); ++nPos )
1241cdf0e10cSrcweir     {
1242cdf0e10cSrcweir         const SwPosition* pEnd = m_rExport.pDoc->GetRedlineTbl()[ nPos ]->End();
1243cdf0e10cSrcweir         if( pEnd->nNode == rNd )
1244cdf0e10cSrcweir         {
1245cdf0e10cSrcweir             if( pEnd->nContent.GetIndex() == nEnd )
1246cdf0e10cSrcweir             {
1247cdf0e10cSrcweir                 bRet = true;
1248cdf0e10cSrcweir                 break;
1249cdf0e10cSrcweir             }
1250cdf0e10cSrcweir         }
1251cdf0e10cSrcweir         else
1252cdf0e10cSrcweir             break;
1253cdf0e10cSrcweir     }
1254cdf0e10cSrcweir     return bRet;
1255cdf0e10cSrcweir }
1256cdf0e10cSrcweir 
GetRedline(xub_StrLen nPos)1257cdf0e10cSrcweir const SwRedlineData* WW8SwAttrIter::GetRedline( xub_StrLen nPos )
1258cdf0e10cSrcweir {
1259cdf0e10cSrcweir     if( pCurRedline )
1260cdf0e10cSrcweir     {
1261cdf0e10cSrcweir         const SwPosition* pEnd = pCurRedline->End();
1262cdf0e10cSrcweir         if( pEnd->nNode == rNd &&
1263cdf0e10cSrcweir             pEnd->nContent.GetIndex() <= nPos )
1264cdf0e10cSrcweir         {
1265cdf0e10cSrcweir             pCurRedline = 0;
1266cdf0e10cSrcweir             ++nCurRedlinePos;
1267cdf0e10cSrcweir         }
1268cdf0e10cSrcweir         else
1269cdf0e10cSrcweir         {
1270cdf0e10cSrcweir             // write data of current redline
1271cdf0e10cSrcweir             return &( pCurRedline->GetRedlineData() );
1272cdf0e10cSrcweir         }
1273cdf0e10cSrcweir     }
1274cdf0e10cSrcweir 
1275cdf0e10cSrcweir     if( !pCurRedline )
1276cdf0e10cSrcweir     {
1277cdf0e10cSrcweir         // search next Redline
1278cdf0e10cSrcweir         for( ; nCurRedlinePos < m_rExport.pDoc->GetRedlineTbl().Count();
1279cdf0e10cSrcweir                 ++nCurRedlinePos )
1280cdf0e10cSrcweir         {
1281cdf0e10cSrcweir             const SwRedline* pRedl = m_rExport.pDoc->GetRedlineTbl()[ nCurRedlinePos ];
1282cdf0e10cSrcweir 
1283cdf0e10cSrcweir             const SwPosition* pStt = pRedl->Start();
1284cdf0e10cSrcweir             const SwPosition* pEnd = pStt == pRedl->GetPoint()
1285cdf0e10cSrcweir                                         ? pRedl->GetMark()
1286cdf0e10cSrcweir                                         : pRedl->GetPoint();
1287cdf0e10cSrcweir 
1288cdf0e10cSrcweir             if( pStt->nNode == rNd )
1289cdf0e10cSrcweir             {
1290cdf0e10cSrcweir                 if( pStt->nContent.GetIndex() >= nPos )
1291cdf0e10cSrcweir                 {
1292cdf0e10cSrcweir                     if( pStt->nContent.GetIndex() == nPos )
1293cdf0e10cSrcweir                     {
1294cdf0e10cSrcweir                         // write data of this redline
1295cdf0e10cSrcweir                         pCurRedline = pRedl;
1296cdf0e10cSrcweir                         return &( pCurRedline->GetRedlineData() );
1297cdf0e10cSrcweir                     }
1298cdf0e10cSrcweir                     break;
1299cdf0e10cSrcweir                 }
1300cdf0e10cSrcweir             }
1301cdf0e10cSrcweir             else
1302cdf0e10cSrcweir                 break;
1303cdf0e10cSrcweir 
1304cdf0e10cSrcweir             if( pEnd->nNode == rNd &&
1305cdf0e10cSrcweir                 pEnd->nContent.GetIndex() < nPos )
1306cdf0e10cSrcweir             {
1307cdf0e10cSrcweir                 pCurRedline = pRedl;
1308cdf0e10cSrcweir                 break;
1309cdf0e10cSrcweir             }
1310cdf0e10cSrcweir         }
1311cdf0e10cSrcweir     }
1312cdf0e10cSrcweir     return NULL;
1313cdf0e10cSrcweir }
1314cdf0e10cSrcweir 
1315cdf0e10cSrcweir /*  */
1316cdf0e10cSrcweir 
GetCurrentPageDirection() const1317cdf0e10cSrcweir short MSWordExportBase::GetCurrentPageDirection() const
1318cdf0e10cSrcweir {
1319cdf0e10cSrcweir     const SwFrmFmt &rFmt = pAktPageDesc
1320cdf0e10cSrcweir                     ? pAktPageDesc->GetMaster()
1321cdf0e10cSrcweir                     : const_cast<const SwDoc *>( pDoc )->GetPageDesc( 0 ).GetMaster();
1322cdf0e10cSrcweir     return rFmt.GetFrmDir().GetValue();
1323cdf0e10cSrcweir }
1324cdf0e10cSrcweir 
GetDefaultFrameDirection() const1325cdf0e10cSrcweir short MSWordExportBase::GetDefaultFrameDirection( ) const
1326cdf0e10cSrcweir {
1327cdf0e10cSrcweir     short nDir = FRMDIR_ENVIRONMENT;
1328cdf0e10cSrcweir 
1329cdf0e10cSrcweir     if ( bOutPageDescs )
1330cdf0e10cSrcweir         nDir = GetCurrentPageDirection(  );
1331cdf0e10cSrcweir     else if ( pOutFmtNode )
1332cdf0e10cSrcweir     {
1333cdf0e10cSrcweir         if ( bOutFlyFrmAttrs ) //frame
1334cdf0e10cSrcweir         {
1335cdf0e10cSrcweir             nDir = TrueFrameDirection( *( const SwFrmFmt * ) pOutFmtNode );
1336cdf0e10cSrcweir         }
1337cdf0e10cSrcweir         else if ( pOutFmtNode->ISA( SwCntntNode ) )    //pagagraph
1338cdf0e10cSrcweir         {
1339cdf0e10cSrcweir             const SwCntntNode *pNd = ( const SwCntntNode * ) pOutFmtNode;
1340cdf0e10cSrcweir             SwPosition aPos( *pNd );
1341cdf0e10cSrcweir             nDir = pDoc->GetTextDirection( aPos );
1342cdf0e10cSrcweir         }
1343cdf0e10cSrcweir         else if ( pOutFmtNode->ISA( SwTxtFmtColl ) )
1344cdf0e10cSrcweir             nDir = FRMDIR_HORI_LEFT_TOP;    //what else can we do :-(
1345cdf0e10cSrcweir     }
1346cdf0e10cSrcweir 
1347cdf0e10cSrcweir     if ( nDir == FRMDIR_ENVIRONMENT )
1348cdf0e10cSrcweir         nDir = FRMDIR_HORI_LEFT_TOP;        //Set something
1349cdf0e10cSrcweir 
1350cdf0e10cSrcweir     return nDir;
1351cdf0e10cSrcweir }
1352cdf0e10cSrcweir 
TrueFrameDirection(const SwFrmFmt & rFlyFmt) const1353cdf0e10cSrcweir short MSWordExportBase::TrueFrameDirection( const SwFrmFmt &rFlyFmt ) const
1354cdf0e10cSrcweir {
1355cdf0e10cSrcweir     const SwFrmFmt *pFlyFmt = &rFlyFmt;
1356cdf0e10cSrcweir     const SvxFrameDirectionItem* pItem = 0;
1357cdf0e10cSrcweir     while ( pFlyFmt )
1358cdf0e10cSrcweir     {
1359cdf0e10cSrcweir         pItem = &pFlyFmt->GetFrmDir();
1360cdf0e10cSrcweir         if ( FRMDIR_ENVIRONMENT == pItem->GetValue() )
1361cdf0e10cSrcweir         {
1362cdf0e10cSrcweir             pItem = 0;
1363cdf0e10cSrcweir             const SwFmtAnchor* pAnchor = &pFlyFmt->GetAnchor();
1364cdf0e10cSrcweir             if ((FLY_AT_PAGE != pAnchor->GetAnchorId()) &&
1365cdf0e10cSrcweir                 pAnchor->GetCntntAnchor() )
1366cdf0e10cSrcweir             {
1367cdf0e10cSrcweir                 pFlyFmt = pAnchor->GetCntntAnchor()->nNode.GetNode().GetFlyFmt();
1368cdf0e10cSrcweir             }
1369cdf0e10cSrcweir             else
1370cdf0e10cSrcweir                 pFlyFmt = 0;
1371cdf0e10cSrcweir         }
1372cdf0e10cSrcweir         else
1373cdf0e10cSrcweir             pFlyFmt = 0;
1374cdf0e10cSrcweir     }
1375cdf0e10cSrcweir 
1376cdf0e10cSrcweir     short nRet;
1377cdf0e10cSrcweir     if ( pItem )
1378cdf0e10cSrcweir         nRet = pItem->GetValue();
1379cdf0e10cSrcweir     else
1380cdf0e10cSrcweir         nRet = GetCurrentPageDirection();
1381cdf0e10cSrcweir 
1382cdf0e10cSrcweir     ASSERT( nRet != FRMDIR_ENVIRONMENT, "leaving with environment direction" );
1383cdf0e10cSrcweir     return nRet;
1384cdf0e10cSrcweir }
1385cdf0e10cSrcweir 
GetCurrentPageBgBrush() const1386cdf0e10cSrcweir const SvxBrushItem* WW8Export::GetCurrentPageBgBrush() const
1387cdf0e10cSrcweir {
1388cdf0e10cSrcweir     const SwFrmFmt  &rFmt = pAktPageDesc
1389cdf0e10cSrcweir                     ? pAktPageDesc->GetMaster()
1390cdf0e10cSrcweir                     : const_cast<const SwDoc *>(pDoc)->GetPageDesc(0).GetMaster();
1391cdf0e10cSrcweir 
1392cdf0e10cSrcweir     const SfxPoolItem* pItem = 0;
1393cdf0e10cSrcweir     //If not set, or "no fill", get real bg
1394cdf0e10cSrcweir     SfxItemState eState = rFmt.GetItemState(RES_BACKGROUND, true, &pItem);
1395cdf0e10cSrcweir 
1396cdf0e10cSrcweir     const SvxBrushItem* pRet = (const SvxBrushItem*)pItem;
1397cdf0e10cSrcweir     if (SFX_ITEM_SET != eState || (!pRet->GetGraphic() &&
1398cdf0e10cSrcweir         pRet->GetColor() == COL_TRANSPARENT))
1399cdf0e10cSrcweir     {
1400cdf0e10cSrcweir         pRet = &(DefaultItemGet<SvxBrushItem>(*pDoc,RES_BACKGROUND));
1401cdf0e10cSrcweir     }
1402cdf0e10cSrcweir     return pRet;
1403cdf0e10cSrcweir }
1404cdf0e10cSrcweir 
TrueFrameBgBrush(const SwFrmFmt & rFlyFmt) const1405cdf0e10cSrcweir SvxBrushItem WW8Export::TrueFrameBgBrush(const SwFrmFmt &rFlyFmt) const
1406cdf0e10cSrcweir {
1407cdf0e10cSrcweir     const SwFrmFmt *pFlyFmt = &rFlyFmt;
1408cdf0e10cSrcweir     const SvxBrushItem* pRet = 0;
1409cdf0e10cSrcweir 
1410cdf0e10cSrcweir     while (pFlyFmt)
1411cdf0e10cSrcweir     {
1412cdf0e10cSrcweir         //If not set, or "no fill", get real bg
1413cdf0e10cSrcweir         const SfxPoolItem* pItem = 0;
1414cdf0e10cSrcweir         SfxItemState eState =
1415cdf0e10cSrcweir             pFlyFmt->GetItemState(RES_BACKGROUND, true, &pItem);
1416cdf0e10cSrcweir         pRet = (const SvxBrushItem*)pItem;
1417cdf0e10cSrcweir         if (SFX_ITEM_SET != eState || (!pRet->GetGraphic() &&
1418cdf0e10cSrcweir             pRet->GetColor() == COL_TRANSPARENT))
1419cdf0e10cSrcweir         {
1420cdf0e10cSrcweir             pRet = 0;
1421cdf0e10cSrcweir             const SwFmtAnchor* pAnchor = &pFlyFmt->GetAnchor();
1422cdf0e10cSrcweir             if ((FLY_AT_PAGE != pAnchor->GetAnchorId()) &&
1423cdf0e10cSrcweir                 pAnchor->GetCntntAnchor())
1424cdf0e10cSrcweir             {
1425cdf0e10cSrcweir                 pFlyFmt =
1426cdf0e10cSrcweir                     pAnchor->GetCntntAnchor()->nNode.GetNode().GetFlyFmt();
1427cdf0e10cSrcweir             }
1428cdf0e10cSrcweir             else
1429cdf0e10cSrcweir                 pFlyFmt = 0;
1430cdf0e10cSrcweir         }
1431cdf0e10cSrcweir         else
1432cdf0e10cSrcweir             pFlyFmt = 0;
1433cdf0e10cSrcweir     }
1434cdf0e10cSrcweir 
1435cdf0e10cSrcweir     if (!pRet)
1436cdf0e10cSrcweir         pRet = GetCurrentPageBgBrush();
1437cdf0e10cSrcweir 
1438cdf0e10cSrcweir     const Color aTmpColor( COL_WHITE );
1439cdf0e10cSrcweir     SvxBrushItem aRet( aTmpColor, RES_BACKGROUND );
1440cdf0e10cSrcweir     if (pRet && (pRet->GetGraphic() ||( pRet->GetColor() != COL_TRANSPARENT)))
1441cdf0e10cSrcweir         aRet = *pRet;
1442cdf0e10cSrcweir 
1443cdf0e10cSrcweir     return aRet;
1444cdf0e10cSrcweir }
1445cdf0e10cSrcweir 
1446cdf0e10cSrcweir 
1447cdf0e10cSrcweir /*
1448cdf0e10cSrcweir Convert characters that need to be converted, the basic replacements and the
1449cdf0e10cSrcweir ridicously complicated title case attribute mapping to hardcoded upper case
1450cdf0e10cSrcweir because word doesn't have the feature
1451cdf0e10cSrcweir */
GetSnippet(const String & rStr,xub_StrLen nAktPos,xub_StrLen nLen) const1452cdf0e10cSrcweir String WW8SwAttrIter::GetSnippet(const String &rStr, xub_StrLen nAktPos,
1453cdf0e10cSrcweir     xub_StrLen nLen) const
1454cdf0e10cSrcweir {
1455cdf0e10cSrcweir     String aSnippet(rStr, nAktPos, nLen);
1456cdf0e10cSrcweir     if (!nLen)
1457cdf0e10cSrcweir         return aSnippet;
1458cdf0e10cSrcweir 
1459cdf0e10cSrcweir     // 0x0a     ( Hard Line Break ) -> 0x0b
1460cdf0e10cSrcweir     // 0xad     ( soft hyphen )     -> 0x1f
1461cdf0e10cSrcweir     // 0x2011   ( hard hyphen )     -> 0x1e
1462cdf0e10cSrcweir     aSnippet.SearchAndReplaceAll(0x0A, 0x0B);
1463cdf0e10cSrcweir     aSnippet.SearchAndReplaceAll(CHAR_HARDHYPHEN, 0x1e);
1464cdf0e10cSrcweir     aSnippet.SearchAndReplaceAll(CHAR_SOFTHYPHEN, 0x1f);
1465cdf0e10cSrcweir 
1466cdf0e10cSrcweir     m_rExport.m_aCurrentCharPropStarts.push( nAktPos );
1467cdf0e10cSrcweir     const SfxPoolItem &rItem = GetItem(RES_CHRATR_CASEMAP);
1468cdf0e10cSrcweir 
1469cdf0e10cSrcweir     if (SVX_CASEMAP_TITEL == ((const SvxCaseMapItem&)rItem).GetValue())
1470cdf0e10cSrcweir     {
1471cdf0e10cSrcweir         sal_uInt16 nScriptType = i18n::ScriptType::LATIN;
1472cdf0e10cSrcweir         if (pBreakIt->GetBreakIter().is())
1473cdf0e10cSrcweir             nScriptType = pBreakIt->GetBreakIter()->getScriptType(aSnippet, 0);
1474cdf0e10cSrcweir 
1475cdf0e10cSrcweir         LanguageType nLanguage;
1476cdf0e10cSrcweir         switch (nScriptType)
1477cdf0e10cSrcweir         {
1478cdf0e10cSrcweir         case i18n::ScriptType::ASIAN:
1479cdf0e10cSrcweir                 nLanguage = ((const SvxLanguageItem&)GetItem(RES_CHRATR_CJK_LANGUAGE)).GetLanguage();
1480cdf0e10cSrcweir                 break;
1481cdf0e10cSrcweir         case i18n::ScriptType::COMPLEX:
1482cdf0e10cSrcweir                 nLanguage = ((const SvxLanguageItem&)GetItem(RES_CHRATR_CTL_LANGUAGE)).GetLanguage();
1483cdf0e10cSrcweir                 break;
1484cdf0e10cSrcweir         case i18n::ScriptType::LATIN:
1485cdf0e10cSrcweir             default:
1486cdf0e10cSrcweir                 nLanguage = ((const SvxLanguageItem&)GetItem(RES_CHRATR_LANGUAGE)).GetLanguage();
1487cdf0e10cSrcweir                 break;
1488cdf0e10cSrcweir         }
1489cdf0e10cSrcweir 
1490cdf0e10cSrcweir         SvxFont aFontHelper;
1491cdf0e10cSrcweir         aFontHelper.SetCaseMap(SVX_CASEMAP_TITEL);
1492cdf0e10cSrcweir         aFontHelper.SetLanguage(nLanguage);
1493cdf0e10cSrcweir         aSnippet = aFontHelper.CalcCaseMap(aSnippet);
1494cdf0e10cSrcweir 
1495cdf0e10cSrcweir         //If we weren't at the begin of a word undo the case change.
1496cdf0e10cSrcweir         //not done before doing the casemap because the sequence might start
1497cdf0e10cSrcweir         //with whitespace
1498cdf0e10cSrcweir         if (pBreakIt->GetBreakIter().is() && !pBreakIt->GetBreakIter()->isBeginWord(
1499cdf0e10cSrcweir             rStr, nAktPos, pBreakIt->GetLocale(nLanguage),
1500cdf0e10cSrcweir             i18n::WordType::ANYWORD_IGNOREWHITESPACES ) )
1501cdf0e10cSrcweir         {
1502cdf0e10cSrcweir             aSnippet.SetChar(0, rStr.GetChar(nAktPos));
1503cdf0e10cSrcweir         }
1504cdf0e10cSrcweir     }
1505cdf0e10cSrcweir     m_rExport.m_aCurrentCharPropStarts.pop();
1506cdf0e10cSrcweir 
1507cdf0e10cSrcweir     return aSnippet;
1508cdf0e10cSrcweir }
1509cdf0e10cSrcweir 
1510cdf0e10cSrcweir /** Delivers the right paragraph style
1511cdf0e10cSrcweir 
1512cdf0e10cSrcweir     Because of the different style handling for delete operations,
1513cdf0e10cSrcweir     the track changes have to be analysed. A deletion, starting in paragraph A
1514cdf0e10cSrcweir     with style A, ending in paragraph B with style B, needs a hack.
1515cdf0e10cSrcweir */
lcl_getFormatCollection(MSWordExportBase & rExport,const SwTxtNode * pTxtNode)1516cdf0e10cSrcweir static SwTxtFmtColl& lcl_getFormatCollection( MSWordExportBase& rExport, const SwTxtNode* pTxtNode )
1517cdf0e10cSrcweir {
1518cdf0e10cSrcweir     sal_uInt16 nPos = 0;
1519cdf0e10cSrcweir     sal_uInt16 nMax = rExport.pDoc->GetRedlineTbl().Count();
1520cdf0e10cSrcweir     while( nPos < nMax )
1521cdf0e10cSrcweir     {
1522cdf0e10cSrcweir         const SwRedline* pRedl = rExport.pDoc->GetRedlineTbl()[ nPos++ ];
1523cdf0e10cSrcweir         const SwPosition* pStt = pRedl->Start();
1524cdf0e10cSrcweir         const SwPosition* pEnd = pStt == pRedl->GetPoint()
1525cdf0e10cSrcweir                                     ? pRedl->GetMark()
1526cdf0e10cSrcweir                                     : pRedl->GetPoint();
1527cdf0e10cSrcweir         // Looking for deletions, which ends in current pTxtNode
1528cdf0e10cSrcweir         if( nsRedlineType_t::REDLINE_DELETE == pRedl->GetRedlineData().GetType() &&
1529cdf0e10cSrcweir             pEnd->nNode == *pTxtNode && pStt->nNode != *pTxtNode &&
1530cdf0e10cSrcweir             pStt->nNode.GetNode().IsTxtNode() )
1531cdf0e10cSrcweir         {
1532cdf0e10cSrcweir             pTxtNode = pStt->nNode.GetNode().GetTxtNode();
1533cdf0e10cSrcweir             nMax = nPos;
1534cdf0e10cSrcweir             nPos = 0;
1535cdf0e10cSrcweir         }
1536cdf0e10cSrcweir     }
1537cdf0e10cSrcweir     return static_cast<SwTxtFmtColl&>( pTxtNode->GetAnyFmtColl() );
1538cdf0e10cSrcweir }
1539cdf0e10cSrcweir 
FormatDrop(const SwTxtNode & rNode,const SwFmtDrop & rSwFmtDrop,sal_uInt16 nStyle,ww8::WW8TableNodeInfo::Pointer_t pTextNodeInfo,ww8::WW8TableNodeInfoInner::Pointer_t pTextNodeInfoInner)1540cdf0e10cSrcweir void WW8AttributeOutput::FormatDrop( const SwTxtNode& rNode, const SwFmtDrop &rSwFmtDrop, sal_uInt16 nStyle,
1541cdf0e10cSrcweir         ww8::WW8TableNodeInfo::Pointer_t pTextNodeInfo, ww8::WW8TableNodeInfoInner::Pointer_t pTextNodeInfoInner )
1542cdf0e10cSrcweir {
1543cdf0e10cSrcweir     short nDropLines = rSwFmtDrop.GetLines();
1544cdf0e10cSrcweir     short nDistance = rSwFmtDrop.GetDistance();
1545cdf0e10cSrcweir     int rFontHeight, rDropHeight, rDropDescent;
1546cdf0e10cSrcweir 
1547cdf0e10cSrcweir     SVBT16 nSty;
1548cdf0e10cSrcweir     ShortToSVBT16( nStyle, nSty );
1549cdf0e10cSrcweir     m_rWW8Export.pO->Insert( (sal_uInt8*)&nSty, 2, m_rWW8Export.pO->Count() );     // Style #
1550cdf0e10cSrcweir 
1551cdf0e10cSrcweir     if ( m_rWW8Export.bWrtWW8 )
1552cdf0e10cSrcweir     {
1553cdf0e10cSrcweir         m_rWW8Export.InsUInt16( NS_sprm::LN_PPc );            // Alignment (sprmPPc)
1554cdf0e10cSrcweir         m_rWW8Export.pO->Insert( 0x20, m_rWW8Export.pO->Count() );
1555cdf0e10cSrcweir 
1556cdf0e10cSrcweir         m_rWW8Export.InsUInt16( NS_sprm::LN_PWr );            // Wrapping (sprmPWr)
1557cdf0e10cSrcweir         m_rWW8Export.pO->Insert( 0x02, m_rWW8Export.pO->Count() );
1558cdf0e10cSrcweir 
1559cdf0e10cSrcweir         m_rWW8Export.InsUInt16( NS_sprm::LN_PDcs );            // Dropcap (sprmPDcs)
1560cdf0e10cSrcweir         int nDCS = ( nDropLines << 3 ) | 0x01;
1561cdf0e10cSrcweir         m_rWW8Export.InsUInt16( static_cast< sal_uInt16 >( nDCS ) );
1562cdf0e10cSrcweir 
1563cdf0e10cSrcweir         m_rWW8Export.InsUInt16( NS_sprm::LN_PDxaFromText );            // Distance from text (sprmPDxaFromText)
1564cdf0e10cSrcweir         m_rWW8Export.InsUInt16( nDistance );
1565cdf0e10cSrcweir 
1566cdf0e10cSrcweir         if ( rNode.GetDropSize( rFontHeight, rDropHeight, rDropDescent ) )
1567cdf0e10cSrcweir         {
1568cdf0e10cSrcweir             m_rWW8Export.InsUInt16( NS_sprm::LN_PDyaLine );            // Line spacing
1569cdf0e10cSrcweir             m_rWW8Export.InsUInt16( static_cast< sal_uInt16 >( -rDropHeight ) );
1570cdf0e10cSrcweir             m_rWW8Export.InsUInt16( 0 );
1571cdf0e10cSrcweir         }
1572cdf0e10cSrcweir     }
1573cdf0e10cSrcweir     else
1574cdf0e10cSrcweir     {
1575cdf0e10cSrcweir         m_rWW8Export.pO->Insert( 29, m_rWW8Export.pO->Count() );    // Alignment (sprmPPc)
1576cdf0e10cSrcweir         m_rWW8Export.pO->Insert( 0x20, m_rWW8Export.pO->Count() );
1577cdf0e10cSrcweir 
1578cdf0e10cSrcweir         m_rWW8Export.pO->Insert( 37, m_rWW8Export.pO->Count() );    // Wrapping (sprmPWr)
1579cdf0e10cSrcweir         m_rWW8Export.pO->Insert( 0x02, m_rWW8Export.pO->Count() );
1580cdf0e10cSrcweir 
1581cdf0e10cSrcweir         m_rWW8Export.pO->Insert( 46, m_rWW8Export.pO->Count() );    // Dropcap (sprmPDcs)
1582cdf0e10cSrcweir         int nDCS = ( nDropLines << 3 ) | 0x01;
1583cdf0e10cSrcweir         m_rWW8Export.InsUInt16( static_cast< sal_uInt16 >( nDCS ) );
1584cdf0e10cSrcweir 
1585cdf0e10cSrcweir         m_rWW8Export.pO->Insert( 49, m_rWW8Export.pO->Count() );      // Distance from text (sprmPDxaFromText)
1586cdf0e10cSrcweir         m_rWW8Export.InsUInt16( nDistance );
1587cdf0e10cSrcweir 
1588cdf0e10cSrcweir         if (rNode.GetDropSize(rFontHeight, rDropHeight, rDropDescent))
1589cdf0e10cSrcweir         {
1590cdf0e10cSrcweir             m_rWW8Export.pO->Insert( 20, m_rWW8Export.pO->Count() );  // Line spacing
1591cdf0e10cSrcweir             m_rWW8Export.InsUInt16( static_cast< sal_uInt16 >( -rDropHeight ) );
1592cdf0e10cSrcweir             m_rWW8Export.InsUInt16( 0 );
1593cdf0e10cSrcweir         }
1594cdf0e10cSrcweir     }
1595cdf0e10cSrcweir 
1596cdf0e10cSrcweir     m_rWW8Export.WriteCR( pTextNodeInfoInner );
1597cdf0e10cSrcweir 
1598cdf0e10cSrcweir     if ( pTextNodeInfo.get() != NULL )
1599cdf0e10cSrcweir     {
1600cdf0e10cSrcweir #ifdef DEBUG
1601cdf0e10cSrcweir         ::std::clog << pTextNodeInfo->toString() << ::std::endl;
1602cdf0e10cSrcweir #endif
1603cdf0e10cSrcweir 
1604cdf0e10cSrcweir         TableInfoCell( pTextNodeInfoInner );
1605cdf0e10cSrcweir     }
1606cdf0e10cSrcweir 
1607cdf0e10cSrcweir     m_rWW8Export.pPapPlc->AppendFkpEntry( m_rWW8Export.Strm().Tell(), m_rWW8Export.pO->Count(), m_rWW8Export.pO->GetData() );
1608cdf0e10cSrcweir     m_rWW8Export.pO->Remove( 0, m_rWW8Export.pO->Count() );
1609cdf0e10cSrcweir 
1610cdf0e10cSrcweir     if ( rNode.GetDropSize( rFontHeight, rDropHeight, rDropDescent ) )
1611cdf0e10cSrcweir     {
1612cdf0e10cSrcweir         if ( m_rWW8Export.bWrtWW8 )
1613cdf0e10cSrcweir         {
1614cdf0e10cSrcweir             const SwCharFmt *pSwCharFmt = rSwFmtDrop.GetCharFmt();
1615cdf0e10cSrcweir             if ( pSwCharFmt )
1616cdf0e10cSrcweir             {
1617cdf0e10cSrcweir                 m_rWW8Export.InsUInt16( NS_sprm::LN_CIstd );
1618cdf0e10cSrcweir                 m_rWW8Export.InsUInt16( m_rWW8Export.GetId( *pSwCharFmt ) );
1619cdf0e10cSrcweir             }
1620cdf0e10cSrcweir 
1621cdf0e10cSrcweir             m_rWW8Export.InsUInt16( NS_sprm::LN_CHpsPos );            // Lower the chars
1622cdf0e10cSrcweir             m_rWW8Export.InsUInt16( static_cast< sal_uInt16 >( -((nDropLines - 1)*rDropDescent) / 10 ) );
1623cdf0e10cSrcweir 
1624cdf0e10cSrcweir             m_rWW8Export.InsUInt16( NS_sprm::LN_CHps );            // Font Size
1625cdf0e10cSrcweir             m_rWW8Export.InsUInt16( static_cast< sal_uInt16 >( rFontHeight / 10 ) );
1626cdf0e10cSrcweir         }
1627cdf0e10cSrcweir         else
1628cdf0e10cSrcweir         {
1629cdf0e10cSrcweir             const SwCharFmt *pSwCharFmt = rSwFmtDrop.GetCharFmt();
1630cdf0e10cSrcweir             if ( pSwCharFmt )
1631cdf0e10cSrcweir             {
1632cdf0e10cSrcweir                 m_rWW8Export.InsUInt16( 80 );
1633cdf0e10cSrcweir                 m_rWW8Export.InsUInt16( m_rWW8Export.GetId( *pSwCharFmt ) );
1634cdf0e10cSrcweir             }
1635cdf0e10cSrcweir 
1636cdf0e10cSrcweir             m_rWW8Export.pO->Insert( 101, m_rWW8Export.pO->Count() );      // Lower the chars
1637cdf0e10cSrcweir             m_rWW8Export.InsUInt16( static_cast< sal_uInt16 >( -((nDropLines - 1)*rDropDescent) / 10 ) );
1638cdf0e10cSrcweir 
1639cdf0e10cSrcweir             m_rWW8Export.pO->Insert( 99, m_rWW8Export.pO->Count() );      // Font Size
1640cdf0e10cSrcweir             m_rWW8Export.InsUInt16( static_cast< sal_uInt16 >( rFontHeight / 10 ) );
1641cdf0e10cSrcweir         }
1642cdf0e10cSrcweir     }
1643cdf0e10cSrcweir 
1644cdf0e10cSrcweir     m_rWW8Export.pChpPlc->AppendFkpEntry( m_rWW8Export.Strm().Tell(), m_rWW8Export.pO->Count(), m_rWW8Export.pO->GetData() );
1645cdf0e10cSrcweir     m_rWW8Export.pO->Remove( 0, m_rWW8Export.pO->Count() );
1646cdf0e10cSrcweir }
1647cdf0e10cSrcweir 
GetNextPos(WW8SwAttrIter * aAttrIter,const SwTxtNode & rNode,xub_StrLen nAktPos)1648cdf0e10cSrcweir xub_StrLen MSWordExportBase::GetNextPos( WW8SwAttrIter* aAttrIter, const SwTxtNode& rNode, xub_StrLen nAktPos  )
1649cdf0e10cSrcweir {
1650cdf0e10cSrcweir     // Get the bookmarks for the normal run
1651cdf0e10cSrcweir     xub_StrLen nNextPos = aAttrIter->WhereNext();
1652cdf0e10cSrcweir     xub_StrLen nNextBookmark = nNextPos;
1653cdf0e10cSrcweir 
1654cdf0e10cSrcweir     if( nNextBookmark > nAktPos )//no need to search for bookmarks otherwise
1655cdf0e10cSrcweir     {
1656cdf0e10cSrcweir         GetSortedBookmarks( rNode, nAktPos, nNextBookmark - nAktPos );
1657cdf0e10cSrcweir         NearestBookmark( nNextBookmark, nAktPos, false );
1658cdf0e10cSrcweir     }
1659cdf0e10cSrcweir     return std::min( nNextPos, nNextBookmark );
1660cdf0e10cSrcweir }
1661cdf0e10cSrcweir 
UpdatePosition(WW8SwAttrIter * aAttrIter,xub_StrLen nAktPos,xub_StrLen)1662cdf0e10cSrcweir void MSWordExportBase::UpdatePosition( WW8SwAttrIter* aAttrIter, xub_StrLen nAktPos, xub_StrLen /*nEnd*/ )
1663cdf0e10cSrcweir {
1664cdf0e10cSrcweir     xub_StrLen nNextPos;
1665cdf0e10cSrcweir 
1666cdf0e10cSrcweir     // go to next attribute if no bookmark is found and if the next attribute position if at the current position
1667cdf0e10cSrcweir     bool bNextBookmark = NearestBookmark( nNextPos, nAktPos, true );
1668cdf0e10cSrcweir     if( !bNextBookmark && nAktPos >= aAttrIter->WhereNext() )
1669cdf0e10cSrcweir         aAttrIter->NextPos();
1670cdf0e10cSrcweir }
1671cdf0e10cSrcweir 
GetBookmarks(const SwTxtNode & rNd,const xub_StrLen nStt,const xub_StrLen nEnd,IMarkVector & rArr)16723b32dd21SOliver-Rainer Wittmann bool MSWordExportBase::GetBookmarks(
16733b32dd21SOliver-Rainer Wittmann     const SwTxtNode& rNd,
16743b32dd21SOliver-Rainer Wittmann     const xub_StrLen nStt,
16753b32dd21SOliver-Rainer Wittmann     const xub_StrLen nEnd,
16763b32dd21SOliver-Rainer Wittmann     IMarkVector& rArr )
1677cdf0e10cSrcweir {
1678cdf0e10cSrcweir     IDocumentMarkAccess* const pMarkAccess = pDoc->getIDocumentMarkAccess();
1679cdf0e10cSrcweir     sal_uLong nNd = rNd.GetIndex( );
1680cdf0e10cSrcweir 
1681*12ad4c42SOliver-Rainer Wittmann     const sal_Int32 nMarks = pMarkAccess->getAllMarksCount();
1682cdf0e10cSrcweir     for ( sal_Int32 i = 0; i < nMarks; i++ )
1683cdf0e10cSrcweir     {
1684*12ad4c42SOliver-Rainer Wittmann         IMark* pMark = ( pMarkAccess->getAllMarksBegin() + i )->get();
1685*12ad4c42SOliver-Rainer Wittmann 
1686*12ad4c42SOliver-Rainer Wittmann         if ( IDocumentMarkAccess::GetType( *(pMark) ) == IDocumentMarkAccess::ANNOTATIONMARK )
1687*12ad4c42SOliver-Rainer Wittmann         {
1688*12ad4c42SOliver-Rainer Wittmann             continue;
1689*12ad4c42SOliver-Rainer Wittmann         }
1690cdf0e10cSrcweir 
1691cdf0e10cSrcweir         // Only keep the bookmarks starting or ending in this node
1692cdf0e10cSrcweir         if ( pMark->GetMarkStart().nNode == nNd ||
1693cdf0e10cSrcweir              pMark->GetMarkEnd().nNode == nNd )
1694cdf0e10cSrcweir         {
16953b32dd21SOliver-Rainer Wittmann             // Keep only the bookmarks starting or ending in the snippet
16963b32dd21SOliver-Rainer Wittmann             const xub_StrLen nBStart = pMark->GetMarkStart().nContent.GetIndex();
16973b32dd21SOliver-Rainer Wittmann             const bool bIsStartOk = ( pMark->GetMarkStart().nNode == nNd ) && ( nBStart >= nStt ) && ( nBStart <= nEnd );
16983b32dd21SOliver-Rainer Wittmann             const xub_StrLen nBEnd = pMark->GetMarkEnd().nContent.GetIndex();
16993b32dd21SOliver-Rainer Wittmann             const bool bIsEndOk = ( pMark->GetMarkEnd().nNode == nNd ) && ( nBEnd >= nStt ) && ( nBEnd <= nEnd );
1700cdf0e10cSrcweir             if ( bIsStartOk || bIsEndOk )
17013b32dd21SOliver-Rainer Wittmann             {
1702dec99bbdSOliver-Rainer Wittmann                 rArr.push_back( pMark );
17033b32dd21SOliver-Rainer Wittmann             }
1704cdf0e10cSrcweir         }
1705cdf0e10cSrcweir     }
1706cdf0e10cSrcweir     return ( rArr.size() > 0 );
1707cdf0e10cSrcweir }
1708cdf0e10cSrcweir 
1709cdf0e10cSrcweir class CompareMarksEnd : public std::binary_function < const IMark *, const IMark *, bool >
1710cdf0e10cSrcweir {
1711cdf0e10cSrcweir public:
operator ()(const IMark * pOneB,const IMark * pTwoB) const1712cdf0e10cSrcweir     inline bool operator() ( const IMark * pOneB, const IMark * pTwoB ) const
1713cdf0e10cSrcweir     {
1714cdf0e10cSrcweir         xub_StrLen nOEnd = pOneB->GetMarkEnd().nContent.GetIndex();
1715cdf0e10cSrcweir         xub_StrLen nTEnd = pTwoB->GetMarkEnd().nContent.GetIndex();
1716cdf0e10cSrcweir 
1717cdf0e10cSrcweir         return nOEnd < nTEnd;
1718cdf0e10cSrcweir     }
1719cdf0e10cSrcweir };
1720cdf0e10cSrcweir 
NearestBookmark(xub_StrLen & rNearest,const xub_StrLen nAktPos,bool bNextPositionOnly)1721cdf0e10cSrcweir bool MSWordExportBase::NearestBookmark( xub_StrLen& rNearest, const xub_StrLen nAktPos, bool bNextPositionOnly )
1722cdf0e10cSrcweir {
1723cdf0e10cSrcweir     bool bHasBookmark = false;
1724cdf0e10cSrcweir 
1725cdf0e10cSrcweir     if ( m_rSortedMarksStart.size( ) > 0 )
1726cdf0e10cSrcweir     {
1727cdf0e10cSrcweir         IMark* pMarkStart = m_rSortedMarksStart.front();
1728cdf0e10cSrcweir         xub_StrLen nNext = pMarkStart->GetMarkStart().nContent.GetIndex();
1729cdf0e10cSrcweir         if( !bNextPositionOnly || (nNext > nAktPos ))
1730cdf0e10cSrcweir         {
1731cdf0e10cSrcweir             rNearest = nNext;
1732cdf0e10cSrcweir             bHasBookmark = true;
1733cdf0e10cSrcweir         }
1734cdf0e10cSrcweir     }
1735cdf0e10cSrcweir 
1736cdf0e10cSrcweir     if ( m_rSortedMarksEnd.size( ) > 0 )
1737cdf0e10cSrcweir     {
1738cdf0e10cSrcweir         IMark* pMarkEnd = m_rSortedMarksEnd[0];
1739cdf0e10cSrcweir         xub_StrLen nNext = pMarkEnd->GetMarkEnd().nContent.GetIndex();
1740cdf0e10cSrcweir         if( !bNextPositionOnly || nNext > nAktPos )
1741cdf0e10cSrcweir         {
1742cdf0e10cSrcweir             if ( !bHasBookmark )
1743cdf0e10cSrcweir                 rNearest = nNext;
1744cdf0e10cSrcweir             else
1745cdf0e10cSrcweir                 rNearest = std::min( rNearest, nNext );
1746cdf0e10cSrcweir             bHasBookmark = true;
1747cdf0e10cSrcweir         }
1748cdf0e10cSrcweir     }
1749cdf0e10cSrcweir 
1750cdf0e10cSrcweir     return bHasBookmark;
1751cdf0e10cSrcweir }
1752cdf0e10cSrcweir 
GetSortedBookmarks(const SwTxtNode & rNode,xub_StrLen nAktPos,xub_StrLen nLen)1753cdf0e10cSrcweir void MSWordExportBase::GetSortedBookmarks( const SwTxtNode& rNode, xub_StrLen nAktPos, xub_StrLen nLen )
1754cdf0e10cSrcweir {
1755cdf0e10cSrcweir     IMarkVector aMarksStart;
1756cdf0e10cSrcweir     if ( GetBookmarks( rNode, nAktPos, nAktPos + nLen, aMarksStart ) )
1757cdf0e10cSrcweir     {
1758cdf0e10cSrcweir         IMarkVector aSortedEnd;
1759cdf0e10cSrcweir         IMarkVector aSortedStart;
1760cdf0e10cSrcweir         for ( IMarkVector::const_iterator it = aMarksStart.begin(), end = aMarksStart.end();
1761cdf0e10cSrcweir               it < end; ++it )
1762cdf0e10cSrcweir         {
1763cdf0e10cSrcweir             IMark* pMark = (*it);
1764cdf0e10cSrcweir 
1765cdf0e10cSrcweir             // Remove the positions egals to the current pos
1766cdf0e10cSrcweir             xub_StrLen nStart = pMark->GetMarkStart().nContent.GetIndex();
1767cdf0e10cSrcweir             xub_StrLen nEnd = pMark->GetMarkEnd().nContent.GetIndex();
1768cdf0e10cSrcweir 
1769cdf0e10cSrcweir             if ( nStart > nAktPos && ( pMark->GetMarkStart().nNode == rNode.GetIndex()) )
1770cdf0e10cSrcweir                 aSortedStart.push_back( pMark );
1771cdf0e10cSrcweir 
1772cdf0e10cSrcweir             if ( nEnd > nAktPos && nEnd <= ( nAktPos + nLen ) && (pMark->GetMarkEnd().nNode == rNode.GetIndex()) )
1773cdf0e10cSrcweir                 aSortedEnd.push_back( pMark );
1774cdf0e10cSrcweir         }
1775cdf0e10cSrcweir 
1776cdf0e10cSrcweir         // Sort the bookmarks by end position
1777cdf0e10cSrcweir         std::sort( aSortedEnd.begin(), aSortedEnd.end(), CompareMarksEnd() );
1778cdf0e10cSrcweir 
1779cdf0e10cSrcweir         m_rSortedMarksStart.swap( aSortedStart );
1780cdf0e10cSrcweir         m_rSortedMarksEnd.swap( aSortedEnd );
1781cdf0e10cSrcweir     }
1782cdf0e10cSrcweir     else
1783cdf0e10cSrcweir     {
1784cdf0e10cSrcweir         m_rSortedMarksStart.clear( );
1785cdf0e10cSrcweir         m_rSortedMarksEnd.clear( );
1786cdf0e10cSrcweir     }
1787cdf0e10cSrcweir }
1788cdf0e10cSrcweir 
OutputTextNode(const SwTxtNode & rNode)1789cdf0e10cSrcweir void MSWordExportBase::OutputTextNode( const SwTxtNode& rNode )
1790cdf0e10cSrcweir {
1791cdf0e10cSrcweir #ifdef DEBUG
1792cdf0e10cSrcweir     ::std::clog << "<OutWW8_SwTxtNode>" << ::std::endl;
1793cdf0e10cSrcweir #endif
1794cdf0e10cSrcweir 
1795cdf0e10cSrcweir     ww8::WW8TableNodeInfo::Pointer_t pTextNodeInfo( mpTableInfo->getTableNodeInfo( &rNode ) );
1796cdf0e10cSrcweir 
179741623124SJian Hong Cheng 	//For i120928,identify the last node
179841623124SJian Hong Cheng 	bool bLastCR = false;
179941623124SJian Hong Cheng 	bool bExported = false;
180041623124SJian Hong Cheng 	{
180141623124SJian Hong Cheng 		SwNodeIndex aNextIdx(rNode,1);
180241623124SJian Hong Cheng 		SwNodeIndex aLastIdx(rNode.GetNodes().GetEndOfContent());
180341623124SJian Hong Cheng 		if (aNextIdx == aLastIdx)
180441623124SJian Hong Cheng 			bLastCR = true;
180541623124SJian Hong Cheng 	}
180641623124SJian Hong Cheng 
1807cdf0e10cSrcweir     AttrOutput().StartParagraph( pTextNodeInfo );
1808cdf0e10cSrcweir 
18096d87d7f9SMichael Stahl     bool bFlyInTable = mpParentFrame && IsInTable();
1810cdf0e10cSrcweir 
1811cdf0e10cSrcweir     if ( !bFlyInTable )
1812cdf0e10cSrcweir         nStyleBeforeFly = GetId( lcl_getFormatCollection( *this, &rNode ) );
1813cdf0e10cSrcweir 
1814cdf0e10cSrcweir     // nStyleBeforeFly may change when we recurse into another node, so we
1815cdf0e10cSrcweir     // have to remember it in nStyle
1816cdf0e10cSrcweir     sal_uInt16 nStyle = nStyleBeforeFly;
1817cdf0e10cSrcweir 
1818cdf0e10cSrcweir     WW8SwAttrIter aAttrIter( *this, rNode );
1819cdf0e10cSrcweir     rtl_TextEncoding eChrSet = aAttrIter.GetCharSet();
1820cdf0e10cSrcweir 
1821cdf0e10cSrcweir     if ( bStartTOX )
1822cdf0e10cSrcweir     {
1823cdf0e10cSrcweir         // ignore TOX header section
1824cdf0e10cSrcweir         const SwSectionNode* pSectNd = rNode.FindSectionNode();
1825cdf0e10cSrcweir         if ( pSectNd && TOX_CONTENT_SECTION == pSectNd->GetSection().GetType() )
1826cdf0e10cSrcweir         {
1827cdf0e10cSrcweir             AttrOutput().StartTOX( pSectNd->GetSection() );
1828cdf0e10cSrcweir             m_aCurrentCharPropStarts.push( 0 );
1829cdf0e10cSrcweir         }
1830cdf0e10cSrcweir     }
1831cdf0e10cSrcweir 
1832cdf0e10cSrcweir     const SwSection* pTOXSect = 0;
1833cdf0e10cSrcweir     if( bInWriteTOX )
1834cdf0e10cSrcweir     {
1835cdf0e10cSrcweir         // check for end of TOX
1836cdf0e10cSrcweir         SwNodeIndex aIdx( rNode, 1 );
1837cdf0e10cSrcweir         if( !aIdx.GetNode().IsTxtNode() )
1838cdf0e10cSrcweir         {
1839cdf0e10cSrcweir             const SwSectionNode* pTOXSectNd = rNode.FindSectionNode();
1840cdf0e10cSrcweir             pTOXSect = &pTOXSectNd->GetSection();
1841cdf0e10cSrcweir 
1842cdf0e10cSrcweir             const SwNode* pNxt = rNode.GetNodes().GoNext( &aIdx );
1843cdf0e10cSrcweir             if( pNxt && pNxt->FindSectionNode() == pTOXSectNd )
1844cdf0e10cSrcweir                 pTOXSect = 0;
1845cdf0e10cSrcweir         }
1846cdf0e10cSrcweir     }
1847cdf0e10cSrcweir 
1848cdf0e10cSrcweir     if ( aAttrIter.RequiresImplicitBookmark() )
1849cdf0e10cSrcweir     {
1850cdf0e10cSrcweir         String sBkmkName = String( RTL_CONSTASCII_STRINGPARAM( "_toc" ) );
1851cdf0e10cSrcweir         sBkmkName += String::CreateFromInt32( rNode.GetIndex() );
1852cdf0e10cSrcweir         AppendWordBookmark( sBkmkName );
1853cdf0e10cSrcweir     }
1854cdf0e10cSrcweir 
1855cdf0e10cSrcweir     //Would need to move into WW8Export, probably not worth it
1856cdf0e10cSrcweir     //ASSERT( pO->Count(), " pO ist am Zeilenanfang nicht leer" );
1857cdf0e10cSrcweir 
1858cdf0e10cSrcweir     String aStr( rNode.GetTxt() );
1859cdf0e10cSrcweir 
1860cdf0e10cSrcweir     xub_StrLen nAktPos = 0;
1861cdf0e10cSrcweir     xub_StrLen const nEnd = aStr.Len();
1862cdf0e10cSrcweir     bool bRedlineAtEnd = false;
1863cdf0e10cSrcweir     int nOpenAttrWithRange = 0;
1864cdf0e10cSrcweir 
1865cdf0e10cSrcweir     ww8::WW8TableNodeInfoInner::Pointer_t pTextNodeInfoInner;
1866cdf0e10cSrcweir     if ( pTextNodeInfo.get() != NULL )
1867cdf0e10cSrcweir         pTextNodeInfoInner = pTextNodeInfo->getFirstInner();
1868cdf0e10cSrcweir 
1869cdf0e10cSrcweir     do {
1870cdf0e10cSrcweir         const SwRedlineData* pRedlineData = aAttrIter.GetRedline( nAktPos );
1871cdf0e10cSrcweir 
1872cdf0e10cSrcweir         AttrOutput().StartRun( pRedlineData );
1873cdf0e10cSrcweir 
1874cdf0e10cSrcweir         xub_StrLen nNextAttr = GetNextPos( &aAttrIter, rNode, nAktPos );
1875cdf0e10cSrcweir 
1876cdf0e10cSrcweir         if( nNextAttr > nEnd )
1877cdf0e10cSrcweir             nNextAttr = nEnd;
1878cdf0e10cSrcweir 
1879cdf0e10cSrcweir         aAttrIter.OutFlys( nAktPos );
1880cdf0e10cSrcweir         //Append bookmarks in this range after flys, exclusive of final
1881cdf0e10cSrcweir         //position of this range
1882cdf0e10cSrcweir         AppendBookmarks( rNode, nAktPos, nNextAttr - nAktPos );
1883cdf0e10cSrcweir         bool bTxtAtr = aAttrIter.IsTxtAttr( nAktPos );
1884cdf0e10cSrcweir         nOpenAttrWithRange += aAttrIter.OutAttrWithRange(nAktPos);
1885cdf0e10cSrcweir 
1886cdf0e10cSrcweir         xub_StrLen nLen = nNextAttr - nAktPos;
1887cdf0e10cSrcweir         if ( !bTxtAtr && nLen )
1888cdf0e10cSrcweir         {
1889cdf0e10cSrcweir             sal_Unicode ch = aStr.GetChar( nAktPos );
1890cdf0e10cSrcweir             int ofs = ( ch == CH_TXT_ATR_FIELDSTART || ch == CH_TXT_ATR_FIELDEND || ch == CH_TXT_ATR_FORMELEMENT? 1: 0 );
1891cdf0e10cSrcweir 
1892cdf0e10cSrcweir             IDocumentMarkAccess* const pMarkAccess = pDoc->getIDocumentMarkAccess();
1893cdf0e10cSrcweir             if ( ch == CH_TXT_ATR_FIELDSTART )
1894cdf0e10cSrcweir             {
1895cdf0e10cSrcweir                 SwPosition aPosition( rNode, SwIndex( const_cast< SwTxtNode* >( &rNode ), nAktPos + 1 ) );
1896cdf0e10cSrcweir                 ::sw::mark::IFieldmark const * const pFieldmark = pMarkAccess->getFieldmarkFor( aPosition );
1897cdf0e10cSrcweir                 OSL_ENSURE( pFieldmark, "Looks like this doc is broken...; where is the Fieldmark for the FIELDSTART??" );
1898cdf0e10cSrcweir 
1899cdf0e10cSrcweir                 if ( pFieldmark->GetFieldname().equalsAscii( ODF_FORMTEXT ) )
1900cdf0e10cSrcweir                     AppendBookmark( pFieldmark->GetName(), false );
19013b32dd21SOliver-Rainer Wittmann 
19023b32dd21SOliver-Rainer Wittmann                 const bool bCommentRange = pFieldmark != NULL && pFieldmark->GetFieldname().equalsAscii( ODF_COMMENTRANGE );
19033b32dd21SOliver-Rainer Wittmann                 if ( bCommentRange )
19043b32dd21SOliver-Rainer Wittmann                 {
19053b32dd21SOliver-Rainer Wittmann                     AttrOutput().WritePostitFieldStart(); // Note: empty for WW8 export
19063b32dd21SOliver-Rainer Wittmann                 }
19073b32dd21SOliver-Rainer Wittmann                 else
19083b32dd21SOliver-Rainer Wittmann                 {
19093b32dd21SOliver-Rainer Wittmann                     OutputField( NULL, lcl_getFieldId( pFieldmark ), lcl_getFieldCode( pFieldmark ), WRITEFIELD_START | WRITEFIELD_CMD_START );
19103b32dd21SOliver-Rainer Wittmann                 }
19113b32dd21SOliver-Rainer Wittmann 
1912cdf0e10cSrcweir                 if ( pFieldmark->GetFieldname( ).equalsAscii( ODF_FORMTEXT ) )
1913cdf0e10cSrcweir                     WriteFormData( *pFieldmark );
1914cdf0e10cSrcweir                 else if ( pFieldmark->GetFieldname( ).equalsAscii( ODF_HYPERLINK ) )
1915cdf0e10cSrcweir                     WriteHyperlinkData( *pFieldmark );
19163b32dd21SOliver-Rainer Wittmann 
19173b32dd21SOliver-Rainer Wittmann                 if ( !bCommentRange )
19183b32dd21SOliver-Rainer Wittmann                 {
19193b32dd21SOliver-Rainer Wittmann                     OutputField( NULL, lcl_getFieldId( pFieldmark ), String(), WRITEFIELD_CMD_END );
19203b32dd21SOliver-Rainer Wittmann                 }
1921cdf0e10cSrcweir             }
1922cdf0e10cSrcweir             else if ( ch == CH_TXT_ATR_FIELDEND )
1923cdf0e10cSrcweir             {
1924cdf0e10cSrcweir                 SwPosition aPosition( rNode, SwIndex( const_cast< SwTxtNode* >( &rNode ), nAktPos ) );
1925cdf0e10cSrcweir                 ::sw::mark::IFieldmark const * const pFieldmark = pMarkAccess->getFieldmarkFor( aPosition );
1926cdf0e10cSrcweir                 OSL_ENSURE( pFieldmark, "Looks like this doc is broken...; where is the Fieldmark for the FIELDSTART??" );
1927cdf0e10cSrcweir 
19283b32dd21SOliver-Rainer Wittmann                 if ( pFieldmark && pFieldmark->GetFieldname().equalsAscii( ODF_COMMENTRANGE ) )
19293b32dd21SOliver-Rainer Wittmann                 {
19303b32dd21SOliver-Rainer Wittmann                     AttrOutput().WritePostitFieldEnd(); // Note: empty for WW8 export
19313b32dd21SOliver-Rainer Wittmann                 }
19323b32dd21SOliver-Rainer Wittmann                 else
19333b32dd21SOliver-Rainer Wittmann                 {
19343b32dd21SOliver-Rainer Wittmann                     OutputField( NULL, lcl_getFieldId( pFieldmark ), String(), WRITEFIELD_CLOSE );
19353b32dd21SOliver-Rainer Wittmann                 }
19363b32dd21SOliver-Rainer Wittmann 
1937cdf0e10cSrcweir                 if ( pFieldmark->GetFieldname().equalsAscii( ODF_FORMTEXT ) )
1938cdf0e10cSrcweir                     AppendBookmark( pFieldmark->GetName(), false );
1939cdf0e10cSrcweir             }
1940cdf0e10cSrcweir             else if ( ch == CH_TXT_ATR_FORMELEMENT )
1941cdf0e10cSrcweir             {
1942cdf0e10cSrcweir                 SwPosition aPosition( rNode, SwIndex( const_cast< SwTxtNode* >( &rNode ), nAktPos ) );
1943cdf0e10cSrcweir                 ::sw::mark::IFieldmark const * const pFieldmark = pMarkAccess->getFieldmarkFor( aPosition );
1944cdf0e10cSrcweir                 OSL_ENSURE( pFieldmark, "Looks like this doc is broken...; where is the Fieldmark for the FIELDSTART??" );
1945cdf0e10cSrcweir 
1946cdf0e10cSrcweir                 bool isDropdownOrCheckbox = pFieldmark->GetFieldname( ).equalsAscii( ODF_FORMDROPDOWN ) ||
1947cdf0e10cSrcweir                     pFieldmark->GetFieldname( ).equalsAscii( ODF_FORMCHECKBOX );
1948cdf0e10cSrcweir 
1949cdf0e10cSrcweir                 if ( isDropdownOrCheckbox )
1950cdf0e10cSrcweir                     AppendBookmark( pFieldmark->GetName(), 0 );
1951cdf0e10cSrcweir                 OutputField( NULL, lcl_getFieldId( pFieldmark ),
1952cdf0e10cSrcweir                         lcl_getFieldCode( pFieldmark ),
1953cdf0e10cSrcweir                         WRITEFIELD_START | WRITEFIELD_CMD_START );
1954cdf0e10cSrcweir                 if ( isDropdownOrCheckbox )
1955cdf0e10cSrcweir                     WriteFormData( *pFieldmark );
1956cdf0e10cSrcweir                 OutputField( NULL, lcl_getFieldId( pFieldmark ), String(), WRITEFIELD_CLOSE );
1957cdf0e10cSrcweir                 if ( isDropdownOrCheckbox )
1958cdf0e10cSrcweir                     AppendBookmark( pFieldmark->GetName(), false );
1959cdf0e10cSrcweir             }
1960cdf0e10cSrcweir             nLen -= static_cast< sal_uInt16 >( ofs );
1961cdf0e10cSrcweir 
1962cdf0e10cSrcweir             String aSnippet( aAttrIter.GetSnippet( aStr, nAktPos + static_cast< sal_uInt16 >( ofs ), nLen ) );
1963cdf0e10cSrcweir             if ( ( nTxtTyp == TXT_EDN || nTxtTyp == TXT_FTN ) && nAktPos == 0 && nLen > 0 )
1964cdf0e10cSrcweir             {
1965cdf0e10cSrcweir                 // Insert tab for aesthetic puposes #i24762#
1966cdf0e10cSrcweir                 if ( aSnippet.GetChar( 0 ) != 0x09 )
1967cdf0e10cSrcweir                     aSnippet.Insert( 0x09, 0 );
1968cdf0e10cSrcweir             }
1969cdf0e10cSrcweir             AttrOutput().RunText( aSnippet, eChrSet );
1970cdf0e10cSrcweir         }
1971cdf0e10cSrcweir 
1972cdf0e10cSrcweir         if ( aAttrIter.IsDropCap( nNextAttr ) )
1973cdf0e10cSrcweir             AttrOutput().FormatDrop( rNode, aAttrIter.GetSwFmtDrop(), nStyle, pTextNodeInfo, pTextNodeInfoInner );
1974cdf0e10cSrcweir 
1975cdf0e10cSrcweir         if (0 != nEnd)
1976cdf0e10cSrcweir         {
1977cdf0e10cSrcweir             // Output the character attributes
1978cdf0e10cSrcweir             // #i51277# do this before writing flys at end of paragraph
1979cdf0e10cSrcweir             AttrOutput().StartRunProperties();
1980cdf0e10cSrcweir             aAttrIter.OutAttr( nAktPos );
1981cdf0e10cSrcweir             AttrOutput().EndRunProperties( pRedlineData );
1982cdf0e10cSrcweir         }
1983cdf0e10cSrcweir 
1984cdf0e10cSrcweir         // At the end of line, output the attributes until the CR.
1985cdf0e10cSrcweir         // Exception: footnotes at the end of line
1986cdf0e10cSrcweir         if ( nNextAttr == nEnd )
1987cdf0e10cSrcweir         {
1988cdf0e10cSrcweir             ASSERT( nOpenAttrWithRange >= 0, "odd to see this happening, expected >= 0" );
1989cdf0e10cSrcweir             if ( !bTxtAtr && nOpenAttrWithRange <= 0 )
1990cdf0e10cSrcweir             {
1991cdf0e10cSrcweir                 if ( aAttrIter.IsRedlineAtEnd( nEnd ) )
1992cdf0e10cSrcweir                     bRedlineAtEnd = true;
1993cdf0e10cSrcweir                 else
1994cdf0e10cSrcweir                 {
1995cdf0e10cSrcweir                     // insert final graphic anchors if any before CR
1996cdf0e10cSrcweir                     aAttrIter.OutFlys( nEnd );
1997cdf0e10cSrcweir                     // insert final bookmarks if any before CR and after flys
1998cdf0e10cSrcweir                     AppendBookmarks( rNode, nEnd, 1 );
1999cdf0e10cSrcweir                     if ( pTOXSect )
2000cdf0e10cSrcweir                     {
2001cdf0e10cSrcweir                         m_aCurrentCharPropStarts.pop();
2002f66c5aafSOliver-Rainer Wittmann                         AttrOutput().EndTOX( *pTOXSect ,false);
2003cdf0e10cSrcweir                     }
200441623124SJian Hong Cheng 			//For i120928,the position of the bullet's graphic is at end of doc
200541623124SJian Hong Cheng 			if (bLastCR && (!bExported))
200641623124SJian Hong Cheng 			{
200741623124SJian Hong Cheng 				ExportGrfBullet(rNode);
200841623124SJian Hong Cheng 				bExported = true;
200941623124SJian Hong Cheng 			}
201041623124SJian Hong Cheng 
2011cdf0e10cSrcweir                     WriteCR( pTextNodeInfoInner );
2012cdf0e10cSrcweir                 }
2013cdf0e10cSrcweir             }
2014cdf0e10cSrcweir         }
2015cdf0e10cSrcweir 
2016cdf0e10cSrcweir         if (0 == nEnd)
2017cdf0e10cSrcweir         {
2018cdf0e10cSrcweir             // Output the character attributes
2019cdf0e10cSrcweir             // do it after WriteCR for an empty paragraph (otherwise
2020cdf0e10cSrcweir             // WW8_WrFkp::Append throws SPRMs away...)
2021cdf0e10cSrcweir             AttrOutput().StartRunProperties();
2022cdf0e10cSrcweir             aAttrIter.OutAttr( nAktPos );
2023cdf0e10cSrcweir             AttrOutput().EndRunProperties( pRedlineData );
2024cdf0e10cSrcweir         }
2025cdf0e10cSrcweir 
2026cdf0e10cSrcweir         // Exception: footnotes at the end of line
2027cdf0e10cSrcweir         if ( nNextAttr == nEnd )
2028cdf0e10cSrcweir         {
2029cdf0e10cSrcweir             ASSERT(nOpenAttrWithRange >= 0,
2030cdf0e10cSrcweir                 "odd to see this happening, expected >= 0");
2031cdf0e10cSrcweir             bool bAttrWithRange = (nOpenAttrWithRange > 0);
2032cdf0e10cSrcweir             if ( nAktPos != nEnd )
2033cdf0e10cSrcweir             {
2034cdf0e10cSrcweir                 nOpenAttrWithRange += aAttrIter.OutAttrWithRange(nEnd);
2035cdf0e10cSrcweir                 ASSERT(nOpenAttrWithRange == 0,
2036cdf0e10cSrcweir                     "odd to see this happening, expected 0");
2037cdf0e10cSrcweir             }
2038cdf0e10cSrcweir 
2039cdf0e10cSrcweir             AttrOutput().OutputFKP();
2040cdf0e10cSrcweir 
2041cdf0e10cSrcweir             if ( bTxtAtr || bAttrWithRange || bRedlineAtEnd )
2042cdf0e10cSrcweir             {
2043cdf0e10cSrcweir                 // insert final graphic anchors if any before CR
2044cdf0e10cSrcweir                 aAttrIter.OutFlys( nEnd );
2045cdf0e10cSrcweir                 // insert final bookmarks if any before CR and after flys
2046cdf0e10cSrcweir                 AppendBookmarks( rNode, nEnd, 1 );
2047f66c5aafSOliver-Rainer Wittmann                 WriteCR( pTextNodeInfoInner );
204841623124SJian Hong Cheng               //For i120928,the position of the bullet's graphic is at end of doc
204941623124SJian Hong Cheng 		if (bLastCR && (!bExported))
205041623124SJian Hong Cheng 		{
205141623124SJian Hong Cheng 			ExportGrfBullet(rNode);
205241623124SJian Hong Cheng 			bExported = true;
205341623124SJian Hong Cheng 		}
2054cdf0e10cSrcweir 
2055cdf0e10cSrcweir                 if ( pTOXSect )
2056cdf0e10cSrcweir                 {
2057cdf0e10cSrcweir                     m_aCurrentCharPropStarts.pop();
2058cdf0e10cSrcweir                     AttrOutput().EndTOX( *pTOXSect );
2059cdf0e10cSrcweir                 }
2060cdf0e10cSrcweir 
2061cdf0e10cSrcweir                 if ( bRedlineAtEnd )
2062cdf0e10cSrcweir                 {
2063cdf0e10cSrcweir                     AttrOutput().Redline( aAttrIter.GetRedline( nEnd ) );
2064cdf0e10cSrcweir                     AttrOutput().OutputFKP();
2065cdf0e10cSrcweir                 }
2066cdf0e10cSrcweir             }
2067cdf0e10cSrcweir         }
2068cdf0e10cSrcweir 
2069cdf0e10cSrcweir         AttrOutput().EndRun();
2070cdf0e10cSrcweir 
2071cdf0e10cSrcweir         nAktPos = nNextAttr;
2072cdf0e10cSrcweir         UpdatePosition( &aAttrIter, nAktPos, nEnd );
2073cdf0e10cSrcweir         eChrSet = aAttrIter.GetCharSet();
2074cdf0e10cSrcweir     }
2075cdf0e10cSrcweir     while ( nAktPos < nEnd );
2076cdf0e10cSrcweir 
2077cdf0e10cSrcweir     AttrOutput().StartParagraphProperties( rNode );
2078cdf0e10cSrcweir 
2079cdf0e10cSrcweir     AttrOutput().ParagraphStyle( nStyle );
2080cdf0e10cSrcweir 
20816d87d7f9SMichael Stahl     if ( mpParentFrame && IsInTable() )    // Fly-Attrs
2082cdf0e10cSrcweir         OutputFormat( mpParentFrame->GetFrmFmt(), false, false, true );
2083cdf0e10cSrcweir 
2084cdf0e10cSrcweir     if ( pTextNodeInfo.get() != NULL )
2085cdf0e10cSrcweir     {
2086cdf0e10cSrcweir #ifdef DEBUG
2087cdf0e10cSrcweir         ::std::clog << pTextNodeInfo->toString() << ::std::endl;
2088cdf0e10cSrcweir #endif
2089cdf0e10cSrcweir 
2090cdf0e10cSrcweir         AttrOutput().TableInfoCell( pTextNodeInfoInner );
2091cdf0e10cSrcweir         if (pTextNodeInfoInner->isFirstInTable())
2092cdf0e10cSrcweir         {
2093cdf0e10cSrcweir             const SwTable * pTable = pTextNodeInfoInner->getTable();
2094cdf0e10cSrcweir 
2095cdf0e10cSrcweir             const SwTableFmt * pTabFmt = pTable->GetTableFmt();
2096cdf0e10cSrcweir             if (pTabFmt != NULL)
2097cdf0e10cSrcweir             {
2098cdf0e10cSrcweir                 if (pTabFmt->GetBreak().GetBreak() == SVX_BREAK_PAGE_BEFORE)
2099cdf0e10cSrcweir                     AttrOutput().PageBreakBefore(true);
2100cdf0e10cSrcweir             }
2101cdf0e10cSrcweir         }
2102cdf0e10cSrcweir     }
2103cdf0e10cSrcweir 
2104cdf0e10cSrcweir     if ( !bFlyInTable )
2105cdf0e10cSrcweir     {
2106cdf0e10cSrcweir         SfxItemSet* pTmpSet = 0;
2107cdf0e10cSrcweir         const sal_uInt8 nPrvNxtNd = rNode.HasPrevNextLayNode();
2108cdf0e10cSrcweir 
2109cdf0e10cSrcweir         if( (ND_HAS_PREV_LAYNODE|ND_HAS_NEXT_LAYNODE ) != nPrvNxtNd )
2110cdf0e10cSrcweir         {
2111cdf0e10cSrcweir             const SfxPoolItem* pItem;
2112cdf0e10cSrcweir             if( SFX_ITEM_SET == rNode.GetSwAttrSet().GetItemState(
2113cdf0e10cSrcweir                     RES_UL_SPACE, true, &pItem ) &&
2114cdf0e10cSrcweir                 ( ( !( ND_HAS_PREV_LAYNODE & nPrvNxtNd ) &&
2115cdf0e10cSrcweir                    ((SvxULSpaceItem*)pItem)->GetUpper()) ||
2116cdf0e10cSrcweir                   ( !( ND_HAS_NEXT_LAYNODE & nPrvNxtNd ) &&
2117cdf0e10cSrcweir                    ((SvxULSpaceItem*)pItem)->GetLower()) ))
2118cdf0e10cSrcweir             {
2119cdf0e10cSrcweir                 pTmpSet = new SfxItemSet( rNode.GetSwAttrSet() );
2120cdf0e10cSrcweir                 SvxULSpaceItem aUL( *(SvxULSpaceItem*)pItem );
2121cdf0e10cSrcweir                 // OD, MMAHER 2004-03-01 #i25901#- consider compatibility option
2122cdf0e10cSrcweir                 if (!pDoc->get(IDocumentSettingAccess::PARA_SPACE_MAX_AT_PAGES))
2123cdf0e10cSrcweir                 {
2124cdf0e10cSrcweir                     if( !(ND_HAS_PREV_LAYNODE & nPrvNxtNd ))
2125cdf0e10cSrcweir                         aUL.SetUpper( 0 );
2126cdf0e10cSrcweir                 }
2127cdf0e10cSrcweir                 // OD, MMAHER 2004-03-01 #i25901# - consider compatibility option
2128cdf0e10cSrcweir                 if (!pDoc->get(IDocumentSettingAccess::ADD_PARA_SPACING_TO_TABLE_CELLS))
2129cdf0e10cSrcweir                 {
2130cdf0e10cSrcweir                     if( !(ND_HAS_NEXT_LAYNODE & nPrvNxtNd ))
2131cdf0e10cSrcweir                         aUL.SetLower( 0 );
2132cdf0e10cSrcweir                 }
2133cdf0e10cSrcweir                 pTmpSet->Put( aUL );
2134cdf0e10cSrcweir             }
2135cdf0e10cSrcweir         }
2136cdf0e10cSrcweir 
2137cdf0e10cSrcweir         sal_Bool bParaRTL = sal_False;
2138cdf0e10cSrcweir         const SvxFrameDirectionItem* pItem = (const SvxFrameDirectionItem*)
2139cdf0e10cSrcweir             rNode.GetSwAttrSet().GetItem(RES_FRAMEDIR);
2140cdf0e10cSrcweir         if ( aAttrIter.IsParaRTL())
2141cdf0e10cSrcweir             bParaRTL = sal_True;
2142cdf0e10cSrcweir 
2143cdf0e10cSrcweir         if( rNode.IsNumbered())
2144cdf0e10cSrcweir         {
2145cdf0e10cSrcweir             const SwNumRule* pRule = rNode.GetNumRule();
2146cdf0e10cSrcweir             sal_uInt8 nLvl = static_cast< sal_uInt8 >( rNode.GetActualListLevel() );
2147cdf0e10cSrcweir             const SwNumFmt* pFmt = pRule->GetNumFmt( nLvl );
2148cdf0e10cSrcweir             if( !pFmt )
2149cdf0e10cSrcweir                 pFmt = &pRule->Get( nLvl );
2150cdf0e10cSrcweir 
2151cdf0e10cSrcweir             if( !pTmpSet )
2152cdf0e10cSrcweir                 pTmpSet = new SfxItemSet( rNode.GetSwAttrSet() );
2153cdf0e10cSrcweir 
2154cdf0e10cSrcweir             SvxLRSpaceItem aLR(ItemGet<SvxLRSpaceItem>(*pTmpSet, RES_LR_SPACE));
2155cdf0e10cSrcweir             // --> OD 2008-06-03 #i86652#
2156cdf0e10cSrcweir             if ( pFmt->GetPositionAndSpaceMode() ==
2157cdf0e10cSrcweir                                     SvxNumberFormat::LABEL_WIDTH_AND_POSITION )
2158cdf0e10cSrcweir             {
2159cdf0e10cSrcweir                 aLR.SetTxtLeft( aLR.GetTxtLeft() + pFmt->GetAbsLSpace() );
2160cdf0e10cSrcweir             }
2161cdf0e10cSrcweir             // <--
2162cdf0e10cSrcweir 
2163cdf0e10cSrcweir             if( rNode.IsNumbered() && rNode.IsCountedInList() )
2164cdf0e10cSrcweir             {
2165cdf0e10cSrcweir                 // --> OD 2008-06-03 #i86652#
2166cdf0e10cSrcweir                 if ( pFmt->GetPositionAndSpaceMode() ==
2167cdf0e10cSrcweir                                         SvxNumberFormat::LABEL_WIDTH_AND_POSITION )
2168cdf0e10cSrcweir                 {
2169cdf0e10cSrcweir                     if (bParaRTL)
2170cdf0e10cSrcweir                         aLR.SetTxtFirstLineOfstValue(pFmt->GetAbsLSpace() - pFmt->GetFirstLineOffset());
2171cdf0e10cSrcweir                     else
2172cdf0e10cSrcweir                         aLR.SetTxtFirstLineOfst(GetWordFirstLineOffset(*pFmt));
2173cdf0e10cSrcweir                 }
2174cdf0e10cSrcweir                 // <--
2175cdf0e10cSrcweir 
2176cdf0e10cSrcweir                 // --> OD 2009-03-09 #100020#
2177cdf0e10cSrcweir                 // correct fix for issue i94187
2178cdf0e10cSrcweir                 if (SFX_ITEM_SET !=
2179cdf0e10cSrcweir                     pTmpSet->GetItemState(RES_PARATR_NUMRULE, false) )
2180cdf0e10cSrcweir                 {
2181cdf0e10cSrcweir                     // List style set via paragraph style - then put it into the itemset.
2182cdf0e10cSrcweir                     // This is needed to get list level and list id exported for
2183cdf0e10cSrcweir                     // the paragraph.
2184cdf0e10cSrcweir                     pTmpSet->Put( SwNumRuleItem( pRule->GetName() ));
2185cdf0e10cSrcweir 
2186cdf0e10cSrcweir                     // Put indent values into the itemset in case that the list
2187cdf0e10cSrcweir                     // style is applied via paragraph style and the list level
2188cdf0e10cSrcweir                     // indent values are not applicable.
2189cdf0e10cSrcweir                     if ( pFmt->GetPositionAndSpaceMode() ==
2190cdf0e10cSrcweir                                             SvxNumberFormat::LABEL_ALIGNMENT &&
2191cdf0e10cSrcweir                          !rNode.AreListLevelIndentsApplicable() )
2192cdf0e10cSrcweir                     {
2193cdf0e10cSrcweir                         pTmpSet->Put( aLR );
2194cdf0e10cSrcweir                     }
2195cdf0e10cSrcweir                 }
2196cdf0e10cSrcweir             }
2197cdf0e10cSrcweir             else
2198cdf0e10cSrcweir                 pTmpSet->ClearItem(RES_PARATR_NUMRULE);
2199cdf0e10cSrcweir 
2200cdf0e10cSrcweir             // --> OD 2008-06-03 #i86652#
2201cdf0e10cSrcweir             if ( pFmt->GetPositionAndSpaceMode() ==
2202cdf0e10cSrcweir                                     SvxNumberFormat::LABEL_WIDTH_AND_POSITION )
2203cdf0e10cSrcweir             {
2204cdf0e10cSrcweir                 pTmpSet->Put(aLR);
2205cdf0e10cSrcweir 
2206cdf0e10cSrcweir                 //#i21847#
2207cdf0e10cSrcweir                 SvxTabStopItem aItem(
2208cdf0e10cSrcweir                     ItemGet<SvxTabStopItem>(*pTmpSet, RES_PARATR_TABSTOP));
2209cdf0e10cSrcweir                 SvxTabStop aTabStop(pFmt->GetAbsLSpace());
2210cdf0e10cSrcweir                 aItem.Insert(aTabStop);
2211cdf0e10cSrcweir                 pTmpSet->Put(aItem);
2212cdf0e10cSrcweir 
2213cdf0e10cSrcweir                 MSWordExportBase::CorrectTabStopInSet(*pTmpSet, pFmt->GetAbsLSpace());
2214cdf0e10cSrcweir             }
2215cdf0e10cSrcweir         }
2216cdf0e10cSrcweir 
2217cdf0e10cSrcweir         /*
2218cdf0e10cSrcweir         If a given para is using the FRMDIR_ENVIRONMENT direction we
2219cdf0e10cSrcweir         cannot export that, its its ltr then that's ok as thats word's
2220cdf0e10cSrcweir         default. Otherwise we must add a RTL attribute to our export list
2221cdf0e10cSrcweir         */
2222cdf0e10cSrcweir         pItem = (const SvxFrameDirectionItem*)
2223cdf0e10cSrcweir             rNode.GetSwAttrSet().GetItem(RES_FRAMEDIR);
2224cdf0e10cSrcweir         if (
2225cdf0e10cSrcweir             (!pItem || pItem->GetValue() == FRMDIR_ENVIRONMENT) &&
2226cdf0e10cSrcweir             aAttrIter.IsParaRTL()
2227cdf0e10cSrcweir            )
2228cdf0e10cSrcweir         {
2229cdf0e10cSrcweir             if ( !pTmpSet )
2230cdf0e10cSrcweir                 pTmpSet = new SfxItemSet(rNode.GetSwAttrSet());
2231cdf0e10cSrcweir 
2232cdf0e10cSrcweir             pTmpSet->Put(SvxFrameDirectionItem(FRMDIR_HORI_RIGHT_TOP, RES_FRAMEDIR));
2233cdf0e10cSrcweir         }
2234cdf0e10cSrcweir         // --> OD 2005-10-18 #126238# - move code for handling of numbered,
2235cdf0e10cSrcweir         // but not counted paragraphs to this place. Otherwise, the paragraph
2236cdf0e10cSrcweir         // isn't exported as numbered, but not counted, if no other attribute
2237cdf0e10cSrcweir         // is found in <pTmpSet>
2238cdf0e10cSrcweir         // #i44815# adjust numbering/indents for numbered paragraphs
2239cdf0e10cSrcweir         //          without number (NO_NUMLEVEL)
2240cdf0e10cSrcweir         // #i47013# need to check rNode.GetNumRule()!=NULL as well.
2241cdf0e10cSrcweir         if ( ! rNode.IsCountedInList() && rNode.GetNumRule()!=NULL )
2242cdf0e10cSrcweir         {
2243cdf0e10cSrcweir             // WW8 does not know numbered paragraphs without number
2244cdf0e10cSrcweir             // (NO_NUMLEVEL). In WW8AttributeOutput::ParaNumRule(), we will export
2245cdf0e10cSrcweir             // the RES_PARATR_NUMRULE as list-id 0, which in WW8 means
2246cdf0e10cSrcweir             // no numbering. Here, we will adjust the indents to match
2247cdf0e10cSrcweir             // visually.
2248cdf0e10cSrcweir 
2249cdf0e10cSrcweir             if ( !pTmpSet )
2250cdf0e10cSrcweir                 pTmpSet = new SfxItemSet(rNode.GetSwAttrSet());
2251cdf0e10cSrcweir 
2252cdf0e10cSrcweir             // create new LRSpace item, based on the current (if present)
2253cdf0e10cSrcweir             const SfxPoolItem* pPoolItem = NULL;
2254cdf0e10cSrcweir             pTmpSet->GetItemState(RES_LR_SPACE, sal_True, &pPoolItem);
2255cdf0e10cSrcweir             SvxLRSpaceItem aLRSpace(
2256cdf0e10cSrcweir                 ( pPoolItem == NULL )
2257cdf0e10cSrcweir                     ? SvxLRSpaceItem(0, 0, 0, 0, RES_LR_SPACE)
2258cdf0e10cSrcweir                     : *static_cast<const SvxLRSpaceItem*>( pPoolItem ) );
2259cdf0e10cSrcweir 
2260cdf0e10cSrcweir             // new left margin = old left + label space
2261cdf0e10cSrcweir             const SwNumRule* pRule = rNode.GetNumRule();
2262cdf0e10cSrcweir             const SwNumFmt& rNumFmt = pRule->Get( static_cast< sal_uInt16 >(rNode.GetActualListLevel()) );
2263cdf0e10cSrcweir             // --> OD 2008-06-03 #i86652#
2264cdf0e10cSrcweir             if ( rNumFmt.GetPositionAndSpaceMode() ==
2265cdf0e10cSrcweir                                     SvxNumberFormat::LABEL_WIDTH_AND_POSITION )
2266cdf0e10cSrcweir             {
2267cdf0e10cSrcweir                 aLRSpace.SetTxtLeft( aLRSpace.GetLeft() + rNumFmt.GetAbsLSpace() );
2268cdf0e10cSrcweir 
2269cdf0e10cSrcweir                 // new first line indent = 0
2270cdf0e10cSrcweir                 // (first line indent is ignored for NO_NUMLEVEL)
2271cdf0e10cSrcweir                 if (!bParaRTL)
2272cdf0e10cSrcweir                     aLRSpace.SetTxtFirstLineOfst( 0 );
2273cdf0e10cSrcweir 
2274cdf0e10cSrcweir                 // put back the new item
2275cdf0e10cSrcweir                 pTmpSet->Put( aLRSpace );
2276cdf0e10cSrcweir             }
2277cdf0e10cSrcweir             // <--
2278cdf0e10cSrcweir 
2279cdf0e10cSrcweir             // assure that numbering rule is in <pTmpSet>
2280cdf0e10cSrcweir             if (SFX_ITEM_SET != pTmpSet->GetItemState(RES_PARATR_NUMRULE, false) )
2281cdf0e10cSrcweir             {
2282cdf0e10cSrcweir                 pTmpSet->Put( SwNumRuleItem( pRule->GetName() ));
2283cdf0e10cSrcweir             }
2284cdf0e10cSrcweir         }
2285cdf0e10cSrcweir 
2286cdf0e10cSrcweir         // --> OD 2007-04-24 #i75457#
2287cdf0e10cSrcweir         // Export page break after attribute from paragraph style.
2288cdf0e10cSrcweir         // If page break attribute at the text node exist, an existing page
2289cdf0e10cSrcweir         // break after at the paragraph style hasn't got to be considered.
2290cdf0e10cSrcweir         if ( !rNode.GetpSwAttrSet() ||
2291cdf0e10cSrcweir              SFX_ITEM_SET != rNode.GetpSwAttrSet()->GetItemState(RES_BREAK, false) )
2292cdf0e10cSrcweir         {
2293cdf0e10cSrcweir             const SvxFmtBreakItem* pBreakAtParaStyle =
2294cdf0e10cSrcweir                 &(ItemGet<SvxFmtBreakItem>(rNode.GetSwAttrSet(), RES_BREAK));
2295cdf0e10cSrcweir             if ( pBreakAtParaStyle &&
2296cdf0e10cSrcweir                  pBreakAtParaStyle->GetBreak() == SVX_BREAK_PAGE_AFTER )
2297cdf0e10cSrcweir             {
2298cdf0e10cSrcweir                 if ( !pTmpSet )
2299cdf0e10cSrcweir                 {
2300cdf0e10cSrcweir                     pTmpSet = new SfxItemSet(rNode.GetSwAttrSet());
2301cdf0e10cSrcweir                 }
2302cdf0e10cSrcweir                 pTmpSet->Put( *pBreakAtParaStyle );
2303cdf0e10cSrcweir             }
2304cdf0e10cSrcweir             else if( pTmpSet )
2305cdf0e10cSrcweir             {   // Even a pagedesc item is set, the break item can be set 'NONE',
2306cdf0e10cSrcweir                 // this has to be overruled.
2307cdf0e10cSrcweir                 const SwFmtPageDesc& rPageDescAtParaStyle =
2308cdf0e10cSrcweir                     ItemGet<SwFmtPageDesc>( rNode, RES_PAGEDESC );
2309cdf0e10cSrcweir                 if( rPageDescAtParaStyle.KnowsPageDesc() )
2310cdf0e10cSrcweir                     pTmpSet->ClearItem( RES_BREAK );
2311cdf0e10cSrcweir             }
2312cdf0e10cSrcweir         }
2313cdf0e10cSrcweir 
2314cdf0e10cSrcweir         // --> FME 2007-05-30 #i76520# Emulate non-splitting tables
2315cdf0e10cSrcweir         if ( bOutTable )
2316cdf0e10cSrcweir         {
2317cdf0e10cSrcweir             const SwTableNode* pTableNode = rNode.FindTableNode();
2318cdf0e10cSrcweir 
2319cdf0e10cSrcweir             if ( pTableNode )
2320cdf0e10cSrcweir             {
2321cdf0e10cSrcweir                 const SwTable& rTable = pTableNode->GetTable();
2322cdf0e10cSrcweir                 const SvxFmtKeepItem& rKeep = rTable.GetFrmFmt()->GetKeep();
2323cdf0e10cSrcweir                 const bool bKeep = rKeep.GetValue();
2324cdf0e10cSrcweir                 const bool bDontSplit = !bKeep ?
2325cdf0e10cSrcweir                                         !rTable.GetFrmFmt()->GetLayoutSplit().GetValue() :
2326cdf0e10cSrcweir                                         false;
2327cdf0e10cSrcweir 
2328cdf0e10cSrcweir                 if ( bKeep || bDontSplit )
2329cdf0e10cSrcweir                 {
2330cdf0e10cSrcweir                     // bKeep: set keep at first paragraphs in all lines
2331cdf0e10cSrcweir                     // bDontSplit : set keep at first paragraphs in all lines except from last line
2332cdf0e10cSrcweir                     // but only for non-complex tables
2333cdf0e10cSrcweir                     const SwTableBox* pBox = rNode.GetTblBox();
2334cdf0e10cSrcweir                     const SwTableLine* pLine = pBox ? pBox->GetUpper() : 0;
2335cdf0e10cSrcweir 
2336cdf0e10cSrcweir                     if ( pLine && !pLine->GetUpper() )
2337cdf0e10cSrcweir                     {
2338cdf0e10cSrcweir                         // check if box is first in that line:
2339cdf0e10cSrcweir                         if ( 0 == pLine->GetTabBoxes().GetPos( pBox ) && pBox->GetSttNd() )
2340cdf0e10cSrcweir                         {
2341cdf0e10cSrcweir                             // check if paragraph is first in that line:
2342cdf0e10cSrcweir                             if ( 1 == ( rNode.GetIndex() - pBox->GetSttNd()->GetIndex() ) )
2343cdf0e10cSrcweir                             {
2344cdf0e10cSrcweir                                 bool bSetAtPara = false;
2345cdf0e10cSrcweir                                 if ( bKeep )
2346cdf0e10cSrcweir                                     bSetAtPara = true;
2347cdf0e10cSrcweir                                 else if ( bDontSplit )
2348cdf0e10cSrcweir                                 {
2349cdf0e10cSrcweir                                     // check if pLine isn't last line in table
2350cdf0e10cSrcweir                                     if ( rTable.GetTabLines().Count() - rTable.GetTabLines().GetPos( pLine ) != 1 )
2351cdf0e10cSrcweir                                         bSetAtPara = true;
2352cdf0e10cSrcweir                                 }
2353cdf0e10cSrcweir 
2354cdf0e10cSrcweir                                 if ( bSetAtPara )
2355cdf0e10cSrcweir                                 {
2356cdf0e10cSrcweir                                     if ( !pTmpSet )
2357cdf0e10cSrcweir                                         pTmpSet = new SfxItemSet(rNode.GetSwAttrSet());
2358cdf0e10cSrcweir 
2359cdf0e10cSrcweir                                     const SvxFmtKeepItem aKeepItem( sal_True, RES_KEEP );
2360cdf0e10cSrcweir                                     pTmpSet->Put( aKeepItem );
2361cdf0e10cSrcweir                                 }
2362cdf0e10cSrcweir                             }
2363cdf0e10cSrcweir                         }
2364cdf0e10cSrcweir                     }
2365cdf0e10cSrcweir                 }
2366cdf0e10cSrcweir             }
2367cdf0e10cSrcweir         }
2368cdf0e10cSrcweir         // <--
2369cdf0e10cSrcweir 
2370cdf0e10cSrcweir         const SfxItemSet* pNewSet = pTmpSet ? pTmpSet : rNode.GetpSwAttrSet();
2371cdf0e10cSrcweir         if( pNewSet )
2372cdf0e10cSrcweir         {                                               // Para-Attrs
2373cdf0e10cSrcweir             pStyAttr = &rNode.GetAnyFmtColl().GetAttrSet();
2374cdf0e10cSrcweir 
2375cdf0e10cSrcweir             const SwModify* pOldMod = pOutFmtNode;
2376cdf0e10cSrcweir             pOutFmtNode = &rNode;
2377cdf0e10cSrcweir 
2378cdf0e10cSrcweir             // Pap-Attrs, so script is not necessary
2379cdf0e10cSrcweir             OutputItemSet( *pNewSet, true, false, i18n::ScriptType::LATIN, false);
2380cdf0e10cSrcweir 
2381cdf0e10cSrcweir             pStyAttr = 0;
2382cdf0e10cSrcweir             pOutFmtNode = pOldMod;
2383cdf0e10cSrcweir 
2384cdf0e10cSrcweir             if( pNewSet != rNode.GetpSwAttrSet() )
2385cdf0e10cSrcweir                 delete pNewSet;
2386cdf0e10cSrcweir         }
2387cdf0e10cSrcweir     }
2388cdf0e10cSrcweir 
2389cdf0e10cSrcweir     AttrOutput().EndParagraphProperties();
2390cdf0e10cSrcweir 
2391cdf0e10cSrcweir     AttrOutput().EndParagraph( pTextNodeInfoInner );
2392cdf0e10cSrcweir 
2393cdf0e10cSrcweir #ifdef DEBUG
2394cdf0e10cSrcweir     ::std::clog << "</OutWW8_SwTxtNode>" << ::std::endl;
2395cdf0e10cSrcweir #endif
2396cdf0e10cSrcweir }
2397cdf0e10cSrcweir 
TableNodeInfo(ww8::WW8TableNodeInfo::Pointer_t pNodeInfo)2398cdf0e10cSrcweir void WW8AttributeOutput::TableNodeInfo( ww8::WW8TableNodeInfo::Pointer_t pNodeInfo )
2399cdf0e10cSrcweir {
2400cdf0e10cSrcweir     SVBT16 nSty;
2401cdf0e10cSrcweir     ShortToSVBT16( GetExport().nStyleBeforeFly, nSty );
2402cdf0e10cSrcweir 
2403cdf0e10cSrcweir     ww8::WW8TableNodeInfo::Inners_t::const_iterator aIt( pNodeInfo->getInners().begin() );
2404cdf0e10cSrcweir     ww8::WW8TableNodeInfo::Inners_t::const_iterator aItEnd( pNodeInfo->getInners().end() );
2405cdf0e10cSrcweir 
2406cdf0e10cSrcweir     while (aIt != aItEnd)
2407cdf0e10cSrcweir     {
2408cdf0e10cSrcweir         ww8::WW8TableNodeInfoInner::Pointer_t pInner = aIt->second;
2409cdf0e10cSrcweir         if ( pInner->isEndOfCell() )
2410cdf0e10cSrcweir         {
2411cdf0e10cSrcweir             TableRowEnd( pInner->getDepth() );
2412cdf0e10cSrcweir 
2413cdf0e10cSrcweir             m_rWW8Export.pO->Insert( (sal_uInt8*)&nSty, 2, m_rWW8Export.pO->Count() );     // Style #
2414cdf0e10cSrcweir             TableInfoRow( pInner );
2415cdf0e10cSrcweir             m_rWW8Export.pPapPlc->AppendFkpEntry( m_rWW8Export.Strm().Tell(), m_rWW8Export.pO->Count(),
2416cdf0e10cSrcweir                                      m_rWW8Export.pO->GetData() );
2417cdf0e10cSrcweir             m_rWW8Export.pO->Remove( 0, m_rWW8Export.pO->Count() );                       // leeren
2418cdf0e10cSrcweir         }
2419cdf0e10cSrcweir 
2420cdf0e10cSrcweir         if ( pInner->isEndOfLine() )
2421cdf0e10cSrcweir         {
2422cdf0e10cSrcweir         }
2423cdf0e10cSrcweir 
2424cdf0e10cSrcweir         aIt++;
2425cdf0e10cSrcweir     }
2426cdf0e10cSrcweir }
2427cdf0e10cSrcweir 
2428cdf0e10cSrcweir #if 0
2429cdf0e10cSrcweir /*  */
2430cdf0e10cSrcweir 
2431cdf0e10cSrcweir sal_uInt16 WW8Export::StartTableFromFrmFmt( WW8Bytes &rAt, const SwFrmFmt *pFmt )
2432cdf0e10cSrcweir {
2433cdf0e10cSrcweir     // Tell the undocumented table hack that everything between here and
2434cdf0e10cSrcweir     // the last table position is nontable text
2435cdf0e10cSrcweir     if ( WW8_CP nPos = Fc2Cp( Strm().Tell() ) )
2436cdf0e10cSrcweir         pMagicTable->Append(nPos,0);
2437cdf0e10cSrcweir 
2438cdf0e10cSrcweir     // sprmPDxaFromText10
2439cdf0e10cSrcweir     if( bWrtWW8 )
2440cdf0e10cSrcweir     {
2441cdf0e10cSrcweir         static sal_uInt8 __READONLY_DATA  aTabLineAttr[] = {
2442cdf0e10cSrcweir                 0, 0,               // Sty # 0
2443cdf0e10cSrcweir                 0x16, 0x24, 1,      // sprmPFInTable
2444cdf0e10cSrcweir                 0x17, 0x24, 1 };    // sprmPFTtp
2445cdf0e10cSrcweir         rAt.Insert( aTabLineAttr, sizeof( aTabLineAttr ), rAt.Count() );
2446cdf0e10cSrcweir     }
2447cdf0e10cSrcweir     else
2448cdf0e10cSrcweir     {
2449cdf0e10cSrcweir         static sal_uInt8 __READONLY_DATA  aTabLineAttr[] = {
2450cdf0e10cSrcweir                 0, 0,               // Sty # 0
2451cdf0e10cSrcweir                 24, 1,              // sprmPFInTable
2452cdf0e10cSrcweir                 25, 1 };            // sprmPFTtp
2453cdf0e10cSrcweir         rAt.Insert( aTabLineAttr, sizeof( aTabLineAttr ), rAt.Count() );
2454cdf0e10cSrcweir     }
2455cdf0e10cSrcweir 
2456cdf0e10cSrcweir     ASSERT( pFmt, "No pFmt!" );
2457cdf0e10cSrcweir     if ( pFmt )
2458cdf0e10cSrcweir     {
2459cdf0e10cSrcweir         const SwFmtHoriOrient &rHori = pFmt->GetHoriOrient();
2460cdf0e10cSrcweir         const SwFmtVertOrient &rVert = pFmt->GetVertOrient();
2461cdf0e10cSrcweir         if (
2462cdf0e10cSrcweir             (text::RelOrientation::PRINT_AREA == rHori.GetRelationOrient() ||
2463cdf0e10cSrcweir              text::RelOrientation::FRAME == rHori.GetRelationOrient())
2464cdf0e10cSrcweir             &&
2465cdf0e10cSrcweir             (text::RelOrientation::PRINT_AREA == rVert.GetRelationOrient() ||
2466cdf0e10cSrcweir              text::RelOrientation::FRAME == rVert.GetRelationOrient())
2467cdf0e10cSrcweir            )
2468cdf0e10cSrcweir         {
2469cdf0e10cSrcweir             sal_Int16 eHOri = rHori.GetHoriOrient();
2470cdf0e10cSrcweir             switch (eHOri)
2471cdf0e10cSrcweir             {
2472cdf0e10cSrcweir                 case text::HoriOrientation::CENTER:
2473cdf0e10cSrcweir                 case text::HoriOrientation::RIGHT:
2474cdf0e10cSrcweir                     if( bWrtWW8 )
2475cdf0e10cSrcweir                         SwWW8Writer::InsUInt16( rAt, NS_sprm::LN_TJc );
2476cdf0e10cSrcweir                     else
2477cdf0e10cSrcweir                         rAt.Insert( 182, rAt.Count() );
2478cdf0e10cSrcweir                     SwWW8Writer::InsUInt16( rAt, (text::HoriOrientation::RIGHT == eHOri ? 2 : 1 ));
2479cdf0e10cSrcweir                     break;
2480cdf0e10cSrcweir                 default:
2481cdf0e10cSrcweir                     break;
2482cdf0e10cSrcweir             }
2483cdf0e10cSrcweir         }
2484cdf0e10cSrcweir     }
2485cdf0e10cSrcweir     return rAt.Count();
2486cdf0e10cSrcweir }
2487cdf0e10cSrcweir 
2488cdf0e10cSrcweir //See #i19484# for why we need this
2489cdf0e10cSrcweir static bool CellContainsProblematicGraphic( const SwWriteTableCell *pCell,
2490cdf0e10cSrcweir     const MSWordExportBase &rExport )
2491cdf0e10cSrcweir {
2492cdf0e10cSrcweir     const SwNode *pStart = pCell ? pCell->GetBox()->GetSttNd() : 0;
2493cdf0e10cSrcweir     const SwNode *pEnd = pStart ? pStart->EndOfSectionNode() : 0;
2494cdf0e10cSrcweir     ASSERT( pStart && pEnd, "No start or end?" );
2495cdf0e10cSrcweir     if ( !pStart || !pEnd )
2496cdf0e10cSrcweir         return false;
2497cdf0e10cSrcweir 
2498cdf0e10cSrcweir     bool bHasGraphic = false;
2499cdf0e10cSrcweir 
2500cdf0e10cSrcweir     sw::Frames aFrames( GetFramesBetweenNodes( rExport.maFrames, *pStart, *pEnd ) );
2501cdf0e10cSrcweir     sw::FrameIter aEnd = aFrames.end();
2502cdf0e10cSrcweir     for ( sw::FrameIter aIter = aFrames.begin(); aIter != aEnd; ++aIter )
2503cdf0e10cSrcweir     {
2504cdf0e10cSrcweir         const SwFrmFmt &rEntry = aIter->GetFrmFmt();
2505cdf0e10cSrcweir         if ( rEntry.GetSurround().GetSurround() == SURROUND_THROUGHT )
2506cdf0e10cSrcweir         {
2507cdf0e10cSrcweir             bHasGraphic = true;
2508cdf0e10cSrcweir             break;
2509cdf0e10cSrcweir         }
2510cdf0e10cSrcweir     }
2511cdf0e10cSrcweir     return bHasGraphic;
2512cdf0e10cSrcweir }
2513cdf0e10cSrcweir 
2514cdf0e10cSrcweir static bool RowContainsProblematicGraphic( const SwWriteTableCellPtr *pRow,
2515cdf0e10cSrcweir     sal_uInt16 nCols, const MSWordExportBase &rExport )
2516cdf0e10cSrcweir {
2517cdf0e10cSrcweir     bool bHasGraphic = false;
2518cdf0e10cSrcweir     for ( sal_uInt16 nI = 0; nI < nCols; ++nI )
2519cdf0e10cSrcweir     {
2520cdf0e10cSrcweir         if ( CellContainsProblematicGraphic( pRow[nI], rExport ) )
2521cdf0e10cSrcweir         {
2522cdf0e10cSrcweir             bHasGraphic = true;
2523cdf0e10cSrcweir             break;
2524cdf0e10cSrcweir         }
2525cdf0e10cSrcweir     }
2526cdf0e10cSrcweir     return bHasGraphic;
2527cdf0e10cSrcweir }
2528cdf0e10cSrcweir #endif
2529cdf0e10cSrcweir //---------------------------------------------------------------------------
2530cdf0e10cSrcweir //       Tabellen
2531cdf0e10cSrcweir //---------------------------------------------------------------------------
2532cdf0e10cSrcweir 
EmptyParagraph()2533cdf0e10cSrcweir void WW8AttributeOutput::EmptyParagraph()
2534cdf0e10cSrcweir {
2535cdf0e10cSrcweir     m_rWW8Export.WriteStringAsPara( aEmptyStr );
2536cdf0e10cSrcweir }
2537cdf0e10cSrcweir 
NoPageBreakSection(const SfxItemSet * pSet)2538cdf0e10cSrcweir bool MSWordExportBase::NoPageBreakSection( const SfxItemSet* pSet )
2539cdf0e10cSrcweir {
2540cdf0e10cSrcweir     bool bRet = false;
2541cdf0e10cSrcweir     const SfxPoolItem* pI;
2542cdf0e10cSrcweir     if( pSet)
2543cdf0e10cSrcweir     {
2544cdf0e10cSrcweir         bool bNoPageBreak = false;
2545cdf0e10cSrcweir         if ( SFX_ITEM_ON != pSet->GetItemState(RES_PAGEDESC, true, &pI)
2546cdf0e10cSrcweir             || 0 == ((SwFmtPageDesc*)pI)->GetPageDesc() )
2547cdf0e10cSrcweir         {
2548cdf0e10cSrcweir             bNoPageBreak = true;
2549cdf0e10cSrcweir         }
2550cdf0e10cSrcweir 
2551cdf0e10cSrcweir         if (bNoPageBreak)
2552cdf0e10cSrcweir         {
2553cdf0e10cSrcweir             if (SFX_ITEM_ON != pSet->GetItemState(RES_BREAK, true, &pI))
2554cdf0e10cSrcweir                 bNoPageBreak = true;
2555cdf0e10cSrcweir             else
2556cdf0e10cSrcweir             {
2557cdf0e10cSrcweir                 SvxBreak eBreak = ((const SvxFmtBreakItem*)pI)->GetBreak();
2558cdf0e10cSrcweir                 switch (eBreak)
2559cdf0e10cSrcweir                 {
2560cdf0e10cSrcweir                     case SVX_BREAK_PAGE_BEFORE:
2561cdf0e10cSrcweir                     case SVX_BREAK_PAGE_AFTER:
2562cdf0e10cSrcweir                         bNoPageBreak = false;
2563cdf0e10cSrcweir                         break;
2564cdf0e10cSrcweir                     default:
2565cdf0e10cSrcweir                         break;
2566cdf0e10cSrcweir                 }
2567cdf0e10cSrcweir             }
2568cdf0e10cSrcweir         }
2569cdf0e10cSrcweir         bRet = bNoPageBreak;
2570cdf0e10cSrcweir     }
2571cdf0e10cSrcweir     return bRet;
2572cdf0e10cSrcweir }
2573cdf0e10cSrcweir 
2574cdf0e10cSrcweir /*  */
2575cdf0e10cSrcweir 
OutputSectionNode(const SwSectionNode & rSectionNode)2576cdf0e10cSrcweir void MSWordExportBase::OutputSectionNode( const SwSectionNode& rSectionNode )
2577cdf0e10cSrcweir {
2578cdf0e10cSrcweir     const SwSection& rSection = rSectionNode.GetSection();
2579cdf0e10cSrcweir 
2580cdf0e10cSrcweir     SwNodeIndex aIdx( rSectionNode, 1 );
2581cdf0e10cSrcweir     const SwNode& rNd = aIdx.GetNode();
2582f66c5aafSOliver-Rainer Wittmann     if ( !rNd.IsSectionNode() && !IsInTable()
2583f66c5aafSOliver-Rainer Wittmann 		&& rSection.GetType() != TOX_CONTENT_SECTION && rSection.GetType() != TOX_HEADER_SECTION) //No sections in table
2584cdf0e10cSrcweir     {
2585cdf0e10cSrcweir         // Bug 74245 - if the first Node inside the section has an own
2586cdf0e10cSrcweir         //              PageDesc or PageBreak attribut, then dont write
2587cdf0e10cSrcweir         //              here the section break
2588cdf0e10cSrcweir         sal_uLong nRstLnNum = 0;
2589cdf0e10cSrcweir         const SfxItemSet* pSet;
2590cdf0e10cSrcweir         if ( rNd.IsTableNode() )
2591cdf0e10cSrcweir             pSet = &rNd.GetTableNode()->GetTable().GetFrmFmt()->GetAttrSet();
2592cdf0e10cSrcweir         else if ( rNd.IsCntntNode() )
2593cdf0e10cSrcweir         {
2594cdf0e10cSrcweir             pSet = &rNd.GetCntntNode()->GetSwAttrSet();
2595cdf0e10cSrcweir             nRstLnNum = ((SwFmtLineNumber&)pSet->Get(
2596cdf0e10cSrcweir                             RES_LINENUMBER )).GetStartValue();
2597cdf0e10cSrcweir         }
2598cdf0e10cSrcweir         else
2599cdf0e10cSrcweir             pSet = 0;
2600cdf0e10cSrcweir 
2601cdf0e10cSrcweir         if ( pSet && NoPageBreakSection( pSet ) )
2602cdf0e10cSrcweir             pSet = 0;
2603cdf0e10cSrcweir 
2604cdf0e10cSrcweir         if ( !pSet )
2605cdf0e10cSrcweir         {
2606cdf0e10cSrcweir             // new Section with no own PageDesc/-Break
2607cdf0e10cSrcweir             //  -> write follow section break;
2608cdf0e10cSrcweir             const SwSectionFmt& rFmt = *rSection.GetFmt();
2609cdf0e10cSrcweir             ReplaceCr( msword::PageBreak ); // Indikator fuer Page/Section-Break
2610cdf0e10cSrcweir 
2611cdf0e10cSrcweir             //Get the page in use at the top of this section
2612cdf0e10cSrcweir             SwNodeIndex aIdxTmp(rSectionNode, 1);
2613cdf0e10cSrcweir             const SwPageDesc *pCurrent =
2614cdf0e10cSrcweir                 SwPageDesc::GetPageDescOfNode(aIdxTmp.GetNode());
2615cdf0e10cSrcweir             if (!pCurrent)
2616cdf0e10cSrcweir                 pCurrent = pAktPageDesc;
2617cdf0e10cSrcweir 
2618cdf0e10cSrcweir             AppendSection( pCurrent, &rFmt, nRstLnNum );
2619cdf0e10cSrcweir         }
2620cdf0e10cSrcweir     }
2621cdf0e10cSrcweir     if ( TOX_CONTENT_SECTION == rSection.GetType() )
2622cdf0e10cSrcweir         bStartTOX = true;
2623cdf0e10cSrcweir }
2624cdf0e10cSrcweir 
2625cdf0e10cSrcweir 
AppendSection(const SwPageDesc * pPageDesc,const SwSectionFmt * pFmt,sal_uLong nLnNum)2626cdf0e10cSrcweir void WW8Export::AppendSection( const SwPageDesc *pPageDesc, const SwSectionFmt* pFmt, sal_uLong nLnNum )
2627cdf0e10cSrcweir {
2628cdf0e10cSrcweir     pSepx->AppendSep(Fc2Cp(Strm().Tell()), pPageDesc, pFmt, nLnNum);
2629cdf0e10cSrcweir }
2630cdf0e10cSrcweir 
2631cdf0e10cSrcweir /*  */
2632cdf0e10cSrcweir 
2633cdf0e10cSrcweir //---------------------------------------------------------------------------
2634cdf0e10cSrcweir //       Flys
2635cdf0e10cSrcweir //---------------------------------------------------------------------------
2636cdf0e10cSrcweir 
OutWW6FlyFrmsInCntnt(const SwTxtNode & rNd)2637cdf0e10cSrcweir void WW8Export::OutWW6FlyFrmsInCntnt( const SwTxtNode& rNd )
2638cdf0e10cSrcweir {
2639cdf0e10cSrcweir     ASSERT(!bWrtWW8, "I shouldn't be needed for Word >=8");
2640cdf0e10cSrcweir     if ( bWrtWW8 )
2641cdf0e10cSrcweir         return;
2642cdf0e10cSrcweir 
2643cdf0e10cSrcweir     if (const SwpHints* pTxtAttrs = rNd.GetpSwpHints())
2644cdf0e10cSrcweir     {
2645cdf0e10cSrcweir         for( sal_uInt16 n=0; n < pTxtAttrs->Count(); ++n )
2646cdf0e10cSrcweir         {
2647cdf0e10cSrcweir             const SwTxtAttr* pAttr = (*pTxtAttrs)[ n ];
2648cdf0e10cSrcweir             if( RES_TXTATR_FLYCNT == pAttr->Which() )
2649cdf0e10cSrcweir             {
2650cdf0e10cSrcweir                 // zeichengebundenes Attribut
2651cdf0e10cSrcweir                 const SwFmtFlyCnt& rFlyCntnt = pAttr->GetFlyCnt();
2652cdf0e10cSrcweir                 const SwFlyFrmFmt& rFlyFrmFmt = *(SwFlyFrmFmt*)rFlyCntnt.GetFrmFmt();
2653cdf0e10cSrcweir                 const SwNodeIndex* pNodeIndex = rFlyFrmFmt.GetCntnt().GetCntntIdx();
2654cdf0e10cSrcweir 
2655cdf0e10cSrcweir                 if( pNodeIndex )
2656cdf0e10cSrcweir                 {
2657cdf0e10cSrcweir                     sal_uLong nStt = pNodeIndex->GetIndex()+1,
2658cdf0e10cSrcweir                           nEnd = pNodeIndex->GetNode().EndOfSectionIndex();
2659cdf0e10cSrcweir 
2660cdf0e10cSrcweir                     if( (nStt < nEnd) && !pDoc->GetNodes()[ nStt ]->IsNoTxtNode() )
2661cdf0e10cSrcweir                     {
2662cdf0e10cSrcweir                         Point aOffset;
2663cdf0e10cSrcweir                         // Rechtecke des Flys und des Absatzes besorgen
2664cdf0e10cSrcweir                         SwRect aParentRect(rNd.FindLayoutRect(false, &aOffset)),
2665cdf0e10cSrcweir                                aFlyRect(rFlyFrmFmt.FindLayoutRect(false, &aOffset ) );
2666cdf0e10cSrcweir 
2667cdf0e10cSrcweir                         aOffset = aFlyRect.Pos() - aParentRect.Pos();
2668cdf0e10cSrcweir 
2669cdf0e10cSrcweir                         // PaM umsetzen: auf Inhalt des Fly-Frameformats
2670cdf0e10cSrcweir                         SaveData( nStt, nEnd );
2671cdf0e10cSrcweir 
2672cdf0e10cSrcweir                         // wird in OutputFormat() ausgewertet
2673cdf0e10cSrcweir                         pFlyOffset = &aOffset;
2674cdf0e10cSrcweir                         eNewAnchorType = rFlyFrmFmt.GetAnchor().GetAnchorId();
2675cdf0e10cSrcweir                         sw::Frame aFrm(rFlyFrmFmt, SwPosition(rNd));
2676cdf0e10cSrcweir                         mpParentFrame = &aFrm;
2677cdf0e10cSrcweir                         // Ok, rausschreiben:
2678cdf0e10cSrcweir                         WriteText();
2679cdf0e10cSrcweir 
2680cdf0e10cSrcweir                         RestoreData();
2681cdf0e10cSrcweir                     }
2682cdf0e10cSrcweir                 }
2683cdf0e10cSrcweir             }
2684cdf0e10cSrcweir         }
2685cdf0e10cSrcweir     }
2686cdf0e10cSrcweir }
2687cdf0e10cSrcweir 
OutputFlyFrame_Impl(const sw::Frame & rFmt,const Point & rNdTopLeft)2688cdf0e10cSrcweir void WW8AttributeOutput::OutputFlyFrame_Impl( const sw::Frame& rFmt, const Point& rNdTopLeft )
2689cdf0e10cSrcweir {
2690cdf0e10cSrcweir     const SwFrmFmt &rFrmFmt = rFmt.GetFrmFmt();
2691cdf0e10cSrcweir     const SwFmtAnchor& rAnch = rFrmFmt.GetAnchor();
2692cdf0e10cSrcweir 
2693cdf0e10cSrcweir     bool bUseEscher = m_rWW8Export.bWrtWW8;
2694cdf0e10cSrcweir 
2695cdf0e10cSrcweir     if ( m_rWW8Export.bWrtWW8 && rFmt.IsInline() )
2696cdf0e10cSrcweir     {
2697cdf0e10cSrcweir         sw::Frame::WriterSource eType = rFmt.GetWriterType();
2698cdf0e10cSrcweir         if ((eType == sw::Frame::eGraphic) || (eType == sw::Frame::eOle))
2699cdf0e10cSrcweir             bUseEscher = false;
2700cdf0e10cSrcweir         else
2701cdf0e10cSrcweir             bUseEscher = true;
2702cdf0e10cSrcweir 
2703cdf0e10cSrcweir         /*
2704cdf0e10cSrcweir          #110185#
2705cdf0e10cSrcweir          A special case for converting some inline form controls to form fields
2706cdf0e10cSrcweir          when in winword 8+ mode
2707cdf0e10cSrcweir         */
2708cdf0e10cSrcweir         if ((bUseEscher == true) && (eType == sw::Frame::eFormControl))
2709cdf0e10cSrcweir         {
2710cdf0e10cSrcweir             if ( m_rWW8Export.MiserableFormFieldExportHack( rFrmFmt ) )
2711cdf0e10cSrcweir                 return ;
2712cdf0e10cSrcweir         }
2713cdf0e10cSrcweir     }
2714cdf0e10cSrcweir 
2715cdf0e10cSrcweir     if (bUseEscher)
2716cdf0e10cSrcweir     {
2717cdf0e10cSrcweir         ASSERT( m_rWW8Export.bWrtWW8, "this has gone horribly wrong" );
2718cdf0e10cSrcweir         // write as escher
2719cdf0e10cSrcweir         m_rWW8Export.AppendFlyInFlys(rFmt, rNdTopLeft);
2720cdf0e10cSrcweir     }
2721cdf0e10cSrcweir     else
2722cdf0e10cSrcweir     {
2723cdf0e10cSrcweir         bool bDone = false;
2724cdf0e10cSrcweir 
2725cdf0e10cSrcweir         // Hole vom Node und vom letzten Node die Position in der Section
2726cdf0e10cSrcweir         const SwNodeIndex* pNodeIndex = rFrmFmt.GetCntnt().GetCntntIdx();
2727cdf0e10cSrcweir 
2728cdf0e10cSrcweir         sal_uLong nStt = pNodeIndex ? pNodeIndex->GetIndex()+1                  : 0;
2729cdf0e10cSrcweir         sal_uLong nEnd = pNodeIndex ? pNodeIndex->GetNode().EndOfSectionIndex() : 0;
2730cdf0e10cSrcweir 
2731cdf0e10cSrcweir         if( nStt >= nEnd )      // kein Bereich, also kein gueltiger Node
2732cdf0e10cSrcweir             return;
2733cdf0e10cSrcweir 
27346d87d7f9SMichael Stahl         if ( !m_rWW8Export.IsInTable() && rFmt.IsInline() )
2735cdf0e10cSrcweir         {
2736cdf0e10cSrcweir             //Test to see if this textbox contains only a single graphic/ole
2737cdf0e10cSrcweir             SwTxtNode* pParTxtNode = rAnch.GetCntntAnchor()->nNode.GetNode().GetTxtNode();
2738cdf0e10cSrcweir             if ( pParTxtNode && !m_rWW8Export.pDoc->GetNodes()[ nStt ]->IsNoTxtNode() )
2739cdf0e10cSrcweir                 bDone = true;
2740cdf0e10cSrcweir         }
2741cdf0e10cSrcweir         if( !bDone )
2742cdf0e10cSrcweir         {
2743cdf0e10cSrcweir             // ein NICHT zeichengebundener Rahmen liegt vor
2744cdf0e10cSrcweir 
2745cdf0e10cSrcweir             // --> OD 2007-04-19 #i43447# - removed
2746cdf0e10cSrcweir //            const SwFmtFrmSize& rS = rFrmFmt.GetFrmSize();
2747cdf0e10cSrcweir //            nFlyWidth  = rS.GetWidth();  // Fuer Anpassung Graphic-Groesse
2748cdf0e10cSrcweir //            nFlyHeight = rS.GetHeight();
2749cdf0e10cSrcweir             // <--
2750cdf0e10cSrcweir 
2751cdf0e10cSrcweir             m_rWW8Export.SaveData( nStt, nEnd );
2752cdf0e10cSrcweir 
2753cdf0e10cSrcweir             Point aOffset;
2754cdf0e10cSrcweir             if ( m_rWW8Export.mpParentFrame )
2755cdf0e10cSrcweir             {
2756cdf0e10cSrcweir                 /*
2757cdf0e10cSrcweir                 #90804#
2758cdf0e10cSrcweir                 Munge flys in fly into absolutely positioned elements for
2759cdf0e10cSrcweir                 word 6
2760cdf0e10cSrcweir                 */
2761cdf0e10cSrcweir                 const SwTxtNode* pParTxtNode = rAnch.GetCntntAnchor()->nNode.GetNode().GetTxtNode();
2762cdf0e10cSrcweir                 const SwRect aPageRect = pParTxtNode->FindPageFrmRect( sal_False, 0, sal_False );
2763cdf0e10cSrcweir 
2764cdf0e10cSrcweir                 aOffset = rFrmFmt.FindLayoutRect().Pos();
2765cdf0e10cSrcweir                 aOffset -= aPageRect.Pos();
2766cdf0e10cSrcweir 
2767cdf0e10cSrcweir                 m_rWW8Export.pFlyOffset = &aOffset;
2768cdf0e10cSrcweir                 m_rWW8Export.eNewAnchorType = FLY_AT_PAGE;
2769cdf0e10cSrcweir             }
2770cdf0e10cSrcweir 
2771cdf0e10cSrcweir             m_rWW8Export.mpParentFrame = &rFmt;
2772cdf0e10cSrcweir             if (
27736d87d7f9SMichael Stahl                 m_rWW8Export.IsInTable() &&
2774cdf0e10cSrcweir                  (FLY_AT_PAGE != rAnch.GetAnchorId()) &&
2775cdf0e10cSrcweir                  !m_rWW8Export.pDoc->GetNodes()[ nStt ]->IsNoTxtNode()
2776cdf0e10cSrcweir                )
2777cdf0e10cSrcweir             {
2778cdf0e10cSrcweir                 // Beachten: Flag  bOutTable  wieder setzen,
2779cdf0e10cSrcweir                 //           denn wir geben ja ganz normalen Content der
2780cdf0e10cSrcweir                 //           Tabelenzelle aus und keinen Rahmen
2781cdf0e10cSrcweir                 //           (Flag wurde oben in  aSaveData()  geloescht)
2782cdf0e10cSrcweir                 m_rWW8Export.bOutTable = true;
2783cdf0e10cSrcweir                 const String& rName = rFrmFmt.GetName();
2784cdf0e10cSrcweir                 m_rWW8Export.StartCommentOutput(rName);
2785cdf0e10cSrcweir                 m_rWW8Export.WriteText();
2786cdf0e10cSrcweir                 m_rWW8Export.EndCommentOutput(rName);
2787cdf0e10cSrcweir             }
2788cdf0e10cSrcweir             else
2789cdf0e10cSrcweir                 m_rWW8Export.WriteText();
2790cdf0e10cSrcweir 
2791cdf0e10cSrcweir             m_rWW8Export.RestoreData();
2792cdf0e10cSrcweir         }
2793cdf0e10cSrcweir     }
2794cdf0e10cSrcweir }
2795cdf0e10cSrcweir 
OutputFlyFrame(const sw::Frame & rFmt)2796cdf0e10cSrcweir void AttributeOutputBase::OutputFlyFrame( const sw::Frame& rFmt )
2797cdf0e10cSrcweir {
2798cdf0e10cSrcweir     if ( !rFmt.GetCntntNode() )
2799cdf0e10cSrcweir         return;
2800cdf0e10cSrcweir 
2801cdf0e10cSrcweir     const SwCntntNode &rNode = *rFmt.GetCntntNode();
2802cdf0e10cSrcweir     Point aNdPos, aPgPos;
2803cdf0e10cSrcweir     Point* pLayPos;
2804cdf0e10cSrcweir     bool bValidNdPos = false, bValidPgPos = false;
2805cdf0e10cSrcweir 
2806cdf0e10cSrcweir     if (FLY_AT_PAGE == rFmt.GetFrmFmt().GetAnchor().GetAnchorId())
2807cdf0e10cSrcweir     {
2808cdf0e10cSrcweir         // get the Layout Node-Position.
2809cdf0e10cSrcweir         if ( !bValidPgPos )
2810cdf0e10cSrcweir         {
2811cdf0e10cSrcweir             aPgPos = rNode.FindPageFrmRect(false, &aPgPos).Pos();
2812cdf0e10cSrcweir             bValidPgPos = true;
2813cdf0e10cSrcweir         }
2814cdf0e10cSrcweir         pLayPos = &aPgPos;
2815cdf0e10cSrcweir     }
2816cdf0e10cSrcweir     else
2817cdf0e10cSrcweir     {
2818cdf0e10cSrcweir         // get the Layout Node-Position.
2819cdf0e10cSrcweir         if ( !bValidNdPos )
2820cdf0e10cSrcweir         {
2821cdf0e10cSrcweir             aNdPos = rNode.FindLayoutRect(false, &aNdPos).Pos();
2822cdf0e10cSrcweir             bValidNdPos = true;
2823cdf0e10cSrcweir         }
2824cdf0e10cSrcweir         pLayPos = &aNdPos;
2825cdf0e10cSrcweir     }
2826cdf0e10cSrcweir 
2827cdf0e10cSrcweir     OutputFlyFrame_Impl( rFmt, *pLayPos );
2828cdf0e10cSrcweir }
2829cdf0e10cSrcweir 
2830cdf0e10cSrcweir // write data of any redline
Redline(const SwRedlineData * pRedline)2831cdf0e10cSrcweir void WW8AttributeOutput::Redline( const SwRedlineData* pRedline )
2832cdf0e10cSrcweir {
2833cdf0e10cSrcweir     if ( !pRedline )
2834cdf0e10cSrcweir         return;
2835cdf0e10cSrcweir 
2836cdf0e10cSrcweir     if ( pRedline->Next() )
2837cdf0e10cSrcweir         Redline( pRedline->Next() );
2838cdf0e10cSrcweir 
2839cdf0e10cSrcweir     static sal_uInt16 __READONLY_DATA aSprmIds[ 2 * 2 * 3 ] =
2840cdf0e10cSrcweir     {
2841cdf0e10cSrcweir         // Ids for insert
2842cdf0e10cSrcweir             NS_sprm::LN_CFRMark, NS_sprm::LN_CIbstRMark, NS_sprm::LN_CDttmRMark,         // for WW8
2843cdf0e10cSrcweir             0x0042, 0x0045, 0x0046,         // for WW6
2844cdf0e10cSrcweir         // Ids for delete
2845cdf0e10cSrcweir             NS_sprm::LN_CFRMarkDel, NS_sprm::LN_CIbstRMarkDel, NS_sprm::LN_CDttmRMarkDel,         // for WW8
2846cdf0e10cSrcweir             0x0041, 0x0045, 0x0046          // for WW6
2847cdf0e10cSrcweir     };
2848cdf0e10cSrcweir 
2849cdf0e10cSrcweir     const sal_uInt16* pSprmIds = 0;
2850cdf0e10cSrcweir     switch( pRedline->GetType() )
2851cdf0e10cSrcweir     {
2852cdf0e10cSrcweir     case nsRedlineType_t::REDLINE_INSERT:
2853cdf0e10cSrcweir         pSprmIds = aSprmIds;
2854cdf0e10cSrcweir         break;
2855cdf0e10cSrcweir 
2856cdf0e10cSrcweir     case nsRedlineType_t::REDLINE_DELETE:
2857cdf0e10cSrcweir         pSprmIds = aSprmIds + (2 * 3);
2858cdf0e10cSrcweir         break;
2859cdf0e10cSrcweir 
2860cdf0e10cSrcweir     case nsRedlineType_t::REDLINE_FORMAT:
2861cdf0e10cSrcweir         if( m_rWW8Export.bWrtWW8 )
2862cdf0e10cSrcweir         {
2863cdf0e10cSrcweir             m_rWW8Export.InsUInt16( NS_sprm::LN_CPropRMark );
2864cdf0e10cSrcweir             m_rWW8Export.pO->Insert( 7, m_rWW8Export.pO->Count() );       // len
2865cdf0e10cSrcweir             m_rWW8Export.pO->Insert( 1, m_rWW8Export.pO->Count() );
2866cdf0e10cSrcweir             m_rWW8Export.InsUInt16( m_rWW8Export.AddRedlineAuthor( pRedline->GetAuthor() ) );
2867cdf0e10cSrcweir             m_rWW8Export.InsUInt32( sw::ms::DateTime2DTTM( pRedline->GetTimeStamp() ));
2868cdf0e10cSrcweir         }
2869cdf0e10cSrcweir         break;
2870cdf0e10cSrcweir     default:
2871cdf0e10cSrcweir         ASSERT(!this, "Unhandled redline type for export");
2872cdf0e10cSrcweir         break;
2873cdf0e10cSrcweir     }
2874cdf0e10cSrcweir 
2875cdf0e10cSrcweir     if ( pSprmIds )
2876cdf0e10cSrcweir     {
2877cdf0e10cSrcweir         if ( !m_rWW8Export.bWrtWW8 )
2878cdf0e10cSrcweir             pSprmIds += 3;
2879cdf0e10cSrcweir 
2880cdf0e10cSrcweir         if ( m_rWW8Export.bWrtWW8 )
2881cdf0e10cSrcweir             m_rWW8Export.InsUInt16( pSprmIds[0] );
2882cdf0e10cSrcweir         else
2883cdf0e10cSrcweir             m_rWW8Export.pO->Insert( msword_cast<sal_uInt8>(pSprmIds[0]), m_rWW8Export.pO->Count() );
2884cdf0e10cSrcweir         m_rWW8Export.pO->Insert( 1, m_rWW8Export.pO->Count() );
2885cdf0e10cSrcweir 
2886cdf0e10cSrcweir         if ( m_rWW8Export.bWrtWW8 )
2887cdf0e10cSrcweir             m_rWW8Export.InsUInt16( pSprmIds[1] );
2888cdf0e10cSrcweir         else
2889cdf0e10cSrcweir             m_rWW8Export.pO->Insert( msword_cast<sal_uInt8>(pSprmIds[1]), m_rWW8Export.pO->Count() );
2890cdf0e10cSrcweir         m_rWW8Export.InsUInt16( m_rWW8Export.AddRedlineAuthor( pRedline->GetAuthor() ) );
2891cdf0e10cSrcweir 
2892cdf0e10cSrcweir         if ( m_rWW8Export.bWrtWW8 )
2893cdf0e10cSrcweir             m_rWW8Export.InsUInt16( pSprmIds[2] );
2894cdf0e10cSrcweir         else
2895cdf0e10cSrcweir             m_rWW8Export.pO->Insert( msword_cast<sal_uInt8>(pSprmIds[2]), m_rWW8Export.pO->Count() );
2896cdf0e10cSrcweir         m_rWW8Export.InsUInt32( sw::ms::DateTime2DTTM( pRedline->GetTimeStamp() ));
2897cdf0e10cSrcweir     }
2898cdf0e10cSrcweir }
2899cdf0e10cSrcweir 
2900cdf0e10cSrcweir /*  */
2901cdf0e10cSrcweir 
OutputContentNode(const SwCntntNode & rNode)2902cdf0e10cSrcweir void MSWordExportBase::OutputContentNode( const SwCntntNode& rNode )
2903cdf0e10cSrcweir {
2904cdf0e10cSrcweir     switch ( rNode.GetNodeType() )
2905cdf0e10cSrcweir     {
2906cdf0e10cSrcweir         case ND_TEXTNODE:
2907cdf0e10cSrcweir         {
2908cdf0e10cSrcweir             const SwTxtNode& rTextNode = *rNode.GetTxtNode();
2909cdf0e10cSrcweir             if( !mbOutOutlineOnly || rTextNode.IsOutline() )
2910cdf0e10cSrcweir                 OutputTextNode( rTextNode );
2911cdf0e10cSrcweir         }
2912cdf0e10cSrcweir         break;
2913cdf0e10cSrcweir         case ND_GRFNODE:
2914cdf0e10cSrcweir             OutputGrfNode( *rNode.GetGrfNode() );
2915cdf0e10cSrcweir             break;
2916cdf0e10cSrcweir         case ND_OLENODE:
2917cdf0e10cSrcweir             OutputOLENode( *rNode.GetOLENode() );
2918cdf0e10cSrcweir             break;
2919cdf0e10cSrcweir         default:
2920cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 0
2921cdf0e10cSrcweir             OSL_TRACE("Unhandled node, type == %d\n", rNode.GetNodeType() );
2922cdf0e10cSrcweir #endif
2923cdf0e10cSrcweir             break;
2924cdf0e10cSrcweir     }
2925cdf0e10cSrcweir }
2926cdf0e10cSrcweir 
2927cdf0e10cSrcweir /* vi:set tabstop=4 shiftwidth=4 expandtab: */
2928