bump product version to 4.1.6.2
[LibreOffice.git] / sw / source / filter / ww8 / ww8par3.cxx
blob13d0646386f333e85f0b53a8805b4cff65e83d66
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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>
53 #include <algorithm>
54 #include <functional>
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>
65 #include <doc.hxx>
66 #include <docary.hxx>
67 #include <docsh.hxx>
68 #include <numrule.hxx>
69 #include <paratr.hxx>
70 #include <charatr.hxx>
71 #include <charfmt.hxx>
72 #include <ndtxt.hxx>
73 #include <expfld.hxx>
74 #include <fmtfld.hxx>
75 #include <flddropdown.hxx>
76 #include "writerhelper.hxx"
77 #include "writerwordglue.hxx"
78 #include "ww8par.hxx"
79 #include "ww8par2.hxx" // wg. Listen-Attributen in Styles
81 #include <IMark.hxx>
82 #include <unotools/fltrcfg.hxx>
83 #include <xmloff/odffields.hxx>
85 #include <stdio.h>
87 using namespace com::sun::star;
88 using namespace sw::util;
89 using namespace sw::types;
90 using namespace sw::mark;
92 //-----------------------------------------
93 // UNO-Controls
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;
101 bEmbeddObj = true;
102 return FLD_TEXT;
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
121 text.
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);
136 return FLD_OK;
137 } else {
138 WW8PLCFx_Book* pB = pPlcxMan->GetBook();
139 String aBookmarkName;
140 if (pB!=NULL) {
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));
166 return FLD_TEXT;
170 eF_ResT SwWW8ImplReader::Read_F_FormCheckBox( WW8FieldDesc* pF, String& rStr )
172 WW8FormulaCheckBox aFormula(*this);
174 if (!pFormImpl)
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);
184 return FLD_OK;
185 } else {
186 String aBookmarkName;
187 WW8PLCFx_Book* pB = pPlcxMan->GetBook();
188 if (pB!=NULL) {
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));
219 if(pCheckboxFm)
220 pCheckboxFm->SetChecked(aFormula.nChecked);
221 // set field data here...
224 return FLD_OK;
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();
238 if (!bUseEnhFields)
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);
254 return FLD_OK;
256 else
258 // TODO: review me
259 String aBookmarkName;
260 WW8PLCFx_Book* pB = pPlcxMan->GetBook();
261 if (pB!=NULL)
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...
297 return FLD_OK;
301 eF_ResT SwWW8ImplReader::Read_F_HTMLControl(WW8FieldDesc*, String&)
303 if( bObj && nPicLocFc )
304 nObjLocFc = nPicLocFc;
305 bEmbeddObj = true;
306 return FLD_TEXT;
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
347 bool bSimpleList;
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)
375 struct WW8LFOLVL
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
386 WW8LFOLVL() :
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,
458 sal_uInt8 nLen)
460 return maSprmParser.findSprmData(nId, &rSprms, nLen);
463 class ListWithId : public std::unary_function<const WW8LSTInfo *, bool>
465 private:
466 sal_uInt32 mnIdLst;
467 public:
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())
479 return 0;
480 return *aResult;
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)
487 nLen = rSrc.Len();
488 for (xub_StrLen nI = nStart; nI < nLen; ++nI)
490 sal_Unicode nChar = rSrc.GetChar(nI);
491 if (nChar > WW8ListManager::nMaxLevel)
492 rDest.Append(nChar);
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)
501 sal_uInt8 aBits1(0);
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);
509 String sPrefix;
510 String sPostfix;
511 WW8LVL aLVL;
513 // 1. LVLF einlesen
515 memset(&aLVL, 0, sizeof( aLVL ));
516 rSt >> aLVL.nStartAt;
517 rSt >> aLVL.nNFC;
518 rSt >> aBits1;
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;
524 bool bLVLOkB = true;
525 sal_uInt8 nLevelB = 0;
526 for(nLevelB = 0; nLevelB < nMaxLevel; ++nLevelB)
528 rSt >> aLVL.aOfsNumsXCH[ nLevelB ];
529 if( 0 != rSt.GetError() )
531 bLVLOkB = false;
532 break;
536 if( !bLVLOkB )
537 return false;
539 sal_uInt8 ixchFollow(0);
540 rSt >> ixchFollow;
541 rSt >> aLVL.nV6DxaSpace;
542 rSt >> aLVL.nV6Indent;
543 rSt >> aLVL.nLenGrpprlChpx;
544 rSt >> aLVL.nLenGrpprlPapx;
545 rSt.SeekRel( 2 );
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))
556 return false;
557 // "sprmPDxaLeft" pap.dxaLeft;dxa;word;
558 sal_uInt8* pSprm;
559 if (
560 (0 != (pSprm = GrpprlHasSprm(0x840F,aGrpprlPapx[0],aLVL.nLenGrpprlPapx))) ||
561 (0 != (pSprm = GrpprlHasSprm(0x845E,aGrpprlPapx[0],aLVL.nLenGrpprlPapx)))
564 sal_uInt8 *pBegin = pSprm-2;
565 for(int i=0;i<4;++i)
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;
573 if (
574 (0 != (pSprm = GrpprlHasSprm(0x8411,aGrpprlPapx[0],aLVL.nLenGrpprlPapx)) ) ||
575 (0 != (pSprm = GrpprlHasSprm(0x8460,aGrpprlPapx[0],aLVL.nLenGrpprlPapx)) )
578 sal_uInt8 *pBegin = pSprm-2;
579 for(int i=0;i<4;++i)
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)) )
587 bool bDone = false;
588 if (*(pSprm-1) == 5)
590 if (*pSprm++ == 0) //nDel
592 if (*pSprm++ == 1) //nIns
594 nTabPos = SVBT16ToShort(pSprm);
595 pSprm+=2;
596 if (*pSprm == 6) //type
598 bDone = true;
603 OSL_ENSURE(bDone, "tab setting in numbering is "
604 "of unexpected configuration");
605 (void)bDone;
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
613 // most of the time.
614 if ( nTabPos != 0 )
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 )
623 bDoAdjust = true;
626 else
628 if ( aLVL.nDxaLeft < nTabPos && nTabPos < nDesired )
630 bDoAdjust = true;
634 if (bDoAdjust)
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))
656 return false;
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);
661 if (pSprmWhichPis)
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)
680 nNewColl = 0;
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,
691 maSprmParser);
692 while (const sal_uInt8* pSprm = aSprmIter.GetSprms())
694 rReader.ImportSprm(pSprm);
695 aSprmIter.advance();
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;
715 switch( aLVL.nNFC )
717 case 0:
718 eType = SVX_NUM_ARABIC;
719 break;
720 case 1:
721 eType = SVX_NUM_ROMAN_UPPER;
722 break;
723 case 2:
724 eType = SVX_NUM_ROMAN_LOWER;
725 break;
726 case 3:
727 eType = SVX_NUM_CHARS_UPPER_LETTER_N;
728 break;
729 case 4:
730 eType = SVX_NUM_CHARS_LOWER_LETTER_N;
731 break;
732 case 5:
733 // eigentlich: ORDINAL
734 eType = SVX_NUM_ARABIC;
735 break;
736 case 23:
737 case 25:
738 eType = SVX_NUM_CHAR_SPECIAL;
739 //For i120928,type info
740 if (bIsPicBullet)
742 eType = SVX_NUM_BITMAP;
745 break;
746 case 255:
747 eType = SVX_NUM_NUMBER_NONE;
748 break;
749 default:
750 // take default
751 eType = SVX_NUM_ARABIC;
752 break;
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()>
784 if ( aIter != aEnd )
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.
790 ++aIter;
791 while (aIter != aEnd)
793 (*aIter) = 0;
794 ++aIter;
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
808 if (!nUpperLevel)
809 nUpperLevel = nMaxLevel;
811 if (SVX_NUM_CHAR_SPECIAL == eType)
813 cBullet = sNumString.Len() ? sNumString.GetChar(0) : 0x2190;
815 if (!cBullet) // unsave control code?
816 cBullet = 0x2190;
818 else if (SVX_NUM_BITMAP == eType) //For i120928,position index info of graphic
820 cGrfBulletCP = nWitchPicIsBullet; // This is a bullet picture ID
822 else
825 #i173#
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
838 if (nUpperLevel)
840 sal_uInt8 nOneBasedNextNoIndex = aOfsNumsXCH[nUpperLevel-1];
841 xub_StrLen nNextNoIndex =
842 nOneBasedNextNoIndex > 0 ? nOneBasedNextNoIndex -1 : STRING_LEN;
843 if (nNextNoIndex != STRING_LEN)
844 ++nNextNoIndex;
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 )
858 case 0:
859 eAdj = SVX_ADJUST_LEFT;
860 break;
861 case 1:
862 eAdj = SVX_ADJUST_CENTER;
863 break;
864 case 2:
865 eAdj = SVX_ADJUST_RIGHT;
866 break;
867 case 3:
868 // Writer here cannot do block justification
869 eAdj = SVX_ADJUST_LEFT;
870 break;
871 default:
872 // undefied value
873 OSL_ENSURE( !this, "Value of aLVL.nAlign is not supported" );
874 // take default
875 eAdj = SVX_ADJUST_LEFT;
876 break;
879 // 6. entsprechendes NumFmt konfigurieren
880 if( bSetStartNo )
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);
897 else
899 // reminder: Garnix ist default Prefix
900 if( sPrefix.Len() )
901 rNumFmt.SetPrefix( sPrefix );
902 // reminder: Point is default Postfix
903 rNumFmt.SetSuffix( sPostfix );
904 rNumFmt.SetIncludeUpperLevels( nUpperLevel );
907 // #i89181#
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);
917 else
919 rNumFmt.SetAbsLSpace( aLVL.nDxaLeft );
920 rNumFmt.SetFirstLineOffset(aLVL.nDxaLeft1);
923 else
925 rNumFmt.SetIndentAt( aLVL.nDxaLeft );
926 rNumFmt.SetFirstLineIndent(aLVL.nDxaLeft1);
927 if ( !aLVL.bV6 )
928 rNumFmt.SetListtabPos( nTabPos );
929 else
930 rNumFmt.SetListtabPos( aLVL.nV6Indent );
931 SvxNumberFormat::LabelFollowedBy eNumLabelFollowedBy = SvxNumberFormat::LISTTAB;
932 switch ( ixchFollow )
934 case 0:
936 eNumLabelFollowedBy = SvxNumberFormat::LISTTAB;
938 break;
939 case 1:
941 eNumLabelFollowedBy = SvxNumberFormat::SPACE;
943 break;
944 case 2:
946 eNumLabelFollowedBy = SvxNumberFormat::NOTHING;
948 break;
950 rNumFmt.SetLabelFollowedBy( eNumLabelFollowedBy );
953 return true;
956 void WW8ListManager::AdjustLVL( sal_uInt8 nLevel, SwNumRule& rNumRule,
957 WW8aISet& rListItemSet, WW8aCFmt& rCharFmt, bool& bNewCharFmtCreated,
958 String sPrefix )
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();
982 while (true)
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;
993 break;
995 if( aIter.IsAtEnd() )
996 break;
997 nWhich = aIter.NextItem()->Which();
1000 if( nIdenticalItemSetLevel != nMaxLevel )
1001 break;
1005 SwCharFmt* pFmt;
1006 if (nMaxLevel == nIdenticalItemSetLevel)
1008 // Style definieren
1009 String aName( sPrefix.Len() ? sPrefix : rNumRule.GetName() );
1010 (aName += 'z') += OUString::number( nLevel );
1012 // const Wegcasten
1013 pFmt = rDoc.MakeCharFmt(aName, (SwCharFmt*)rDoc.GetDfltCharFmt());
1014 bNewCharFmtCreated = true;
1015 // Attribute reinsetzen
1016 pFmt->SetFmtAttr( *pThisLevelItemSet );
1018 else
1020 // passenden Style hier anhaengen
1021 pFmt = rCharFmt[ nIdenticalItemSetLevel ];
1024 // merken
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
1033 else
1035 SwCharFmt* pFmt = aNumFmt.GetCharFmt();
1036 if ( !pFmt)
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();
1053 Font aFont;
1054 if( !pFmt )
1056 aFont = numfunc::GetDefBulletFont();
1058 else
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++);
1080 // #i86652#
1081 sal_uInt16 nRul =
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);
1087 return pMyNumRule;
1090 SwNumRule* WW8ListManager::GetNumRule(size_t i)
1092 if (i < maLSTInfos.size())
1093 return maLSTInfos[i]->pNumRule;
1094 else
1095 return 0;
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_),
1103 nUniqueList(1)
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
1111 // Arrays anlegen
1112 bool bLVLOk = true;
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);
1121 if (!bOk)
1122 return;
1124 sal_uInt32 nRemainingPlcfLst = rFib.lcbPlcfLst;
1126 sal_uInt16 nListCount(0);
1127 rSt >> nListCount;
1128 nRemainingPlcfLst -= 2;
1129 bOk = nListCount > 0;
1131 if (!bOk)
1132 return;
1135 // 1.1 alle LST einlesen
1137 for (sal_uInt16 nList=0; nList < nListCount; ++nList)
1139 if (nRemainingPlcfLst < cbLSTF)
1140 break;
1142 WW8LST aLST;
1143 memset(&aLST, 0, sizeof( aLST ));
1146 // 1.1.1 Daten einlesen
1148 rSt >> aLST.nIdLst;
1149 rSt >> aLST.nTplC;
1150 for (sal_uInt16 nLevel = 0; nLevel < nMaxLevel; ++nLevel)
1151 rSt >> aLST.aIdSty[ nLevel ];
1153 sal_uInt8 aBits1(0);
1154 rSt >> aBits1;
1156 rSt.SeekRel( 1 );
1158 if( aBits1 & 0x01 )
1159 aLST.bSimpleList = true;
1160 if( aBits1 & 0x02 )
1161 aLST.bRestartHdn = true;
1163 // 1.1.2 new NumRule inserted in Doc and WW8LSTInfo marked
1166 #i1869#
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 ) );
1207 // LVLF einlesen
1208 bLVLOk = ReadLVL( aNumFmt, pListInfo->aItemSet[nLevel],
1209 pListInfo->aIdSty[nLevel], true, aNotReallyThere, nLevel,
1210 pListInfo->maParaSprms[nLevel]);
1211 if( !bLVLOk )
1212 break;
1213 // und in die rMyNumRule aufnehmen
1214 rMyNumRule.Set( nLevel, aNumFmt );
1216 if( !bLVLOk )
1217 break;
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)
1224 bool bDummy;
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);
1240 if (!bOk)
1241 return;
1243 sal_Int32 nLfoCount(0);
1244 rSt >> nLfoCount;
1245 bOk = nLfoCount > 0;
1247 if (!bOk)
1248 return;
1251 // 2.1 alle LFO einlesen
1253 for (sal_uInt16 nLfo = 0; nLfo < nLfoCount; ++nLfo)
1255 bOk = false;
1257 if (rSt.IsEof())
1258 break;
1260 WW8LFO aLFO;
1261 memset(&aLFO, 0, sizeof( aLFO ));
1263 rSt >> aLFO.nIdLst;
1264 rSt.SeekRel( 8 );
1265 rSt >> aLFO.nLfoLvl;
1266 rSt.SeekRel( 3 );
1267 // soviele Overrides existieren
1268 if ((nMaxLevel < aLFO.nLfoLvl) || rSt.GetError())
1269 break;
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);
1293 bOk = true;
1296 if( bOk )
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)
1304 bOk = false;
1305 WW8LFOInfo& rLFOInfo = pLFOInfos[nLfo];
1306 // stehen hierfuer ueberhaupt LFOLVL an ?
1307 if( rLFOInfo.bOverride )
1309 WW8LSTInfo* pParentListInfo = GetLSTByListId(rLFOInfo.nIdLst);
1310 if (!pParentListInfo)
1311 break;
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 )
1318 break;
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
1327 // referenziert:
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);
1335 else
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
1344 // einlesen
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# ?
1357 sal_uInt32 nTest;
1358 rSt >> nTest;
1361 nTest = 0;
1362 rSt >> nTest;
1364 while (nTest == 0xFFFFFFFF);
1365 rSt.SeekRel(-4);
1367 std::deque<bool> aNotReallyThere(WW8ListManager::nMaxLevel);
1368 for (sal_uInt8 nLevel = 0; nLevel < rLFOInfo.nLfoLvl; ++nLevel)
1370 WW8LFOLVL aLFOLVL;
1371 bLVLOk = false;
1374 // 2.2.2.1 den LFOLVL einlesen
1376 rSt >> aLFOLVL.nStartAt;
1377 sal_uInt8 aBits1(0);
1378 rSt >> aBits1;
1379 rSt.SeekRel( 3 );
1380 if (rSt.GetError())
1381 break;
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
1389 // WW8LFOInfo")
1390 aLFOLVL.nLevel = aBits1 & 0x0F;
1391 if( (0xFF > aBits1) &&
1392 (nMaxLevel > aLFOLVL.nLevel) )
1394 if (aBits1 & 0x10)
1395 aLFOLVL.bStartAt = true;
1396 else
1397 aLFOLVL.bStartAt = false;
1399 // 2.2.2.2 eventuell auch den zugehoerigen LVL einlesen
1401 SwNumFmt aNumFmt(
1402 rLFOInfo.pNumRule->Get(aLFOLVL.nLevel));
1403 if (aBits1 & 0x20)
1405 aLFOLVL.bFormat = true;
1406 // falls bStartup true, hier den Startup-Level
1407 // durch den im LVL vermerkten ersetzen LVLF
1408 // einlesen
1409 bLVLOk = ReadLVL(aNumFmt, aItemSet[nLevel],
1410 pParentListInfo->aIdSty[nLevel],
1411 aLFOLVL.bStartAt, aNotReallyThere, nLevel,
1412 rLFOInfo.maParaSprms[nLevel]);
1414 if (!bLVLOk)
1415 break;
1417 else if (aLFOLVL.bStartAt)
1419 aNumFmt.SetStart(
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);
1427 bLVLOk = true;
1429 if (nMaxLevel > aLFOLVL.nLevel)
1430 rLFOInfo.maOverrides[aLFOLVL.nLevel] = aLFOLVL;
1432 if( !bLVLOk )
1433 break;
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 ];
1451 bOk = true;
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());
1473 delete *aIter;
1475 boost::ptr_vector<WW8LFOInfo >::reverse_iterator aIter;
1476 for (aIter = pLFOInfos.rbegin() ;
1477 aIter < pLFOInfos.rend();
1478 ++aIter )
1480 if (aIter->bOverride
1481 && aIter->pNumRule
1482 && !aIter->bUsedInDoc
1483 && aIter->pNumRule->IsAutoRule())
1485 rDoc.DelNumRule( aIter->pNumRule->GetName() );
1490 bool IsEqualFormatting(const SwNumRule &rOne, const SwNumRule &rTwo)
1492 bool bRet =
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()
1502 if (bRet)
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);
1509 if (!(rO == rT))
1511 bRet = false;
1512 break;
1516 return bRet;
1519 SwNumRule* WW8ListManager::GetNumRuleForActivation(sal_uInt16 nLFOPosition,
1520 const sal_uInt8 nLevel, std::vector<sal_uInt8> &rParaSprms, SwTxtNode *pNode)
1522 if (pLFOInfos.size() <= nLFOPosition)
1523 return 0;
1525 WW8LFOInfo& rLFOInfo = pLFOInfos[nLFOPosition];
1527 bool bFirstUse = !rLFOInfo.bUsedInDoc;
1528 rLFOInfo.bUsedInDoc = true;
1530 if( !rLFOInfo.pNumRule )
1531 return 0;
1533 // #i25545#
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;
1546 #i1869#
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
1555 my bewilderment.
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 ?
1598 if (bFirstUse)
1600 if (rOverride.bStartAt)
1602 const SwNumFmt &rFmt =
1603 pParentListInfo->pNumRule->Get(nLevel);
1604 if (
1605 rFmt.GetStart() ==
1606 rLFOInfo.maOverrides[nLevel].nStartAt
1609 bRestart = true;
1611 else
1613 bNewstart = true;
1614 nStart = writer_cast<sal_uInt16>
1615 (rLFOInfo.maOverrides[nLevel].nStartAt);
1620 pParentListInfo->bUsedInDoc = true;
1625 if (pNode)
1627 pNode->SetAttrListLevel(nLevel);
1629 if (bRestart || bNewstart)
1630 pNode->SetListRestart(true);
1631 if (bNewstart)
1632 pNode->SetAttrListRestartValue(nStart);
1634 return pRet;
1637 //----------------------------------------------------------------------------
1638 // SwWW8ImplReader: anhaengen einer Liste an einen Style oder Absatz
1639 //----------------------------------------------------------------------------
1640 bool SwWW8ImplReader::SetTxtFmtCollAndListLevel(const SwPaM& rRg,
1641 SwWW8StyInf& rStyleInfo)
1643 bool bRes = true;
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" );
1649 // make code robust
1650 if ( !pTxtNode )
1652 return bRes;
1655 SwNumRule * pNumRule = pTxtNode->GetNumRule(); // #i27610#
1657 if( !IsInvalidOrToBeMergedTabCell() &&
1658 ! (pNumRule && pNumRule->IsOutlineRule()) ) // #i27610#
1659 pTxtNode->ResetAttr( RES_PARATR_NUMRULE );
1661 if( !rStyleInfo.pOutlineNumrule )
1663 if (
1664 (USHRT_MAX > rStyleInfo.nLFOIndex) &&
1665 (WW8ListManager::nMaxLevel > rStyleInfo.nListLevel)
1668 RegisterNumFmtOnTxtNode(rStyleInfo.nLFOIndex,
1669 rStyleInfo.nListLevel, false);
1672 else
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
1678 // outline rule.
1679 pTxtNode->SetAttrListLevel( rStyleInfo.nOutlineLevel );
1682 return bRes;
1685 void UseListIndent(SwWW8StyInf &rStyle, const SwNumFmt &rFmt)
1687 // #i86652#
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#
1710 else
1712 aLR.SetTxtLeft(0);
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())
1723 return;
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
1730 if( pAktColl )
1732 // jetzt nur die Parameter vermerken: die tatsaechliche Liste wird
1733 // spaeter drangehaengt, wenn die Listendefinitionen gelesen sind...
1734 if (
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;
1744 if (
1745 (USHRT_MAX > nActLFO) &&
1746 (WW8ListManager::nMaxLevel > nActLevel)
1749 std::vector<sal_uInt8> aParaSprms;
1750 SwNumRule *pNmRule =
1751 pLstManager->GetNumRuleForActivation(nActLFO,
1752 nActLevel, aParaSprms);
1753 if (pNmRule)
1754 UseListIndent(rStyleInf, pNmRule->Get(nActLevel));
1761 void SwWW8ImplReader::RegisterNumFmtOnStyle(sal_uInt16 nStyle)
1764 if (nStyle >= vColl.size())
1765 return;
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;
1778 if (
1779 (USHRT_MAX > nLFO) &&
1780 (WW8ListManager::nMaxLevel > nLevel)
1783 std::vector<sal_uInt8> aParaSprms;
1784 pNmRule = pLstManager->GetNumRuleForActivation(nLFO, nLevel,
1785 aParaSprms);
1787 if (pNmRule)
1789 if( MAXLEVEL > rStyleInf.nOutlineLevel )
1790 rStyleInf.pOutlineNumrule = pNmRule;
1791 else
1793 rStyleInf.pFmt->SetFmtAttr(
1794 SwNumRuleItem( pNmRule->GetName() ) );
1795 rStyleInf.bHasStyNumRule = true;
1800 if (pNmRule)
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");
1817 if (!pTxtNd)
1818 return;
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
1835 is unchanged
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
1847 //it to the new one
1848 if (bSetAttr)
1850 const SwNumRule *pNormal = pTxtNd->GetNumRule();
1851 if (pNormal != pRule)
1853 pTxtNd->SetAttr
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 );
1866 // #i99822#
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,
1883 RES_LR_SPACE);
1884 const SvxLRSpaceItem *pItem = (const SvxLRSpaceItem*)(
1885 GetFmtAttr(RES_LR_SPACE));
1886 OSL_ENSURE(pItem, "impossible");
1887 if (pItem)
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];
1901 while (0 < nLen)
1903 sal_uInt16 nL1 = ImportSprm(pSprms1);
1904 nLen = nLen - nL1;
1905 pSprms1 += nL1;
1908 SetAktItemSet(pOldAktItemSet);
1911 const SvxLRSpaceItem *pLR =
1912 HasItem<SvxLRSpaceItem>(aListIndent, RES_LR_SPACE);
1913 OSL_ENSURE(pLR, "Impossible");
1914 if (pLR)
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 ?
1927 if (pAktColl)
1928 SetStylesList( nAktColl , nActLFO, nActLevel);
1929 else
1930 RegisterNumFmtOnTxtNode(nActLFO, nActLevel);
1933 void SwWW8ImplReader::Read_ListLevel(sal_uInt16, const sal_uInt8* pData,
1934 short nLen)
1936 if (pPlcxMan && pPlcxMan->GetDoingDrawTextBox())
1937 return;
1939 if( nLen < 0 )
1941 // the actual level is finished, what should we do ?
1942 nListLevel = WW8ListManager::nMaxLevel;
1943 if (pStyles && !bVer67)
1944 pStyles->nWwNumLevel = 0;
1946 else
1948 // security check
1949 if( !pData )
1950 return;
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;
1968 else if
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,
1982 short nLen)
1984 if (pPlcxMan && pPlcxMan->GetDoingDrawTextBox())
1985 return;
1987 if( nLen < 0 )
1989 // the actual level is finished, what should we do ?
1990 nLFOPosition = USHRT_MAX;
1991 nListLevel = WW8ListManager::nMaxLevel;
1993 else
1995 // security check
1996 if( !pData )
1997 return;
1999 short nData = SVBT16ToShort( pData );
2000 if( 0 >= nData )
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
2008 setting.
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
2014 if (pAktColl)
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);
2037 if( pLR )
2038 aLR = *static_cast<const SvxLRSpaceItem*>(pLR);
2040 // reset/blank the left indent (and only the left)
2041 aLR.SetTxtLeft(0);
2042 aLR.SetTxtFirstLineOfst(0);
2044 // apply the modified SvxLRSpaceItem to the current paragraph
2045 pTxtNode->SetAttr( aLR );
2048 nLFOPosition = USHRT_MAX;
2050 else
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
2058 braindeadness
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)
2069 nListLevel = 0;
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+
2081 docs
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 )
2097 bool bRet=false;
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);
2119 break;
2122 pPlcxMan->advance();
2123 nStart = pPlcxMan->Where();
2125 sal_uLong nOffset = nPicLocFc;
2126 aSave.Restore(this);
2128 sal_uLong nOldPos = pDataStream->Tell();
2129 WW8_PIC aPic;
2130 pDataStream->Seek( nOffset);
2131 PicRead( pDataStream, &aPic, bVer67);
2133 if((aPic.lcb > 0x3A) && !pDataStream->GetError() )
2135 aFormula.FormulaRead(nWhich,pDataStream);
2136 bRet = true;
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
2142 version C.
2144 pDataStream->Seek( nOldPos );
2145 return(bRet);
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())
2156 return sal_False;
2158 awt::Size aSz;
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);
2167 return bRet;
2170 void WW8FormulaControl::FormulaRead(SwWw8ControlType nWhich,
2171 SvStream *pDataStream)
2173 sal_uInt8 nField;
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. )
2184 sal_uInt8 bits1;
2185 *pDataStream >> bits1;
2186 sal_uInt8 bits2;
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 ) )
2194 return; // bail out
2196 sal_uInt8 iRes = (bits1 & 0x7C) >> 2;
2198 sal_uInt16 cch;
2199 *pDataStream >> cch;
2201 sal_uInt16 hps;
2202 *pDataStream >> hps;
2204 // xstzName
2205 sTitle = read_uInt16_BeltAndBracesString(*pDataStream);
2207 if (nWhich == WW8_CT_EDIT)
2208 { // Field is a textbox
2209 // Default text
2210 // xstzTextDef
2211 sDefault = read_uInt16_BeltAndBracesString(*pDataStream);
2213 else
2215 // CheckBox or ComboBox
2216 sal_uInt16 wDef = 0;
2217 *pDataStream >> wDef;
2218 nChecked = wDef; // default
2219 if (nWhich == WW8_CT_CHECKBOX)
2221 if ( iRes != 25 )
2222 nChecked = iRes;
2223 sDefault = ( wDef == 0 ) ? OUString( "0" ) : OUString( "1" );
2226 // xstzTextFormat
2227 sFormatting = read_uInt16_BeltAndBracesString(*pDataStream);
2228 // xstzHelpText
2229 sHelp = read_uInt16_BeltAndBracesString(*pDataStream);
2230 // xstzStatText
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)
2238 bool bAllOk = true;
2239 // SSTB (see Spec. 2.2.4)
2240 sal_uInt16 fExtend;
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)
2247 bAllOk = false;
2248 *pDataStream >> nNoStrings;
2250 // I guess this should be zero ( and we should ensure that )
2251 sal_uInt16 cbExtra;
2252 *pDataStream >> cbExtra;
2254 OSL_ENSURE(bAllOk,
2255 "Unknown formfield dropdown list structure. Report to cmc");
2256 if (!bAllOk) //Not as expected, don't risk it at all.
2257 nNoStrings = 0;
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;
2267 nField = bits2;
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)
2286 awt::Size aRet;
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" },
2301 { 0, 0 }
2304 Font aFont;
2305 uno::Reference< beans::XPropertySetInfo > xPropSetInfo =
2306 rPropSet->getPropertySetInfo();
2308 uno::Any aTmp;
2309 for (const CtrlFontMapEntry* pMap = aMapTable; pMap->nWhichId; ++pMap)
2311 bool bSet = true;
2312 const SfxPoolItem* pItem = GetFmtAttr( pMap->nWhichId );
2313 OSL_ENSURE(pItem, "Impossible");
2314 if (!pItem)
2315 continue;
2317 switch ( pMap->nWhichId )
2319 case RES_CHRATR_COLOR:
2321 String pNm;
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());
2329 break;
2330 case RES_CHRATR_FONT:
2332 const SvxFontItem *pFontItem = (SvxFontItem *)pItem;
2333 String pNm;
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() );
2362 break;
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,
2371 MAP_100TH_MM));
2373 break;
2375 case RES_CHRATR_WEIGHT:
2376 aTmp <<= (float)VCLUnoHelper::ConvertFontWeight(
2377 ((SvxWeightItem*)pItem)->GetWeight() );
2378 aFont.SetWeight( ((SvxWeightItem*)pItem)->GetWeight() );
2379 break;
2381 case RES_CHRATR_UNDERLINE:
2382 aTmp <<= (sal_Int16)(((SvxUnderlineItem*)pItem)->GetLineStyle());
2383 aFont.SetUnderline(((SvxUnderlineItem*)pItem)->GetLineStyle());
2384 break;
2386 case RES_CHRATR_CROSSEDOUT:
2387 aTmp <<= (sal_Int16)( ((SvxCrossedOutItem*)pItem)->GetStrikeout() );
2388 aFont.SetStrikeout( ((SvxCrossedOutItem*)pItem)->GetStrikeout() );
2389 break;
2391 case RES_CHRATR_POSTURE:
2392 aTmp <<= (sal_Int16)( ((SvxPostureItem*)pItem)->GetPosture() );
2393 aFont.SetItalic( ((SvxPostureItem*)pItem)->GetPosture() );
2394 break;
2396 default:
2397 bSet = false;
2398 break;
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");
2407 if (pOut)
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();
2415 pOut->Pop();
2417 return aRet;
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");
2425 if( !xCreate.is() )
2426 return sal_False;
2428 rFComp = uno::Reference<form::XFormComponent>(xCreate, uno::UNO_QUERY);
2429 if( !rFComp.is() )
2430 return sal_False;
2432 uno::Reference<beans::XPropertySet> xPropSet(xCreate, uno::UNO_QUERY);
2434 uno::Any aTmp;
2435 if (!sTitle.isEmpty())
2436 aTmp <<= sTitle;
2437 else
2438 aTmp <<= sName;
2439 xPropSet->setPropertyValue("Name", aTmp );
2441 if (!sToolTip.isEmpty())
2443 aTmp <<= sToolTip;
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];
2463 else
2465 aTmp <<= aListSource[0];
2468 xPropSet->setPropertyValue("DefaultText", aTmp );
2470 rSz = rRdr.MiserableDropDownFormHack(maListEntries[0], xPropSet);
2472 else
2474 static const sal_Unicode aBlank[] =
2476 0x2002,0x2002,0x2002,0x2002,0x2002
2478 rSz = rRdr.MiserableDropDownFormHack(OUString(aBlank, SAL_N_ELEMENTS(aBlank)), xPropSet);
2481 return sal_True;
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
2502 (rPropertyName,
2503 static_cast<sal_Int16>(beans::PropertyAttribute::BOUND |
2504 beans::PropertyAttribute::REMOVABLE),
2505 aAny);
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");
2517 if( !xCreate.is() )
2518 return sal_False;
2520 rFComp = uno::Reference< form::XFormComponent >( xCreate, uno::UNO_QUERY );
2521 if( !rFComp.is() )
2522 return sal_False;
2524 uno::Reference< beans::XPropertySet > xPropSet( xCreate, uno::UNO_QUERY );
2526 rSz.Width = 16 * hpsCheckBox;
2527 rSz.Height = 16 * hpsCheckBox;
2529 uno::Any aTmp;
2530 if (!sTitle.isEmpty())
2531 aTmp <<= sTitle;
2532 else
2533 aTmp <<= sName;
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);
2545 return sal_True;
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() )
2567 return sal_False;
2569 uno::Reference< uno::XInterface > xCreate = rServiceFactory->createInstance(
2570 "com.sun.star.drawing.ControlShape");
2571 if( !xCreate.is() )
2572 return sal_False;
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;
2585 sal_Int16 nTemp;
2586 if (bFloatingCtrl)
2587 nTemp= text::TextContentAnchorType_AT_PARAGRAPH;
2588 else
2589 nTemp= text::TextContentAnchorType_AS_CHARACTER;
2591 aTmp <<= nTemp;
2592 xShapePropSet->setPropertyValue("AnchorType", aTmp );
2594 nTemp= text::VertOrientation::TOP;
2595 aTmp <<= nTemp;
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,
2608 uno::UNO_QUERY );
2609 uno::Reference< awt::XControlModel > xControlModel( rFComp,
2610 uno::UNO_QUERY );
2611 xControlShape->setControl( xControlModel );
2613 if (pShape)
2614 *pShape = xShape;
2616 return sal_True;
2619 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */