1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: ww8par3.cxx,v $
10 * $Revision: 1.93.92.2 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sw.hxx"
33 /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil -*- */
36 #include <svtools/itemiter.hxx>
37 #include <vcl/svapp.hxx>
38 #include <vcl/outdev.hxx>
40 #include <toolkit/helper/vclunohelper.hxx>
41 #include <com/sun/star/form/XFormsSupplier.hpp>
42 #include <com/sun/star/form/XForm.hpp>
43 #include <com/sun/star/form/XImageProducerSupplier.hpp>
44 #include <com/sun/star/form/XFormController.hpp>
45 #include <com/sun/star/frame/XStorable.hpp>
46 #include <com/sun/star/frame/XModel.hpp>
47 #include <com/sun/star/drawing/XConnectableShape.hpp>
48 #include <com/sun/star/drawing/XConnectorShape.hpp>
49 #include <com/sun/star/drawing/XShape.hpp>
50 #include <com/sun/star/drawing/XControlShape.hpp>
51 #include <com/sun/star/drawing/XShapeAligner.hpp>
52 #include <com/sun/star/drawing/XShapeGroup.hpp>
53 #include <com/sun/star/drawing/XUniversalShapeDescriptor.hpp>
54 #include <com/sun/star/drawing/XShapeMirror.hpp>
55 #include <com/sun/star/drawing/XShapeArranger.hpp>
56 #include <com/sun/star/drawing/XDrawPage.hpp>
57 #include <com/sun/star/drawing/XDrawPageSupplier.hpp>
58 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
59 #include <com/sun/star/lang/XSingleServiceFactory.hpp>
60 #include <com/sun/star/container/XIndexContainer.hpp>
61 #include <com/sun/star/text/VertOrientation.hpp>
62 #include <com/sun/star/text/TextContentAnchorType.hpp>
63 #include <comphelper/extract.hxx>
64 #include <com/sun/star/beans/XPropertyContainer.hpp>
65 #include <com/sun/star/beans/PropertyAttribute.hpp>
69 #include <hintids.hxx>
70 #include <svx/fontitem.hxx>
71 #include <svx/lrspitem.hxx>
72 #include <svx/fhgtitem.hxx>
73 #include <svx/colritem.hxx>
74 #include <svx/wghtitem.hxx>
75 #include <svx/crsditem.hxx>
76 #include <svx/udlnitem.hxx>
77 #include <svx/postitem.hxx>
78 #include <svx/msocximex.hxx>
84 #include <numrule.hxx>
86 #include <charatr.hxx>
87 #include <charfmt.hxx>
91 #include <flddropdown.hxx>
92 #include "writerhelper.hxx"
93 #include "writerwordglue.hxx"
95 #include "ww8par2.hxx" // wg. Listen-Attributen in Styles
98 #include <svtools/fltrcfg.hxx>
99 #include <ecmaflds.hxx>
103 using namespace com::sun::star
;
104 using namespace sw::util
;
105 using namespace sw::types
;
106 using namespace sw::mark
;
108 //-----------------------------------------
110 //-----------------------------------------
112 //cmc, OCX i.e. word 97 form controls
113 eF_ResT
SwWW8ImplReader::Read_F_OCX( WW8FieldDesc
*, String
& )
115 if( bObj
&& nPicLocFc
)
116 nObjLocFc
= nPicLocFc
;
121 eF_ResT
SwWW8ImplReader::Read_F_FormTextBox( WW8FieldDesc
* pF
, String
& rStr
)
123 WW8FormulaEditBox
aFormula(*this);
125 if (0x01 == rStr
.GetChar(writer_cast
<xub_StrLen
>(pF
->nLCode
-1))) {
126 ImportFormulaControl(aFormula
,pF
->nSCode
+pF
->nLCode
-1, WW8_CT_EDIT
);
130 Here we have a small complication. This formula control contains
131 the default text that is displayed if you edit the form field in
132 the "default text" area. But MSOffice does not display that
133 information, instead it display the result of the field,
134 MSOffice just uses the default text of the control as its
135 initial value for the displayed default text. So we will swap in
136 the field result into the formula here in place of the default
140 const SvtFilterOptions
* pOpt
= SvtFilterOptions::Get();
141 sal_Bool bUseEnhFields
=(pOpt
&& pOpt
->IsUseEnhancedFields());
143 if (!bUseEnhFields
) {
144 aFormula
.sDefault
= GetFieldResult(pF
);
146 #if 0 // why not? (flr)
147 //substituting Unicode spacing 0x2002 with double space for layout
148 aFormula
.sDefault
.SearchAndReplaceAll(
149 String(static_cast< sal_Unicode
>(0x2002)),
150 CREATE_CONST_ASC(" "));
153 SwInputField
aFld((SwInputFieldType
*)rDoc
.GetSysFldType( RES_INPUTFLD
),
154 aFormula
.sDefault
, aFormula
.sTitle
, INP_TXT
, 0 );
155 aFld
.SetHelp(aFormula
.sHelp
);
156 aFld
.SetToolTip(aFormula
.sToolTip
);
158 rDoc
.Insert(*pPaM
, SwFmtFld(aFld
), 0);
161 WW8PLCFx_Book
* pB
= pPlcxMan
->GetBook();
162 String aBookmarkName
;
164 WW8_CP currentCP
=pF
->nSCode
;
165 WW8_CP currentLen
=pF
->nLen
;
168 String aBookmarkFind
=pB
->GetBookmark(currentCP
-1, currentCP
+currentLen
-1, bkmFindIdx
);
170 if (aBookmarkFind
.Len()>0) {
171 pB
->SetStatus(bkmFindIdx
, BOOK_FIELD
); // mark bookmark as consumed, such that tl'll not get inserted as a "normal" bookmark again
172 if (aBookmarkFind
.Len()>0) {
173 aBookmarkName
=aBookmarkFind
;
178 if (pB
!=NULL
&& aBookmarkName
.Len()==0) {
179 aBookmarkName
=pB
->GetUniqueBookmarkName(aFormula
.sTitle
);
183 if (aBookmarkName
.Len()>0) {
184 maFieldStack
.back().SetBookmarkName(aBookmarkName
);
185 maFieldStack
.back().SetBookmarkType(::rtl::OUString::createFromAscii(ECMA_FORMTEXT
));
186 maFieldStack
.back().AddParam(::rtl::OUString::createFromAscii("Description"), aFormula
.sToolTip
);
187 maFieldStack
.back().AddParam(::rtl::OUString::createFromAscii("Name"), aFormula
.sTitle
);
193 eF_ResT
SwWW8ImplReader::Read_F_FormCheckBox( WW8FieldDesc
* pF
, String
& rStr
)
195 WW8FormulaCheckBox
aFormula(*this);
198 pFormImpl
= new SwMSConvertControls(mpDocShell
, pPaM
);
200 if (0x01 == rStr
.GetChar(writer_cast
<xub_StrLen
>(pF
->nLCode
-1)))
201 ImportFormulaControl(aFormula
,pF
->nSCode
+pF
->nLCode
-1, WW8_CT_CHECKBOX
);
202 const SvtFilterOptions
* pOpt
= SvtFilterOptions::Get();
203 sal_Bool bUseEnhFields
=(pOpt
&& pOpt
->IsUseEnhancedFields());
205 if (!bUseEnhFields
) {
206 pFormImpl
->InsertFormula(aFormula
);
209 String aBookmarkName
;
210 WW8PLCFx_Book
* pB
= pPlcxMan
->GetBook();
212 WW8_CP currentCP
=pF
->nSCode
;
213 WW8_CP currentLen
=pF
->nLen
;
216 String aBookmarkFind
=pB
->GetBookmark(currentCP
-1, currentCP
+currentLen
-1, bkmFindIdx
);
218 if (aBookmarkFind
.Len()>0) {
219 pB
->SetStatus(bkmFindIdx
, BOOK_FIELD
); // mark as consumed by field
220 if (aBookmarkFind
.Len()>0) {
221 aBookmarkName
=aBookmarkFind
;
226 if (pB
!=NULL
&& aBookmarkName
.Len()==0) {
227 aBookmarkName
=pB
->GetUniqueBookmarkName(aFormula
.sTitle
);
230 if (aBookmarkName
.Len()>0)
232 IDocumentMarkAccess
* pMarksAccess
= rDoc
.getIDocumentMarkAccess( );
233 IFieldmark
* pFieldmark
= dynamic_cast<IFieldmark
*>( pMarksAccess
->makeNoTextFieldBookmark(
234 *pPaM
, aBookmarkName
,
235 rtl::OUString::createFromAscii( ECMA_FORMCHECKBOX
) ) );
236 ASSERT(pFieldmark
!=NULL
, "hmmm; why was the bookmark not created?");
237 if (pFieldmark
!=NULL
) {
238 pFieldmark
->addParam(
239 rtl::OUString::createFromAscii(ECMA_FORMCHECKBOX_NAME
),
240 rtl::OUString( aFormula
.sTitle
) );
241 pFieldmark
->addParam(
242 rtl::OUString::createFromAscii(ECMA_FORMCHECKBOX_HELPTEXT
), aFormula
.sToolTip
);
243 pFieldmark
->addParam(
244 rtl::OUString::createFromAscii(ECMA_FORMCHECKBOX_CHECKED
),
245 ::rtl::OUString::createFromAscii(aFormula
.nChecked
!=0?"on":"off"));
246 // set field data here...
253 eF_ResT
SwWW8ImplReader::Read_F_FormListBox( WW8FieldDesc
* pF
, String
& rStr
)
255 WW8FormulaListBox
aFormula(*this);
257 if (0x01 == rStr
.GetChar(writer_cast
<xub_StrLen
>(pF
->nLCode
-1)))
258 ImportFormulaControl(aFormula
,pF
->nSCode
+pF
->nLCode
-1, WW8_CT_DROPDOWN
);
260 const SvtFilterOptions
* pOpt
= SvtFilterOptions::Get();
261 sal_Bool bUseEnhFields
=(pOpt
&& pOpt
->IsUseEnhancedFields());
263 if (!bUseEnhFields
) {
264 SwDropDownField
aFld(
265 (SwDropDownFieldType
*)rDoc
.GetSysFldType(RES_DROPDOWN
));
267 aFld
.SetName(aFormula
.sTitle
);
268 aFld
.SetHelp(aFormula
.sHelp
);
269 aFld
.SetToolTip(aFormula
.sToolTip
);
271 if (!aFormula
.maListEntries
.empty())
273 aFld
.SetItems(aFormula
.maListEntries
);
274 int nIndex
= aFormula
.fDropdownIndex
< aFormula
.maListEntries
.size()
275 ? aFormula
.fDropdownIndex
: 0;
276 aFld
.SetSelectedItem(aFormula
.maListEntries
[nIndex
]);
279 rDoc
.Insert(*pPaM
, SwFmtFld(aFld
), 0);
282 //@TODO fix: copy pasting here!!!!!!!!!!!!!!
283 //REVIEW: don't let this throught.... sometime I forget to get rid of my proof of concept stuff. Please kindly remind me!!!!!
285 String aBookmarkName
;
286 WW8PLCFx_Book
* pB
= pPlcxMan
->GetBook();
288 WW8_CP currentCP
=pF
->nSCode
;
289 WW8_CP currentLen
=pF
->nLen
;
292 String aBookmarkFind
=pB
->GetBookmark(currentCP
-1, currentCP
+currentLen
-1, bkmFindIdx
);
294 if (aBookmarkFind
.Len()>0) {
295 pB
->SetStatus(bkmFindIdx
, BOOK_FIELD
); // mark as consumed by field
296 if (aBookmarkFind
.Len()>0) {
297 aBookmarkName
=aBookmarkFind
;
302 if (pB
!=NULL
&& aBookmarkName
.Len()==0) {
303 aBookmarkName
=pB
->GetUniqueBookmarkName(aFormula
.sTitle
);
306 if (aBookmarkName
.Len()>0)
308 IDocumentMarkAccess
* pMarksAccess
= rDoc
.getIDocumentMarkAccess( );
309 IFieldmark
*pFieldmark
= dynamic_cast<IFieldmark
*>( pMarksAccess
->makeNoTextFieldBookmark(
310 *pPaM
, aBookmarkName
, ::rtl::OUString::createFromAscii( ECMA_FORMDROPDOWN
) ) );
311 ASSERT(pFieldmark
!=NULL
, "hmmm; why was the bookmark not created?");
312 if ( pFieldmark
!= NULL
) {
313 rtl::OUString sListEntry
=rtl::OUString::createFromAscii( ECMA_FORMDROPDOWN_LISTENTRY
);
314 std::vector
<String
>::iterator it
= aFormula
.maListEntries
.begin();
315 for( ; it
!= aFormula
.maListEntries
.end(); it
++ )
316 pFieldmark
->addParam(sListEntry
, *it
, false);
318 int nIndex
= aFormula
.fDropdownIndex
< aFormula
.maListEntries
.size() ? aFormula
.fDropdownIndex
: 0;
319 pFieldmark
->addParam(ECMA_FORMDROPDOWN_RESULT
, nIndex
);
320 // set field data here...
329 eF_ResT
SwWW8ImplReader::Read_F_HTMLControl( WW8FieldDesc
* pF
, String
& rStr
)
331 if( bObj
&& nPicLocFc
)
332 nObjLocFc
= nPicLocFc
;
337 void SwWW8ImplReader::DeleteFormImpl()
339 delete pFormImpl
, pFormImpl
= 0;
342 //----------------------------------------------------------------------------
343 // WW8ListManager oeffentliche Methoden stehen ganz am Ende
344 //------------------------- ============ --------------- ============ --------
348 // Hilfs-Deklarationen ///////////////////////////////////////////////////////
350 // Style Id's for each level
351 typedef sal_uInt16 WW8aIdSty
[WW8ListManager::nMaxLevel
];
352 // Zeichenattribute aus GrpprlChpx
353 typedef SfxItemSet
* WW8aISet
[WW8ListManager::nMaxLevel
];
354 // Zeichen Style Pointer
355 typedef SwCharFmt
* WW8aCFmt
[WW8ListManager::nMaxLevel
];
357 struct WW8LST
// nur DIE Eintraege, die WIR benoetigen!
359 WW8aIdSty aIdSty
; // Style Id's for each level,
360 // nIStDNil if no style linked
361 sal_uInt32 nIdLst
; // Unique List ID
362 sal_uInt32 nTplC
; // Unique template code - Was ist das bloss?
363 BYTE bSimpleList
:1; // Flag: Liste hat nur EINEN Level
364 BYTE bRestartHdn
:1; // WW6-Kompatibilitaets-Flag:
365 // true if the list should start numbering over
366 }; // at the beginning of each section
368 struct WW8LFO
// nur DIE Eintraege, die WIR benoetigen!
370 SwNumRule
* pNumRule
; // Parent NumRule
371 sal_uInt32 nIdLst
; // Unique List ID
372 sal_uInt8 nLfoLvl
; // count of levels whose format is overridden
376 struct WW8LVL
// nur DIE Eintraege, die WIR benoetigen!
378 long nStartAt
; // start at value for this value
379 long nV6DxaSpace
;// Ver6-Compatible: min Space between Num anf text::Paragraph
380 long nV6Indent
; // Ver6-Compatible: Breite des Prefix Textes; ggfs. zur
381 // Definition d. Erstzl.einzug nutzen!
382 // Absatzattribute aus GrpprlPapx
383 sal_uInt16 nDxaLeft
; // linker Einzug
384 short nDxaLeft1
; // Erstzeilen-Einzug
386 sal_uInt8 nNFC
; // number format code
387 // Offset der Feldkodes im Num-X-String
388 sal_uInt8 aOfsNumsXCH
[WW8ListManager::nMaxLevel
];
389 sal_uInt8 nLenGrpprlChpx
; // length, in bytes, of the LVL's grpprlChpx
390 sal_uInt8 nLenGrpprlPapx
; // length, in bytes, of the LVL's grpprlPapx
391 sal_uInt8 nAlign
: 2; // alignment (left, right, centered) of the number
392 BYTE bLegal
: 1; // egal
393 BYTE bNoRest
:1; // egal
394 BYTE bV6Prev
:1; // Ver6-Compatible: number will include previous levels
395 BYTE bV6PrSp
:1; // Ver6-Compatible: egal
396 BYTE bV6
: 1; // falls true , beachte die V6-Compatible Eintraege!
397 sal_uInt8 bDummy
: 1; // (macht das Byte voll)
403 long nStartAt
; // start-at value if bFormat==false and bStartAt == true
404 // (if bFormat==true, the start-at is stored in the LVL)
405 sal_uInt8 nLevel
; // the level to be overridden
406 // dieses Byte ist _absichtlich_ nicht in das folgende Byte hineingepackt !!
407 // (siehe Kommentar unten bei struct WW8LFOInfo)
409 BYTE bStartAt
:1; // true if the start-at value is overridden
410 BYTE bFormat
:1; // true if the formatting is overriden
413 nStartAt(1), nLevel(0), bStartAt(1), bFormat(0) {}
416 // in den ListenInfos zu speichernde Daten ///////////////////////////////////
418 struct WW8LSTInfo
// sortiert nach nIdLst (in WW8 verwendete Listen-Id)
420 std::vector
<ww::bytes
> maParaSprms
;
421 WW8aIdSty aIdSty
; // Style Id's for each level
422 WW8aISet aItemSet
; // Zeichenattribute aus GrpprlChpx
423 WW8aCFmt aCharFmt
; // Zeichen Style Pointer
425 SwNumRule
* pNumRule
; // Zeiger auf entsprechende Listenvorlage im Writer
426 sal_uInt32 nIdLst
; // WW8Id dieser Liste
427 BYTE bSimpleList
:1;// Flag, ob diese NumRule nur einen Level verwendet
428 BYTE bUsedInDoc
:1;// Flag, ob diese NumRule im Doc verwendet wird,
429 // oder beim Reader-Ende geloescht werden sollte
431 WW8LSTInfo(SwNumRule
* pNumRule_
, WW8LST
& aLST
)
432 : pNumRule(pNumRule_
), nIdLst(aLST
.nIdLst
),
433 bSimpleList(aLST
.bSimpleList
), bUsedInDoc(0)
435 memcpy( aIdSty
, aLST
.aIdSty
, sizeof( aIdSty
));
436 memset(&aItemSet
, 0, sizeof( aItemSet
));
437 memset(&aCharFmt
, 0, sizeof( aCharFmt
));
442 // in den ListenFormatOverrideInfos zu speichernde Daten /////////////////////
444 struct WW8LFOInfo
// unsortiert, d.h. Reihenfolge genau wie im WW8 Stream
446 std::vector
<ww::bytes
> maParaSprms
;
447 std::vector
<WW8LFOLVL
> maOverrides
;
448 SwNumRule
* pNumRule
; // Zeiger auf entsprechende Listenvorlage im Writer
449 // entweder: Liste in LSTInfos oder eigene Liste
450 // (im Ctor erstmal die aus den LSTInfos merken)
452 sal_uInt32 nIdLst
; // WW8-Id der betreffenden Liste
453 sal_uInt8 nLfoLvl
; // count of levels whose format is overridden
454 // Ja, ich natuerlich koennten wir nLfoLvl (mittels :4) noch in das folgende
455 // Byte mit hineinpacken, doch waere das eine ziemliche Fehlerquelle,
456 // an dem Tag, wo MS ihr Listenformat auf mehr als 15 Level aufbohren.
458 BYTE bOverride
:1;// Flag, ob die NumRule nicht in maLSTInfos steht,
459 // sondern fuer pLFOInfos NEU angelegt wurde
460 BYTE bSimpleList
:1;// Flag, ob diese NumRule nur einen Level verwendet
461 BYTE bUsedInDoc
:1;// Flag, ob diese NumRule im Doc verwendet wird,
462 // oder beim Reader-Ende geloescht werden sollte
463 BYTE bLSTbUIDSet
:1;// Flag, ob bUsedInDoc in maLSTInfos gesetzt wurde,
464 // und nicht nochmals gesetzt zu werden braucht
465 WW8LFOInfo(const WW8LFO
& rLFO
);
468 WW8LFOInfo::WW8LFOInfo(const WW8LFO
& rLFO
)
469 : maParaSprms(WW8ListManager::nMaxLevel
),
470 maOverrides(WW8ListManager::nMaxLevel
), pNumRule(rLFO
.pNumRule
),
471 nIdLst(rLFO
.nIdLst
), nLfoLvl(rLFO
.nLfoLvl
),
472 bOverride(rLFO
.nLfoLvl
? true : false), bSimpleList(rLFO
.bSimpleList
),
473 bUsedInDoc(0), bLSTbUIDSet(0)
477 SV_IMPL_PTRARR( WW8LFOInfos
, WW8LFOInfo_Ptr
);
480 // Hilfs-Methoden ////////////////////////////////////////////////////////////
483 // finden der Sprm-Parameter-Daten, falls Sprm im Grpprl enthalten
484 sal_uInt8
* WW8ListManager::GrpprlHasSprm(sal_uInt16 nId
, sal_uInt8
& rSprms
,
487 sal_uInt8
* pSprms
= &rSprms
;
491 sal_uInt16 nAktId
= maSprmParser
.GetSprmId(pSprms
);
492 if( nAktId
== nId
) // Sprm found
493 return pSprms
+ maSprmParser
.DistanceToData(nId
);
495 // gib Zeiger auf Daten
496 USHORT x
= maSprmParser
.GetSprmSize(nAktId
, pSprms
);
500 return 0; // Sprm not found
503 class ListWithId
: public std::unary_function
<const WW8LSTInfo
*, bool>
508 explicit ListWithId(sal_uInt32 nIdLst
) : mnIdLst(nIdLst
) {}
509 bool operator() (const WW8LSTInfo
*pEntry
) const
510 { return (pEntry
->nIdLst
== mnIdLst
); }
513 // Zugriff ueber die List-Id des LST Eintrags
514 WW8LSTInfo
* WW8ListManager::GetLSTByListId( sal_uInt32 nIdLst
) const
516 std::vector
<WW8LSTInfo
*>::const_iterator aResult
=
517 std::find_if(maLSTInfos
.begin(),maLSTInfos
.end(),ListWithId(nIdLst
));
518 if (aResult
== maLSTInfos
.end())
523 void lcl_CopyGreaterEight(String
&rDest
, String
&rSrc
,
524 xub_StrLen nStart
, xub_StrLen nLen
= STRING_LEN
)
526 if (nLen
== STRING_LEN
)
528 for (xub_StrLen nI
= nStart
; nI
< nLen
; ++nI
)
530 sal_Unicode nChar
= rSrc
.GetChar(nI
);
531 if (nChar
> WW8ListManager::nMaxLevel
)
536 bool WW8ListManager::ReadLVL(SwNumFmt
& rNumFmt
, SfxItemSet
*& rpItemSet
,
537 sal_uInt16 nLevelStyle
, bool bSetStartNo
,
538 std::deque
<bool> &rNotReallyThere
, sal_uInt16 nLevel
,
539 ww::bytes
&rParaSprms
)
542 sal_uInt16 nStartNo
= 0; // Start-Nr. fuer den Writer
543 SvxExtNumType eType
; // Writer-Num-Typ
544 SvxAdjust eAdj
; // Ausrichtung (Links/rechts/zent.)
545 sal_Unicode
cBullet(0x2190); // default safe bullet
552 memset(&aLVL
, 0, sizeof( aLVL
));
553 rSt
>> aLVL
.nStartAt
;
556 if( 0 != rSt
.GetError() ) return false;
557 aLVL
.nAlign
= (aBits1
& 0x03);
558 if( aBits1
& 0x10 ) aLVL
.bV6Prev
= true;
559 if( aBits1
& 0x20 ) aLVL
.bV6PrSp
= true;
560 if( aBits1
& 0x40 ) aLVL
.bV6
= true;
562 sal_uInt8 nLevelB
= 0;
563 for(nLevelB
= 0; nLevelB
< nMaxLevel
; ++nLevelB
)
565 rSt
>> aLVL
.aOfsNumsXCH
[ nLevelB
];
566 if( 0 != rSt
.GetError() )
576 sal_uInt8 ixchFollow
;
579 rReader
.maTracer
.Log(sw::log::eTabInNumbering
);
580 rSt
>> aLVL
.nV6DxaSpace
;
581 rSt
>> aLVL
.nV6Indent
;
582 rSt
>> aLVL
.nLenGrpprlChpx
;
583 rSt
>> aLVL
.nLenGrpprlPapx
;
585 if( 0 != rSt
.GetError()) return false;
588 // 2. ggfs. PAPx einlesen und nach Einzug-Werten suchen
590 // --> OD 2008-06-04 #i86652# - read tab setting
593 if( aLVL
.nLenGrpprlPapx
)
595 sal_uInt8 aGrpprlPapx
[ 255 ];
596 if(aLVL
.nLenGrpprlPapx
!= rSt
.Read(&aGrpprlPapx
,aLVL
.nLenGrpprlPapx
))
598 // "sprmPDxaLeft" pap.dxaLeft;dxa;word;
601 (0 != (pSprm
= GrpprlHasSprm(0x840F,aGrpprlPapx
[0],aLVL
.nLenGrpprlPapx
))) ||
602 (0 != (pSprm
= GrpprlHasSprm(0x845E,aGrpprlPapx
[0],aLVL
.nLenGrpprlPapx
)))
605 sal_uInt8
*pBegin
= pSprm
-2;
607 rParaSprms
.push_back(*pBegin
++);
608 short nDxaLeft
= SVBT16ToShort( pSprm
);
609 aLVL
.nDxaLeft
= (0 < nDxaLeft
) ? (sal_uInt16
)nDxaLeft
610 : (sal_uInt16
)(-nDxaLeft
);
613 // "sprmPDxaLeft1" pap.dxaLeft1;dxa;word;
615 (0 != (pSprm
= GrpprlHasSprm(0x8411,aGrpprlPapx
[0],aLVL
.nLenGrpprlPapx
)) ) ||
616 (0 != (pSprm
= GrpprlHasSprm(0x8460,aGrpprlPapx
[0],aLVL
.nLenGrpprlPapx
)) )
619 sal_uInt8
*pBegin
= pSprm
-2;
621 rParaSprms
.push_back(*pBegin
++);
622 aLVL
.nDxaLeft1
= SVBT16ToShort( pSprm
);
625 // --> OD 2008-06-04 #i86652# - read tab setting
626 if(0 != (pSprm
= GrpprlHasSprm(0xC615,aGrpprlPapx
[0],aLVL
.nLenGrpprlPapx
)) )
631 if (*pSprm
++ == 0) //nDel
633 if (*pSprm
++ == 1) //nIns
635 nTabPos
= SVBT16ToShort(pSprm
);
637 if (*pSprm
== 6) //type
644 ASSERT(bDone
, "tab setting in numbering is "
645 "of unexpected configuration");
647 if ( rNumFmt
.GetPositionAndSpaceMode() ==
648 SvxNumberFormat::LABEL_WIDTH_AND_POSITION
)
650 // If there is a tab setting with a larger value, then use that.
651 // Ideally we would allow tabs to be used in numbering fields and set
652 // this on the containing paragraph which would make it actually work
656 const USHORT nDesired
= aLVL
.nDxaLeft
+ aLVL
.nDxaLeft1
;
658 bool bDoAdjust
= false;
659 if ( nDesired
< aLVL
.nDxaLeft
)
661 if ( nDesired
< nTabPos
&& nTabPos
< aLVL
.nDxaLeft
)
668 if ( aLVL
.nDxaLeft
< nTabPos
&& nTabPos
< nDesired
)
676 aLVL
.nDxaLeft
= (0 < nTabPos
)
677 ? (sal_uInt16
)nTabPos
678 : (sal_uInt16
)(-nTabPos
);
680 aLVL
.nDxaLeft1
= nDesired
- aLVL
.nDxaLeft
;
687 // 3. ggfs. CHPx einlesen und
689 if( aLVL
.nLenGrpprlChpx
)
691 sal_uInt8 aGrpprlChpx
[ 255 ];
692 memset(&aGrpprlChpx
, 0, sizeof( aGrpprlChpx
));
693 if(aLVL
.nLenGrpprlChpx
!= rSt
.Read(&aGrpprlChpx
, aLVL
.nLenGrpprlChpx
))
695 // neues ItemSet fuer die Zeichenattribute anlegen
696 rpItemSet
= new SfxItemSet( rDoc
.GetAttrPool(), RES_CHRATR_BEGIN
,
697 RES_CHRATR_END
- 1 );
699 // Reader-ItemSet-Pointer darauf zeigen lassen
700 rReader
.SetAktItemSet( rpItemSet
);
701 // Reader-Style auf den Style dieses Levels setzen
702 sal_uInt16 nOldColl
= rReader
.GetNAktColl();
703 sal_uInt16 nNewColl
= nLevelStyle
;
704 if (ww::stiNil
== nNewColl
)
706 rReader
.SetNAktColl( nNewColl
);
708 // Nun den GrpprlChpx einfach durchnudeln: die Read_xy() Methoden
709 // in WW8PAR6.CXX rufen ganz normal ihr NewAttr() oder GetFmtAttr()
710 // und diese merken am besetzten Reader-ItemSet-Pointer, dass dieser
711 // spezielle ItemSet relevant ist - und nicht ein Stack oder Style!
712 USHORT nOldFlags1
= rReader
.GetToggleAttrFlags();
713 USHORT nOldFlags2
= rReader
.GetToggleBiDiAttrFlags();
714 short nLen
= aLVL
.nLenGrpprlChpx
;
715 sal_uInt8
* pSprms1
= &aGrpprlChpx
[0];
718 sal_uInt16 nL1
= rReader
.ImportSprm( pSprms1
);
722 // Reader-ItemSet-Pointer und Reader-Style zuruecksetzen
723 rReader
.SetAktItemSet( 0 );
724 rReader
.SetNAktColl( nOldColl
);
725 rReader
.SetToggleAttrFlags(nOldFlags1
);
726 rReader
.SetToggleBiDiAttrFlags(nOldFlags2
);
729 // 4. den Nummerierungsstring einlesen: ergibt Prefix und Postfix
731 String
sNumString(WW8Read_xstz(rSt
, 0, false));
734 // 5. gelesene Werte in Writer Syntax umwandeln
736 if( 0 <= aLVL
.nStartAt
)
737 nStartNo
= (sal_uInt16
)aLVL
.nStartAt
;
742 eType
= SVX_NUM_ARABIC
;
745 eType
= SVX_NUM_ROMAN_UPPER
;
748 eType
= SVX_NUM_ROMAN_LOWER
;
751 eType
= SVX_NUM_CHARS_UPPER_LETTER_N
;
754 eType
= SVX_NUM_CHARS_LOWER_LETTER_N
;
757 // eigentlich: ORDINAL
758 eType
= SVX_NUM_ARABIC
;
762 eType
= SVX_NUM_CHAR_SPECIAL
;
765 eType
= SVX_NUM_NUMBER_NONE
;
769 eType
= SVX_NUM_ARABIC
;
773 //If a number level is not going to be used, then record this fact
774 if (SVX_NUM_NUMBER_NONE
== eType
)
775 rNotReallyThere
[nLevel
] = true;
778 If a number level was not used (i.e. is in NotReallyThere), and that
779 number level appears at one of the positions in the display string of the
780 list, then it effectively is not there at all. So remove that level entry
781 from a copy of the aOfsNumsXCH.
783 std::vector
<sal_uInt8
> aOfsNumsXCH
;
784 typedef std::vector
<sal_uInt8
>::iterator myIter
;
785 aOfsNumsXCH
.reserve(nMaxLevel
);
787 for(nLevelB
= 0; nLevelB
< nMaxLevel
; ++nLevelB
)
788 aOfsNumsXCH
.push_back(aLVL
.aOfsNumsXCH
[nLevelB
]);
790 for(nLevelB
= 0; nLevelB
<= nLevel
; ++nLevelB
)
792 sal_uInt8 nPos
= aOfsNumsXCH
[nLevelB
];
793 if (nPos
&& sNumString
.GetChar(nPos
-1) < nMaxLevel
)
795 if (rNotReallyThere
[nLevelB
])
796 aOfsNumsXCH
[nLevelB
] = 0;
799 myIter aIter
= std::remove(aOfsNumsXCH
.begin(), aOfsNumsXCH
.end(), 0);
800 myIter aEnd
= aOfsNumsXCH
.end();
801 // --> OD 2006-01-16 #i60633# - suppress access on <aOfsNumsXCH.end()>
804 // Somehow the first removed vector element, at which <aIter>
805 // points to, isn't reset to zero.
806 // Investigation is needed to clarify why. It seems that only
807 // special arrays are handled correctly by this code.
809 while (aIter
!= aEnd
)
817 sal_uInt8 nUpperLevel
= 0; // akt. Anzeigetiefe fuer den Writer
818 for(nLevelB
= 0; nLevelB
< nMaxLevel
; ++nLevelB
)
820 if (!nUpperLevel
&& !aOfsNumsXCH
[nLevelB
])
821 nUpperLevel
= nLevelB
;
824 // falls kein NULL als Terminierungs-Char kam,
825 // ist die Liste voller Indices, d.h. alle Plaetze sind besetzt,
826 // also sind alle Level anzuzeigen
828 nUpperLevel
= nMaxLevel
;
830 if (SVX_NUM_CHAR_SPECIAL
== eType
)
832 cBullet
= sNumString
.Len() ? sNumString
.GetChar(0) : 0x2190;
834 if (!cBullet
) // unsave control code?
840 #83154#, #82192#, #i173#, #109158#
841 Our aOfsNumsXCH seems generally to be an array that contains the
842 offset into sNumString of locations where the numbers should be
843 filled in, so if the first "fill in a number" slot is greater than
844 1 there is a "prefix" before the number
846 //First number appears at
847 sal_uInt8 nOneBasedFirstNoIndex
= aOfsNumsXCH
[0];
848 xub_StrLen nFirstNoIndex
=
849 nOneBasedFirstNoIndex
> 0 ? nOneBasedFirstNoIndex
-1 : STRING_LEN
;
850 lcl_CopyGreaterEight(sPrefix
, sNumString
, 0, nFirstNoIndex
);
852 //Next number appears at
855 sal_uInt8 nOneBasedNextNoIndex
= aOfsNumsXCH
[nUpperLevel
-1];
856 xub_StrLen nNextNoIndex
=
857 nOneBasedNextNoIndex
> 0 ? nOneBasedNextNoIndex
-1 : STRING_LEN
;
858 if (nNextNoIndex
!= STRING_LEN
)
860 if (sNumString
.Len() > nNextNoIndex
)
861 lcl_CopyGreaterEight(sPostfix
, sNumString
, nNextNoIndex
);
865 We use lcl_CopyGreaterEight because once if we have removed unused
866 number indexes from the aOfsNumsXCH then placeholders remain in
867 sNumString which must not be copied into the final numbering strings
871 switch( aLVL
.nAlign
)
874 eAdj
= SVX_ADJUST_LEFT
;
877 eAdj
= SVX_ADJUST_CENTER
;
880 eAdj
= SVX_ADJUST_RIGHT
;
883 // Writer here cannot do block justification
884 eAdj
= SVX_ADJUST_LEFT
;
888 ASSERT( !this, "Value of aLVL.nAlign is not supported" );
890 eAdj
= SVX_ADJUST_LEFT
;
894 // 6. entsprechendes NumFmt konfigurieren
896 rNumFmt
.SetStart( nStartNo
);
897 rNumFmt
.SetNumberingType( static_cast< sal_Int16
>(eType
) );
898 rNumFmt
.SetNumAdjust( eAdj
);
900 if( SVX_NUM_CHAR_SPECIAL
== eType
)
902 // first character of the Prefix-Text is the Bullet
903 rNumFmt
.SetBulletChar(cBullet
);
904 // Don't forget: unten, nach dem Bauen eventueller Styles auch noch
905 // SetBulletFont() rufen !!!
909 // reminder: Garnix ist default Prefix
911 rNumFmt
.SetPrefix( sPrefix
);
912 // reminder: Point is default Postfix
913 rNumFmt
.SetSuffix( sPostfix
);
914 rNumFmt
.SetIncludeUpperLevels( nUpperLevel
);
917 // --> OD 2008-06-04 #i89181#
918 if ( rNumFmt
.GetPositionAndSpaceMode() ==
919 SvxNumberFormat::LABEL_WIDTH_AND_POSITION
)
921 if (eAdj
== SVX_ADJUST_RIGHT
)
923 rNumFmt
.SetAbsLSpace(aLVL
.nDxaLeft
);
924 rNumFmt
.SetFirstLineOffset(-aLVL
.nDxaLeft
);
925 rNumFmt
.SetCharTextDistance(-aLVL
.nDxaLeft1
);
929 rNumFmt
.SetAbsLSpace( aLVL
.nDxaLeft
);
930 rNumFmt
.SetFirstLineOffset(aLVL
.nDxaLeft1
);
935 rNumFmt
.SetIndentAt( aLVL
.nDxaLeft
);
936 rNumFmt
.SetFirstLineIndent(aLVL
.nDxaLeft1
);
937 rNumFmt
.SetListtabPos( nTabPos
);
938 SvxNumberFormat::SvxNumLabelFollowedBy eNumLabelFollowedBy
= SvxNumberFormat::LISTTAB
;
939 switch ( ixchFollow
)
943 eNumLabelFollowedBy
= SvxNumberFormat::LISTTAB
;
948 eNumLabelFollowedBy
= SvxNumberFormat::SPACE
;
953 eNumLabelFollowedBy
= SvxNumberFormat::NOTHING
;
957 rNumFmt
.SetLabelFollowedBy( eNumLabelFollowedBy
);
963 void WW8ListManager::AdjustLVL( sal_uInt8 nLevel
, SwNumRule
& rNumRule
,
964 WW8aISet
& rListItemSet
, WW8aCFmt
& rCharFmt
, bool& bNewCharFmtCreated
,
967 bNewCharFmtCreated
= false;
968 SfxItemSet
* pThisLevelItemSet
;
969 SfxItemSet
* pLowerLevelItemSet
;
970 sal_uInt8 nIdenticalItemSetLevel
;
971 const SfxPoolItem
* pItem
;
973 SwNumFmt aNumFmt
= rNumRule
.Get( nLevel
);
975 pThisLevelItemSet
= rListItemSet
[ nLevel
];
977 if( pThisLevelItemSet
&& pThisLevelItemSet
->Count())
979 nIdenticalItemSetLevel
= nMaxLevel
;
980 SfxItemIter
aIter( *pThisLevelItemSet
);
981 for (sal_uInt8 nLowerLevel
= 0; nLowerLevel
< nLevel
; ++nLowerLevel
)
983 pLowerLevelItemSet
= rListItemSet
[ nLowerLevel
];
984 if( pLowerLevelItemSet
985 && (pLowerLevelItemSet
->Count() == pThisLevelItemSet
->Count()) )
987 nIdenticalItemSetLevel
= nLowerLevel
;
988 sal_uInt16 nWhich
= aIter
.GetCurItem()->Which();
991 if( // ggfs. passenden pItem im pLowerLevelItemSet finden
992 (SFX_ITEM_SET
!= pLowerLevelItemSet
->GetItemState(
993 nWhich
, false, &pItem
) )
994 || // virtuellen "!=" Operator anwenden
995 (*pItem
!= *aIter
.GetCurItem() ) )
996 // falls kein Item mit gleicher nWhich gefunden oder Werte
997 // der Items ungleich, Ungleichheit merken und abbrechen!
999 nIdenticalItemSetLevel
= nMaxLevel
;
1002 if( aIter
.IsAtEnd() )
1004 nWhich
= aIter
.NextItem()->Which();
1007 if( nIdenticalItemSetLevel
!= nMaxLevel
)
1013 if (nMaxLevel
== nIdenticalItemSetLevel
)
1016 String
aName( sPrefix
.Len() ? sPrefix
: rNumRule
.GetName() );
1017 (aName
+= 'z') += String::CreateFromInt32( nLevel
);
1020 pFmt
= rDoc
.MakeCharFmt(aName
, (SwCharFmt
*)rDoc
.GetDfltCharFmt());
1021 bNewCharFmtCreated
= true;
1022 // Attribute reinsetzen
1023 pFmt
->SetFmtAttr( *pThisLevelItemSet
);
1027 // passenden Style hier anhaengen
1028 pFmt
= rCharFmt
[ nIdenticalItemSetLevel
];
1032 rCharFmt
[ nLevel
] = pFmt
;
1035 // Style an das NumFormat haengen
1037 aNumFmt
.SetCharFmt( pFmt
);
1040 // ggfs. Bullet Font an das NumFormat haengen
1042 if( SVX_NUM_CHAR_SPECIAL
== aNumFmt
.GetNumberingType() )
1044 SwCharFmt
* pFmt
= aNumFmt
.GetCharFmt();
1048 // --> OD 2006-06-27 #b6440955#
1049 // aFont = SwNumRule::GetDefBulletFont();
1050 aFont
= numfunc::GetDefBulletFont();
1055 const SvxFontItem
& rFontItem
= pFmt
->GetFont();
1056 aFont
.SetFamily( rFontItem
.GetFamily() );
1057 aFont
.SetName( rFontItem
.GetFamilyName() );
1058 aFont
.SetStyleName( rFontItem
.GetStyleName() );
1059 aFont
.SetPitch( rFontItem
.GetPitch() );
1060 aFont
.SetCharSet( rFontItem
.GetCharSet() );
1062 aNumFmt
.SetBulletFont( &aFont
);
1065 // und wieder rein in die NumRule
1067 rNumRule
.Set(nLevel
, aNumFmt
);
1070 SwNumRule
* WW8ListManager::CreateNextRule(bool bSimple
)
1072 // wird erstmal zur Bildung des Style Namens genommen
1073 String
sPrefix(CREATE_CONST_ASC("WW8Num"));
1074 sPrefix
+= String::CreateFromInt32(nUniqueList
++);
1075 // --> OD 2008-06-04 #i86652#
1076 // sal_uInt16 nRul = rDoc.MakeNumRule(rDoc.GetUniqueNumRuleName(&sPrefix));
1078 rDoc
.MakeNumRule( rDoc
.GetUniqueNumRuleName(&sPrefix
), 0, FALSE
,
1079 SvxNumberFormat::LABEL_ALIGNMENT
);
1081 SwNumRule
* pMyNumRule
= rDoc
.GetNumRuleTbl()[nRul
];
1082 pMyNumRule
->SetAutoRule(false);
1083 pMyNumRule
->SetContinusNum(bSimple
);
1087 // oeffentliche Methoden /////////////////////////////////////////////////////
1089 WW8ListManager::WW8ListManager(SvStream
& rSt_
, SwWW8ImplReader
& rReader_
)
1090 : maSprmParser(rReader_
.GetFib().GetFIBVersion()), rReader(rReader_
),
1091 rDoc(rReader
.GetDoc()), rFib(rReader
.GetFib()), rSt(rSt_
), pLFOInfos(0),
1094 // LST und LFO gibts erst ab WW8
1095 if( ( 8 > rFib
.nVersion
)
1096 || ( rFib
.fcPlcfLst
== rFib
.fcPlfLfo
)
1097 || ( !rFib
.lcbPlcfLst
)
1098 || ( !rFib
.lcbPlfLfo
) ) return; // offensichtlich keine Listen da
1101 pLFOInfos
= new WW8LFOInfos
;
1105 nLastLFOPosition
= USHRT_MAX
;
1106 long nOriginalPos
= rSt
.Tell();
1108 // 1. PLCF LST auslesen und die Listen Vorlagen im Writer anlegen
1110 rSt
.Seek( rFib
.fcPlcfLst
);
1111 sal_uInt16 nListCount
;
1113 bool bOk
= 0 < nListCount
;
1118 // 1.1 alle LST einlesen
1120 for (sal_uInt16 nList
=0; nList
< nListCount
; ++nList
)
1123 memset(&aLST
, 0, sizeof( aLST
));
1126 // 1.1.1 Daten einlesen
1130 for (nLevel
= 0; nLevel
< nMaxLevel
; ++nLevel
)
1131 rSt
>> aLST
.aIdSty
[ nLevel
];
1142 aLST
.bSimpleList
= true;
1144 aLST
.bRestartHdn
= true;
1146 // 1.1.2 new NumRule inserted in Doc and WW8LSTInfo marked
1150 In word 2000 microsoft got rid of creating new "simple lists" with
1151 only 1 level, all new lists are created with 9 levels. To hack it
1152 so that the list types formerly known as simple lists still have
1153 their own tab page to themselves one of the reserved bits is used
1154 to show that a given list is to be in the simple list tabpage.
1155 This has now nothing to do with the actual number of list level a
1156 list has, only how many will be shown in the user interface.
1158 i.e. create a simple list in 2000 and open it in 97 and 97 will
1159 claim (correctly) that it is an outline list. We can set our
1160 continous flag in these lists to store this information.
1162 SwNumRule
* pMyNumRule
= CreateNextRule(
1163 aLST
.bSimpleList
|| (aBits1
& 0x10));
1165 WW8LSTInfo
* pLSTInfo
= new WW8LSTInfo(pMyNumRule
, aLST
);
1166 maLSTInfos
.push_back(pLSTInfo
);
1174 // 1.2 alle LVL aller aLST einlesen
1177 sal_uInt16 nLSTInfos
= static_cast< sal_uInt16
>(maLSTInfos
.size());
1178 for (sal_uInt16 nList
= 0; nList
< nLSTInfos
; ++nList
)
1181 WW8LSTInfo
* pListInfo
= maLSTInfos
[nList
];
1182 if( !pListInfo
|| !pListInfo
->pNumRule
) break;
1183 SwNumRule
& rMyNumRule
= *pListInfo
->pNumRule
;
1185 // 1.2.1 betreffende(n) LVL(s) fuer diese aLST einlesen
1187 sal_uInt16 nLvlCount
= static_cast< sal_uInt16
>(pListInfo
->bSimpleList
? nMinLevel
: nMaxLevel
);
1188 std::deque
<bool> aNotReallyThere
;
1189 aNotReallyThere
.resize(nMaxLevel
);
1190 pListInfo
->maParaSprms
.resize(nMaxLevel
);
1191 for (nLevel
= 0; nLevel
< nLvlCount
; ++nLevel
)
1193 SwNumFmt
aNumFmt( rMyNumRule
.Get( nLevel
) );
1195 bLVLOk
= ReadLVL( aNumFmt
, pListInfo
->aItemSet
[nLevel
],
1196 pListInfo
->aIdSty
[nLevel
], true, aNotReallyThere
, nLevel
,
1197 pListInfo
->maParaSprms
[nLevel
]);
1200 // und in die rMyNumRule aufnehmen
1201 rMyNumRule
.Set( nLevel
, aNumFmt
);
1206 // 1.2.2 die ItemPools mit den CHPx Einstellungen der verschiedenen
1207 // Level miteinander vergleichen und ggfs. Style(s) erzeugen
1210 for (nLevel
= 0; nLevel
< nLvlCount
; ++nLevel
)
1212 AdjustLVL( nLevel
, rMyNumRule
, pListInfo
->aItemSet
,
1213 pListInfo
->aCharFmt
, bDummy
);
1216 // 1.2.3 ItemPools leeren und loeschen
1218 for (nLevel
= 0; nLevel
< nLvlCount
; ++nLevel
)
1219 delete pListInfo
->aItemSet
[ nLevel
];
1225 // Fehler aufgetreten - LSTInfos abraeumen !!!
1231 // 2. PLF LFO auslesen und speichern
1236 rSt
.Seek(rFib
.fcPlfLfo
);
1246 // 2.1 alle LFO einlesen
1248 for (sal_uInt16 nLfo
= 0; nLfo
< nLfoCount
; ++nLfo
)
1251 memset(&aLFO
, 0, sizeof( aLFO
));
1254 rSt
>> aLFO
.nLfoLvl
;
1256 // soviele Overrides existieren
1257 if ((nMaxLevel
< aLFO
.nLfoLvl
) || rSt
.GetError())
1260 // die Parent NumRule der entsprechenden Liste ermitteln
1261 WW8LSTInfo
* pParentListInfo
= GetLSTByListId(aLFO
.nIdLst
);
1262 if (pParentListInfo
)
1264 // hier, im ersten Schritt, erst mal diese NumRule festhalten
1265 aLFO
.pNumRule
= pParentListInfo
->pNumRule
;
1267 // hat die Liste mehrere Level ?
1268 aLFO
.bSimpleList
= pParentListInfo
->bSimpleList
;
1270 // und rein ins Merk-Array mit dem Teil
1271 WW8LFOInfo
* pLFOInfo
= new WW8LFOInfo(aLFO
);
1272 if (pParentListInfo
)
1274 //Copy the basic paragraph properties for each level from the
1275 //original list into the list format override levels.
1276 int nMaxSize
= pParentListInfo
->maParaSprms
.size();
1277 pLFOInfo
->maParaSprms
.resize(nMaxSize
);
1278 for (int i
= 0; i
< nMaxSize
; ++i
)
1279 pLFOInfo
->maParaSprms
[i
] = pParentListInfo
->maParaSprms
[i
];
1281 pLFOInfos
->Insert(pLFOInfo
, pLFOInfos
->Count());
1288 // 2.2 fuer alle LFO die zugehoerigen LFOLVL einlesen
1290 sal_uInt16 nLFOInfos
= pLFOInfos
? pLFOInfos
->Count() : 0;
1291 for (sal_uInt16 nLfo
= 0; nLfo
< nLFOInfos
; ++nLfo
)
1294 WW8LFOInfo
* pLFOInfo
= pLFOInfos
->GetObject( nLfo
);
1297 // stehen hierfuer ueberhaupt LFOLVL an ?
1298 if( pLFOInfo
->bOverride
)
1300 WW8LSTInfo
* pParentListInfo
= GetLSTByListId(pLFOInfo
->nIdLst
);
1301 if (!pParentListInfo
) //e.g. #112324#
1304 // 2.2.1 eine neue NumRule fuer diese Liste anlegen
1306 SwNumRule
* pParentNumRule
= pLFOInfo
->pNumRule
;
1307 ASSERT(pParentNumRule
, "ww: Impossible lists, please report");
1308 if( !pParentNumRule
)
1310 // Nauemsprefix aufbauen: fuer NumRule-Name (eventuell)
1311 // und (falls vorhanden) fuer Style-Name (dann auf jeden Fall)
1312 String
sPrefix(CREATE_CONST_ASC( "WW8NumSt" ));
1313 sPrefix
+= String::CreateFromInt32( nLfo
+ 1 );
1314 // jetzt dem pNumRule seinen RICHTIGEN Wert zuweisen !!!
1315 // (bis dahin war hier die Parent NumRule vermerkt )
1317 // Dazu erst mal nachsehen, ob ein Style diesen LFO
1319 if( USHRT_MAX
> rReader
.StyleUsingLFO( nLfo
) )
1321 sal_uInt16 nRul
= rDoc
.MakeNumRule(
1322 rDoc
.GetUniqueNumRuleName( &sPrefix
), pParentNumRule
);
1323 pLFOInfo
->pNumRule
= rDoc
.GetNumRuleTbl()[ nRul
];
1324 pLFOInfo
->pNumRule
->SetAutoRule(false);
1328 sal_uInt16 nRul
= rDoc
.MakeNumRule(
1329 rDoc
.GetUniqueNumRuleName(), pParentNumRule
);
1330 pLFOInfo
->pNumRule
= rDoc
.GetNumRuleTbl()[ nRul
];
1331 pLFOInfo
->pNumRule
->SetAutoRule(true); // = default
1334 // 2.2.2 alle LFOLVL (und ggfs. LVL) fuer die neue NumRule
1337 WW8aISet aItemSet
; // Zeichenattribute aus GrpprlChpx
1338 WW8aCFmt aCharFmt
; // Zeichen Style Pointer
1339 memset(&aItemSet
, 0, sizeof( aItemSet
));
1340 memset(&aCharFmt
, 0, sizeof( aCharFmt
));
1342 //2.2.2.0 skip inter-group of override header ?
1343 //See #i25438# for why I moved this here, compare
1344 //that original bugdoc's binary to what it looks like
1345 //when resaved with word, i.e. there is always a
1346 //4 byte header, there might be more than one if
1347 //that header was 0xFFFFFFFF, e.g. #114412# ?
1352 while (nTest
== 0xFFFFFFFF);
1355 std::deque
<bool> aNotReallyThere(WW8ListManager::nMaxLevel
);
1356 sal_uInt8 nLevel
= 0;
1357 for (nLevel
= 0; nLevel
< pLFOInfo
->nLfoLvl
; ++nLevel
)
1363 // 2.2.2.1 den LFOLVL einlesen
1365 rSt
>> aLFOLVL
.nStartAt
;
1371 // beachte: Die Witzbolde bei MS quetschen die
1372 // Override-Level-Nummer in vier Bits hinein, damit sie
1373 // wieder einen Grund haben, ihr Dateiformat zu aendern,
1374 // falls ihnen einfaellt, dass sie eigentlich doch gerne
1375 // bis zu 16 Listen-Level haetten. Wir tun das *nicht*
1376 // (siehe Kommentar oben bei "struct
1378 aLFOLVL
.nLevel
= aBits1
& 0x0F;
1379 if( (0xFF > aBits1
) &&
1380 (nMaxLevel
> aLFOLVL
.nLevel
) )
1383 aLFOLVL
.bStartAt
= true;
1385 aLFOLVL
.bStartAt
= false;
1387 // 2.2.2.2 eventuell auch den zugehoerigen LVL einlesen
1390 pLFOInfo
->pNumRule
->Get(aLFOLVL
.nLevel
));
1393 aLFOLVL
.bFormat
= true;
1394 // falls bStartup true, hier den Startup-Level
1395 // durch den im LVL vermerkten ersetzen LVLF
1397 bLVLOk
= ReadLVL(aNumFmt
, aItemSet
[nLevel
],
1398 pParentListInfo
->aIdSty
[nLevel
],
1399 aLFOLVL
.bStartAt
, aNotReallyThere
, nLevel
,
1400 pLFOInfo
->maParaSprms
[nLevel
]);
1405 else if (aLFOLVL
.bStartAt
)
1408 writer_cast
<USHORT
>(aLFOLVL
.nStartAt
));
1411 // 2.2.2.3 das NumFmt in die NumRule aufnehmen
1413 pLFOInfo
->pNumRule
->Set(aLFOLVL
.nLevel
, aNumFmt
);
1416 pLFOInfo
->maOverrides
[aLFOLVL
.nLevel
] = aLFOLVL
;
1421 // 2.2.3 die LVL der neuen NumRule anpassen
1423 sal_uInt16 aFlagsNewCharFmt
= 0;
1424 bool bNewCharFmtCreated
= false;
1425 for (nLevel
= 0; nLevel
< pLFOInfo
->nLfoLvl
; ++nLevel
)
1427 AdjustLVL( nLevel
, *pLFOInfo
->pNumRule
, aItemSet
, aCharFmt
,
1428 bNewCharFmtCreated
, sPrefix
);
1429 if( bNewCharFmtCreated
)
1430 aFlagsNewCharFmt
+= (1 << nLevel
);
1433 // 2.2.4 ItemPools leeren und loeschen
1435 for (nLevel
= 0; nLevel
< pLFOInfo
->nLfoLvl
; ++nLevel
)
1436 delete aItemSet
[ nLevel
];
1443 // Fehler aufgetreten - LSTInfos und LFOInfos abraeumen !!!
1446 // und schon sind wir fertig!
1447 rSt
.Seek( nOriginalPos
);
1450 WW8ListManager::~WW8ListManager()
1453 named lists remain in doc!!!
1454 unnamed lists are deleted when unused
1455 pLFOInfos are in any case destructed
1457 for(std::vector
<WW8LSTInfo
*>::iterator aIter
= maLSTInfos
.begin();
1458 aIter
!= maLSTInfos
.end(); ++aIter
)
1460 if ((*aIter
)->pNumRule
&& !(*aIter
)->bUsedInDoc
&&
1461 (*aIter
)->pNumRule
->IsAutoRule())
1463 rDoc
.DelNumRule((*aIter
)->pNumRule
->GetName());
1470 for(sal_uInt16 nInfo
= pLFOInfos
->Count(); nInfo
; )
1472 WW8LFOInfo
*pActInfo
= pLFOInfos
->GetObject(--nInfo
);
1473 if (pActInfo
->bOverride
&& pActInfo
->pNumRule
1474 && !pActInfo
->bUsedInDoc
&& pActInfo
->pNumRule
->IsAutoRule())
1476 rDoc
.DelNumRule( pActInfo
->pNumRule
->GetName() );
1483 bool IsEqualFormatting(const SwNumRule
&rOne
, const SwNumRule
&rTwo
)
1487 rOne
.GetRuleType() == rTwo
.GetRuleType() &&
1488 rOne
.IsContinusNum() == rTwo
.IsContinusNum() &&
1489 rOne
.IsAbsSpaces() == rTwo
.IsAbsSpaces() &&
1490 rOne
.GetPoolFmtId() == rTwo
.GetPoolFmtId() &&
1491 rOne
.GetPoolHelpId() == rTwo
.GetPoolHelpId() &&
1492 rTwo
.GetPoolHlpFileId() == rTwo
.GetPoolHlpFileId()
1497 for (BYTE n
= 0; n
< MAXLEVEL
; ++n
)
1499 //The SvxNumberFormat compare, not the SwNumFmt compare
1500 const SvxNumberFormat
&rO
= rOne
.Get(n
);
1501 const SvxNumberFormat
&rT
= rTwo
.Get(n
);
1512 SwNumRule
* WW8ListManager::GetNumRuleForActivation(sal_uInt16 nLFOPosition
,
1513 const BYTE nLevel
, std::vector
<sal_uInt8
> &rParaSprms
, SwTxtNode
*pNode
)
1515 sal_uInt16 nLFOInfos
= pLFOInfos
? pLFOInfos
->Count() : 0;
1516 if( nLFOInfos
<= nLFOPosition
)
1519 WW8LFOInfo
* pLFOInfo
= pLFOInfos
->GetObject( nLFOPosition
);
1524 bool bFirstUse
= !pLFOInfo
->bUsedInDoc
;
1525 pLFOInfo
->bUsedInDoc
= true;
1527 if( !pLFOInfo
->pNumRule
)
1531 // --> OD 2009-03-12 #i100132# - a number format does not have to exist on given list level
1532 // SwNumFmt pFmt(*(pLFOInfo->pNumRule->GetNumFmt(nLevel)));
1533 SwNumFmt
pFmt(pLFOInfo
->pNumRule
->Get(nLevel
));
1535 if (rReader
.IsRightToLeft() && nLastLFOPosition
!= nLFOPosition
) {
1536 if ( pFmt
.GetNumAdjust() == SVX_ADJUST_RIGHT
)
1537 pFmt
.SetNumAdjust(SVX_ADJUST_LEFT
);
1538 else if ( pFmt
.GetNumAdjust() == SVX_ADJUST_LEFT
)
1539 pFmt
.SetNumAdjust(SVX_ADJUST_RIGHT
);
1540 pLFOInfo
->pNumRule
->Set(nLevel
, pFmt
);
1542 nLastLFOPosition
= nLFOPosition
;
1545 If this list has had its bits set in word 2000 to pretend that it is a
1546 simple list from the point of view of the user, then it is almost
1547 certainly a simple continous list, and we will try to keep it like that.
1548 Otherwise when we save again it will be shown as the true outline list
1549 that it is, confusing the user that just wanted what they thought was a
1550 simple list. On the otherhand it is possible that some of the other levels
1551 were used by the user, in which case we will not pretend anymore that it
1552 is a simple list. Something that word 2000 does anyway, that 97 didn't, to
1555 if (nLevel
&& pLFOInfo
->pNumRule
->IsContinusNum())
1556 pLFOInfo
->pNumRule
->SetContinusNum(false);
1558 if( (!pLFOInfo
->bOverride
) && (!pLFOInfo
->bLSTbUIDSet
) )
1560 WW8LSTInfo
* pParentListInfo
= GetLSTByListId( pLFOInfo
->nIdLst
);
1561 if( pParentListInfo
)
1562 pParentListInfo
->bUsedInDoc
= true;
1563 pLFOInfo
->bLSTbUIDSet
= true;
1566 if (pLFOInfo
->maParaSprms
.size() > nLevel
)
1567 rParaSprms
= pLFOInfo
->maParaSprms
[nLevel
];
1569 SwNumRule
*pRet
= pLFOInfo
->pNumRule
;
1571 bool bRestart(false);
1573 bool bNewstart(false);
1575 Note: If you fiddle with this then you have to make sure that #i18322#
1576 #i13833#, #i20095# and #112466# continue to work
1578 Check if there were overrides for this level
1580 if (pLFOInfo
->bOverride
&& nLevel
< pLFOInfo
->nLfoLvl
)
1582 WW8LSTInfo
* pParentListInfo
= GetLSTByListId(pLFOInfo
->nIdLst
);
1583 ASSERT(pParentListInfo
, "ww: Impossible lists, please report");
1584 if (pParentListInfo
&& pParentListInfo
->pNumRule
)
1586 const WW8LFOLVL
&rOverride
= pLFOInfo
->maOverrides
[nLevel
];
1587 bool bNoChangeFromParent
=
1588 IsEqualFormatting(*pRet
, *(pParentListInfo
->pNumRule
));
1590 //If so then I think word still uses the parent (maybe)
1591 if (bNoChangeFromParent
)
1593 pRet
= pParentListInfo
->pNumRule
;
1595 //did it not affect start at value ?
1598 if (rOverride
.bStartAt
)
1600 const SwNumFmt
&rFmt
=
1601 pParentListInfo
->pNumRule
->Get(nLevel
);
1604 pLFOInfo
->maOverrides
[nLevel
].nStartAt
1612 nStart
= writer_cast
<USHORT
>
1613 (pLFOInfo
->maOverrides
[nLevel
].nStartAt
);
1618 pParentListInfo
->bUsedInDoc
= true;
1625 pNode
->SetAttrListLevel(nLevel
);
1627 if (bRestart
|| bNewstart
) //#112466# (I think)
1628 pNode
->SetListRestart(true);
1630 pNode
->SetAttrListRestartValue(nStart
);
1635 //----------------------------------------------------------------------------
1636 // SwWW8ImplReader: anhaengen einer Liste an einen Style oder Absatz
1637 //----------------------------------------------------------------------------
1638 bool SwWW8ImplReader::SetTxtFmtCollAndListLevel(const SwPaM
& rRg
,
1639 SwWW8StyInf
& rStyleInfo
)
1642 if( rStyleInfo
.pFmt
&& rStyleInfo
.bColl
)
1644 bRes
= rDoc
.SetTxtFmtColl(rRg
, (SwTxtFmtColl
*)rStyleInfo
.pFmt
)
1646 SwTxtNode
* pTxtNode
= pPaM
->GetNode()->GetTxtNode();
1647 ASSERT( pTxtNode
, "No Text-Node at PaM-Position" );
1648 // --> OD 2006-10-19 #134160# - make code robust
1655 SwNumRule
* pNumRule
= pTxtNode
->GetNumRule(); // #i27610#
1657 if( !IsInvalidOrToBeMergedTabCell() &&
1658 ! (pNumRule
&& pNumRule
->IsOutlineRule()) ) // #i27610#
1659 pTxtNode
->ResetAttr( RES_PARATR_NUMRULE
);
1661 if( !rStyleInfo
.pOutlineNumrule
)
1664 (USHRT_MAX
> rStyleInfo
.nLFOIndex
) &&
1665 (WW8ListManager::nMaxLevel
> rStyleInfo
.nListLevel
)
1668 RegisterNumFmtOnTxtNode(rStyleInfo
.nLFOIndex
,
1669 rStyleInfo
.nListLevel
, false);
1674 // --> OD 2005-11-07 #127520#
1675 // Use outline level set at the style info <rStyleInfo> instead of
1676 // the outline level at the text format, because the WW8 document
1677 // could contain more than one outline numbering rule and the one
1678 // of the text format isn't the one, which a chosen as the Writer
1681 // SetLevel(((SwTxtFmtColl*) rStyleInfo.pFmt)->GetOutlineLevel());
1682 pTxtNode
->SetAttrListLevel( rStyleInfo
.nOutlineLevel
);
1689 void UseListIndent(SwWW8StyInf
&rStyle
, const SwNumFmt
&rFmt
)
1691 // --> OD 2008-06-03 #i86652#
1692 if ( rFmt
.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_WIDTH_AND_POSITION
)
1694 const long nAbsLSpace
= rFmt
.GetAbsLSpace();
1695 const long nListFirstLineIndent
= GetListFirstLineIndent(rFmt
);
1696 SvxLRSpaceItem
aLR(ItemGet
<SvxLRSpaceItem
>(*rStyle
.pFmt
, RES_LR_SPACE
));
1697 aLR
.SetTxtLeft(nAbsLSpace
);
1698 aLR
.SetTxtFirstLineOfst(writer_cast
<short>(nListFirstLineIndent
));
1699 rStyle
.pFmt
->SetFmtAttr(aLR
);
1700 rStyle
.bListReleventIndentSet
= true;
1705 void SetStyleIndent(SwWW8StyInf
&rStyle
, const SwNumFmt
&rFmt
)
1707 // --> OD 2008-06-03 #i86652#
1708 if ( rFmt
.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_WIDTH_AND_POSITION
)
1711 SvxLRSpaceItem
aLR(ItemGet
<SvxLRSpaceItem
>(*rStyle
.pFmt
, RES_LR_SPACE
));
1712 if (rStyle
.bListReleventIndentSet
)
1713 SyncIndentWithList(aLR
, rFmt
);
1717 aLR
.SetTxtFirstLineOfst(0);
1719 rStyle
.pFmt
->SetFmtAttr(aLR
);
1723 void SwWW8ImplReader::SetStylesList(sal_uInt16 nStyle
, sal_uInt16 nActLFO
,
1724 sal_uInt8 nActLevel
)
1726 SwWW8StyInf
&rStyleInf
= pCollA
[nStyle
];
1727 if (rStyleInf
.bValid
)
1729 ASSERT(pAktColl
, "Cannot be called outside of style import");
1730 // Phase 1: Nummerierungsattribute beim Einlesen einer StyleDef
1733 // jetzt nur die Parameter vermerken: die tatsaechliche Liste wird
1734 // spaeter drangehaengt, wenn die Listendefinitionen gelesen sind...
1736 (USHRT_MAX
> nActLFO
) &&
1737 (WW8ListManager::nMaxLevel
> nActLevel
)
1740 rStyleInf
.nLFOIndex
= nActLFO
;
1741 rStyleInf
.nListLevel
= nActLevel
;
1744 (USHRT_MAX
> nActLFO
) &&
1745 (WW8ListManager::nMaxLevel
> nActLevel
)
1748 std::vector
<sal_uInt8
> aParaSprms
;
1749 SwNumRule
*pNmRule
=
1750 pLstManager
->GetNumRuleForActivation(nActLFO
,
1751 nActLevel
, aParaSprms
);
1753 UseListIndent(rStyleInf
, pNmRule
->Get(nActLevel
));
1760 void SwWW8ImplReader::RegisterNumFmtOnStyle(sal_uInt16 nStyle
)
1762 SwWW8StyInf
&rStyleInf
= pCollA
[nStyle
];
1763 if (rStyleInf
.bValid
&& rStyleInf
.pFmt
)
1765 //Save old pre-list modified indent, which are the word indent values
1766 rStyleInf
.maWordLR
=
1767 ItemGet
<SvxLRSpaceItem
>(*rStyleInf
.pFmt
, RES_LR_SPACE
);
1769 // Phase 2: aktualisieren der StyleDef nach einlesen aller Listen
1770 SwNumRule
* pNmRule
= 0;
1771 sal_uInt16 nLFO
= rStyleInf
.nLFOIndex
;
1772 sal_uInt8 nLevel
= rStyleInf
.nListLevel
;
1774 (USHRT_MAX
> nLFO
) &&
1775 (WW8ListManager::nMaxLevel
> nLevel
)
1778 std::vector
<sal_uInt8
> aParaSprms
;
1779 pNmRule
= pLstManager
->GetNumRuleForActivation(nLFO
, nLevel
,
1784 if( MAXLEVEL
> rStyleInf
.nOutlineLevel
)
1785 rStyleInf
.pOutlineNumrule
= pNmRule
;
1788 rStyleInf
.pFmt
->SetFmtAttr(
1789 SwNumRuleItem( pNmRule
->GetName() ) );
1790 rStyleInf
.bHasStyNumRule
= true;
1796 SetStyleIndent(rStyleInf
, pNmRule
->Get(nLevel
));
1800 void SwWW8ImplReader::RegisterNumFmtOnTxtNode(sal_uInt16 nActLFO
,
1801 sal_uInt8 nActLevel
, bool bSetAttr
)
1803 // beachte: die Methode haengt die NumRule an den Text Node, falls
1804 // bSetAttr (dann muessen natuerlich vorher die Listen gelesen sein)
1805 // stellt sie NUR den Level ein, im Vertrauen darauf, dass am STYLE eine
1806 // NumRule haengt - dies wird NICHT ueberprueft !!!
1808 if (pLstManager
) // sind die Listendeklarationen gelesen?
1810 std::vector
<sal_uInt8
> aParaSprms
;
1811 SwTxtNode
* pTxtNd
= pPaM
->GetNode()->GetTxtNode();
1812 ASSERT(pTxtNd
, "Kein Text-Node an PaM-Position");
1814 const SwNumRule
* pRule
= bSetAttr
?
1815 pLstManager
->GetNumRuleForActivation( nActLFO
, nActLevel
,
1816 aParaSprms
, pTxtNd
) : 0;
1818 if (pRule
|| !bSetAttr
)
1820 //#i24136# old is the same as new, and its the outline numbering,
1821 //then we don't set the numrule again, and we just take the num node
1822 //(the actual outline numbering gets set in SetOutlineNum)
1823 using namespace sw::util
;
1824 bool bUnchangedOutlineNumbering
= false;
1826 If the node is outline numbered, and the new numbering to apply
1827 is the one that was chosen to be the outline numbering then all
1830 // --> OD 2005-11-04 #???# - correct condition according to the
1831 // above given comment.
1832 if ( pTxtNd
->GetNumRule() == rDoc
.GetOutlineNumRule() &&
1833 pRule
== mpChosenOutlineNumRule
)
1836 bUnchangedOutlineNumbering
= true;
1838 if (!bUnchangedOutlineNumbering
)
1840 //If its normal numbering, see if its the same as it already
1841 //was, if its not, and we have been asked to set it, then set
1845 const SwNumRule
*pNormal
= pTxtNd
->GetNumRule();
1846 if (pNormal
!= pRule
)
1849 (SwNumRuleItem(pRule
->GetName()));
1853 // --> OD 2005-10-17 #126238#
1854 // - re-introduce fix for issue #i49037#, which got lost by
1855 // accident on a re-synchronisation on the master.
1856 // if (pTxtNd->IsOutline() && pTxtNd->Len() == 0)
1857 // pTxtNd->SetCounted(false);
1860 pTxtNd
->SetAttrListLevel(nActLevel
);
1861 // --> OD 2005-11-01 #126924#
1862 // - <IsCounted()> state of text node has to be adjusted accordingly.
1863 if ( /*nActLevel >= 0 &&*/ nActLevel
< MAXLEVEL
)
1865 pTxtNd
->SetCountedInList( true );
1869 // --> OD 2009-03-04 #i99822#
1870 // Direct application of the list level formatting no longer
1871 // needed for list levels of mode LABEL_ALIGNMENT
1872 bool bApplyListLevelIndentDirectlyAtPara( true );
1873 if ( pTxtNd
->GetNumRule() && nActLevel
< MAXLEVEL
)
1875 const SwNumFmt
& rFmt
= pTxtNd
->GetNumRule()->Get( nActLevel
);
1876 if ( rFmt
.GetPositionAndSpaceMode() ==
1877 SvxNumberFormat::LABEL_ALIGNMENT
)
1879 bApplyListLevelIndentDirectlyAtPara
= false;
1883 if ( bApplyListLevelIndentDirectlyAtPara
)
1885 SfxItemSet
aListIndent(rDoc
.GetAttrPool(), RES_LR_SPACE
,
1887 const SvxLRSpaceItem
*pItem
= (const SvxLRSpaceItem
*)(
1888 GetFmtAttr(RES_LR_SPACE
));
1889 ASSERT(pItem
, "impossible");
1891 aListIndent
.Put(*pItem
);
1894 Take the original paragraph sprms attached to this list level
1895 formatting and apply them to the paragraph. I'm convinced that
1896 this is exactly what word does.
1898 if (short nLen
= static_cast< short >(aParaSprms
.size()))
1900 SfxItemSet
* pOldAktItemSet
= pAktItemSet
;
1901 SetAktItemSet(&aListIndent
);
1903 sal_uInt8
* pSprms1
= &aParaSprms
[0];
1906 sal_uInt16 nL1
= ImportSprm(pSprms1
);
1911 SetAktItemSet(pOldAktItemSet
);
1914 const SvxLRSpaceItem
*pLR
=
1915 HasItem
<SvxLRSpaceItem
>(aListIndent
, RES_LR_SPACE
);
1916 ASSERT(pLR
, "Impossible");
1919 pCtrlStck
->NewAttr(*pPaM
->GetPoint(), *pLR
);
1920 pCtrlStck
->SetAttr(*pPaM
->GetPoint(), RES_LR_SPACE
);
1928 void SwWW8ImplReader::RegisterNumFmt(sal_uInt16 nActLFO
, sal_uInt8 nActLevel
)
1930 // sind wir erst beim Einlesen der StyleDef ?
1932 SetStylesList( nAktColl
, nActLFO
, nActLevel
);
1934 RegisterNumFmtOnTxtNode(nActLFO
, nActLevel
);
1937 void SwWW8ImplReader::Read_ListLevel(sal_uInt16
, const sal_uInt8
* pData
,
1940 if (pPlcxMan
&& pPlcxMan
->GetDoingDrawTextBox())
1945 // aktuelle Liste ist hier zu Ende, was ist zu tun ???
1946 nListLevel
= WW8ListManager::nMaxLevel
;
1947 if (pStyles
&& !bVer67
)
1948 pStyles
->nWwNumLevel
= 0;
1952 // Sicherheitspruefung auf NIL Pointer
1953 if( !pData
) return;
1954 // die Streamdaten sind hier Null basiert, so wie wir es brauchen
1955 nListLevel
= *pData
;
1957 if (pStyles
&& !bVer67
)
1961 if this is the case, then if the numbering is actually stored in
1962 winword 6 format, and its likely that sprmPIlvl has been abused
1963 to set the ww6 list level information which we will need when we
1964 reach the true ww6 list def. So set it now
1966 pStyles
->nWwNumLevel
= nListLevel
;
1969 if (WW8ListManager::nMaxLevel
<= nListLevel
)
1970 nListLevel
= WW8ListManager::nMaxLevel
;
1973 (USHRT_MAX
> nLFOPosition
) &&
1974 (WW8ListManager::nMaxLevel
> nListLevel
)
1977 RegisterNumFmt(nLFOPosition
, nListLevel
);
1978 nLFOPosition
= USHRT_MAX
;
1979 nListLevel
= WW8ListManager::nMaxLevel
;
1984 void SwWW8ImplReader::Read_LFOPosition(sal_uInt16
, const sal_uInt8
* pData
,
1987 if (pPlcxMan
&& pPlcxMan
->GetDoingDrawTextBox())
1992 // aktueller Level ist hier zu Ende, was ist zu tun ???
1993 nLFOPosition
= USHRT_MAX
;
1994 nListLevel
= WW8ListManager::nMaxLevel
;
1998 // Sicherheitspruefung auf NIL Pointer
2001 short nData
= SVBT16ToShort( pData
);
2006 If you have a paragraph in word with left and/or hanging indent
2007 and remove its numbering, then the indentation appears to get
2008 reset, but not back to the base style, instead its goes to a blank
2010 Unless its a broken ww6 list in 97 in which case more hackery is
2011 required, some more details about that in
2012 ww8par6.cxx#SwWW8ImplReader::Read_LR
2017 pAktColl
->SetFmtAttr(*GetDfltAttr( RES_PARATR_NUMRULE
));
2018 pAktColl
->SetFmtAttr(SvxLRSpaceItem(RES_LR_SPACE
)); //#94672#
2020 else if (SwTxtNode
* pTxtNode
= pPaM
->GetNode()->GetTxtNode())
2022 // --> OD 2005-10-21 #i54393#
2023 // - Reset hard set numbering rule at paragraph instead of
2024 // setting hard no numbering.
2025 // pTxtNode->SwCntntNode::SetAttr
2026 // (*GetDfltAttr(RES_PARATR_NUMRULE));
2027 pTxtNode
->ResetAttr( RES_PARATR_NUMRULE
);
2029 pTxtNode
->SetCountedInList(false);
2033 Hmm, I can't remove outline numbering on a per txtnode basis,
2034 but I can set some normal numbering, and that overrides outline
2035 numbering, and then I can say when I come to say that I want no
2036 number on the normal numbering rule, that should all work out
2039 No special outline number in textnode any more
2041 if (pTxtNode
->IsOutline())
2043 // OD 2005-10-21 #i54393#
2044 // It's not needed to call <SetCounted( false )> again - see above.
2045 // --> OD 2005-10-21 #i54393#
2046 // Assure that the numbering rule, which is retrieved at
2047 // the paragraph is the outline numbering rule, instead of
2048 // incorrectly setting the chosen outline rule.
2049 // Note: The chosen outline rule doesn't have to correspond
2050 // to the outline rule
2051 if ( pTxtNode
->GetNumRule() != rDoc
.GetOutlineNumRule() )
2054 SwNumRuleItem( rDoc
.GetOutlineNumRule()->GetName() ) );
2060 pCtrlStck
->NewAttr(*pPaM
->GetPoint(), SvxLRSpaceItem(RES_LR_SPACE
));
2061 pCtrlStck
->SetAttr(*pPaM
->GetPoint(), RES_LR_SPACE
);
2063 nLFOPosition
= USHRT_MAX
;
2067 nLFOPosition
= (sal_uInt16
)nData
-1;
2070 If we are a ww8+ style with ww7- style lists then there is a
2071 bizarre broken word bug where when the list is removed from a para
2072 the ww6 list first line indent still affects the first line
2073 indentation. Setting this flag will allow us to recover from this
2076 if (pAktColl
&& (nLFOPosition
== 2047-1))
2077 pCollA
[nAktColl
].bHasBrokenWW6List
= true;
2079 // die Streamdaten sind hier 1 basiert, wir ziehen EINS ab
2080 if (USHRT_MAX
> nLFOPosition
)
2082 if (nLFOPosition
!= 2047-1) //Normal ww8+ list behaviour
2084 if (WW8ListManager::nMaxLevel
== nListLevel
)
2086 else if (WW8ListManager::nMaxLevel
> nListLevel
)
2088 RegisterNumFmt(nLFOPosition
, nListLevel
);
2089 nLFOPosition
= USHRT_MAX
;
2090 nListLevel
= WW8ListManager::nMaxLevel
;
2093 else if (pPlcxMan
&& pPlcxMan
->HasParaSprm(0xC63E))
2096 #i8114# Horrific backwards compatible ww7- lists in ww8+
2099 Read_ANLevelNo(13 /*equiv ww7- sprm no*/, &nListLevel
, 1);
2106 // -------------------------------------------------------------------
2107 // ------------------------- Reading Controls ------------------------
2108 // -------------------------------------------------------------------
2110 bool SwWW8ImplReader::ImportFormulaControl(WW8FormulaControl
&aFormula
,
2111 WW8_CP nStart
, SwWw8ControlType nWhich
)
2115 * Save the reader state and process the sprms for this anchor cp.
2116 * Doing so will set the nPicLocFc to the offset to find the hypertext
2117 * data in the data stream.
2119 WW8_CP nEndCp
= nStart
+1; //Only interested in the single 0x01 character
2121 WW8ReaderSave
aSave(this,nStart
);
2123 WW8PLCFManResult aRes
;
2124 nStart
= pPlcxMan
->Where();
2125 while(nStart
<= nEndCp
)
2127 if ( pPlcxMan
->Get(&aRes
)
2128 && aRes
.pMemPos
&& aRes
.nSprmId
)
2130 //only interested in sprms which would set nPicLocFc
2131 if ( (68 == aRes
.nSprmId
) || (0x6A03 == aRes
.nSprmId
) )
2133 Read_PicLoc( aRes
.nSprmId
, aRes
.pMemPos
+
2134 mpSprmParser
->DistanceToData(aRes
.nSprmId
), 4);
2139 nStart
= pPlcxMan
->Where();
2141 ULONG nOffset
= nPicLocFc
;
2142 aSave
.Restore(this);
2144 ULONG nOldPos
= pDataStream
->Tell();
2146 pDataStream
->Seek( nOffset
);
2147 PicRead( pDataStream
, &aPic
, bVer67
);
2149 if((aPic
.lcb
> 0x3A) && !pDataStream
->GetError() )
2151 #if 0 // some debug fun; remove this later...
2152 int len
=aPic
.lcb
-aPic
.cbHeader
;
2153 char *pBuf
=(char*)malloc(len
);
2154 pDataStream
->Read( pBuf
, len
);
2157 sprintf(fname
, "data%03i.data", _h
++);
2158 FILE *out
=fopen(fname
, "wb");
2159 fwrite(pBuf
, len
, 1, out
);
2161 pDataStream
->Seek( nPicLocFc
+ aPic
.cbHeader
);
2163 aFormula
.FormulaRead(nWhich
,pDataStream
);
2168 There is a problem with aPic, the WW8_PIC is always used even though it
2169 is too big for the WW95 files, it needs to be modified to check the
2172 pDataStream
->Seek( nOldPos
);
2176 sal_Bool
SwMSConvertControls::InsertFormula(WW8FormulaControl
&rFormula
)
2178 sal_Bool bRet
= sal_False
;
2180 const uno::Reference
< lang::XMultiServiceFactory
> & rServiceFactory
=
2181 GetServiceFactory();
2183 if(!rServiceFactory
.is())
2187 uno::Reference
< form::XFormComponent
> xFComp
;
2189 if (sal_True
== (bRet
= rFormula
.Import(rServiceFactory
, xFComp
, aSz
)))
2191 uno::Reference
<drawing::XShape
> xShapeRef
;
2192 if (sal_True
== (bRet
= InsertControl(xFComp
, aSz
, &xShapeRef
, false)))
2193 GetShapes()->add(xShapeRef
);
2198 void WW8FormulaControl::FormulaRead(SwWw8ControlType nWhich
,
2199 SvStream
*pDataStream
)
2205 *pDataStream
>> nHeaderByte
;
2206 if (nHeaderByte
== 0xFF) //Guesswork time, difference between 97 and 95 ?
2208 pDataStream
->SeekRel(3);
2209 *pDataStream
>> nHeaderByte
;
2212 fUnknown
= nHeaderByte
& 0x3;
2213 fDropdownIndex
= (nHeaderByte
& 0xFC) >> 2;
2214 *pDataStream
>> nField
;
2215 fToolTip
= nField
& 0x01;
2216 fNoMark
= (nField
& 0x02)>>1;
2217 fUseSize
= (nField
& 0x04)>>2;
2218 fNumbersOnly
= (nField
& 0x08)>>3;
2219 fDateOnly
= (nField
& 0x10)>>4;
2220 fUnused
= (nField
& 0xE0)>>5;
2221 *pDataStream
>> nSize
;
2223 *pDataStream
>> hpsCheckBox
;
2225 pDataStream
->SeekRel(2); //Guess
2227 rtl_TextEncoding eEnc
= rRdr
.eStructCharSet
;
2228 sTitle
= !nType
? WW8ReadPString(*pDataStream
, eEnc
, true)
2229 : WW8Read_xstz(*pDataStream
, 0, true);
2231 if (nWhich
== WW8_CT_CHECKBOX
)
2233 *pDataStream
>> nDefaultChecked
;
2234 nChecked
= nDefaultChecked
;
2235 //Don't know the details yet
2236 switch (nHeaderByte
)
2238 case 0x65: //01100101
2241 case 0x1: //00000001
2242 //swap to unchecked from checked (#114841)?
2245 case 0x5: //00000101
2250 ASSERT(!this, "unknown option, please report to cmc");
2254 else if (nWhich
== WW8_CT_DROPDOWN
)
2255 *pDataStream
>> nChecked
;
2258 sDefault
= !nType
? WW8ReadPString(*pDataStream
, eEnc
, true)
2259 : WW8Read_xstz(*pDataStream
, 0, true);
2262 sFormatting
= !nType
? WW8ReadPString(*pDataStream
, eEnc
, true)
2263 : WW8Read_xstz(*pDataStream
, 0, true);
2265 sHelp
= !nType
? WW8ReadPString(*pDataStream
, eEnc
, true)
2266 : WW8Read_xstz(*pDataStream
, 0, true);
2268 if (nWhich
== WW8_CT_DROPDOWN
) //is this the case ?
2273 sToolTip
= !nType
? WW8ReadPString(*pDataStream
, eEnc
, true)
2274 : WW8Read_xstz(*pDataStream
, 0, true);
2277 if (nWhich
== WW8_CT_DROPDOWN
)
2280 pDataStream
->SeekRel(4 * (nType
? 2 : 1));
2282 *pDataStream
>> nDummy
;
2283 sal_uInt32 nNoStrings
;
2286 sal_uInt16 nWord95NoStrings
;
2287 *pDataStream
>> nWord95NoStrings
;
2288 nNoStrings
= nWord95NoStrings
;
2289 *pDataStream
>> nWord95NoStrings
;
2290 if (nNoStrings
!= nWord95NoStrings
)
2292 nNoStrings
= nWord95NoStrings
;
2294 *pDataStream
>> nDummy2
;
2297 *pDataStream
>> nDummy2
;
2300 if (!bAllOk
) //Not as expected, don't risk it at all.
2302 for (sal_uInt16 nI
= 0; nI
< nNoStrings
; ++nI
)
2303 pDataStream
->SeekRel(2);
2307 if (nDummy
!= 0xFFFF)
2309 *pDataStream
>> nNoStrings
;
2312 "Unknown formfield dropdown list structure. Report to cmc");
2313 if (!bAllOk
) //Not as expected, don't risk it at all.
2315 maListEntries
.reserve(nNoStrings
);
2316 for (sal_uInt32 nI
= 0; nI
< nNoStrings
; ++nI
)
2318 String sEntry
= !nType
? WW8ReadPString(*pDataStream
, eEnc
, false)
2319 : WW8Read_xstz(*pDataStream
, 0, false);
2320 maListEntries
.push_back(sEntry
);
2325 WW8FormulaListBox::WW8FormulaListBox(SwWW8ImplReader
&rR
)
2326 : WW8FormulaControl( CREATE_CONST_ASC(SL::aListBox
), rR
)
2330 //Miserable hack to get a hardcoded guesstimate of the size of a list dropdown
2331 //box's first entry to set as the lists default size
2332 awt::Size
SwWW8ImplReader::MiserableDropDownFormHack(const String
&rString
,
2333 uno::Reference
<beans::XPropertySet
>& rPropSet
)
2336 struct CtrlFontMapEntry
2339 const sal_Char
* pPropNm
;
2341 const CtrlFontMapEntry aMapTable
[] =
2343 { RES_CHRATR_COLOR
, "TextColor" },
2344 { RES_CHRATR_FONT
, "FontName" },
2345 { RES_CHRATR_FONTSIZE
, "FontHeight" },
2346 { RES_CHRATR_WEIGHT
, "FontWeight" },
2347 { RES_CHRATR_UNDERLINE
, "FontUnderline" },
2348 { RES_CHRATR_CROSSEDOUT
, "FontStrikeout" },
2349 { RES_CHRATR_POSTURE
, "FontSlant" },
2354 uno::Reference
< beans::XPropertySetInfo
> xPropSetInfo
=
2355 rPropSet
->getPropertySetInfo();
2358 for (const CtrlFontMapEntry
* pMap
= aMapTable
; pMap
->nWhichId
; ++pMap
)
2361 const SfxPoolItem
* pItem
= GetFmtAttr( pMap
->nWhichId
);
2362 ASSERT(pItem
, "Impossible");
2366 switch ( pMap
->nWhichId
)
2368 case RES_CHRATR_COLOR
:
2371 if (xPropSetInfo
->hasPropertyByName(pNm
= C2U("TextColor")))
2373 aTmp
<<= (sal_Int32
)((SvxColorItem
*)pItem
)->GetValue().GetColor();
2374 rPropSet
->setPropertyValue(pNm
, aTmp
);
2377 aFont
.SetColor(((SvxColorItem
*)pItem
)->GetValue());
2379 case RES_CHRATR_FONT
:
2381 const SvxFontItem
*pFontItem
= (SvxFontItem
*)pItem
;
2383 if (xPropSetInfo
->hasPropertyByName(pNm
= C2U("FontStyleName")))
2385 aTmp
<<= rtl::OUString( pFontItem
->GetStyleName());
2386 rPropSet
->setPropertyValue( pNm
, aTmp
);
2388 if (xPropSetInfo
->hasPropertyByName(pNm
= C2U("FontFamily")))
2390 aTmp
<<= (sal_Int16
)pFontItem
->GetFamily();
2391 rPropSet
->setPropertyValue( pNm
, aTmp
);
2393 if (xPropSetInfo
->hasPropertyByName(pNm
= C2U("FontCharset")))
2395 aTmp
<<= (sal_Int16
)pFontItem
->GetCharSet();
2396 rPropSet
->setPropertyValue( pNm
, aTmp
);
2398 if (xPropSetInfo
->hasPropertyByName(pNm
= C2U("FontPitch")))
2400 aTmp
<<= (sal_Int16
)pFontItem
->GetPitch();
2401 rPropSet
->setPropertyValue( pNm
, aTmp
);
2404 aTmp
<<= rtl::OUString( pFontItem
->GetFamilyName());
2405 aFont
.SetName( pFontItem
->GetFamilyName() );
2406 aFont
.SetStyleName( pFontItem
->GetStyleName() );
2407 aFont
.SetFamily( pFontItem
->GetFamily() );
2408 aFont
.SetCharSet( pFontItem
->GetCharSet() );
2409 aFont
.SetPitch( pFontItem
->GetPitch() );
2413 case RES_CHRATR_FONTSIZE
:
2415 Size
aSize( aFont
.GetSize().Width(),
2416 ((SvxFontHeightItem
*)pItem
)->GetHeight() );
2417 aTmp
<<= ((float)aSize
.Height()) / 20.0;
2419 aFont
.SetSize(OutputDevice::LogicToLogic(aSize
, MAP_TWIP
,
2424 case RES_CHRATR_WEIGHT
:
2425 aTmp
<<= (float)VCLUnoHelper::ConvertFontWeight(
2426 ((SvxWeightItem
*)pItem
)->GetWeight() );
2427 aFont
.SetWeight( ((SvxWeightItem
*)pItem
)->GetWeight() );
2430 case RES_CHRATR_UNDERLINE
:
2431 aTmp
<<= (sal_Int16
)(((SvxUnderlineItem
*)pItem
)->GetLineStyle());
2432 aFont
.SetUnderline(((SvxUnderlineItem
*)pItem
)->GetLineStyle());
2435 case RES_CHRATR_CROSSEDOUT
:
2436 aTmp
<<= (sal_Int16
)( ((SvxCrossedOutItem
*)pItem
)->GetStrikeout() );
2437 aFont
.SetStrikeout( ((SvxCrossedOutItem
*)pItem
)->GetStrikeout() );
2440 case RES_CHRATR_POSTURE
:
2441 aTmp
<<= (sal_Int16
)( ((SvxPostureItem
*)pItem
)->GetPosture() );
2442 aFont
.SetItalic( ((SvxPostureItem
*)pItem
)->GetPosture() );
2450 if (bSet
&& xPropSetInfo
->hasPropertyByName(C2U(pMap
->pPropNm
)))
2451 rPropSet
->setPropertyValue(C2U(pMap
->pPropNm
), aTmp
);
2453 // now calculate the size of the control
2454 OutputDevice
* pOut
= Application::GetDefaultDevice();
2455 ASSERT(pOut
, "Impossible");
2458 pOut
->Push( PUSH_FONT
| PUSH_MAPMODE
);
2459 pOut
->SetMapMode( MapMode( MAP_100TH_MM
));
2460 pOut
->SetFont( aFont
);
2461 aRet
.Width
= pOut
->GetTextWidth(rString
);
2462 aRet
.Width
+= 500; //plus size of button, total hack territory
2463 aRet
.Height
= pOut
->GetTextHeight();
2469 sal_Bool
WW8FormulaListBox::Import(const uno::Reference
<
2470 lang::XMultiServiceFactory
> &rServiceFactory
,
2471 uno::Reference
<form::XFormComponent
> &rFComp
,awt::Size
&rSz
)
2473 uno::Reference
<uno::XInterface
> xCreate
= rServiceFactory
->createInstance(
2474 C2U("com.sun.star.form.component.ComboBox"));
2478 rFComp
= uno::Reference
<form::XFormComponent
>(xCreate
, uno::UNO_QUERY
);
2482 uno::Reference
<beans::XPropertySet
> xPropSet(xCreate
, uno::UNO_QUERY
);
2486 aTmp
<<= rtl::OUString(sTitle
);
2488 aTmp
<<= rtl::OUString(sName
);
2489 xPropSet
->setPropertyValue(C2U("Name"), aTmp
);
2493 aTmp
<<= rtl::OUString(sToolTip
);
2494 xPropSet
->setPropertyValue(C2U("HelpText"), aTmp
);
2497 sal_Bool
bDropDown(sal_True
);
2498 xPropSet
->setPropertyValue(C2U("Dropdown"), cppu::bool2any(bDropDown
));
2500 if (!maListEntries
.empty())
2502 sal_uInt32 nLen
= maListEntries
.size();
2503 uno::Sequence
< ::rtl::OUString
> aListSource(nLen
);
2504 for (sal_uInt32 nI
= 0; nI
< nLen
; ++nI
)
2505 aListSource
[nI
] = rtl::OUString(maListEntries
[nI
]);
2506 aTmp
<<= aListSource
;
2507 xPropSet
->setPropertyValue(C2U("StringItemList"), aTmp
);
2509 aTmp
<<= aListSource
[0];
2510 xPropSet
->setPropertyValue(C2U("DefaultText"), aTmp
);
2512 rSz
= rRdr
.MiserableDropDownFormHack(maListEntries
[0], xPropSet
);
2516 static const sal_Unicode aBlank
[] =
2518 0x2002,0x2002,0x2002,0x2002,0x2002
2520 rSz
= rRdr
.MiserableDropDownFormHack(String(aBlank
), xPropSet
);
2526 WW8FormulaCheckBox::WW8FormulaCheckBox(SwWW8ImplReader
&rR
)
2527 : WW8FormulaControl( CREATE_CONST_ASC(SL::aCheckBox
), rR
)
2531 static void lcl_AddToPropertyContainer
2532 (uno::Reference
<beans::XPropertySet
> xPropSet
,
2533 const rtl::OUString
& rPropertyName
, const rtl::OUString
& rValue
)
2535 uno::Reference
<beans::XPropertySetInfo
> xPropSetInfo
=
2536 xPropSet
->getPropertySetInfo();
2537 if (xPropSetInfo
.is() &&
2538 ! xPropSetInfo
->hasPropertyByName(rPropertyName
))
2540 uno::Reference
<beans::XPropertyContainer
>
2541 xPropContainer(xPropSet
, uno::UNO_QUERY
);
2542 uno::Any
aAny(C2U(""));
2543 xPropContainer
->addProperty
2545 static_cast<sal_Int16
>(beans::PropertyAttribute::BOUND
||
2546 beans::PropertyAttribute::REMOVABLE
),
2550 uno::Any
aAnyValue(rValue
);
2551 xPropSet
->setPropertyValue(rPropertyName
, aAnyValue
);
2554 sal_Bool
WW8FormulaCheckBox::Import(const uno::Reference
<
2555 lang::XMultiServiceFactory
> &rServiceFactory
,
2556 uno::Reference
<form::XFormComponent
> &rFComp
,awt::Size
&rSz
)
2558 uno::Reference
< uno::XInterface
> xCreate
= rServiceFactory
->createInstance(
2559 C2U("com.sun.star.form.component.CheckBox"));
2563 rFComp
= uno::Reference
< form::XFormComponent
>( xCreate
, uno::UNO_QUERY
);
2567 uno::Reference
< beans::XPropertySet
> xPropSet( xCreate
, uno::UNO_QUERY
);
2569 rSz
.Width
= 16 * hpsCheckBox
;
2570 rSz
.Height
= 16 * hpsCheckBox
;
2574 aTmp
<<= rtl::OUString(sTitle
);
2576 aTmp
<<= rtl::OUString(sName
);
2577 xPropSet
->setPropertyValue(C2U("Name"), aTmp
);
2579 aTmp
<<= (sal_Int16
)nChecked
;
2580 xPropSet
->setPropertyValue(C2U("DefaultState"), aTmp
);
2582 if( sToolTip
.Len() )
2583 lcl_AddToPropertyContainer(xPropSet
, C2U("HelpText"), sToolTip
);
2586 lcl_AddToPropertyContainer(xPropSet
, C2U("HelpF1Text"), sHelp
);
2592 WW8FormulaEditBox::WW8FormulaEditBox(SwWW8ImplReader
&rR
)
2593 : WW8FormulaControl( CREATE_CONST_ASC(SL::aTextField
) ,rR
)
2597 sal_Bool
SwMSConvertControls::InsertControl(
2598 const uno::Reference
< form::XFormComponent
> & rFComp
,
2599 const awt::Size
& rSize
, uno::Reference
< drawing::XShape
> *pShape
,
2602 const uno::Reference
< container::XIndexContainer
> &rComps
= GetFormComps();
2603 uno::Any
aTmp( &rFComp
, ::getCppuType((const uno::Reference
<
2604 form::XFormComponent
>*)0) );
2605 rComps
->insertByIndex( rComps
->getCount(), aTmp
);
2607 const uno::Reference
< lang::XMultiServiceFactory
> &rServiceFactory
=
2608 GetServiceFactory();
2609 if( !rServiceFactory
.is() )
2612 uno::Reference
< uno::XInterface
> xCreate
= rServiceFactory
->createInstance(
2613 C2U("com.sun.star.drawing.ControlShape"));
2617 uno::Reference
< drawing::XShape
> xShape
=
2618 uno::Reference
< drawing::XShape
>(xCreate
, uno::UNO_QUERY
);
2620 DBG_ASSERT(xShape
.is(), "XShape nicht erhalten");
2621 xShape
->setSize(rSize
);
2623 uno::Reference
< beans::XPropertySet
> xShapePropSet(
2624 xCreate
, uno::UNO_QUERY
);
2626 //I lay a small bet that this will change to
2627 //INT16 nTemp=TextContentAnchorType::AS_CHARACTER;
2630 nTemp
= text::TextContentAnchorType_AT_PARAGRAPH
;
2632 nTemp
= text::TextContentAnchorType_AS_CHARACTER
;
2635 xShapePropSet
->setPropertyValue(C2U("AnchorType"), aTmp
);
2637 nTemp
= text::VertOrientation::TOP
;
2639 xShapePropSet
->setPropertyValue(C2U("VertOrient"), aTmp
);
2641 uno::Reference
< text::XText
> xDummyTxtRef
;
2642 uno::Reference
< text::XTextRange
> xTxtRg
=
2643 new SwXTextRange( *pPaM
, xDummyTxtRef
);
2645 aTmp
.setValue(&xTxtRg
,::getCppuType((
2646 uno::Reference
< text::XTextRange
>*)0));
2647 xShapePropSet
->setPropertyValue(C2U("TextRange"), aTmp
);
2649 // Das Control-Model am Control-Shape setzen
2650 uno::Reference
< drawing::XControlShape
> xControlShape( xShape
,
2652 uno::Reference
< awt::XControlModel
> xControlModel( rFComp
,
2654 xControlShape
->setControl( xControlModel
);
2662 /* vi:set tabstop=4 shiftwidth=4 expandtab: */