1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 #include <svl/itemiter.hxx>
22 #include <vcl/svapp.hxx>
23 #include <vcl/outdev.hxx>
25 #include <toolkit/helper/vclunohelper.hxx>
26 #include <com/sun/star/form/XFormsSupplier.hpp>
27 #include <com/sun/star/form/XForm.hpp>
28 #include <com/sun/star/form/XImageProducerSupplier.hpp>
29 #include <com/sun/star/form/XFormController.hpp>
30 #include <com/sun/star/frame/XStorable.hpp>
31 #include <com/sun/star/frame/XModel.hpp>
32 #include <com/sun/star/drawing/XConnectableShape.hpp>
33 #include <com/sun/star/drawing/XConnectorShape.hpp>
34 #include <com/sun/star/drawing/XShape.hpp>
35 #include <com/sun/star/drawing/XControlShape.hpp>
36 #include <com/sun/star/drawing/XShapeAligner.hpp>
37 #include <com/sun/star/drawing/XShapeGroup.hpp>
38 #include <com/sun/star/drawing/XUniversalShapeDescriptor.hpp>
39 #include <com/sun/star/drawing/XShapeMirror.hpp>
40 #include <com/sun/star/drawing/XShapeArranger.hpp>
41 #include <com/sun/star/drawing/XDrawPage.hpp>
42 #include <com/sun/star/drawing/XDrawPageSupplier.hpp>
43 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
44 #include <com/sun/star/lang/XSingleServiceFactory.hpp>
45 #include <com/sun/star/container/XIndexContainer.hpp>
46 #include <com/sun/star/text/VertOrientation.hpp>
47 #include <com/sun/star/text/TextContentAnchorType.hpp>
48 #include <comphelper/extract.hxx>
49 #include <comphelper/stlunosequence.hxx>
50 #include <com/sun/star/beans/XPropertyContainer.hpp>
51 #include <com/sun/star/beans/PropertyAttribute.hpp>
55 #include <hintids.hxx>
56 #include <editeng/fontitem.hxx>
57 #include <editeng/lrspitem.hxx>
58 #include <editeng/fhgtitem.hxx>
59 #include <editeng/colritem.hxx>
60 #include <editeng/wghtitem.hxx>
61 #include <editeng/crossedoutitem.hxx>
62 #include <editeng/udlnitem.hxx>
63 #include <editeng/postitem.hxx>
64 #include <unotextrange.hxx>
68 #include <numrule.hxx>
70 #include <charatr.hxx>
71 #include <charfmt.hxx>
75 #include <flddropdown.hxx>
76 #include "writerhelper.hxx"
77 #include "writerwordglue.hxx"
79 #include "ww8par2.hxx" // wg. Listen-Attributen in Styles
82 #include <unotools/fltrcfg.hxx>
83 #include <xmloff/odffields.hxx>
87 using namespace com::sun::star
;
88 using namespace sw::util
;
89 using namespace sw::types
;
90 using namespace sw::mark
;
92 //-----------------------------------------
94 //-----------------------------------------
96 //cmc, OCX i.e. word 97 form controls
97 eF_ResT
SwWW8ImplReader::Read_F_OCX( WW8FieldDesc
*, String
& )
99 if( bObj
&& nPicLocFc
)
100 nObjLocFc
= nPicLocFc
;
105 eF_ResT
SwWW8ImplReader::Read_F_FormTextBox( WW8FieldDesc
* pF
, String
& rStr
)
107 WW8FormulaEditBox
aFormula(*this);
109 if (0x01 == rStr
.GetChar(writer_cast
<xub_StrLen
>(pF
->nLCode
-1))) {
110 ImportFormulaControl(aFormula
,pF
->nSCode
+pF
->nLCode
-1, WW8_CT_EDIT
);
114 Here we have a small complication. This formula control contains
115 the default text that is displayed if you edit the form field in
116 the "default text" area. But MSOffice does not display that
117 information, instead it display the result of the field,
118 MSOffice just uses the default text of the control as its
119 initial value for the displayed default text. So we will swap in
120 the field result into the formula here in place of the default
124 const SvtFilterOptions
& rOpt
= SvtFilterOptions::Get();
125 sal_Bool bUseEnhFields
= rOpt
.IsUseEnhancedFields();
127 if (!bUseEnhFields
) {
128 aFormula
.sDefault
= GetFieldResult(pF
);
130 SwInputField
aFld((SwInputFieldType
*)rDoc
.GetSysFldType( RES_INPUTFLD
),
131 aFormula
.sDefault
, aFormula
.sTitle
, INP_TXT
, 0 );
132 aFld
.SetHelp(aFormula
.sHelp
);
133 aFld
.SetToolTip(aFormula
.sToolTip
);
135 rDoc
.InsertPoolItem(*pPaM
, SwFmtFld(aFld
), 0);
138 WW8PLCFx_Book
* pB
= pPlcxMan
->GetBook();
139 String aBookmarkName
;
141 WW8_CP currentCP
=pF
->nSCode
;
142 WW8_CP currentLen
=pF
->nLen
;
144 sal_uInt16 bkmFindIdx
;
145 String aBookmarkFind
=pB
->GetBookmark(currentCP
-1, currentCP
+currentLen
-1, bkmFindIdx
);
147 if (aBookmarkFind
.Len()>0) {
148 pB
->SetStatus(bkmFindIdx
, BOOK_FIELD
); // mark bookmark as consumed, such that tl'll not get inserted as a "normal" bookmark again
149 if (aBookmarkFind
.Len()>0) {
150 aBookmarkName
=aBookmarkFind
;
155 if (pB
!=NULL
&& aBookmarkName
.Len()==0) {
156 aBookmarkName
=pB
->GetUniqueBookmarkName(aFormula
.sTitle
);
160 if (aBookmarkName
.Len()>0) {
161 maFieldStack
.back().SetBookmarkName(aBookmarkName
);
162 maFieldStack
.back().SetBookmarkType(ODF_FORMTEXT
);
163 maFieldStack
.back().getParameters()["Description"] = uno::makeAny(OUString(aFormula
.sToolTip
));
164 maFieldStack
.back().getParameters()["Name"] = uno::makeAny(OUString(aFormula
.sTitle
));
170 eF_ResT
SwWW8ImplReader::Read_F_FormCheckBox( WW8FieldDesc
* pF
, String
& rStr
)
172 WW8FormulaCheckBox
aFormula(*this);
175 pFormImpl
= new SwMSConvertControls(mpDocShell
, pPaM
);
177 if (0x01 == rStr
.GetChar(writer_cast
<xub_StrLen
>(pF
->nLCode
-1)))
178 ImportFormulaControl(aFormula
,pF
->nSCode
+pF
->nLCode
-1, WW8_CT_CHECKBOX
);
179 const SvtFilterOptions
& rOpt
= SvtFilterOptions::Get();
180 sal_Bool bUseEnhFields
= rOpt
.IsUseEnhancedFields();
182 if (!bUseEnhFields
) {
183 pFormImpl
->InsertFormula(aFormula
);
186 String aBookmarkName
;
187 WW8PLCFx_Book
* pB
= pPlcxMan
->GetBook();
189 WW8_CP currentCP
=pF
->nSCode
;
190 WW8_CP currentLen
=pF
->nLen
;
192 sal_uInt16 bkmFindIdx
;
193 String aBookmarkFind
=pB
->GetBookmark(currentCP
-1, currentCP
+currentLen
-1, bkmFindIdx
);
195 if (aBookmarkFind
.Len()>0) {
196 pB
->SetStatus(bkmFindIdx
, BOOK_FIELD
); // mark as consumed by field
197 if (aBookmarkFind
.Len()>0) {
198 aBookmarkName
=aBookmarkFind
;
203 if (pB
!=NULL
&& aBookmarkName
.Len()==0) {
204 aBookmarkName
=pB
->GetUniqueBookmarkName(aFormula
.sTitle
);
207 if (aBookmarkName
.Len()>0)
209 IDocumentMarkAccess
* pMarksAccess
= rDoc
.getIDocumentMarkAccess( );
210 IFieldmark
* pFieldmark
= dynamic_cast<IFieldmark
*>( pMarksAccess
->makeNoTextFieldBookmark(
211 *pPaM
, aBookmarkName
, ODF_FORMCHECKBOX
) );
212 OSL_ENSURE(pFieldmark
!=NULL
, "hmmm; why was the bookmark not created?");
213 if (pFieldmark
!=NULL
) {
214 IFieldmark::parameter_map_t
* const pParameters
= pFieldmark
->GetParameters();
215 ICheckboxFieldmark
* pCheckboxFm
= dynamic_cast<ICheckboxFieldmark
*>(pFieldmark
);
216 (*pParameters
)[ODF_FORMCHECKBOX_NAME
] = uno::makeAny(OUString(aFormula
.sTitle
));
217 (*pParameters
)[ODF_FORMCHECKBOX_HELPTEXT
] = uno::makeAny(OUString(aFormula
.sToolTip
));
220 pCheckboxFm
->SetChecked(aFormula
.nChecked
);
221 // set field data here...
228 eF_ResT
SwWW8ImplReader::Read_F_FormListBox( WW8FieldDesc
* pF
, String
& rStr
)
230 WW8FormulaListBox
aFormula(*this);
232 if (0x01 == rStr
.GetChar(writer_cast
<xub_StrLen
>(pF
->nLCode
-1)))
233 ImportFormulaControl(aFormula
,pF
->nSCode
+pF
->nLCode
-1, WW8_CT_DROPDOWN
);
235 const SvtFilterOptions
& rOpt
= SvtFilterOptions::Get();
236 sal_Bool bUseEnhFields
= rOpt
.IsUseEnhancedFields();
240 SwDropDownField
aFld((SwDropDownFieldType
*)rDoc
.GetSysFldType(RES_DROPDOWN
));
242 aFld
.SetName(aFormula
.sTitle
);
243 aFld
.SetHelp(aFormula
.sHelp
);
244 aFld
.SetToolTip(aFormula
.sToolTip
);
246 if (!aFormula
.maListEntries
.empty())
248 aFld
.SetItems(aFormula
.maListEntries
);
249 int nIndex
= aFormula
.fDropdownIndex
< aFormula
.maListEntries
.size() ? aFormula
.fDropdownIndex
: 0;
250 aFld
.SetSelectedItem(aFormula
.maListEntries
[nIndex
]);
253 rDoc
.InsertPoolItem(*pPaM
, SwFmtFld(aFld
), 0);
259 String aBookmarkName
;
260 WW8PLCFx_Book
* pB
= pPlcxMan
->GetBook();
263 WW8_CP currentCP
=pF
->nSCode
;
264 WW8_CP currentLen
=pF
->nLen
;
266 sal_uInt16 bkmFindIdx
;
267 String aBookmarkFind
=pB
->GetBookmark(currentCP
-1, currentCP
+currentLen
-1, bkmFindIdx
);
269 if (aBookmarkFind
.Len()>0)
271 pB
->SetStatus(bkmFindIdx
, BOOK_FIELD
); // mark as consumed by field
272 if (aBookmarkFind
.Len()>0)
273 aBookmarkName
=aBookmarkFind
;
277 if (pB
!=NULL
&& aBookmarkName
.Len()==0)
278 aBookmarkName
=pB
->GetUniqueBookmarkName(aFormula
.sTitle
);
280 if (aBookmarkName
.Len()>0)
282 IDocumentMarkAccess
* pMarksAccess
= rDoc
.getIDocumentMarkAccess( );
283 IFieldmark
*pFieldmark
= dynamic_cast<IFieldmark
*>(
284 pMarksAccess
->makeNoTextFieldBookmark( *pPaM
, aBookmarkName
, ODF_FORMDROPDOWN
) );
285 OSL_ENSURE(pFieldmark
!=NULL
, "hmmm; why was the bookmark not created?");
286 if ( pFieldmark
!= NULL
)
288 uno::Sequence
< OUString
> vListEntries(aFormula
.maListEntries
.size());
289 ::std::copy(aFormula
.maListEntries
.begin(), aFormula
.maListEntries
.end(), ::comphelper::stl_begin(vListEntries
));
290 (*pFieldmark
->GetParameters())[ODF_FORMDROPDOWN_LISTENTRY
] = uno::makeAny(vListEntries
);
291 sal_Int32 nIndex
= aFormula
.fDropdownIndex
< aFormula
.maListEntries
.size() ? aFormula
.fDropdownIndex
: 0;
292 (*pFieldmark
->GetParameters())[ODF_FORMDROPDOWN_RESULT
] = uno::makeAny(nIndex
);
293 // set field data here...
301 eF_ResT
SwWW8ImplReader::Read_F_HTMLControl(WW8FieldDesc
*, String
&)
303 if( bObj
&& nPicLocFc
)
304 nObjLocFc
= nPicLocFc
;
309 void SwWW8ImplReader::DeleteFormImpl()
311 delete pFormImpl
, pFormImpl
= 0;
314 //----------------------------------------------------------------------------
315 // WW8ListManager oeffentliche Methoden stehen ganz am Ende
316 //------------------------- ============ --------------- ============ --------
320 // Hilfs-Deklarationen ///////////////////////////////////////////////////////
322 // Style Id's for each level
323 typedef sal_uInt16 WW8aIdSty
[WW8ListManager::nMaxLevel
];
324 // Zeichenattribute aus GrpprlChpx
325 typedef SfxItemSet
* WW8aISet
[WW8ListManager::nMaxLevel
];
326 // Zeichen Style Pointer
327 typedef SwCharFmt
* WW8aCFmt
[WW8ListManager::nMaxLevel
];
329 struct WW8LST
// nur DIE Eintraege, die WIR benoetigen!
331 WW8aIdSty aIdSty
; // Style Id's for each level,
332 // nIStDNil if no style linked
333 sal_uInt32 nIdLst
; // Unique List ID
334 sal_uInt32 nTplC
; // Unique template code - Was ist das bloss?
335 sal_uInt8 bSimpleList
:1; // Flag: Liste hat nur EINEN Level
336 sal_uInt8 bRestartHdn
:1; // WW6-Kompatibilitaets-Flag:
337 // true if the list should start numbering over
338 }; // at the beginning of each section
340 const sal_uInt32 cbLSTF
=28;
342 struct WW8LFO
// nur DIE Eintraege, die WIR benoetigen!
344 SwNumRule
* pNumRule
; // Parent NumRule
345 sal_uInt32 nIdLst
; // Unique List ID
346 sal_uInt8 nLfoLvl
; // count of levels whose format is overridden
350 struct WW8LVL
// nur DIE Eintraege, die WIR benoetigen!
352 sal_Int32 nStartAt
; // start at value for this value
353 sal_Int32 nV6DxaSpace
;// Ver6-Compatible: min Space between Num anf text::Paragraph
354 sal_Int32 nV6Indent
; // Ver6-Compatible: Breite des Prefix Textes; ggfs. zur
355 // Definition d. Erstzl.einzug nutzen!
356 // Absatzattribute aus GrpprlPapx
357 sal_uInt16 nDxaLeft
; // linker Einzug
358 short nDxaLeft1
; // Erstzeilen-Einzug
360 sal_uInt8 nNFC
; // number format code
361 // Offset der Feldkodes im Num-X-String
362 sal_uInt8 aOfsNumsXCH
[WW8ListManager::nMaxLevel
];
363 sal_uInt8 nLenGrpprlChpx
; // length, in bytes, of the LVL's grpprlChpx
364 sal_uInt8 nLenGrpprlPapx
; // length, in bytes, of the LVL's grpprlPapx
365 sal_uInt8 nAlign
: 2; // alignment (left, right, centered) of the number
366 sal_uInt8 bLegal
: 1; // egal
367 sal_uInt8 bNoRest
:1; // egal
368 sal_uInt8 bV6Prev
:1; // Ver6-Compatible: number will include previous levels
369 sal_uInt8 bV6PrSp
:1; // Ver6-Compatible: egal
370 sal_uInt8 bV6
: 1; // falls true , beachte die V6-Compatible Eintraege!
371 sal_uInt8 bDummy
: 1; // (macht das Byte voll)
377 sal_Int32 nStartAt
; // start-at value if bFormat==false and bStartAt == true
378 // (if bFormat==true, the start-at is stored in the LVL)
379 sal_uInt8 nLevel
; // the level to be overridden
380 // dieses Byte ist _absichtlich_ nicht in das folgende Byte hineingepackt !!
381 // (siehe Kommentar unten bei struct WW8LFOInfo)
383 sal_uInt8 bStartAt
:1; // true if the start-at value is overridden
384 sal_uInt8 bFormat
:1; // true if the formatting is overriden
387 nStartAt(1), nLevel(0), bStartAt(1), bFormat(0) {}
390 // in den ListenInfos zu speichernde Daten ///////////////////////////////////
392 struct WW8LSTInfo
// sortiert nach nIdLst (in WW8 verwendete Listen-Id)
394 std::vector
<ww::bytes
> maParaSprms
;
395 WW8aIdSty aIdSty
; // Style Id's for each level
396 WW8aISet aItemSet
; // Zeichenattribute aus GrpprlChpx
397 WW8aCFmt aCharFmt
; // Zeichen Style Pointer
399 SwNumRule
* pNumRule
; // Zeiger auf entsprechende Listenvorlage im Writer
400 sal_uInt32 nIdLst
; // WW8Id dieser Liste
401 sal_uInt8 bSimpleList
:1;// Flag, ob diese NumRule nur einen Level verwendet
402 sal_uInt8 bUsedInDoc
:1;// Flag, ob diese NumRule im Doc verwendet wird,
403 // oder beim Reader-Ende geloescht werden sollte
405 WW8LSTInfo(SwNumRule
* pNumRule_
, WW8LST
& aLST
)
406 : pNumRule(pNumRule_
), nIdLst(aLST
.nIdLst
),
407 bSimpleList(aLST
.bSimpleList
), bUsedInDoc(0)
409 memcpy( aIdSty
, aLST
.aIdSty
, sizeof( aIdSty
));
410 memset(&aItemSet
, 0, sizeof( aItemSet
));
411 memset(&aCharFmt
, 0, sizeof( aCharFmt
));
416 // in den ListenFormatOverrideInfos zu speichernde Daten /////////////////////
418 struct WW8LFOInfo
// unsortiert, d.h. Reihenfolge genau wie im WW8 Stream
420 std::vector
<ww::bytes
> maParaSprms
;
421 std::vector
<WW8LFOLVL
> maOverrides
;
422 SwNumRule
* pNumRule
; // Zeiger auf entsprechende Listenvorlage im Writer
423 // entweder: Liste in LSTInfos oder eigene Liste
424 // (im Ctor erstmal die aus den LSTInfos merken)
426 sal_uInt32 nIdLst
; // WW8-Id der betreffenden Liste
427 sal_uInt8 nLfoLvl
; // count of levels whose format is overridden
428 // Ja, ich natuerlich koennten wir nLfoLvl (mittels :4) noch in das folgende
429 // Byte mit hineinpacken, doch waere das eine ziemliche Fehlerquelle,
430 // an dem Tag, wo MS ihr Listenformat auf mehr als 15 Level aufbohren.
432 sal_uInt8 bOverride
:1;// Flag, ob die NumRule nicht in maLSTInfos steht,
433 // sondern fuer pLFOInfos NEU angelegt wurde
434 sal_uInt8 bSimpleList
:1;// Flag, ob diese NumRule nur einen Level verwendet
435 sal_uInt8 bUsedInDoc
:1;// Flag, ob diese NumRule im Doc verwendet wird,
436 // oder beim Reader-Ende geloescht werden sollte
437 sal_uInt8 bLSTbUIDSet
:1;// Flag, ob bUsedInDoc in maLSTInfos gesetzt wurde,
438 // und nicht nochmals gesetzt zu werden braucht
439 WW8LFOInfo(const WW8LFO
& rLFO
);
442 WW8LFOInfo::WW8LFOInfo(const WW8LFO
& rLFO
)
443 : maParaSprms(WW8ListManager::nMaxLevel
),
444 maOverrides(WW8ListManager::nMaxLevel
), pNumRule(rLFO
.pNumRule
),
445 nIdLst(rLFO
.nIdLst
), nLfoLvl(rLFO
.nLfoLvl
),
446 bOverride(rLFO
.nLfoLvl
? true : false), bSimpleList(rLFO
.bSimpleList
),
447 bUsedInDoc(0), bLSTbUIDSet(0)
453 // Hilfs-Methoden ////////////////////////////////////////////////////////////
456 // finden der Sprm-Parameter-Daten, falls Sprm im Grpprl enthalten
457 sal_uInt8
* WW8ListManager::GrpprlHasSprm(sal_uInt16 nId
, sal_uInt8
& rSprms
,
460 return maSprmParser
.findSprmData(nId
, &rSprms
, nLen
);
463 class ListWithId
: public std::unary_function
<const WW8LSTInfo
*, bool>
468 explicit ListWithId(sal_uInt32 nIdLst
) : mnIdLst(nIdLst
) {}
469 bool operator() (const WW8LSTInfo
*pEntry
) const
470 { return (pEntry
->nIdLst
== mnIdLst
); }
473 // Zugriff ueber die List-Id des LST Eintrags
474 WW8LSTInfo
* WW8ListManager::GetLSTByListId( sal_uInt32 nIdLst
) const
476 std::vector
<WW8LSTInfo
*>::const_iterator aResult
=
477 std::find_if(maLSTInfos
.begin(),maLSTInfos
.end(),ListWithId(nIdLst
));
478 if (aResult
== maLSTInfos
.end())
483 static void lcl_CopyGreaterEight(String
&rDest
, String
&rSrc
,
484 xub_StrLen nStart
, xub_StrLen nLen
= STRING_LEN
)
486 if (nLen
> rSrc
.Len() || nLen
== STRING_LEN
)
488 for (xub_StrLen nI
= nStart
; nI
< nLen
; ++nI
)
490 sal_Unicode nChar
= rSrc
.GetChar(nI
);
491 if (nChar
> WW8ListManager::nMaxLevel
)
496 bool WW8ListManager::ReadLVL(SwNumFmt
& rNumFmt
, SfxItemSet
*& rpItemSet
,
497 sal_uInt16 nLevelStyle
, bool bSetStartNo
,
498 std::deque
<bool> &rNotReallyThere
, sal_uInt16 nLevel
,
499 ww::bytes
&rParaSprms
)
502 sal_uInt16
nStartNo(0); // Start-Nr. fuer den Writer
503 SvxExtNumType eType
; // Writer-Num-Typ
504 SvxAdjust eAdj
; // Ausrichtung (Links/rechts/zent.)
505 sal_Unicode
cBullet(0x2190); // default safe bullet
507 sal_Unicode
cGrfBulletCP(USHRT_MAX
);
515 memset(&aLVL
, 0, sizeof( aLVL
));
516 rSt
>> aLVL
.nStartAt
;
519 if( 0 != rSt
.GetError() ) return false;
520 aLVL
.nAlign
= (aBits1
& 0x03);
521 if( aBits1
& 0x10 ) aLVL
.bV6Prev
= true;
522 if( aBits1
& 0x20 ) aLVL
.bV6PrSp
= true;
523 if( aBits1
& 0x40 ) aLVL
.bV6
= true;
525 sal_uInt8 nLevelB
= 0;
526 for(nLevelB
= 0; nLevelB
< nMaxLevel
; ++nLevelB
)
528 rSt
>> aLVL
.aOfsNumsXCH
[ nLevelB
];
529 if( 0 != rSt
.GetError() )
539 sal_uInt8
ixchFollow(0);
541 rSt
>> aLVL
.nV6DxaSpace
;
542 rSt
>> aLVL
.nV6Indent
;
543 rSt
>> aLVL
.nLenGrpprlChpx
;
544 rSt
>> aLVL
.nLenGrpprlPapx
;
546 if( 0 != rSt
.GetError()) return false;
549 // 2. ggfs. PAPx einlesen und nach Einzug-Werten suchen
551 short nTabPos
= 0; // #i86652# - read tab setting
552 if( aLVL
.nLenGrpprlPapx
)
554 sal_uInt8 aGrpprlPapx
[ 255 ];
555 if(aLVL
.nLenGrpprlPapx
!= rSt
.Read(&aGrpprlPapx
,aLVL
.nLenGrpprlPapx
))
557 // "sprmPDxaLeft" pap.dxaLeft;dxa;word;
560 (0 != (pSprm
= GrpprlHasSprm(0x840F,aGrpprlPapx
[0],aLVL
.nLenGrpprlPapx
))) ||
561 (0 != (pSprm
= GrpprlHasSprm(0x845E,aGrpprlPapx
[0],aLVL
.nLenGrpprlPapx
)))
564 sal_uInt8
*pBegin
= pSprm
-2;
566 rParaSprms
.push_back(*pBegin
++);
567 short nDxaLeft
= SVBT16ToShort( pSprm
);
568 aLVL
.nDxaLeft
= (0 < nDxaLeft
) ? (sal_uInt16
)nDxaLeft
569 : (sal_uInt16
)(-nDxaLeft
);
572 // "sprmPDxaLeft1" pap.dxaLeft1;dxa;word;
574 (0 != (pSprm
= GrpprlHasSprm(0x8411,aGrpprlPapx
[0],aLVL
.nLenGrpprlPapx
)) ) ||
575 (0 != (pSprm
= GrpprlHasSprm(0x8460,aGrpprlPapx
[0],aLVL
.nLenGrpprlPapx
)) )
578 sal_uInt8
*pBegin
= pSprm
-2;
580 rParaSprms
.push_back(*pBegin
++);
581 aLVL
.nDxaLeft1
= SVBT16ToShort( pSprm
);
584 // #i86652# - read tab setting
585 if(0 != (pSprm
= GrpprlHasSprm(0xC615,aGrpprlPapx
[0],aLVL
.nLenGrpprlPapx
)) )
590 if (*pSprm
++ == 0) //nDel
592 if (*pSprm
++ == 1) //nIns
594 nTabPos
= SVBT16ToShort(pSprm
);
596 if (*pSprm
== 6) //type
603 OSL_ENSURE(bDone
, "tab setting in numbering is "
604 "of unexpected configuration");
607 if ( rNumFmt
.GetPositionAndSpaceMode() ==
608 SvxNumberFormat::LABEL_WIDTH_AND_POSITION
)
610 // If there is a tab setting with a larger value, then use that.
611 // Ideally we would allow tabs to be used in numbering fields and set
612 // this on the containing paragraph which would make it actually work
616 const sal_uInt16 nDesired
= aLVL
.nDxaLeft
+ aLVL
.nDxaLeft1
;
618 bool bDoAdjust
= false;
619 if ( nDesired
< aLVL
.nDxaLeft
)
621 if ( nDesired
< nTabPos
&& nTabPos
< aLVL
.nDxaLeft
)
628 if ( aLVL
.nDxaLeft
< nTabPos
&& nTabPos
< nDesired
)
636 aLVL
.nDxaLeft
= (0 < nTabPos
)
637 ? (sal_uInt16
)nTabPos
638 : (sal_uInt16
)(-nTabPos
);
640 aLVL
.nDxaLeft1
= nDesired
- aLVL
.nDxaLeft
;
646 // 3. ggfs. CHPx einlesen und
648 sal_uInt16 nWitchPicIsBullet
= USHRT_MAX
;
649 bool bIsPicBullet
= false;
651 if( aLVL
.nLenGrpprlChpx
)
653 sal_uInt8 aGrpprlChpx
[ 255 ];
654 memset(&aGrpprlChpx
, 0, sizeof( aGrpprlChpx
));
655 if(aLVL
.nLenGrpprlChpx
!= rSt
.Read(&aGrpprlChpx
, aLVL
.nLenGrpprlChpx
))
658 //For i120928,parse the graphic info of bullets
659 sal_uInt8
*pSprmWhichPis
= GrpprlHasSprm(0x6887,aGrpprlChpx
[0],aLVL
.nLenGrpprlChpx
);
660 sal_uInt8
*pSprmIsPicBullet
= GrpprlHasSprm(0x4888,aGrpprlChpx
[0],aLVL
.nLenGrpprlChpx
);
663 nWitchPicIsBullet
= *pSprmWhichPis
;
665 if (pSprmIsPicBullet
)
667 bIsPicBullet
= (*pSprmIsPicBullet
) & 0x0001;
670 // neues ItemSet fuer die Zeichenattribute anlegen
671 rpItemSet
= new SfxItemSet( rDoc
.GetAttrPool(), RES_CHRATR_BEGIN
,
672 RES_CHRATR_END
- 1 );
674 // Reader-ItemSet-Pointer darauf zeigen lassen
675 rReader
.SetAktItemSet( rpItemSet
);
676 // Reader-Style auf den Style dieses Levels setzen
677 sal_uInt16 nOldColl
= rReader
.GetNAktColl();
678 sal_uInt16 nNewColl
= nLevelStyle
;
679 if (ww::stiNil
== nNewColl
)
681 rReader
.SetNAktColl( nNewColl
);
683 // Nun den GrpprlChpx einfach durchnudeln: die Read_xy() Methoden
684 // in WW8PAR6.CXX rufen ganz normal ihr NewAttr() oder GetFmtAttr()
685 // und diese merken am besetzten Reader-ItemSet-Pointer, dass dieser
686 // spezielle ItemSet relevant ist - und nicht ein Stack oder Style!
687 sal_uInt16 nOldFlags1
= rReader
.GetToggleAttrFlags();
688 sal_uInt16 nOldFlags2
= rReader
.GetToggleBiDiAttrFlags();
690 WW8SprmIter
aSprmIter(&aGrpprlChpx
[0], aLVL
.nLenGrpprlChpx
,
692 while (const sal_uInt8
* pSprm
= aSprmIter
.GetSprms())
694 rReader
.ImportSprm(pSprm
);
698 // Reader-ItemSet-Pointer und Reader-Style zuruecksetzen
699 rReader
.SetAktItemSet( 0 );
700 rReader
.SetNAktColl( nOldColl
);
701 rReader
.SetToggleAttrFlags(nOldFlags1
);
702 rReader
.SetToggleBiDiAttrFlags(nOldFlags2
);
705 // 4. den Nummerierungsstring einlesen: ergibt Prefix und Postfix
707 String
sNumString(read_uInt16_PascalString(rSt
));
710 // 5. gelesene Werte in Writer Syntax umwandeln
712 if( 0 <= aLVL
.nStartAt
)
713 nStartNo
= (sal_uInt16
)aLVL
.nStartAt
;
718 eType
= SVX_NUM_ARABIC
;
721 eType
= SVX_NUM_ROMAN_UPPER
;
724 eType
= SVX_NUM_ROMAN_LOWER
;
727 eType
= SVX_NUM_CHARS_UPPER_LETTER_N
;
730 eType
= SVX_NUM_CHARS_LOWER_LETTER_N
;
733 // eigentlich: ORDINAL
734 eType
= SVX_NUM_ARABIC
;
738 eType
= SVX_NUM_CHAR_SPECIAL
;
739 //For i120928,type info
742 eType
= SVX_NUM_BITMAP
;
747 eType
= SVX_NUM_NUMBER_NONE
;
751 eType
= SVX_NUM_ARABIC
;
755 //If a number level is not going to be used, then record this fact
756 if (SVX_NUM_NUMBER_NONE
== eType
)
757 rNotReallyThere
[nLevel
] = true;
760 If a number level was not used (i.e. is in NotReallyThere), and that
761 number level appears at one of the positions in the display string of the
762 list, then it effectively is not there at all. So remove that level entry
763 from a copy of the aOfsNumsXCH.
765 std::vector
<sal_uInt8
> aOfsNumsXCH
;
766 typedef std::vector
<sal_uInt8
>::iterator myIter
;
767 aOfsNumsXCH
.reserve(nMaxLevel
);
769 for(nLevelB
= 0; nLevelB
< nMaxLevel
; ++nLevelB
)
770 aOfsNumsXCH
.push_back(aLVL
.aOfsNumsXCH
[nLevelB
]);
772 for(nLevelB
= 0; nLevelB
<= nLevel
; ++nLevelB
)
774 sal_uInt8 nPos
= aOfsNumsXCH
[nLevelB
];
775 if (nPos
&& nPos
< sNumString
.Len() && sNumString
.GetChar(nPos
-1) < nMaxLevel
)
777 if (rNotReallyThere
[nLevelB
])
778 aOfsNumsXCH
[nLevelB
] = 0;
781 myIter aIter
= std::remove(aOfsNumsXCH
.begin(), aOfsNumsXCH
.end(), 0);
782 myIter aEnd
= aOfsNumsXCH
.end();
783 // #i60633# - suppress access on <aOfsNumsXCH.end()>
786 // Somehow the first removed vector element, at which <aIter>
787 // points to, isn't reset to zero.
788 // Investigation is needed to clarify why. It seems that only
789 // special arrays are handled correctly by this code.
791 while (aIter
!= aEnd
)
798 sal_uInt8 nUpperLevel
= 0; // akt. Anzeigetiefe fuer den Writer
799 for(nLevelB
= 0; nLevelB
< nMaxLevel
; ++nLevelB
)
801 if (!nUpperLevel
&& !aOfsNumsXCH
[nLevelB
])
802 nUpperLevel
= nLevelB
;
805 // falls kein NULL als Terminierungs-Char kam,
806 // ist die Liste voller Indices, d.h. alle Plaetze sind besetzt,
807 // also sind alle Level anzuzeigen
809 nUpperLevel
= nMaxLevel
;
811 if (SVX_NUM_CHAR_SPECIAL
== eType
)
813 cBullet
= sNumString
.Len() ? sNumString
.GetChar(0) : 0x2190;
815 if (!cBullet
) // unsave control code?
818 else if (SVX_NUM_BITMAP
== eType
) //For i120928,position index info of graphic
820 cGrfBulletCP
= nWitchPicIsBullet
; // This is a bullet picture ID
826 Our aOfsNumsXCH seems generally to be an array that contains the
827 offset into sNumString of locations where the numbers should be
828 filled in, so if the first "fill in a number" slot is greater than
829 1 there is a "prefix" before the number
831 //First number appears at
832 sal_uInt8 nOneBasedFirstNoIndex
= aOfsNumsXCH
[0];
833 xub_StrLen nFirstNoIndex
=
834 nOneBasedFirstNoIndex
> 0 ? nOneBasedFirstNoIndex
-1 : STRING_LEN
;
835 lcl_CopyGreaterEight(sPrefix
, sNumString
, 0, nFirstNoIndex
);
837 //Next number appears at
840 sal_uInt8 nOneBasedNextNoIndex
= aOfsNumsXCH
[nUpperLevel
-1];
841 xub_StrLen nNextNoIndex
=
842 nOneBasedNextNoIndex
> 0 ? nOneBasedNextNoIndex
-1 : STRING_LEN
;
843 if (nNextNoIndex
!= STRING_LEN
)
845 if (sNumString
.Len() > nNextNoIndex
)
846 lcl_CopyGreaterEight(sPostfix
, sNumString
, nNextNoIndex
);
850 We use lcl_CopyGreaterEight because once if we have removed unused
851 number indexes from the aOfsNumsXCH then placeholders remain in
852 sNumString which must not be copied into the final numbering strings
856 switch( aLVL
.nAlign
)
859 eAdj
= SVX_ADJUST_LEFT
;
862 eAdj
= SVX_ADJUST_CENTER
;
865 eAdj
= SVX_ADJUST_RIGHT
;
868 // Writer here cannot do block justification
869 eAdj
= SVX_ADJUST_LEFT
;
873 OSL_ENSURE( !this, "Value of aLVL.nAlign is not supported" );
875 eAdj
= SVX_ADJUST_LEFT
;
879 // 6. entsprechendes NumFmt konfigurieren
881 rNumFmt
.SetStart( nStartNo
);
882 rNumFmt
.SetNumberingType( static_cast< sal_Int16
>(eType
) );
883 rNumFmt
.SetNumAdjust( eAdj
);
885 if( SVX_NUM_CHAR_SPECIAL
== eType
)
887 // first character of the Prefix-Text is the Bullet
888 rNumFmt
.SetBulletChar(cBullet
);
889 // Don't forget: unten, nach dem Bauen eventueller Styles auch noch
890 // SetBulletFont() rufen !!!
892 //For i120928,position index info
893 else if (SVX_NUM_BITMAP
== eType
)
895 rNumFmt
.SetGrfBulletCP(cGrfBulletCP
);
899 // reminder: Garnix ist default Prefix
901 rNumFmt
.SetPrefix( sPrefix
);
902 // reminder: Point is default Postfix
903 rNumFmt
.SetSuffix( sPostfix
);
904 rNumFmt
.SetIncludeUpperLevels( nUpperLevel
);
908 if ( rNumFmt
.GetPositionAndSpaceMode() ==
909 SvxNumberFormat::LABEL_WIDTH_AND_POSITION
)
911 if (eAdj
== SVX_ADJUST_RIGHT
)
913 rNumFmt
.SetAbsLSpace(aLVL
.nDxaLeft
);
914 rNumFmt
.SetFirstLineOffset(-aLVL
.nDxaLeft
);
915 rNumFmt
.SetCharTextDistance(-aLVL
.nDxaLeft1
);
919 rNumFmt
.SetAbsLSpace( aLVL
.nDxaLeft
);
920 rNumFmt
.SetFirstLineOffset(aLVL
.nDxaLeft1
);
925 rNumFmt
.SetIndentAt( aLVL
.nDxaLeft
);
926 rNumFmt
.SetFirstLineIndent(aLVL
.nDxaLeft1
);
928 rNumFmt
.SetListtabPos( nTabPos
);
930 rNumFmt
.SetListtabPos( aLVL
.nV6Indent
);
931 SvxNumberFormat::LabelFollowedBy eNumLabelFollowedBy
= SvxNumberFormat::LISTTAB
;
932 switch ( ixchFollow
)
936 eNumLabelFollowedBy
= SvxNumberFormat::LISTTAB
;
941 eNumLabelFollowedBy
= SvxNumberFormat::SPACE
;
946 eNumLabelFollowedBy
= SvxNumberFormat::NOTHING
;
950 rNumFmt
.SetLabelFollowedBy( eNumLabelFollowedBy
);
956 void WW8ListManager::AdjustLVL( sal_uInt8 nLevel
, SwNumRule
& rNumRule
,
957 WW8aISet
& rListItemSet
, WW8aCFmt
& rCharFmt
, bool& bNewCharFmtCreated
,
960 bNewCharFmtCreated
= false;
961 SfxItemSet
* pThisLevelItemSet
;
962 sal_uInt8 nIdenticalItemSetLevel
;
963 const SfxPoolItem
* pItem
;
965 SwNumFmt aNumFmt
= rNumRule
.Get( nLevel
);
967 pThisLevelItemSet
= rListItemSet
[ nLevel
];
969 if( pThisLevelItemSet
&& pThisLevelItemSet
->Count())
971 nIdenticalItemSetLevel
= nMaxLevel
;
972 SfxItemIter
aIter( *pThisLevelItemSet
);
973 SfxItemSet
* pLowerLevelItemSet
;
974 for (sal_uInt8 nLowerLevel
= 0; nLowerLevel
< nLevel
; ++nLowerLevel
)
976 pLowerLevelItemSet
= rListItemSet
[ nLowerLevel
];
977 if( pLowerLevelItemSet
978 && (pLowerLevelItemSet
->Count() == pThisLevelItemSet
->Count()) )
980 nIdenticalItemSetLevel
= nLowerLevel
;
981 sal_uInt16 nWhich
= aIter
.GetCurItem()->Which();
984 if( // ggfs. passenden pItem im pLowerLevelItemSet finden
985 (SFX_ITEM_SET
!= pLowerLevelItemSet
->GetItemState(
986 nWhich
, false, &pItem
) )
987 || // virtuellen "!=" Operator anwenden
988 (*pItem
!= *aIter
.GetCurItem() ) )
989 // falls kein Item mit gleicher nWhich gefunden oder Werte
990 // der Items ungleich, Ungleichheit merken und abbrechen!
992 nIdenticalItemSetLevel
= nMaxLevel
;
995 if( aIter
.IsAtEnd() )
997 nWhich
= aIter
.NextItem()->Which();
1000 if( nIdenticalItemSetLevel
!= nMaxLevel
)
1006 if (nMaxLevel
== nIdenticalItemSetLevel
)
1009 String
aName( sPrefix
.Len() ? sPrefix
: rNumRule
.GetName() );
1010 (aName
+= 'z') += OUString::number( nLevel
);
1013 pFmt
= rDoc
.MakeCharFmt(aName
, (SwCharFmt
*)rDoc
.GetDfltCharFmt());
1014 bNewCharFmtCreated
= true;
1015 // Attribute reinsetzen
1016 pFmt
->SetFmtAttr( *pThisLevelItemSet
);
1020 // passenden Style hier anhaengen
1021 pFmt
= rCharFmt
[ nIdenticalItemSetLevel
];
1025 rCharFmt
[ nLevel
] = pFmt
;
1028 // Style an das NumFormat haengen
1030 aNumFmt
.SetCharFmt( pFmt
);
1032 //Ensure the default char fmt is initialized for any level of num ruler if no customized attr
1035 SwCharFmt
* pFmt
= aNumFmt
.GetCharFmt();
1038 OUString aName
= ( sPrefix
.Len() ? sPrefix
: rNumRule
.GetName() );
1039 aName
+= "z" + OUString::number( nLevel
);
1041 pFmt
= rDoc
.MakeCharFmt(aName
, (SwCharFmt
*)rDoc
.GetDfltCharFmt());
1042 bNewCharFmtCreated
= true;
1043 rCharFmt
[ nLevel
] = pFmt
;
1044 aNumFmt
.SetCharFmt( pFmt
);
1048 // ggfs. Bullet Font an das NumFormat haengen
1050 if( SVX_NUM_CHAR_SPECIAL
== aNumFmt
.GetNumberingType() )
1052 SwCharFmt
* pFmt
= aNumFmt
.GetCharFmt();
1056 aFont
= numfunc::GetDefBulletFont();
1060 const SvxFontItem
& rFontItem
= pFmt
->GetFont();
1061 aFont
.SetFamily( rFontItem
.GetFamily() );
1062 aFont
.SetName( rFontItem
.GetFamilyName() );
1063 aFont
.SetStyleName( rFontItem
.GetStyleName() );
1064 aFont
.SetPitch( rFontItem
.GetPitch() );
1065 aFont
.SetCharSet( rFontItem
.GetCharSet() );
1067 aNumFmt
.SetBulletFont( &aFont
);
1070 // und wieder rein in die NumRule
1072 rNumRule
.Set(nLevel
, aNumFmt
);
1075 SwNumRule
* WW8ListManager::CreateNextRule(bool bSimple
)
1077 // wird erstmal zur Bildung des Style Namens genommen
1078 String
sPrefix(OUString("WW8Num"));
1079 sPrefix
+= OUString::number(nUniqueList
++);
1082 rDoc
.MakeNumRule( rDoc
.GetUniqueNumRuleName(&sPrefix
), 0, false,
1083 SvxNumberFormat::LABEL_ALIGNMENT
);
1084 SwNumRule
* pMyNumRule
= rDoc
.GetNumRuleTbl()[nRul
];
1085 pMyNumRule
->SetAutoRule(false);
1086 pMyNumRule
->SetContinusNum(bSimple
);
1090 SwNumRule
* WW8ListManager::GetNumRule(size_t i
)
1092 if (i
< maLSTInfos
.size())
1093 return maLSTInfos
[i
]->pNumRule
;
1098 // oeffentliche Methoden /////////////////////////////////////////////////////
1100 WW8ListManager::WW8ListManager(SvStream
& rSt_
, SwWW8ImplReader
& rReader_
)
1101 : maSprmParser(rReader_
.GetFib().GetFIBVersion()), rReader(rReader_
),
1102 rDoc(rReader
.GetDoc()), rFib(rReader
.GetFib()), rSt(rSt_
),
1105 // LST und LFO gibts erst ab WW8
1106 if( ( 8 > rFib
.nVersion
)
1107 || ( rFib
.fcPlcfLst
== rFib
.fcPlfLfo
)
1108 || ( rFib
.lcbPlcfLst
< 2 )
1109 || ( rFib
.lcbPlfLfo
< 2) ) return; // offensichtlich keine Listen da
1114 nLastLFOPosition
= USHRT_MAX
;
1115 long nOriginalPos
= rSt
.Tell();
1117 // 1. PLCF LST auslesen und die Listen Vorlagen im Writer anlegen
1119 bool bOk
= checkSeek(rSt
, rFib
.fcPlcfLst
);
1124 sal_uInt32 nRemainingPlcfLst
= rFib
.lcbPlcfLst
;
1126 sal_uInt16
nListCount(0);
1128 nRemainingPlcfLst
-= 2;
1129 bOk
= nListCount
> 0;
1135 // 1.1 alle LST einlesen
1137 for (sal_uInt16 nList
=0; nList
< nListCount
; ++nList
)
1139 if (nRemainingPlcfLst
< cbLSTF
)
1143 memset(&aLST
, 0, sizeof( aLST
));
1146 // 1.1.1 Daten einlesen
1150 for (sal_uInt16 nLevel
= 0; nLevel
< nMaxLevel
; ++nLevel
)
1151 rSt
>> aLST
.aIdSty
[ nLevel
];
1153 sal_uInt8
aBits1(0);
1159 aLST
.bSimpleList
= true;
1161 aLST
.bRestartHdn
= true;
1163 // 1.1.2 new NumRule inserted in Doc and WW8LSTInfo marked
1167 In word 2000 microsoft got rid of creating new "simple lists" with
1168 only 1 level, all new lists are created with 9 levels. To hack it
1169 so that the list types formerly known as simple lists still have
1170 their own tab page to themselves one of the reserved bits is used
1171 to show that a given list is to be in the simple list tabpage.
1172 This has now nothing to do with the actual number of list level a
1173 list has, only how many will be shown in the user interface.
1175 i.e. create a simple list in 2000 and open it in 97 and 97 will
1176 claim (correctly) that it is an outline list. We can set our
1177 continous flag in these lists to store this information.
1179 SwNumRule
* pMyNumRule
= CreateNextRule(
1180 aLST
.bSimpleList
|| (aBits1
& 0x10));
1182 WW8LSTInfo
* pLSTInfo
= new WW8LSTInfo(pMyNumRule
, aLST
);
1183 maLSTInfos
.push_back(pLSTInfo
);
1185 nRemainingPlcfLst
-= cbLSTF
;
1189 // 1.2 alle LVL aller aLST einlesen
1191 sal_uInt16 nLSTInfos
= static_cast< sal_uInt16
>(maLSTInfos
.size());
1192 for (sal_uInt16 nList
= 0; nList
< nLSTInfos
; ++nList
)
1194 WW8LSTInfo
* pListInfo
= maLSTInfos
[nList
];
1195 if( !pListInfo
|| !pListInfo
->pNumRule
) break;
1196 SwNumRule
& rMyNumRule
= *pListInfo
->pNumRule
;
1198 // 1.2.1 betreffende(n) LVL(s) fuer diese aLST einlesen
1200 sal_uInt16 nLvlCount
= static_cast< sal_uInt16
>(pListInfo
->bSimpleList
? nMinLevel
: nMaxLevel
);
1201 std::deque
<bool> aNotReallyThere
;
1202 aNotReallyThere
.resize(nMaxLevel
);
1203 pListInfo
->maParaSprms
.resize(nMaxLevel
);
1204 for (sal_uInt8 nLevel
= 0; nLevel
< nLvlCount
; ++nLevel
)
1206 SwNumFmt
aNumFmt( rMyNumRule
.Get( nLevel
) );
1208 bLVLOk
= ReadLVL( aNumFmt
, pListInfo
->aItemSet
[nLevel
],
1209 pListInfo
->aIdSty
[nLevel
], true, aNotReallyThere
, nLevel
,
1210 pListInfo
->maParaSprms
[nLevel
]);
1213 // und in die rMyNumRule aufnehmen
1214 rMyNumRule
.Set( nLevel
, aNumFmt
);
1219 // 1.2.2 die ItemPools mit den CHPx Einstellungen der verschiedenen
1220 // Level miteinander vergleichen und ggfs. Style(s) erzeugen
1222 for (sal_uInt8 nLevel
= 0; nLevel
< nLvlCount
; ++nLevel
)
1225 AdjustLVL( nLevel
, rMyNumRule
, pListInfo
->aItemSet
,
1226 pListInfo
->aCharFmt
, bDummy
);
1229 // 1.2.3 ItemPools leeren und loeschen
1231 for (sal_uInt8 nLevel
= 0; nLevel
< nLvlCount
; ++nLevel
)
1232 delete pListInfo
->aItemSet
[ nLevel
];
1236 // 2. PLF LFO auslesen und speichern
1238 bOk
= checkSeek(rSt
, rFib
.fcPlfLfo
);
1243 sal_Int32
nLfoCount(0);
1245 bOk
= nLfoCount
> 0;
1251 // 2.1 alle LFO einlesen
1253 for (sal_uInt16 nLfo
= 0; nLfo
< nLfoCount
; ++nLfo
)
1261 memset(&aLFO
, 0, sizeof( aLFO
));
1265 rSt
>> aLFO
.nLfoLvl
;
1267 // soviele Overrides existieren
1268 if ((nMaxLevel
< aLFO
.nLfoLvl
) || rSt
.GetError())
1271 // die Parent NumRule der entsprechenden Liste ermitteln
1272 WW8LSTInfo
* pParentListInfo
= GetLSTByListId(aLFO
.nIdLst
);
1273 if (pParentListInfo
)
1275 // hier, im ersten Schritt, erst mal diese NumRule festhalten
1276 aLFO
.pNumRule
= pParentListInfo
->pNumRule
;
1278 // hat die Liste mehrere Level ?
1279 aLFO
.bSimpleList
= pParentListInfo
->bSimpleList
;
1281 // und rein ins Merk-Array mit dem Teil
1282 WW8LFOInfo
* pLFOInfo
= new WW8LFOInfo(aLFO
);
1283 if (pParentListInfo
)
1285 //Copy the basic paragraph properties for each level from the
1286 //original list into the list format override levels.
1287 int nMaxSize
= pParentListInfo
->maParaSprms
.size();
1288 pLFOInfo
->maParaSprms
.resize(nMaxSize
);
1289 for (int i
= 0; i
< nMaxSize
; ++i
)
1290 pLFOInfo
->maParaSprms
[i
] = pParentListInfo
->maParaSprms
[i
];
1292 pLFOInfos
.push_back(pLFOInfo
);
1299 // 2.2 fuer alle LFO die zugehoerigen LFOLVL einlesen
1301 size_t nLFOInfos
= pLFOInfos
.size();
1302 for (size_t nLfo
= 0; nLfo
< nLFOInfos
; ++nLfo
)
1305 WW8LFOInfo
& rLFOInfo
= pLFOInfos
[nLfo
];
1306 // stehen hierfuer ueberhaupt LFOLVL an ?
1307 if( rLFOInfo
.bOverride
)
1309 WW8LSTInfo
* pParentListInfo
= GetLSTByListId(rLFOInfo
.nIdLst
);
1310 if (!pParentListInfo
)
1313 // 2.2.1 eine neue NumRule fuer diese Liste anlegen
1315 SwNumRule
* pParentNumRule
= rLFOInfo
.pNumRule
;
1316 OSL_ENSURE(pParentNumRule
, "ww: Impossible lists, please report");
1317 if( !pParentNumRule
)
1319 // Nauemsprefix aufbauen: fuer NumRule-Name (eventuell)
1320 // und (falls vorhanden) fuer Style-Name (dann auf jeden Fall)
1321 String
sPrefix(OUString("WW8NumSt"));
1322 sPrefix
+= OUString::number( nLfo
+ 1 );
1323 // jetzt dem pNumRule seinen RICHTIGEN Wert zuweisen !!!
1324 // (bis dahin war hier die Parent NumRule vermerkt )
1326 // Dazu erst mal nachsehen, ob ein Style diesen LFO
1328 if( USHRT_MAX
> rReader
.StyleUsingLFO( nLfo
) )
1330 sal_uInt16 nRul
= rDoc
.MakeNumRule(
1331 rDoc
.GetUniqueNumRuleName( &sPrefix
), pParentNumRule
);
1332 rLFOInfo
.pNumRule
= rDoc
.GetNumRuleTbl()[ nRul
];
1333 rLFOInfo
.pNumRule
->SetAutoRule(false);
1337 sal_uInt16 nRul
= rDoc
.MakeNumRule(
1338 rDoc
.GetUniqueNumRuleName(), pParentNumRule
);
1339 rLFOInfo
.pNumRule
= rDoc
.GetNumRuleTbl()[ nRul
];
1340 rLFOInfo
.pNumRule
->SetAutoRule(true); // = default
1343 // 2.2.2 alle LFOLVL (und ggfs. LVL) fuer die neue NumRule
1346 WW8aISet aItemSet
; // Zeichenattribute aus GrpprlChpx
1347 WW8aCFmt aCharFmt
; // Zeichen Style Pointer
1348 memset(&aItemSet
, 0, sizeof( aItemSet
));
1349 memset(&aCharFmt
, 0, sizeof( aCharFmt
));
1351 //2.2.2.0 skip inter-group of override header ?
1352 //See #i25438# for why I moved this here, compare
1353 //that original bugdoc's binary to what it looks like
1354 //when resaved with word, i.e. there is always a
1355 //4 byte header, there might be more than one if
1356 //that header was 0xFFFFFFFF, e.g. #114412# ?
1364 while (nTest
== 0xFFFFFFFF);
1367 std::deque
<bool> aNotReallyThere(WW8ListManager::nMaxLevel
);
1368 for (sal_uInt8 nLevel
= 0; nLevel
< rLFOInfo
.nLfoLvl
; ++nLevel
)
1374 // 2.2.2.1 den LFOLVL einlesen
1376 rSt
>> aLFOLVL
.nStartAt
;
1377 sal_uInt8
aBits1(0);
1383 // beachte: Die Witzbolde bei MS quetschen die
1384 // Override-Level-Nummer in vier Bits hinein, damit sie
1385 // wieder einen Grund haben, ihr Dateiformat zu aendern,
1386 // falls ihnen einfaellt, dass sie eigentlich doch gerne
1387 // bis zu 16 Listen-Level haetten. Wir tun das *nicht*
1388 // (siehe Kommentar oben bei "struct
1390 aLFOLVL
.nLevel
= aBits1
& 0x0F;
1391 if( (0xFF > aBits1
) &&
1392 (nMaxLevel
> aLFOLVL
.nLevel
) )
1395 aLFOLVL
.bStartAt
= true;
1397 aLFOLVL
.bStartAt
= false;
1399 // 2.2.2.2 eventuell auch den zugehoerigen LVL einlesen
1402 rLFOInfo
.pNumRule
->Get(aLFOLVL
.nLevel
));
1405 aLFOLVL
.bFormat
= true;
1406 // falls bStartup true, hier den Startup-Level
1407 // durch den im LVL vermerkten ersetzen LVLF
1409 bLVLOk
= ReadLVL(aNumFmt
, aItemSet
[nLevel
],
1410 pParentListInfo
->aIdSty
[nLevel
],
1411 aLFOLVL
.bStartAt
, aNotReallyThere
, nLevel
,
1412 rLFOInfo
.maParaSprms
[nLevel
]);
1417 else if (aLFOLVL
.bStartAt
)
1420 writer_cast
<sal_uInt16
>(aLFOLVL
.nStartAt
));
1423 // 2.2.2.3 das NumFmt in die NumRule aufnehmen
1425 rLFOInfo
.pNumRule
->Set(aLFOLVL
.nLevel
, aNumFmt
);
1429 if (nMaxLevel
> aLFOLVL
.nLevel
)
1430 rLFOInfo
.maOverrides
[aLFOLVL
.nLevel
] = aLFOLVL
;
1435 // 2.2.3 die LVL der neuen NumRule anpassen
1437 sal_uInt16 aFlagsNewCharFmt
= 0;
1438 bool bNewCharFmtCreated
= false;
1439 for (sal_uInt8 nLevel
= 0; nLevel
< rLFOInfo
.nLfoLvl
; ++nLevel
)
1441 AdjustLVL( nLevel
, *rLFOInfo
.pNumRule
, aItemSet
, aCharFmt
,
1442 bNewCharFmtCreated
, sPrefix
);
1443 if( bNewCharFmtCreated
)
1444 aFlagsNewCharFmt
+= (1 << nLevel
);
1447 // 2.2.4 ItemPools leeren und loeschen
1449 for (sal_uInt8 nLevel
= 0; nLevel
< rLFOInfo
.nLfoLvl
; ++nLevel
)
1450 delete aItemSet
[ nLevel
];
1455 // und schon sind wir fertig!
1456 rSt
.Seek( nOriginalPos
);
1459 WW8ListManager::~WW8ListManager()
1462 named lists remain in document
1463 unused automatic lists are removed from document (DelNumRule)
1465 for(std::vector
<WW8LSTInfo
*>::iterator aIter
= maLSTInfos
.begin();
1466 aIter
!= maLSTInfos
.end(); ++aIter
)
1468 if ((*aIter
)->pNumRule
&& !(*aIter
)->bUsedInDoc
&&
1469 (*aIter
)->pNumRule
->IsAutoRule())
1471 rDoc
.DelNumRule((*aIter
)->pNumRule
->GetName());
1475 boost::ptr_vector
<WW8LFOInfo
>::reverse_iterator aIter
;
1476 for (aIter
= pLFOInfos
.rbegin() ;
1477 aIter
< pLFOInfos
.rend();
1480 if (aIter
->bOverride
1482 && !aIter
->bUsedInDoc
1483 && aIter
->pNumRule
->IsAutoRule())
1485 rDoc
.DelNumRule( aIter
->pNumRule
->GetName() );
1490 bool IsEqualFormatting(const SwNumRule
&rOne
, const SwNumRule
&rTwo
)
1494 rOne
.GetRuleType() == rTwo
.GetRuleType() &&
1495 rOne
.IsContinusNum() == rTwo
.IsContinusNum() &&
1496 rOne
.IsAbsSpaces() == rTwo
.IsAbsSpaces() &&
1497 rOne
.GetPoolFmtId() == rTwo
.GetPoolFmtId() &&
1498 rOne
.GetPoolHelpId() == rTwo
.GetPoolHelpId() &&
1499 rTwo
.GetPoolHlpFileId() == rTwo
.GetPoolHlpFileId()
1504 for (sal_uInt8 n
= 0; n
< MAXLEVEL
; ++n
)
1506 //The SvxNumberFormat compare, not the SwNumFmt compare
1507 const SvxNumberFormat
&rO
= rOne
.Get(n
);
1508 const SvxNumberFormat
&rT
= rTwo
.Get(n
);
1519 SwNumRule
* WW8ListManager::GetNumRuleForActivation(sal_uInt16 nLFOPosition
,
1520 const sal_uInt8 nLevel
, std::vector
<sal_uInt8
> &rParaSprms
, SwTxtNode
*pNode
)
1522 if (pLFOInfos
.size() <= nLFOPosition
)
1525 WW8LFOInfo
& rLFOInfo
= pLFOInfos
[nLFOPosition
];
1527 bool bFirstUse
= !rLFOInfo
.bUsedInDoc
;
1528 rLFOInfo
.bUsedInDoc
= true;
1530 if( !rLFOInfo
.pNumRule
)
1534 // #i100132# - a number format does not have to exist on given list level
1535 SwNumFmt
pFmt(rLFOInfo
.pNumRule
->Get(nLevel
));
1537 if (rReader
.IsRightToLeft() && nLastLFOPosition
!= nLFOPosition
) {
1538 if ( pFmt
.GetNumAdjust() == SVX_ADJUST_RIGHT
)
1539 pFmt
.SetNumAdjust(SVX_ADJUST_LEFT
);
1540 else if ( pFmt
.GetNumAdjust() == SVX_ADJUST_LEFT
)
1541 pFmt
.SetNumAdjust(SVX_ADJUST_RIGHT
);
1542 rLFOInfo
.pNumRule
->Set(nLevel
, pFmt
);
1544 nLastLFOPosition
= nLFOPosition
;
1547 If this list has had its bits set in word 2000 to pretend that it is a
1548 simple list from the point of view of the user, then it is almost
1549 certainly a simple continous list, and we will try to keep it like that.
1550 Otherwise when we save again it will be shown as the true outline list
1551 that it is, confusing the user that just wanted what they thought was a
1552 simple list. On the otherhand it is possible that some of the other levels
1553 were used by the user, in which case we will not pretend anymore that it
1554 is a simple list. Something that word 2000 does anyway, that 97 didn't, to
1557 if (nLevel
&& rLFOInfo
.pNumRule
->IsContinusNum())
1558 rLFOInfo
.pNumRule
->SetContinusNum(false);
1560 if( (!rLFOInfo
.bOverride
) && (!rLFOInfo
.bLSTbUIDSet
) )
1562 WW8LSTInfo
* pParentListInfo
= GetLSTByListId( rLFOInfo
.nIdLst
);
1563 if( pParentListInfo
)
1564 pParentListInfo
->bUsedInDoc
= true;
1565 rLFOInfo
.bLSTbUIDSet
= true;
1568 if (rLFOInfo
.maParaSprms
.size() > nLevel
)
1569 rParaSprms
= rLFOInfo
.maParaSprms
[nLevel
];
1571 SwNumRule
*pRet
= rLFOInfo
.pNumRule
;
1573 bool bRestart(false);
1574 sal_uInt16
nStart(0);
1575 bool bNewstart(false);
1577 Note: If you fiddle with this then you have to make sure that #i18322#
1578 #i13833#, #i20095# and #112466# continue to work
1580 Check if there were overrides for this level
1582 if (rLFOInfo
.bOverride
&& nLevel
< rLFOInfo
.nLfoLvl
)
1584 WW8LSTInfo
* pParentListInfo
= GetLSTByListId(rLFOInfo
.nIdLst
);
1585 OSL_ENSURE(pParentListInfo
, "ww: Impossible lists, please report");
1586 if (pParentListInfo
&& pParentListInfo
->pNumRule
)
1588 const WW8LFOLVL
&rOverride
= rLFOInfo
.maOverrides
[nLevel
];
1589 bool bNoChangeFromParent
=
1590 IsEqualFormatting(*pRet
, *(pParentListInfo
->pNumRule
));
1592 //If so then I think word still uses the parent (maybe)
1593 if (bNoChangeFromParent
)
1595 pRet
= pParentListInfo
->pNumRule
;
1597 //did it not affect start at value ?
1600 if (rOverride
.bStartAt
)
1602 const SwNumFmt
&rFmt
=
1603 pParentListInfo
->pNumRule
->Get(nLevel
);
1606 rLFOInfo
.maOverrides
[nLevel
].nStartAt
1614 nStart
= writer_cast
<sal_uInt16
>
1615 (rLFOInfo
.maOverrides
[nLevel
].nStartAt
);
1620 pParentListInfo
->bUsedInDoc
= true;
1627 pNode
->SetAttrListLevel(nLevel
);
1629 if (bRestart
|| bNewstart
)
1630 pNode
->SetListRestart(true);
1632 pNode
->SetAttrListRestartValue(nStart
);
1637 //----------------------------------------------------------------------------
1638 // SwWW8ImplReader: anhaengen einer Liste an einen Style oder Absatz
1639 //----------------------------------------------------------------------------
1640 bool SwWW8ImplReader::SetTxtFmtCollAndListLevel(const SwPaM
& rRg
,
1641 SwWW8StyInf
& rStyleInfo
)
1644 if( rStyleInfo
.pFmt
&& rStyleInfo
.bColl
)
1646 bRes
= rDoc
.SetTxtFmtColl(rRg
, (SwTxtFmtColl
*)rStyleInfo
.pFmt
);
1647 SwTxtNode
* pTxtNode
= pPaM
->GetNode()->GetTxtNode();
1648 OSL_ENSURE( pTxtNode
, "No Text-Node at PaM-Position" );
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 // Use outline level set at the style info <rStyleInfo> instead of
1675 // the outline level at the text format, because the WW8 document
1676 // could contain more than one outline numbering rule and the one
1677 // of the text format isn't the one, which a chosen as the Writer
1679 pTxtNode
->SetAttrListLevel( rStyleInfo
.nOutlineLevel
);
1685 void UseListIndent(SwWW8StyInf
&rStyle
, const SwNumFmt
&rFmt
)
1688 if ( rFmt
.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_WIDTH_AND_POSITION
)
1690 const long nAbsLSpace
= rFmt
.GetAbsLSpace();
1691 const long nListFirstLineIndent
= GetListFirstLineIndent(rFmt
);
1692 SvxLRSpaceItem
aLR(ItemGet
<SvxLRSpaceItem
>(*rStyle
.pFmt
, RES_LR_SPACE
));
1693 aLR
.SetTxtLeft(nAbsLSpace
);
1694 aLR
.SetTxtFirstLineOfst(writer_cast
<short>(nListFirstLineIndent
));
1695 rStyle
.pFmt
->SetFmtAttr(aLR
);
1696 rStyle
.bListReleventIndentSet
= true;
1700 void SetStyleIndent(SwWW8StyInf
&rStyle
, const SwNumFmt
&rFmt
)
1702 if ( rFmt
.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_WIDTH_AND_POSITION
) // #i86652#
1704 SvxLRSpaceItem
aLR(ItemGet
<SvxLRSpaceItem
>(*rStyle
.pFmt
, RES_LR_SPACE
));
1705 if (rStyle
.bListReleventIndentSet
)
1708 SyncIndentWithList( aLR
, rFmt
, false, false ); // #i103711#, #i105414#
1713 aLR
.SetTxtFirstLineOfst(0);
1715 rStyle
.pFmt
->SetFmtAttr(aLR
);
1719 void SwWW8ImplReader::SetStylesList(sal_uInt16 nStyle
, sal_uInt16 nActLFO
,
1720 sal_uInt8 nActLevel
)
1722 if (nStyle
>= vColl
.size())
1725 SwWW8StyInf
&rStyleInf
= vColl
[nStyle
];
1726 if (rStyleInf
.bValid
)
1728 OSL_ENSURE(pAktColl
, "Cannot be called outside of style import");
1729 // Phase 1: Nummerierungsattribute beim Einlesen einer StyleDef
1732 // jetzt nur die Parameter vermerken: die tatsaechliche Liste wird
1733 // spaeter drangehaengt, wenn die Listendefinitionen gelesen sind...
1735 (USHRT_MAX
> nActLFO
) &&
1736 (WW8ListManager::nMaxLevel
> nActLevel
)
1739 rStyleInf
.nLFOIndex
= nActLFO
;
1740 rStyleInf
.nListLevel
= nActLevel
;
1741 if (nActLevel
> 0) // it must be an outline list
1742 rStyleInf
.nOutlineLevel
= nActLevel
;
1745 (USHRT_MAX
> nActLFO
) &&
1746 (WW8ListManager::nMaxLevel
> nActLevel
)
1749 std::vector
<sal_uInt8
> aParaSprms
;
1750 SwNumRule
*pNmRule
=
1751 pLstManager
->GetNumRuleForActivation(nActLFO
,
1752 nActLevel
, aParaSprms
);
1754 UseListIndent(rStyleInf
, pNmRule
->Get(nActLevel
));
1761 void SwWW8ImplReader::RegisterNumFmtOnStyle(sal_uInt16 nStyle
)
1764 if (nStyle
>= vColl
.size())
1767 SwWW8StyInf
&rStyleInf
= vColl
[nStyle
];
1768 if (rStyleInf
.bValid
&& rStyleInf
.pFmt
)
1770 //Save old pre-list modified indent, which are the word indent values
1771 rStyleInf
.maWordLR
=
1772 ItemGet
<SvxLRSpaceItem
>(*rStyleInf
.pFmt
, RES_LR_SPACE
);
1774 // Phase 2: aktualisieren der StyleDef nach einlesen aller Listen
1775 SwNumRule
* pNmRule
= 0;
1776 sal_uInt16 nLFO
= rStyleInf
.nLFOIndex
;
1777 sal_uInt8 nLevel
= rStyleInf
.nListLevel
;
1779 (USHRT_MAX
> nLFO
) &&
1780 (WW8ListManager::nMaxLevel
> nLevel
)
1783 std::vector
<sal_uInt8
> aParaSprms
;
1784 pNmRule
= pLstManager
->GetNumRuleForActivation(nLFO
, nLevel
,
1789 if( MAXLEVEL
> rStyleInf
.nOutlineLevel
)
1790 rStyleInf
.pOutlineNumrule
= pNmRule
;
1793 rStyleInf
.pFmt
->SetFmtAttr(
1794 SwNumRuleItem( pNmRule
->GetName() ) );
1795 rStyleInf
.bHasStyNumRule
= true;
1801 SetStyleIndent(rStyleInf
, pNmRule
->Get(nLevel
));
1805 void SwWW8ImplReader::RegisterNumFmtOnTxtNode(sal_uInt16 nActLFO
,
1806 sal_uInt8 nActLevel
, bool bSetAttr
)
1808 // beachte: die Methode haengt die NumRule an den Text Node, falls
1809 // bSetAttr (dann muessen natuerlich vorher die Listen gelesen sein)
1810 // stellt sie NUR den Level ein, im Vertrauen darauf, dass am STYLE eine
1811 // NumRule haengt - dies wird NICHT ueberprueft !!!
1813 if (pLstManager
) // sind die Listendeklarationen gelesen?
1815 SwTxtNode
* pTxtNd
= pPaM
->GetNode()->GetTxtNode();
1816 OSL_ENSURE(pTxtNd
, "No Text-Node at PaM-Position");
1820 std::vector
<sal_uInt8
> aParaSprms
;
1821 const SwNumRule
* pRule
= bSetAttr
?
1822 pLstManager
->GetNumRuleForActivation( nActLFO
, nActLevel
,
1823 aParaSprms
, pTxtNd
) : 0;
1825 if (pRule
|| !bSetAttr
)
1827 //#i24136# old is the same as new, and its the outline numbering,
1828 //then we don't set the numrule again, and we just take the num node
1829 //(the actual outline numbering gets set in SetOutlineNum)
1830 using namespace sw::util
;
1831 bool bUnchangedOutlineNumbering
= false;
1833 If the node is outline numbered, and the new numbering to apply
1834 is the one that was chosen to be the outline numbering then all
1837 // correct condition according to the above given comment.
1838 if ( pTxtNd
->GetNumRule() == rDoc
.GetOutlineNumRule() &&
1839 pRule
== mpChosenOutlineNumRule
)
1841 bUnchangedOutlineNumbering
= true;
1843 if (!bUnchangedOutlineNumbering
)
1845 //If its normal numbering, see if its the same as it already
1846 //was, if its not, and we have been asked to set it, then set
1850 const SwNumRule
*pNormal
= pTxtNd
->GetNumRule();
1851 if (pNormal
!= pRule
)
1854 (SwNumRuleItem(pRule
->GetName()));
1858 pTxtNd
->SetAttrListLevel(nActLevel
);
1860 // <IsCounted()> state of text node has to be adjusted accordingly.
1861 if ( /*nActLevel >= 0 &&*/ nActLevel
< MAXLEVEL
)
1863 pTxtNd
->SetCountedInList( true );
1867 // Direct application of the list level formatting no longer
1868 // needed for list levels of mode LABEL_ALIGNMENT
1869 bool bApplyListLevelIndentDirectlyAtPara( true );
1870 if ( pTxtNd
->GetNumRule() && nActLevel
< MAXLEVEL
)
1872 const SwNumFmt
& rFmt
= pTxtNd
->GetNumRule()->Get( nActLevel
);
1873 if ( rFmt
.GetPositionAndSpaceMode() ==
1874 SvxNumberFormat::LABEL_ALIGNMENT
)
1876 bApplyListLevelIndentDirectlyAtPara
= false;
1880 if ( bApplyListLevelIndentDirectlyAtPara
)
1882 SfxItemSet
aListIndent(rDoc
.GetAttrPool(), RES_LR_SPACE
,
1884 const SvxLRSpaceItem
*pItem
= (const SvxLRSpaceItem
*)(
1885 GetFmtAttr(RES_LR_SPACE
));
1886 OSL_ENSURE(pItem
, "impossible");
1888 aListIndent
.Put(*pItem
);
1891 Take the original paragraph sprms attached to this list level
1892 formatting and apply them to the paragraph. I'm convinced that
1893 this is exactly what word does.
1895 if (short nLen
= static_cast< short >(aParaSprms
.size()))
1897 SfxItemSet
* pOldAktItemSet
= pAktItemSet
;
1898 SetAktItemSet(&aListIndent
);
1900 sal_uInt8
* pSprms1
= &aParaSprms
[0];
1903 sal_uInt16 nL1
= ImportSprm(pSprms1
);
1908 SetAktItemSet(pOldAktItemSet
);
1911 const SvxLRSpaceItem
*pLR
=
1912 HasItem
<SvxLRSpaceItem
>(aListIndent
, RES_LR_SPACE
);
1913 OSL_ENSURE(pLR
, "Impossible");
1916 pCtrlStck
->NewAttr(*pPaM
->GetPoint(), *pLR
);
1917 pCtrlStck
->SetAttr(*pPaM
->GetPoint(), RES_LR_SPACE
);
1924 void SwWW8ImplReader::RegisterNumFmt(sal_uInt16 nActLFO
, sal_uInt8 nActLevel
)
1926 // sind wir erst beim Einlesen der StyleDef ?
1928 SetStylesList( nAktColl
, nActLFO
, nActLevel
);
1930 RegisterNumFmtOnTxtNode(nActLFO
, nActLevel
);
1933 void SwWW8ImplReader::Read_ListLevel(sal_uInt16
, const sal_uInt8
* pData
,
1936 if (pPlcxMan
&& pPlcxMan
->GetDoingDrawTextBox())
1941 // the actual level is finished, what should we do ?
1942 nListLevel
= WW8ListManager::nMaxLevel
;
1943 if (pStyles
&& !bVer67
)
1944 pStyles
->nWwNumLevel
= 0;
1952 // die Streamdaten sind hier Null basiert, so wie wir es brauchen
1953 nListLevel
= *pData
;
1955 if (pStyles
&& !bVer67
)
1958 if this is the case, then if the numbering is actually stored in
1959 winword 6 format, and its likely that sprmPIlvl has been abused
1960 to set the ww6 list level information which we will need when we
1961 reach the true ww6 list def. So set it now
1963 pStyles
->nWwNumLevel
= nListLevel
;
1966 if (WW8ListManager::nMaxLevel
<= nListLevel
)
1967 nListLevel
= WW8ListManager::nMaxLevel
;
1970 (USHRT_MAX
> nLFOPosition
) &&
1971 (WW8ListManager::nMaxLevel
> nListLevel
)
1974 RegisterNumFmt(nLFOPosition
, nListLevel
);
1975 nLFOPosition
= USHRT_MAX
;
1976 nListLevel
= WW8ListManager::nMaxLevel
;
1981 void SwWW8ImplReader::Read_LFOPosition(sal_uInt16
, const sal_uInt8
* pData
,
1984 if (pPlcxMan
&& pPlcxMan
->GetDoingDrawTextBox())
1989 // the actual level is finished, what should we do ?
1990 nLFOPosition
= USHRT_MAX
;
1991 nListLevel
= WW8ListManager::nMaxLevel
;
1999 short nData
= SVBT16ToShort( pData
);
2002 // disable the numbering/list style apply to the paragraph or the style
2005 If you have a paragraph in word with left and/or hanging indent
2006 and remove its numbering, then the indentation appears to get
2007 reset, but not back to the base style, instead its goes to a blank
2009 Unless its a broken ww6 list in 97 in which case more hackery is
2010 required, some more details about broken ww6 list in
2011 ww8par6.cxx#SwWW8ImplReader::Read_LR
2016 // here a "named" style is beeing configured
2018 // disable the numbering/list in the style currently configured
2019 pAktColl
->SetFmtAttr(*GetDfltAttr(RES_PARATR_NUMRULE
));
2021 // reset/blank the indent
2022 pAktColl
->SetFmtAttr(SvxLRSpaceItem(RES_LR_SPACE
));
2024 else if (SwTxtNode
* pTxtNode
= pPaM
->GetNode()->GetTxtNode())
2026 // here a paragraph is being directly formated
2028 // empty the numbering/list style applied to the current paragraph
2029 SwNumRuleItem
aEmptyRule( aEmptyStr
);
2030 pTxtNode
->SetAttr( aEmptyRule
);
2032 // create an empty SvxLRSpaceItem
2033 SvxLRSpaceItem
aLR( RES_LR_SPACE
);
2035 // replace it with the one of the current node if it exist
2036 const SfxPoolItem
* pLR
= GetFmtAttr(RES_LR_SPACE
);
2038 aLR
= *static_cast<const SvxLRSpaceItem
*>(pLR
);
2040 // reset/blank the left indent (and only the left)
2042 aLR
.SetTxtFirstLineOfst(0);
2044 // apply the modified SvxLRSpaceItem to the current paragraph
2045 pTxtNode
->SetAttr( aLR
);
2048 nLFOPosition
= USHRT_MAX
;
2052 nLFOPosition
= (sal_uInt16
)nData
-1;
2054 If we are a ww8+ style with ww7- style lists then there is a
2055 bizarre broken word bug where when the list is removed from a para
2056 the ww6 list first line indent still affects the first line
2057 indentation. Setting this flag will allow us to recover from this
2060 if (pAktColl
&& (nLFOPosition
== 2047-1) && nAktColl
< vColl
.size())
2061 vColl
[nAktColl
].bHasBrokenWW6List
= true;
2063 // die Streamdaten sind hier 1 basiert, wir ziehen EINS ab
2064 if (USHRT_MAX
> nLFOPosition
)
2066 if (nLFOPosition
!= 2047-1) //Normal ww8+ list behaviour
2068 if (WW8ListManager::nMaxLevel
== nListLevel
)
2070 else if (WW8ListManager::nMaxLevel
> nListLevel
)
2072 RegisterNumFmt(nLFOPosition
, nListLevel
);
2073 nLFOPosition
= USHRT_MAX
;
2074 nListLevel
= WW8ListManager::nMaxLevel
;
2077 else if (pPlcxMan
&& pPlcxMan
->HasParaSprm(0xC63E))
2080 #i8114# Horrific backwards compatible ww7- lists in ww8+
2083 Read_ANLevelNo(13 /*equiv ww7- sprm no*/, &nListLevel
, 1);
2090 // -------------------------------------------------------------------
2091 // ------------------------- Reading Controls ------------------------
2092 // -------------------------------------------------------------------
2094 bool SwWW8ImplReader::ImportFormulaControl(WW8FormulaControl
&aFormula
,
2095 WW8_CP nStart
, SwWw8ControlType nWhich
)
2099 * Save the reader state and process the sprms for this anchor cp.
2100 * Doing so will set the nPicLocFc to the offset to find the hypertext
2101 * data in the data stream.
2103 WW8_CP nEndCp
= nStart
+1; //Only interested in the single 0x01 character
2105 WW8ReaderSave
aSave(this,nStart
);
2107 WW8PLCFManResult aRes
;
2108 nStart
= pPlcxMan
->Where();
2109 while(nStart
<= nEndCp
)
2111 if ( pPlcxMan
->Get(&aRes
)
2112 && aRes
.pMemPos
&& aRes
.nSprmId
)
2114 //only interested in sprms which would set nPicLocFc
2115 if ( (68 == aRes
.nSprmId
) || (0x6A03 == aRes
.nSprmId
) )
2117 Read_PicLoc( aRes
.nSprmId
, aRes
.pMemPos
+
2118 mpSprmParser
->DistanceToData(aRes
.nSprmId
), 4);
2122 pPlcxMan
->advance();
2123 nStart
= pPlcxMan
->Where();
2125 sal_uLong nOffset
= nPicLocFc
;
2126 aSave
.Restore(this);
2128 sal_uLong nOldPos
= pDataStream
->Tell();
2130 pDataStream
->Seek( nOffset
);
2131 PicRead( pDataStream
, &aPic
, bVer67
);
2133 if((aPic
.lcb
> 0x3A) && !pDataStream
->GetError() )
2135 aFormula
.FormulaRead(nWhich
,pDataStream
);
2140 There is a problem with aPic, the WW8_PIC is always used even though it
2141 is too big for the WW95 files, it needs to be modified to check the
2144 pDataStream
->Seek( nOldPos
);
2148 sal_Bool
SwMSConvertControls::InsertFormula(WW8FormulaControl
&rFormula
)
2150 sal_Bool bRet
= sal_False
;
2152 const uno::Reference
< lang::XMultiServiceFactory
> & rServiceFactory
=
2153 GetServiceFactory();
2155 if(!rServiceFactory
.is())
2159 uno::Reference
< form::XFormComponent
> xFComp
;
2161 if (sal_True
== (bRet
= rFormula
.Import(rServiceFactory
, xFComp
, aSz
)))
2163 uno::Reference
<drawing::XShape
> xShapeRef
;
2164 if (sal_True
== (bRet
= InsertControl(xFComp
, aSz
, &xShapeRef
, false)))
2165 GetShapes()->add(xShapeRef
);
2170 void WW8FormulaControl::FormulaRead(SwWw8ControlType nWhich
,
2171 SvStream
*pDataStream
)
2174 // nHeaderBype == version
2175 sal_uInt32 nHeaderByte
;
2177 // The following is a FFData structure as described in
2178 // Microsoft's DOC specification (chapter 2.9.78)
2180 *pDataStream
>> nHeaderByte
;
2182 // might be better to read the bits as a 16 bit word
2183 // ( like it is in the spec. )
2185 *pDataStream
>> bits1
;
2187 *pDataStream
>> bits2
;
2189 sal_uInt8 iType
= ( bits1
& 0x3 );
2191 // we should verify that bits.iType & nWhich concur
2192 OSL_ENSURE( iType
== nWhich
, "something wrong, expect control type read from stream doesn't match nWhich passed in");
2193 if ( !( iType
== nWhich
) )
2196 sal_uInt8 iRes
= (bits1
& 0x7C) >> 2;
2199 *pDataStream
>> cch
;
2202 *pDataStream
>> hps
;
2205 sTitle
= read_uInt16_BeltAndBracesString(*pDataStream
);
2207 if (nWhich
== WW8_CT_EDIT
)
2208 { // Field is a textbox
2211 sDefault
= read_uInt16_BeltAndBracesString(*pDataStream
);
2215 // CheckBox or ComboBox
2216 sal_uInt16 wDef
= 0;
2217 *pDataStream
>> wDef
;
2218 nChecked
= wDef
; // default
2219 if (nWhich
== WW8_CT_CHECKBOX
)
2223 sDefault
= ( wDef
== 0 ) ? OUString( "0" ) : OUString( "1" );
2227 sFormatting
= read_uInt16_BeltAndBracesString(*pDataStream
);
2229 sHelp
= read_uInt16_BeltAndBracesString(*pDataStream
);
2231 sToolTip
= read_uInt16_BeltAndBracesString(*pDataStream
);
2233 /*String sEntryMacro =*/ read_uInt16_BeltAndBracesString(*pDataStream
);
2234 /*String sExitMcr =*/ read_uInt16_BeltAndBracesString(*pDataStream
);
2236 if (nWhich
== WW8_CT_DROPDOWN
)
2239 // SSTB (see Spec. 2.2.4)
2241 *pDataStream
>> fExtend
;
2242 sal_uInt16 nNoStrings
;
2244 // Isn't it that if fExtend isn't 0xFFFF then fExtend actually
2245 // doesn't exist and we really have just read nNoStrings ( or cData )?
2246 if (fExtend
!= 0xFFFF)
2248 *pDataStream
>> nNoStrings
;
2250 // I guess this should be zero ( and we should ensure that )
2252 *pDataStream
>> cbExtra
;
2255 "Unknown formfield dropdown list structure. Report to cmc");
2256 if (!bAllOk
) //Not as expected, don't risk it at all.
2258 maListEntries
.reserve(nNoStrings
);
2259 for (sal_uInt32 nI
= 0; nI
< nNoStrings
; ++nI
)
2261 String sEntry
= read_uInt16_PascalString(*pDataStream
);
2262 maListEntries
.push_back(sEntry
);
2265 fDropdownIndex
= iRes
;
2268 fToolTip
= nField
& 0x01;
2269 fNoMark
= (nField
& 0x02)>>1;
2270 fUseSize
= (nField
& 0x04)>>2;
2271 fNumbersOnly
= (nField
& 0x08)>>3;
2272 fDateOnly
= (nField
& 0x10)>>4;
2273 fUnused
= (nField
& 0xE0)>>5;
2276 WW8FormulaListBox::WW8FormulaListBox(SwWW8ImplReader
&rR
)
2277 : WW8FormulaControl(OUString(SL::aListBox
), rR
)
2281 //Miserable hack to get a hardcoded guesstimate of the size of a list dropdown
2282 //box's first entry to set as the lists default size
2283 awt::Size
SwWW8ImplReader::MiserableDropDownFormHack(const String
&rString
,
2284 uno::Reference
<beans::XPropertySet
>& rPropSet
)
2287 struct CtrlFontMapEntry
2289 sal_uInt16 nWhichId
;
2290 const sal_Char
* pPropNm
;
2292 const CtrlFontMapEntry aMapTable
[] =
2294 { RES_CHRATR_COLOR
, "TextColor" },
2295 { RES_CHRATR_FONT
, "FontName" },
2296 { RES_CHRATR_FONTSIZE
, "FontHeight" },
2297 { RES_CHRATR_WEIGHT
, "FontWeight" },
2298 { RES_CHRATR_UNDERLINE
, "FontUnderline" },
2299 { RES_CHRATR_CROSSEDOUT
, "FontStrikeout" },
2300 { RES_CHRATR_POSTURE
, "FontSlant" },
2305 uno::Reference
< beans::XPropertySetInfo
> xPropSetInfo
=
2306 rPropSet
->getPropertySetInfo();
2309 for (const CtrlFontMapEntry
* pMap
= aMapTable
; pMap
->nWhichId
; ++pMap
)
2312 const SfxPoolItem
* pItem
= GetFmtAttr( pMap
->nWhichId
);
2313 OSL_ENSURE(pItem
, "Impossible");
2317 switch ( pMap
->nWhichId
)
2319 case RES_CHRATR_COLOR
:
2322 if (xPropSetInfo
->hasPropertyByName(pNm
= "TextColor"))
2324 aTmp
<<= (sal_Int32
)((SvxColorItem
*)pItem
)->GetValue().GetColor();
2325 rPropSet
->setPropertyValue(pNm
, aTmp
);
2328 aFont
.SetColor(((SvxColorItem
*)pItem
)->GetValue());
2330 case RES_CHRATR_FONT
:
2332 const SvxFontItem
*pFontItem
= (SvxFontItem
*)pItem
;
2334 if (xPropSetInfo
->hasPropertyByName(pNm
= "FontStyleName"))
2336 aTmp
<<= OUString( pFontItem
->GetStyleName());
2337 rPropSet
->setPropertyValue( pNm
, aTmp
);
2339 if (xPropSetInfo
->hasPropertyByName(pNm
= "FontFamily"))
2341 aTmp
<<= (sal_Int16
)pFontItem
->GetFamily();
2342 rPropSet
->setPropertyValue( pNm
, aTmp
);
2344 if (xPropSetInfo
->hasPropertyByName(pNm
= "FontCharset"))
2346 aTmp
<<= (sal_Int16
)pFontItem
->GetCharSet();
2347 rPropSet
->setPropertyValue( pNm
, aTmp
);
2349 if (xPropSetInfo
->hasPropertyByName(pNm
= "FontPitch"))
2351 aTmp
<<= (sal_Int16
)pFontItem
->GetPitch();
2352 rPropSet
->setPropertyValue( pNm
, aTmp
);
2355 aTmp
<<= OUString( pFontItem
->GetFamilyName());
2356 aFont
.SetName( pFontItem
->GetFamilyName() );
2357 aFont
.SetStyleName( pFontItem
->GetStyleName() );
2358 aFont
.SetFamily( pFontItem
->GetFamily() );
2359 aFont
.SetCharSet( pFontItem
->GetCharSet() );
2360 aFont
.SetPitch( pFontItem
->GetPitch() );
2364 case RES_CHRATR_FONTSIZE
:
2366 Size
aSize( aFont
.GetSize().Width(),
2367 ((SvxFontHeightItem
*)pItem
)->GetHeight() );
2368 aTmp
<<= ((float)aSize
.Height()) / 20.0;
2370 aFont
.SetSize(OutputDevice::LogicToLogic(aSize
, MAP_TWIP
,
2375 case RES_CHRATR_WEIGHT
:
2376 aTmp
<<= (float)VCLUnoHelper::ConvertFontWeight(
2377 ((SvxWeightItem
*)pItem
)->GetWeight() );
2378 aFont
.SetWeight( ((SvxWeightItem
*)pItem
)->GetWeight() );
2381 case RES_CHRATR_UNDERLINE
:
2382 aTmp
<<= (sal_Int16
)(((SvxUnderlineItem
*)pItem
)->GetLineStyle());
2383 aFont
.SetUnderline(((SvxUnderlineItem
*)pItem
)->GetLineStyle());
2386 case RES_CHRATR_CROSSEDOUT
:
2387 aTmp
<<= (sal_Int16
)( ((SvxCrossedOutItem
*)pItem
)->GetStrikeout() );
2388 aFont
.SetStrikeout( ((SvxCrossedOutItem
*)pItem
)->GetStrikeout() );
2391 case RES_CHRATR_POSTURE
:
2392 aTmp
<<= (sal_Int16
)( ((SvxPostureItem
*)pItem
)->GetPosture() );
2393 aFont
.SetItalic( ((SvxPostureItem
*)pItem
)->GetPosture() );
2401 if (bSet
&& xPropSetInfo
->hasPropertyByName(OUString::createFromAscii(pMap
->pPropNm
)))
2402 rPropSet
->setPropertyValue(OUString::createFromAscii(pMap
->pPropNm
), aTmp
);
2404 // now calculate the size of the control
2405 OutputDevice
* pOut
= Application::GetDefaultDevice();
2406 OSL_ENSURE(pOut
, "Impossible");
2409 pOut
->Push( PUSH_FONT
| PUSH_MAPMODE
);
2410 pOut
->SetMapMode( MapMode( MAP_100TH_MM
));
2411 pOut
->SetFont( aFont
);
2412 aRet
.Width
= pOut
->GetTextWidth(rString
);
2413 aRet
.Width
+= 500; //plus size of button, total hack territory
2414 aRet
.Height
= pOut
->GetTextHeight();
2420 sal_Bool
WW8FormulaListBox::Import(const uno::Reference
<
2421 lang::XMultiServiceFactory
> &rServiceFactory
,
2422 uno::Reference
<form::XFormComponent
> &rFComp
,awt::Size
&rSz
)
2424 uno::Reference
<uno::XInterface
> xCreate
= rServiceFactory
->createInstance("com.sun.star.form.component.ComboBox");
2428 rFComp
= uno::Reference
<form::XFormComponent
>(xCreate
, uno::UNO_QUERY
);
2432 uno::Reference
<beans::XPropertySet
> xPropSet(xCreate
, uno::UNO_QUERY
);
2435 if (!sTitle
.isEmpty())
2439 xPropSet
->setPropertyValue("Name", aTmp
);
2441 if (!sToolTip
.isEmpty())
2444 xPropSet
->setPropertyValue("HelpText", aTmp
);
2447 sal_Bool
bDropDown(sal_True
);
2448 xPropSet
->setPropertyValue("Dropdown", cppu::bool2any(bDropDown
));
2450 if (!maListEntries
.empty())
2452 sal_uInt32 nLen
= maListEntries
.size();
2453 uno::Sequence
< OUString
> aListSource(nLen
);
2454 for (sal_uInt32 nI
= 0; nI
< nLen
; ++nI
)
2455 aListSource
[nI
] = OUString(maListEntries
[nI
]);
2456 aTmp
<<= aListSource
;
2457 xPropSet
->setPropertyValue("StringItemList", aTmp
);
2459 if (fDropdownIndex
< nLen
)
2461 aTmp
<<= aListSource
[fDropdownIndex
];
2465 aTmp
<<= aListSource
[0];
2468 xPropSet
->setPropertyValue("DefaultText", aTmp
);
2470 rSz
= rRdr
.MiserableDropDownFormHack(maListEntries
[0], xPropSet
);
2474 static const sal_Unicode aBlank
[] =
2476 0x2002,0x2002,0x2002,0x2002,0x2002
2478 rSz
= rRdr
.MiserableDropDownFormHack(OUString(aBlank
, SAL_N_ELEMENTS(aBlank
)), xPropSet
);
2484 WW8FormulaCheckBox::WW8FormulaCheckBox(SwWW8ImplReader
&rR
)
2485 : WW8FormulaControl(OUString(SL::aCheckBox
), rR
)
2489 static void lcl_AddToPropertyContainer
2490 (uno::Reference
<beans::XPropertySet
> xPropSet
,
2491 const OUString
& rPropertyName
, const OUString
& rValue
)
2493 uno::Reference
<beans::XPropertySetInfo
> xPropSetInfo
=
2494 xPropSet
->getPropertySetInfo();
2495 if (xPropSetInfo
.is() &&
2496 ! xPropSetInfo
->hasPropertyByName(rPropertyName
))
2498 uno::Reference
<beans::XPropertyContainer
>
2499 xPropContainer(xPropSet
, uno::UNO_QUERY
);
2500 uno::Any
aAny(OUString(""));
2501 xPropContainer
->addProperty
2503 static_cast<sal_Int16
>(beans::PropertyAttribute::BOUND
|
2504 beans::PropertyAttribute::REMOVABLE
),
2508 uno::Any
aAnyValue(rValue
);
2509 xPropSet
->setPropertyValue(rPropertyName
, aAnyValue
);
2512 sal_Bool
WW8FormulaCheckBox::Import(const uno::Reference
<
2513 lang::XMultiServiceFactory
> &rServiceFactory
,
2514 uno::Reference
<form::XFormComponent
> &rFComp
,awt::Size
&rSz
)
2516 uno::Reference
< uno::XInterface
> xCreate
= rServiceFactory
->createInstance("com.sun.star.form.component.CheckBox");
2520 rFComp
= uno::Reference
< form::XFormComponent
>( xCreate
, uno::UNO_QUERY
);
2524 uno::Reference
< beans::XPropertySet
> xPropSet( xCreate
, uno::UNO_QUERY
);
2526 rSz
.Width
= 16 * hpsCheckBox
;
2527 rSz
.Height
= 16 * hpsCheckBox
;
2530 if (!sTitle
.isEmpty())
2534 xPropSet
->setPropertyValue("Name", aTmp
);
2536 aTmp
<<= (sal_Int16
)nChecked
;
2537 xPropSet
->setPropertyValue("DefaultState", aTmp
);
2539 if (!sToolTip
.isEmpty())
2540 lcl_AddToPropertyContainer(xPropSet
, "HelpText", sToolTip
);
2542 if (!sHelp
.isEmpty())
2543 lcl_AddToPropertyContainer(xPropSet
, "HelpF1Text", sHelp
);
2549 WW8FormulaEditBox::WW8FormulaEditBox(SwWW8ImplReader
&rR
)
2550 : WW8FormulaControl(OUString(SL::aTextField
) ,rR
)
2554 sal_Bool
SwMSConvertControls::InsertControl(
2555 const uno::Reference
< form::XFormComponent
> & rFComp
,
2556 const awt::Size
& rSize
, uno::Reference
< drawing::XShape
> *pShape
,
2557 sal_Bool bFloatingCtrl
)
2559 const uno::Reference
< container::XIndexContainer
> &rComps
= GetFormComps();
2560 uno::Any
aTmp( &rFComp
, ::getCppuType((const uno::Reference
<
2561 form::XFormComponent
>*)0) );
2562 rComps
->insertByIndex( rComps
->getCount(), aTmp
);
2564 const uno::Reference
< lang::XMultiServiceFactory
> &rServiceFactory
=
2565 GetServiceFactory();
2566 if( !rServiceFactory
.is() )
2569 uno::Reference
< uno::XInterface
> xCreate
= rServiceFactory
->createInstance(
2570 "com.sun.star.drawing.ControlShape");
2574 uno::Reference
< drawing::XShape
> xShape
=
2575 uno::Reference
< drawing::XShape
>(xCreate
, uno::UNO_QUERY
);
2577 OSL_ENSURE(xShape
.is(), "XShape nicht erhalten");
2578 xShape
->setSize(rSize
);
2580 uno::Reference
< beans::XPropertySet
> xShapePropSet(
2581 xCreate
, uno::UNO_QUERY
);
2583 //I lay a small bet that this will change to
2584 //sal_Int16 nTemp=TextContentAnchorType::AS_CHARACTER;
2587 nTemp
= text::TextContentAnchorType_AT_PARAGRAPH
;
2589 nTemp
= text::TextContentAnchorType_AS_CHARACTER
;
2592 xShapePropSet
->setPropertyValue("AnchorType", aTmp
);
2594 nTemp
= text::VertOrientation::TOP
;
2596 xShapePropSet
->setPropertyValue("VertOrient", aTmp
);
2598 uno::Reference
< text::XText
> xDummyTxtRef
;
2599 uno::Reference
< text::XTextRange
> xTxtRg
=
2600 new SwXTextRange( *pPaM
, xDummyTxtRef
);
2602 aTmp
.setValue(&xTxtRg
,::getCppuType((
2603 uno::Reference
< text::XTextRange
>*)0));
2604 xShapePropSet
->setPropertyValue("TextRange", aTmp
);
2606 // Das Control-Model am Control-Shape setzen
2607 uno::Reference
< drawing::XControlShape
> xControlShape( xShape
,
2609 uno::Reference
< awt::XControlModel
> xControlModel( rFComp
,
2611 xControlShape
->setControl( xControlModel
);
2619 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */