Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : :
30 : : #include <svl/itemiter.hxx>
31 : : #include <vcl/svapp.hxx>
32 : : #include <vcl/outdev.hxx>
33 : :
34 : : #include <toolkit/helper/vclunohelper.hxx>
35 : : #include <com/sun/star/form/XFormsSupplier.hpp>
36 : : #include <com/sun/star/form/XForm.hpp>
37 : : #include <com/sun/star/form/XImageProducerSupplier.hpp>
38 : : #include <com/sun/star/form/XFormController.hpp>
39 : : #include <com/sun/star/frame/XStorable.hpp>
40 : : #include <com/sun/star/frame/XModel.hpp>
41 : : #include <com/sun/star/drawing/XConnectableShape.hpp>
42 : : #include <com/sun/star/drawing/XConnectorShape.hpp>
43 : : #include <com/sun/star/drawing/XShape.hpp>
44 : : #include <com/sun/star/drawing/XControlShape.hpp>
45 : : #include <com/sun/star/drawing/XShapeAligner.hpp>
46 : : #include <com/sun/star/drawing/XShapeGroup.hpp>
47 : : #include <com/sun/star/drawing/XUniversalShapeDescriptor.hpp>
48 : : #include <com/sun/star/drawing/XShapeMirror.hpp>
49 : : #include <com/sun/star/drawing/XShapeArranger.hpp>
50 : : #include <com/sun/star/drawing/XDrawPage.hpp>
51 : : #include <com/sun/star/drawing/XDrawPageSupplier.hpp>
52 : : #include <com/sun/star/lang/XMultiServiceFactory.hpp>
53 : : #include <com/sun/star/lang/XSingleServiceFactory.hpp>
54 : : #include <com/sun/star/container/XIndexContainer.hpp>
55 : : #include <com/sun/star/text/VertOrientation.hpp>
56 : : #include <com/sun/star/text/TextContentAnchorType.hpp>
57 : : #include <comphelper/extract.hxx>
58 : : #include <comphelper/stlunosequence.hxx>
59 : : #include <com/sun/star/beans/XPropertyContainer.hpp>
60 : : #include <com/sun/star/beans/PropertyAttribute.hpp>
61 : :
62 : : #include <algorithm>
63 : : #include <functional>
64 : : #include <hintids.hxx>
65 : : #include <editeng/fontitem.hxx>
66 : : #include <editeng/lrspitem.hxx>
67 : : #include <editeng/fhgtitem.hxx>
68 : : #include <editeng/colritem.hxx>
69 : : #include <editeng/wghtitem.hxx>
70 : : #include <editeng/crsditem.hxx>
71 : : #include <editeng/udlnitem.hxx>
72 : : #include <editeng/postitem.hxx>
73 : : #include <unotextrange.hxx>
74 : : #include <doc.hxx>
75 : : #include <docary.hxx>
76 : : #include <docsh.hxx>
77 : : #include <numrule.hxx>
78 : : #include <paratr.hxx>
79 : : #include <charatr.hxx>
80 : : #include <charfmt.hxx>
81 : : #include <ndtxt.hxx>
82 : : #include <expfld.hxx>
83 : : #include <fmtfld.hxx>
84 : : #include <flddropdown.hxx>
85 : : #include "writerhelper.hxx"
86 : : #include "writerwordglue.hxx"
87 : : #include "ww8par.hxx"
88 : : #include "ww8par2.hxx" // wg. Listen-Attributen in Styles
89 : :
90 : : #include <IMark.hxx>
91 : : #include <unotools/fltrcfg.hxx>
92 : : #include <xmloff/odffields.hxx>
93 : :
94 : : #include <stdio.h>
95 : :
96 : : using namespace com::sun::star;
97 : : using namespace sw::util;
98 : : using namespace sw::types;
99 : : using namespace sw::mark;
100 : :
101 : : //-----------------------------------------
102 : : // UNO-Controls
103 : : //-----------------------------------------
104 : :
105 : : //cmc, OCX i.e. word 97 form controls
106 : 0 : eF_ResT SwWW8ImplReader::Read_F_OCX( WW8FieldDesc*, String& )
107 : : {
108 [ # # ][ # # ]: 0 : if( bObj && nPicLocFc )
109 : 0 : nObjLocFc = nPicLocFc;
110 : 0 : bEmbeddObj = true;
111 : 0 : return FLD_TEXT;
112 : : }
113 : :
114 : 0 : eF_ResT SwWW8ImplReader::Read_F_FormTextBox( WW8FieldDesc* pF, String& rStr )
115 : : {
116 [ # # ]: 0 : WW8FormulaEditBox aFormula(*this);
117 : :
118 [ # # ][ # # ]: 0 : if (0x01 == rStr.GetChar(writer_cast<xub_StrLen>(pF->nLCode-1))) {
119 [ # # ]: 0 : ImportFormulaControl(aFormula,pF->nSCode+pF->nLCode-1, WW8_CT_EDIT);
120 : : }
121 : :
122 : : /*
123 : : Here we have a small complication. This formula control contains
124 : : the default text that is displayed if you edit the form field in
125 : : the "default text" area. But MSOffice does not display that
126 : : information, instead it display the result of the field,
127 : : MSOffice just uses the default text of the control as its
128 : : initial value for the displayed default text. So we will swap in
129 : : the field result into the formula here in place of the default
130 : : text.
131 : : */
132 : :
133 [ # # ]: 0 : const SvtFilterOptions& rOpt = SvtFilterOptions::Get();
134 [ # # ]: 0 : sal_Bool bUseEnhFields = rOpt.IsUseEnhancedFields();
135 : :
136 [ # # ]: 0 : if (!bUseEnhFields) {
137 [ # # ][ # # ]: 0 : aFormula.sDefault = GetFieldResult(pF);
[ # # ]
138 : :
139 [ # # ]: 0 : SwInputField aFld((SwInputFieldType*)rDoc.GetSysFldType( RES_INPUTFLD ),
140 [ # # ][ # # ]: 0 : aFormula.sDefault , aFormula.sTitle , INP_TXT, 0 );
[ # # ][ # # ]
[ # # ]
141 [ # # ][ # # ]: 0 : aFld.SetHelp(aFormula.sHelp);
[ # # ]
142 [ # # ][ # # ]: 0 : aFld.SetToolTip(aFormula.sToolTip);
[ # # ]
143 : :
144 [ # # ][ # # ]: 0 : rDoc.InsertPoolItem(*pPaM, SwFmtFld(aFld), 0);
[ # # ]
145 [ # # ]: 0 : return FLD_OK;
146 : : } else {
147 : 0 : WW8PLCFx_Book* pB = pPlcxMan->GetBook();
148 [ # # ]: 0 : String aBookmarkName;
149 [ # # ]: 0 : if (pB!=NULL) {
150 : 0 : WW8_CP currentCP=pF->nSCode;
151 : 0 : WW8_CP currentLen=pF->nLen;
152 : :
153 : : sal_uInt16 bkmFindIdx;
154 [ # # ]: 0 : String aBookmarkFind=pB->GetBookmark(currentCP-1, currentCP+currentLen-1, bkmFindIdx);
155 : :
156 [ # # ]: 0 : if (aBookmarkFind.Len()>0) {
157 [ # # ]: 0 : pB->SetStatus(bkmFindIdx, BOOK_FIELD); // mark bookmark as consumed, such that tl'll not get inserted as a "normal" bookmark again
158 [ # # ]: 0 : if (aBookmarkFind.Len()>0) {
159 [ # # ]: 0 : aBookmarkName=aBookmarkFind;
160 : : }
161 [ # # ]: 0 : }
162 : : }
163 : :
164 [ # # ][ # # ]: 0 : if (pB!=NULL && aBookmarkName.Len()==0) {
[ # # ]
165 [ # # ][ # # ]: 0 : aBookmarkName=pB->GetUniqueBookmarkName(aFormula.sTitle);
166 : : }
167 : :
168 : :
169 [ # # ]: 0 : if (aBookmarkName.Len()>0) {
170 [ # # ][ # # ]: 0 : maFieldStack.back().SetBookmarkName(aBookmarkName);
[ # # ]
171 [ # # ][ # # ]: 0 : maFieldStack.back().SetBookmarkType(ODF_FORMTEXT);
172 [ # # ][ # # ]: 0 : maFieldStack.back().getParameters()["Description"] = uno::makeAny(::rtl::OUString(aFormula.sToolTip));
[ # # ][ # # ]
173 [ # # ][ # # ]: 0 : maFieldStack.back().getParameters()["Name"] = uno::makeAny(::rtl::OUString(aFormula.sTitle));
[ # # ][ # # ]
174 : : }
175 [ # # ]: 0 : return FLD_TEXT;
176 : 0 : }
177 : : }
178 : :
179 : 0 : eF_ResT SwWW8ImplReader::Read_F_FormCheckBox( WW8FieldDesc* pF, String& rStr )
180 : : {
181 [ # # ]: 0 : WW8FormulaCheckBox aFormula(*this);
182 : :
183 [ # # ]: 0 : if (!pFormImpl)
184 [ # # ][ # # ]: 0 : pFormImpl = new SwMSConvertControls(mpDocShell, pPaM);
185 : :
186 [ # # ][ # # ]: 0 : if (0x01 == rStr.GetChar(writer_cast<xub_StrLen>(pF->nLCode-1)))
187 [ # # ]: 0 : ImportFormulaControl(aFormula,pF->nSCode+pF->nLCode-1, WW8_CT_CHECKBOX);
188 [ # # ]: 0 : const SvtFilterOptions& rOpt = SvtFilterOptions::Get();
189 [ # # ]: 0 : sal_Bool bUseEnhFields = rOpt.IsUseEnhancedFields();
190 : :
191 [ # # ]: 0 : if (!bUseEnhFields) {
192 [ # # ]: 0 : pFormImpl->InsertFormula(aFormula);
193 : 0 : return FLD_OK;
194 : : } else {
195 [ # # ]: 0 : String aBookmarkName;
196 : 0 : WW8PLCFx_Book* pB = pPlcxMan->GetBook();
197 [ # # ]: 0 : if (pB!=NULL) {
198 : 0 : WW8_CP currentCP=pF->nSCode;
199 : 0 : WW8_CP currentLen=pF->nLen;
200 : :
201 : : sal_uInt16 bkmFindIdx;
202 [ # # ]: 0 : String aBookmarkFind=pB->GetBookmark(currentCP-1, currentCP+currentLen-1, bkmFindIdx);
203 : :
204 [ # # ]: 0 : if (aBookmarkFind.Len()>0) {
205 [ # # ]: 0 : pB->SetStatus(bkmFindIdx, BOOK_FIELD); // mark as consumed by field
206 [ # # ]: 0 : if (aBookmarkFind.Len()>0) {
207 [ # # ]: 0 : aBookmarkName=aBookmarkFind;
208 : : }
209 [ # # ]: 0 : }
210 : : }
211 : :
212 [ # # ][ # # ]: 0 : if (pB!=NULL && aBookmarkName.Len()==0) {
[ # # ]
213 [ # # ][ # # ]: 0 : aBookmarkName=pB->GetUniqueBookmarkName(aFormula.sTitle);
214 : : }
215 : :
216 [ # # ]: 0 : if (aBookmarkName.Len()>0)
217 : : {
218 [ # # ]: 0 : IDocumentMarkAccess* pMarksAccess = rDoc.getIDocumentMarkAccess( );
219 : : IFieldmark* pFieldmark = dynamic_cast<IFieldmark*>( pMarksAccess->makeNoTextFieldBookmark(
220 [ # # ][ # # ]: 0 : *pPaM, aBookmarkName, ODF_FORMCHECKBOX ) );
221 : : OSL_ENSURE(pFieldmark!=NULL, "hmmm; why was the bookmark not created?");
222 [ # # ]: 0 : if (pFieldmark!=NULL) {
223 [ # # ]: 0 : IFieldmark::parameter_map_t* const pParameters = pFieldmark->GetParameters();
224 [ # # ]: 0 : ICheckboxFieldmark* pCheckboxFm = dynamic_cast<ICheckboxFieldmark*>(pFieldmark);
225 [ # # ][ # # ]: 0 : (*pParameters)[ODF_FORMCHECKBOX_NAME] = uno::makeAny(::rtl::OUString(aFormula.sTitle));
226 [ # # ][ # # ]: 0 : (*pParameters)[ODF_FORMCHECKBOX_HELPTEXT] = uno::makeAny(::rtl::OUString(aFormula.sToolTip));
227 : :
228 [ # # ]: 0 : if(pCheckboxFm)
229 [ # # ]: 0 : pCheckboxFm->SetChecked(aFormula.nChecked);
230 : : // set field data here...
231 : : }
232 : : }
233 [ # # ]: 0 : return FLD_OK;
234 : 0 : }
235 : : }
236 : :
237 : 0 : eF_ResT SwWW8ImplReader::Read_F_FormListBox( WW8FieldDesc* pF, String& rStr)
238 : : {
239 [ # # ]: 0 : WW8FormulaListBox aFormula(*this);
240 : :
241 [ # # ][ # # ]: 0 : if (0x01 == rStr.GetChar(writer_cast<xub_StrLen>(pF->nLCode-1)))
242 [ # # ]: 0 : ImportFormulaControl(aFormula,pF->nSCode+pF->nLCode-1, WW8_CT_DROPDOWN);
243 : :
244 [ # # ]: 0 : const SvtFilterOptions& rOpt = SvtFilterOptions::Get();
245 [ # # ]: 0 : sal_Bool bUseEnhFields = rOpt.IsUseEnhancedFields();
246 : :
247 [ # # ]: 0 : if (!bUseEnhFields)
248 : : {
249 [ # # ][ # # ]: 0 : SwDropDownField aFld((SwDropDownFieldType*)rDoc.GetSysFldType(RES_DROPDOWN));
250 : :
251 [ # # ]: 0 : aFld.SetName(aFormula.sTitle);
252 [ # # ]: 0 : aFld.SetHelp(aFormula.sHelp);
253 [ # # ]: 0 : aFld.SetToolTip(aFormula.sToolTip);
254 : :
255 [ # # ]: 0 : if (!aFormula.maListEntries.empty())
256 : : {
257 [ # # ]: 0 : aFld.SetItems(aFormula.maListEntries);
258 [ # # ]: 0 : int nIndex = aFormula.fDropdownIndex < aFormula.maListEntries.size() ? aFormula.fDropdownIndex : 0;
259 [ # # ]: 0 : aFld.SetSelectedItem(aFormula.maListEntries[nIndex]);
260 : : }
261 : :
262 [ # # ][ # # ]: 0 : rDoc.InsertPoolItem(*pPaM, SwFmtFld(aFld), 0);
[ # # ]
263 [ # # ]: 0 : return FLD_OK;
264 : : }
265 : : else
266 : : {
267 : : // TODO: review me
268 [ # # ]: 0 : String aBookmarkName;
269 : 0 : WW8PLCFx_Book* pB = pPlcxMan->GetBook();
270 [ # # ]: 0 : if (pB!=NULL)
271 : : {
272 : 0 : WW8_CP currentCP=pF->nSCode;
273 : 0 : WW8_CP currentLen=pF->nLen;
274 : :
275 : : sal_uInt16 bkmFindIdx;
276 [ # # ]: 0 : String aBookmarkFind=pB->GetBookmark(currentCP-1, currentCP+currentLen-1, bkmFindIdx);
277 : :
278 [ # # ]: 0 : if (aBookmarkFind.Len()>0)
279 : : {
280 [ # # ]: 0 : pB->SetStatus(bkmFindIdx, BOOK_FIELD); // mark as consumed by field
281 [ # # ]: 0 : if (aBookmarkFind.Len()>0)
282 [ # # ]: 0 : aBookmarkName=aBookmarkFind;
283 [ # # ]: 0 : }
284 : : }
285 : :
286 [ # # ][ # # ]: 0 : if (pB!=NULL && aBookmarkName.Len()==0)
[ # # ]
287 [ # # ][ # # ]: 0 : aBookmarkName=pB->GetUniqueBookmarkName(aFormula.sTitle);
288 : :
289 [ # # ]: 0 : if (aBookmarkName.Len()>0)
290 : : {
291 [ # # ]: 0 : IDocumentMarkAccess* pMarksAccess = rDoc.getIDocumentMarkAccess( );
292 : : IFieldmark *pFieldmark = dynamic_cast<IFieldmark*>(
293 [ # # ][ # # ]: 0 : pMarksAccess->makeNoTextFieldBookmark( *pPaM, aBookmarkName, ODF_FORMDROPDOWN ) );
294 : : OSL_ENSURE(pFieldmark!=NULL, "hmmm; why was the bookmark not created?");
295 [ # # ]: 0 : if ( pFieldmark != NULL )
296 : : {
297 [ # # ]: 0 : uno::Sequence< ::rtl::OUString > vListEntries(aFormula.maListEntries.size());
298 [ # # ][ # # ]: 0 : ::std::copy(aFormula.maListEntries.begin(), aFormula.maListEntries.end(), ::comphelper::stl_begin(vListEntries));
299 [ # # ][ # # ]: 0 : (*pFieldmark->GetParameters())[ODF_FORMDROPDOWN_LISTENTRY] = uno::makeAny(vListEntries);
[ # # ]
300 [ # # ]: 0 : sal_Int32 nIndex = aFormula.fDropdownIndex < aFormula.maListEntries.size() ? aFormula.fDropdownIndex : 0;
301 [ # # ][ # # ]: 0 : (*pFieldmark->GetParameters())[ODF_FORMDROPDOWN_RESULT] = uno::makeAny(nIndex);
[ # # ][ # # ]
302 : : // set field data here...
303 : : }
304 : : }
305 : :
306 [ # # ]: 0 : return FLD_OK;
307 : 0 : }
308 : : }
309 : :
310 : 0 : eF_ResT SwWW8ImplReader::Read_F_HTMLControl(WW8FieldDesc*, String&)
311 : : {
312 [ # # ][ # # ]: 0 : if( bObj && nPicLocFc )
313 : 0 : nObjLocFc = nPicLocFc;
314 : 0 : bEmbeddObj = true;
315 : 0 : return FLD_TEXT;
316 : : }
317 : :
318 : 42 : void SwWW8ImplReader::DeleteFormImpl()
319 : : {
320 [ + - ]: 42 : delete pFormImpl, pFormImpl = 0;
321 : 42 : }
322 : :
323 : : //----------------------------------------------------------------------------
324 : : // WW8ListManager oeffentliche Methoden stehen ganz am Ende
325 : : //------------------------- ============ --------------- ============ --------
326 : :
327 : :
328 : :
329 : : // Hilfs-Deklarationen ///////////////////////////////////////////////////////
330 : : //
331 : : // Style Id's for each level
332 : : typedef sal_uInt16 WW8aIdSty[WW8ListManager::nMaxLevel];
333 : : // Zeichenattribute aus GrpprlChpx
334 : : typedef SfxItemSet* WW8aISet[WW8ListManager::nMaxLevel];
335 : : // Zeichen Style Pointer
336 : : typedef SwCharFmt* WW8aCFmt[WW8ListManager::nMaxLevel];
337 : :
338 : : struct WW8LST // nur DIE Eintraege, die WIR benoetigen!
339 : : {
340 : : WW8aIdSty aIdSty; // Style Id's for each level,
341 : : // nIStDNil if no style linked
342 : : sal_uInt32 nIdLst; // Unique List ID
343 : : sal_uInt32 nTplC; // Unique template code - Was ist das bloss?
344 : : sal_uInt8 bSimpleList:1; // Flag: Liste hat nur EINEN Level
345 : : sal_uInt8 bRestartHdn:1; // WW6-Kompatibilitaets-Flag:
346 : : // true if the list should start numbering over
347 : : }; // at the beginning of each section
348 : :
349 : : const sal_uInt32 cbLSTF=28;
350 : :
351 : : struct WW8LFO // nur DIE Eintraege, die WIR benoetigen!
352 : : {
353 : : SwNumRule* pNumRule; // Parent NumRule
354 : : sal_uInt32 nIdLst; // Unique List ID
355 : : sal_uInt8 nLfoLvl; // count of levels whose format is overridden
356 : : bool bSimpleList;
357 : : };
358 : :
359 : : struct WW8LVL // nur DIE Eintraege, die WIR benoetigen!
360 : : {
361 : : sal_Int32 nStartAt; // start at value for this value
362 : : sal_Int32 nV6DxaSpace;// Ver6-Compatible: min Space between Num anf text::Paragraph
363 : : sal_Int32 nV6Indent; // Ver6-Compatible: Breite des Prefix Textes; ggfs. zur
364 : : // Definition d. Erstzl.einzug nutzen!
365 : : // Absatzattribute aus GrpprlPapx
366 : : sal_uInt16 nDxaLeft; // linker Einzug
367 : : short nDxaLeft1; // Erstzeilen-Einzug
368 : :
369 : : sal_uInt8 nNFC; // number format code
370 : : // Offset der Feldkodes im Num-X-String
371 : : sal_uInt8 aOfsNumsXCH[WW8ListManager::nMaxLevel];
372 : : sal_uInt8 nLenGrpprlChpx; // length, in bytes, of the LVL's grpprlChpx
373 : : sal_uInt8 nLenGrpprlPapx; // length, in bytes, of the LVL's grpprlPapx
374 : : sal_uInt8 nAlign: 2; // alignment (left, right, centered) of the number
375 : : sal_uInt8 bLegal: 1; // egal
376 : : sal_uInt8 bNoRest:1; // egal
377 : : sal_uInt8 bV6Prev:1; // Ver6-Compatible: number will include previous levels
378 : : sal_uInt8 bV6PrSp:1; // Ver6-Compatible: egal
379 : : sal_uInt8 bV6: 1; // falls true , beachte die V6-Compatible Eintraege!
380 : : sal_uInt8 bDummy: 1; // (macht das Byte voll)
381 : :
382 : : };
383 : :
384 : : struct WW8LFOLVL
385 : : {
386 : : sal_Int32 nStartAt; // start-at value if bFormat==false and bStartAt == true
387 : : // (if bFormat==true, the start-at is stored in the LVL)
388 : : sal_uInt8 nLevel; // the level to be overridden
389 : : // dieses Byte ist _absichtlich_ nicht in das folgende Byte hineingepackt !!
390 : : // (siehe Kommentar unten bei struct WW8LFOInfo)
391 : :
392 : : sal_uInt8 bStartAt :1; // true if the start-at value is overridden
393 : : sal_uInt8 bFormat :1; // true if the formatting is overriden
394 : :
395 : 6315 : WW8LFOLVL() :
396 : 6315 : nStartAt(1), nLevel(0), bStartAt(1), bFormat(0) {}
397 : : };
398 : :
399 : : // in den ListenInfos zu speichernde Daten ///////////////////////////////////
400 : : //
401 : 693 : struct WW8LSTInfo // sortiert nach nIdLst (in WW8 verwendete Listen-Id)
402 : : {
403 : : std::vector<ww::bytes> maParaSprms;
404 : : WW8aIdSty aIdSty; // Style Id's for each level
405 : : WW8aISet aItemSet; // Zeichenattribute aus GrpprlChpx
406 : : WW8aCFmt aCharFmt; // Zeichen Style Pointer
407 : :
408 : : SwNumRule* pNumRule; // Zeiger auf entsprechende Listenvorlage im Writer
409 : : sal_uInt32 nIdLst; // WW8Id dieser Liste
410 : : sal_uInt8 bSimpleList:1;// Flag, ob diese NumRule nur einen Level verwendet
411 : : sal_uInt8 bUsedInDoc :1;// Flag, ob diese NumRule im Doc verwendet wird,
412 : : // oder beim Reader-Ende geloescht werden sollte
413 : :
414 : 693 : WW8LSTInfo(SwNumRule* pNumRule_, WW8LST& aLST)
415 : : : pNumRule(pNumRule_), nIdLst(aLST.nIdLst),
416 : 693 : bSimpleList(aLST.bSimpleList), bUsedInDoc(0)
417 : : {
418 : 693 : memcpy( aIdSty, aLST.aIdSty, sizeof( aIdSty ));
419 : 693 : memset(&aItemSet, 0, sizeof( aItemSet ));
420 : 693 : memset(&aCharFmt, 0, sizeof( aCharFmt ));
421 : 693 : }
422 : :
423 : : };
424 : :
425 : : // in den ListenFormatOverrideInfos zu speichernde Daten /////////////////////
426 : : //
427 : 699 : struct WW8LFOInfo // unsortiert, d.h. Reihenfolge genau wie im WW8 Stream
428 : : {
429 : : std::vector<ww::bytes> maParaSprms;
430 : : std::vector<WW8LFOLVL> maOverrides;
431 : : SwNumRule* pNumRule; // Zeiger auf entsprechende Listenvorlage im Writer
432 : : // entweder: Liste in LSTInfos oder eigene Liste
433 : : // (im Ctor erstmal die aus den LSTInfos merken)
434 : :
435 : : sal_uInt32 nIdLst; // WW8-Id der betreffenden Liste
436 : : sal_uInt8 nLfoLvl; // count of levels whose format is overridden
437 : : // Ja, ich natuerlich koennten wir nLfoLvl (mittels :4) noch in das folgende
438 : : // Byte mit hineinpacken, doch waere das eine ziemliche Fehlerquelle,
439 : : // an dem Tag, wo MS ihr Listenformat auf mehr als 15 Level aufbohren.
440 : :
441 : : sal_uInt8 bOverride :1;// Flag, ob die NumRule nicht in maLSTInfos steht,
442 : : // sondern fuer pLFOInfos NEU angelegt wurde
443 : : sal_uInt8 bSimpleList:1;// Flag, ob diese NumRule nur einen Level verwendet
444 : : sal_uInt8 bUsedInDoc :1;// Flag, ob diese NumRule im Doc verwendet wird,
445 : : // oder beim Reader-Ende geloescht werden sollte
446 : : sal_uInt8 bLSTbUIDSet :1;// Flag, ob bUsedInDoc in maLSTInfos gesetzt wurde,
447 : : // und nicht nochmals gesetzt zu werden braucht
448 : : WW8LFOInfo(const WW8LFO& rLFO);
449 : : };
450 : :
451 : 699 : WW8LFOInfo::WW8LFOInfo(const WW8LFO& rLFO)
452 : : : maParaSprms(WW8ListManager::nMaxLevel),
453 : : maOverrides(WW8ListManager::nMaxLevel), pNumRule(rLFO.pNumRule),
454 : : nIdLst(rLFO.nIdLst), nLfoLvl(rLFO.nLfoLvl),
455 : : bOverride(rLFO.nLfoLvl ? true : false), bSimpleList(rLFO.bSimpleList),
456 [ + - ]: 699 : bUsedInDoc(0), bLSTbUIDSet(0)
457 : : {
458 : 699 : }
459 : :
460 : :
461 : :
462 : : // Hilfs-Methoden ////////////////////////////////////////////////////////////
463 : : //
464 : :
465 : : // finden der Sprm-Parameter-Daten, falls Sprm im Grpprl enthalten
466 : 13830 : sal_uInt8* WW8ListManager::GrpprlHasSprm(sal_uInt16 nId, sal_uInt8& rSprms,
467 : : sal_uInt8 nLen)
468 : : {
469 : 13830 : return maSprmParser.findSprmData(nId, &rSprms, nLen);
470 : : }
471 : :
472 : : class ListWithId : public std::unary_function<const WW8LSTInfo *, bool>
473 : : {
474 : : private:
475 : : sal_uInt32 mnIdLst;
476 : : public:
477 : 843 : explicit ListWithId(sal_uInt32 nIdLst) : mnIdLst(nIdLst) {}
478 : 21141 : bool operator() (const WW8LSTInfo *pEntry) const
479 : 21141 : { return (pEntry->nIdLst == mnIdLst); }
480 : : };
481 : :
482 : : // Zugriff ueber die List-Id des LST Eintrags
483 : 843 : WW8LSTInfo* WW8ListManager::GetLSTByListId( sal_uInt32 nIdLst ) const
484 : : {
485 : : std::vector<WW8LSTInfo *>::const_iterator aResult =
486 [ + - ]: 843 : std::find_if(maLSTInfos.begin(),maLSTInfos.end(),ListWithId(nIdLst));
487 [ + - ][ - + ]: 843 : if (aResult == maLSTInfos.end())
488 : 0 : return 0;
489 : 843 : return *aResult;
490 : : }
491 : :
492 : 5643 : void lcl_CopyGreaterEight(String &rDest, String &rSrc,
493 : : xub_StrLen nStart, xub_StrLen nLen = STRING_LEN)
494 : : {
495 [ + + ][ - + ]: 5643 : if (nLen > rSrc.Len() || nLen == STRING_LEN)
[ + + ]
496 : 1623 : nLen = rSrc.Len();
497 [ + + ]: 62568 : for (xub_StrLen nI = nStart; nI < nLen; ++nI)
498 : : {
499 : 56925 : sal_Unicode nChar = rSrc.GetChar(nI);
500 [ + + ]: 56925 : if (nChar > WW8ListManager::nMaxLevel)
501 : 32976 : rDest.Append(nChar);
502 : : }
503 : 5643 : }
504 : :
505 : 5877 : bool WW8ListManager::ReadLVL(SwNumFmt& rNumFmt, SfxItemSet*& rpItemSet,
506 : : sal_uInt16 nLevelStyle, bool bSetStartNo,
507 : : std::deque<bool> &rNotReallyThere, sal_uInt16 nLevel,
508 : : ww::bytes &rParaSprms)
509 : : {
510 : 5877 : sal_uInt8 aBits1(0);
511 : 5877 : sal_uInt16 nStartNo(0); // Start-Nr. fuer den Writer
512 : : SvxExtNumType eType; // Writer-Num-Typ
513 : : SvxAdjust eAdj; // Ausrichtung (Links/rechts/zent.)
514 : 5877 : sal_Unicode cBullet(0x2190); // default safe bullet
515 [ + - ]: 5877 : String sPrefix;
516 [ + - ]: 5877 : String sPostfix;
517 : : WW8LVL aLVL;
518 : : //
519 : : // 1. LVLF einlesen
520 : : //
521 : 5877 : memset(&aLVL, 0, sizeof( aLVL ));
522 [ + - ]: 5877 : rSt >> aLVL.nStartAt;
523 [ + - ]: 5877 : rSt >> aLVL.nNFC;
524 [ + - ]: 5877 : rSt >> aBits1;
525 [ - + ]: 5877 : if( 0 != rSt.GetError() ) return false;
526 : 5877 : aLVL.nAlign = (aBits1 & 0x03);
527 [ + + ]: 5877 : if( aBits1 & 0x10 ) aLVL.bV6Prev = true;
528 [ - + ]: 5877 : if( aBits1 & 0x20 ) aLVL.bV6PrSp = true;
529 [ - + ]: 5877 : if( aBits1 & 0x40 ) aLVL.bV6 = true;
530 : 5877 : bool bLVLOkB = true;
531 : 5877 : sal_uInt8 nLevelB = 0;
532 [ + + ]: 58770 : for(nLevelB = 0; nLevelB < nMaxLevel; ++nLevelB)
533 : : {
534 [ + - ]: 52893 : rSt >> aLVL.aOfsNumsXCH[ nLevelB ];
535 [ - + ]: 52893 : if( 0 != rSt.GetError() )
536 : : {
537 : 0 : bLVLOkB = false;
538 : 0 : break;
539 : : }
540 : : }
541 : :
542 [ - + ]: 5877 : if( !bLVLOkB )
543 : 0 : return false;
544 : :
545 : 5877 : sal_uInt8 ixchFollow(0);
546 [ + - ]: 5877 : rSt >> ixchFollow;
547 [ + - ]: 5877 : rSt >> aLVL.nV6DxaSpace;
548 [ + - ]: 5877 : rSt >> aLVL.nV6Indent;
549 [ + - ]: 5877 : rSt >> aLVL.nLenGrpprlChpx;
550 [ + - ]: 5877 : rSt >> aLVL.nLenGrpprlPapx;
551 [ + - ]: 5877 : rSt.SeekRel( 2 );
552 [ - + ]: 5877 : if( 0 != rSt.GetError()) return false;
553 : :
554 : : //
555 : : // 2. ggfs. PAPx einlesen und nach Einzug-Werten suchen
556 : : //
557 : 5877 : short nTabPos = 0; // #i86652# - read tab setting
558 [ + + ]: 5877 : if( aLVL.nLenGrpprlPapx )
559 : : {
560 : : sal_uInt8 aGrpprlPapx[ 255 ];
561 [ + - ][ - + ]: 4584 : if(aLVL.nLenGrpprlPapx != rSt.Read(&aGrpprlPapx,aLVL.nLenGrpprlPapx))
562 : 0 : return false;
563 : : // "sprmPDxaLeft" pap.dxaLeft;dxa;word;
564 : : sal_uInt8* pSprm;
565 [ + - ][ + + ]: 4584 : if (
[ + - ][ + + ]
[ + + ]
566 : 4584 : (0 != (pSprm = GrpprlHasSprm(0x840F,aGrpprlPapx[0],aLVL.nLenGrpprlPapx))) ||
567 : 39 : (0 != (pSprm = GrpprlHasSprm(0x845E,aGrpprlPapx[0],aLVL.nLenGrpprlPapx)))
568 : : )
569 : : {
570 : 4572 : sal_uInt8 *pBegin = pSprm-2;
571 [ + + ]: 22860 : for(int i=0;i<4;++i)
572 [ + - ]: 18288 : rParaSprms.push_back(*pBegin++);
573 : 4572 : short nDxaLeft = SVBT16ToShort( pSprm );
574 : : aLVL.nDxaLeft = (0 < nDxaLeft) ? (sal_uInt16)nDxaLeft
575 [ + - ]: 4572 : : (sal_uInt16)(-nDxaLeft);
576 : : }
577 : :
578 : : // "sprmPDxaLeft1" pap.dxaLeft1;dxa;word;
579 [ + - ][ + + ]: 4584 : if (
[ + - ][ + + ]
[ + + ]
580 : 4584 : (0 != (pSprm = GrpprlHasSprm(0x8411,aGrpprlPapx[0],aLVL.nLenGrpprlPapx)) ) ||
581 : 39 : (0 != (pSprm = GrpprlHasSprm(0x8460,aGrpprlPapx[0],aLVL.nLenGrpprlPapx)) )
582 : : )
583 : : {
584 : 4572 : sal_uInt8 *pBegin = pSprm-2;
585 [ + + ]: 22860 : for(int i=0;i<4;++i)
586 [ + - ]: 18288 : rParaSprms.push_back(*pBegin++);
587 : 4572 : aLVL.nDxaLeft1 = SVBT16ToShort( pSprm );
588 : : }
589 : :
590 : : // #i86652# - read tab setting
591 [ + - ][ + + ]: 4584 : if(0 != (pSprm = GrpprlHasSprm(0xC615,aGrpprlPapx[0],aLVL.nLenGrpprlPapx)) )
592 : : {
593 : 4572 : bool bDone = false;
594 [ + - ]: 4572 : if (*(pSprm-1) == 5)
595 : : {
596 [ + - ]: 4572 : if (*pSprm++ == 0) //nDel
597 : : {
598 [ + - ]: 4572 : if (*pSprm++ == 1) //nIns
599 : : {
600 : 4572 : nTabPos = SVBT16ToShort(pSprm);
601 : 4572 : pSprm+=2;
602 [ + - ]: 4572 : if (*pSprm == 6) //type
603 : : {
604 : 4572 : bDone = true;
605 : : }
606 : : }
607 : : }
608 : : }
609 : : OSL_ENSURE(bDone, "tab setting in numbering is "
610 : : "of unexpected configuration");
611 : : (void)bDone;
612 : : }
613 [ + - ][ - + ]: 4584 : if ( rNumFmt.GetPositionAndSpaceMode() ==
614 : : SvxNumberFormat::LABEL_WIDTH_AND_POSITION )
615 : : {
616 : : // If there is a tab setting with a larger value, then use that.
617 : : // Ideally we would allow tabs to be used in numbering fields and set
618 : : // this on the containing paragraph which would make it actually work
619 : : // most of the time.
620 [ # # ]: 0 : if ( nTabPos != 0 )
621 : : {
622 : 0 : const sal_uInt16 nDesired = aLVL.nDxaLeft + aLVL.nDxaLeft1;
623 : :
624 : 0 : bool bDoAdjust = false;
625 [ # # ]: 0 : if ( nDesired < aLVL.nDxaLeft )
626 : : {
627 [ # # ][ # # ]: 0 : if ( nDesired < nTabPos && nTabPos < aLVL.nDxaLeft )
628 : : {
629 : 0 : bDoAdjust = true;
630 : : }
631 : : }
632 : : else
633 : : {
634 [ # # ][ # # ]: 0 : if ( aLVL.nDxaLeft < nTabPos && nTabPos < nDesired )
635 : : {
636 : 0 : bDoAdjust = true;
637 : : }
638 : : }
639 : :
640 [ # # ]: 0 : if (bDoAdjust)
641 : : {
642 : : aLVL.nDxaLeft = (0 < nTabPos)
643 : : ? (sal_uInt16)nTabPos
644 [ # # ]: 0 : : (sal_uInt16)(-nTabPos);
645 : :
646 : 4584 : aLVL.nDxaLeft1 = nDesired - aLVL.nDxaLeft;
647 : : }
648 : : }
649 : : }
650 : : }
651 : : //
652 : : // 3. ggfs. CHPx einlesen und
653 : : //
654 [ + + ]: 5877 : if( aLVL.nLenGrpprlChpx )
655 : : {
656 : : sal_uInt8 aGrpprlChpx[ 255 ];
657 : 4482 : memset(&aGrpprlChpx, 0, sizeof( aGrpprlChpx ));
658 [ + - ][ - + ]: 4482 : if(aLVL.nLenGrpprlChpx != rSt.Read(&aGrpprlChpx, aLVL.nLenGrpprlChpx))
659 : 0 : return false;
660 : : // neues ItemSet fuer die Zeichenattribute anlegen
661 : 4482 : rpItemSet = new SfxItemSet( rDoc.GetAttrPool(), RES_CHRATR_BEGIN,
662 [ + - ][ + - ]: 4482 : RES_CHRATR_END - 1 );
663 : :
664 : : // Reader-ItemSet-Pointer darauf zeigen lassen
665 : 4482 : rReader.SetAktItemSet( rpItemSet );
666 : : // Reader-Style auf den Style dieses Levels setzen
667 : 4482 : sal_uInt16 nOldColl = rReader.GetNAktColl();
668 : 4482 : sal_uInt16 nNewColl = nLevelStyle;
669 [ + + ]: 4482 : if (ww::stiNil == nNewColl)
670 : 4368 : nNewColl = 0;
671 : 4482 : rReader.SetNAktColl( nNewColl );
672 : :
673 : : // Nun den GrpprlChpx einfach durchnudeln: die Read_xy() Methoden
674 : : // in WW8PAR6.CXX rufen ganz normal ihr NewAttr() oder GetFmtAttr()
675 : : // und diese merken am besetzten Reader-ItemSet-Pointer, dass dieser
676 : : // spezielle ItemSet relevant ist - und nicht ein Stack oder Style!
677 [ + - ]: 4482 : sal_uInt16 nOldFlags1 = rReader.GetToggleAttrFlags();
678 [ + - ]: 4482 : sal_uInt16 nOldFlags2 = rReader.GetToggleBiDiAttrFlags();
679 : :
680 : : WW8SprmIter aSprmIter(&aGrpprlChpx[0], aLVL.nLenGrpprlChpx,
681 [ + - ]: 4482 : maSprmParser);
682 [ + + ]: 10491 : while (const sal_uInt8* pSprm = aSprmIter.GetSprms())
683 : : {
684 [ + - ]: 6009 : rReader.ImportSprm(pSprm);
685 [ + - ]: 6009 : aSprmIter.advance();
686 : : }
687 : :
688 : : // Reader-ItemSet-Pointer und Reader-Style zuruecksetzen
689 : 4482 : rReader.SetAktItemSet( 0 );
690 : 4482 : rReader.SetNAktColl( nOldColl );
691 [ + - ]: 4482 : rReader.SetToggleAttrFlags(nOldFlags1);
692 [ + - ]: 4482 : rReader.SetToggleBiDiAttrFlags(nOldFlags2);
693 : : }
694 : : //
695 : : // 4. den Nummerierungsstring einlesen: ergibt Prefix und Postfix
696 : : //
697 [ + - ]: 5877 : String sNumString(read_uInt16_PascalString(rSt));
698 : :
699 : : //
700 : : // 5. gelesene Werte in Writer Syntax umwandeln
701 : : //
702 [ + - ]: 5877 : if( 0 <= aLVL.nStartAt )
703 : 5877 : nStartNo = (sal_uInt16)aLVL.nStartAt;
704 : :
705 [ + - + - : 5877 : switch( aLVL.nNFC )
+ - + +
+ ]
706 : : {
707 : : case 0:
708 : 5145 : eType = SVX_NUM_ARABIC;
709 : 5145 : break;
710 : : case 1:
711 : 0 : eType = SVX_NUM_ROMAN_UPPER;
712 : 0 : break;
713 : : case 2:
714 : 84 : eType = SVX_NUM_ROMAN_LOWER;
715 : 84 : break;
716 : : case 3:
717 : 0 : eType = SVX_NUM_CHARS_UPPER_LETTER_N;
718 : 0 : break;
719 : : case 4:
720 : 81 : eType = SVX_NUM_CHARS_LOWER_LETTER_N;
721 : 81 : break;
722 : : case 5:
723 : : // eigentlich: ORDINAL
724 : 0 : eType = SVX_NUM_ARABIC;
725 : 0 : break;
726 : : case 23:
727 : : case 25:
728 : 537 : eType = SVX_NUM_CHAR_SPECIAL;
729 : 537 : break;
730 : : case 255:
731 : 27 : eType = SVX_NUM_NUMBER_NONE;
732 : 27 : break;
733 : : default:
734 : : // take default
735 : 3 : eType = SVX_NUM_ARABIC;
736 : 3 : break;
737 : : }
738 : :
739 : : //If a number level is not going to be used, then record this fact
740 [ + + ]: 5877 : if (SVX_NUM_NUMBER_NONE == eType)
741 [ + - ]: 27 : rNotReallyThere[nLevel] = true;
742 : :
743 : : /*
744 : : If a number level was not used (i.e. is in NotReallyThere), and that
745 : : number level appears at one of the positions in the display string of the
746 : : list, then it effectively is not there at all. So remove that level entry
747 : : from a copy of the aOfsNumsXCH.
748 : : */
749 [ + - ]: 5877 : std::vector<sal_uInt8> aOfsNumsXCH;
750 : : typedef std::vector<sal_uInt8>::iterator myIter;
751 [ + - ]: 5877 : aOfsNumsXCH.reserve(nMaxLevel);
752 : :
753 [ + + ]: 58770 : for(nLevelB = 0; nLevelB < nMaxLevel; ++nLevelB)
754 [ + - ]: 52893 : aOfsNumsXCH.push_back(aLVL.aOfsNumsXCH[nLevelB]);
755 : :
756 [ + + ]: 35082 : for(nLevelB = 0; nLevelB <= nLevel; ++nLevelB)
757 : : {
758 [ + - ]: 29205 : sal_uInt8 nPos = aOfsNumsXCH[nLevelB];
759 [ + + ][ + + ]: 29205 : if (nPos && nPos < sNumString.Len() && sNumString.GetChar(nPos-1) < nMaxLevel)
[ + + ][ + + ]
760 : : {
761 [ + - ][ - + ]: 15303 : if (rNotReallyThere[nLevelB])
762 [ # # ]: 0 : aOfsNumsXCH[nLevelB] = 0;
763 : : }
764 : : }
765 [ + - ]: 5877 : myIter aIter = std::remove(aOfsNumsXCH.begin(), aOfsNumsXCH.end(), 0);
766 : 5877 : myIter aEnd = aOfsNumsXCH.end();
767 : : // #i60633# - suppress access on <aOfsNumsXCH.end()>
768 [ + + ][ + - ]: 5877 : if ( aIter != aEnd )
769 : : {
770 : : // Somehow the first removed vector element, at which <aIter>
771 : : // points to, isn't reset to zero.
772 : : // Investigation is needed to clarify why. It seems that only
773 : : // special arrays are handled correctly by this code.
774 [ + - ]: 5460 : ++aIter;
775 [ + - ][ + + ]: 33834 : while (aIter != aEnd)
776 : : {
777 [ + - ]: 28374 : (*aIter) = 0;
778 [ + - ]: 28374 : ++aIter;
779 : : }
780 : : }
781 : :
782 : 5877 : sal_uInt8 nUpperLevel = 0; // akt. Anzeigetiefe fuer den Writer
783 [ + + ]: 58770 : for(nLevelB = 0; nLevelB < nMaxLevel; ++nLevelB)
784 : : {
785 [ + + ][ + - ]: 52893 : if (!nUpperLevel && !aOfsNumsXCH[nLevelB])
[ + + ][ + + ]
786 : 7314 : nUpperLevel = nLevelB;
787 : : }
788 : :
789 : : // falls kein NULL als Terminierungs-Char kam,
790 : : // ist die Liste voller Indices, d.h. alle Plaetze sind besetzt,
791 : : // also sind alle Level anzuzeigen
792 [ + + ]: 5877 : if (!nUpperLevel)
793 : 417 : nUpperLevel = nMaxLevel;
794 : :
795 [ + + ]: 5877 : if (SVX_NUM_CHAR_SPECIAL == eType)
796 : : {
797 [ + - ]: 537 : cBullet = sNumString.Len() ? sNumString.GetChar(0) : 0x2190;
798 : :
799 [ - + ]: 537 : if (!cBullet) // unsave control code?
800 : 0 : cBullet = 0x2190;
801 : : }
802 : : else
803 : : {
804 : : /*
805 : : #i173#
806 : : Our aOfsNumsXCH seems generally to be an array that contains the
807 : : offset into sNumString of locations where the numbers should be
808 : : filled in, so if the first "fill in a number" slot is greater than
809 : : 1 there is a "prefix" before the number
810 : : */
811 : : //First number appears at
812 [ + - ]: 5340 : sal_uInt8 nOneBasedFirstNoIndex = aOfsNumsXCH[0];
813 : : xub_StrLen nFirstNoIndex =
814 [ + + ]: 5340 : nOneBasedFirstNoIndex > 0 ? nOneBasedFirstNoIndex -1 : STRING_LEN;
815 [ + - ]: 5340 : lcl_CopyGreaterEight(sPrefix, sNumString, 0, nFirstNoIndex);
816 : :
817 : : //Next number appears at
818 [ + - ]: 5340 : if (nUpperLevel)
819 : : {
820 [ + - ]: 5340 : sal_uInt8 nOneBasedNextNoIndex = aOfsNumsXCH[nUpperLevel-1];
821 : : xub_StrLen nNextNoIndex =
822 [ + + ]: 5340 : nOneBasedNextNoIndex > 0 ? nOneBasedNextNoIndex -1 : STRING_LEN;
823 [ + + ]: 5340 : if (nNextNoIndex != STRING_LEN)
824 : 4023 : ++nNextNoIndex;
825 [ + + ]: 5340 : if (sNumString.Len() > nNextNoIndex)
826 [ + - ]: 303 : lcl_CopyGreaterEight(sPostfix, sNumString, nNextNoIndex);
827 : : }
828 : :
829 : : /*
830 : : We use lcl_CopyGreaterEight because once if we have removed unused
831 : : number indexes from the aOfsNumsXCH then placeholders remain in
832 : : sNumString which must not be copied into the final numbering strings
833 : : */
834 : : }
835 : :
836 [ + - + - : 5877 : switch( aLVL.nAlign )
- ]
837 : : {
838 : : case 0:
839 : 5796 : eAdj = SVX_ADJUST_LEFT;
840 : 5796 : break;
841 : : case 1:
842 : 0 : eAdj = SVX_ADJUST_CENTER;
843 : 0 : break;
844 : : case 2:
845 : 81 : eAdj = SVX_ADJUST_RIGHT;
846 : 81 : break;
847 : : case 3:
848 : : // Writer here cannot do block justification
849 : 0 : eAdj = SVX_ADJUST_LEFT;
850 : 0 : break;
851 : : default:
852 : : // undefied value
853 : : OSL_ENSURE( !this, "Value of aLVL.nAlign is not supported" );
854 : : // take default
855 : 0 : eAdj = SVX_ADJUST_LEFT;
856 : 0 : break;
857 : : }
858 : :
859 : : // 6. entsprechendes NumFmt konfigurieren
860 [ + - ]: 5877 : if( bSetStartNo )
861 : 5877 : rNumFmt.SetStart( nStartNo );
862 : 5877 : rNumFmt.SetNumberingType( static_cast< sal_Int16 >(eType) );
863 : 5877 : rNumFmt.SetNumAdjust( eAdj );
864 : :
865 [ + + ]: 5877 : if( SVX_NUM_CHAR_SPECIAL == eType )
866 : : {
867 : : // first character of the Prefix-Text is the Bullet
868 : 537 : rNumFmt.SetBulletChar(cBullet);
869 : : // Don't forget: unten, nach dem Bauen eventueller Styles auch noch
870 : : // SetBulletFont() rufen !!!
871 : : }
872 : : else
873 : : {
874 : : // reminder: Garnix ist default Prefix
875 [ + + ]: 5340 : if( sPrefix.Len() )
876 [ + - ]: 3 : rNumFmt.SetPrefix( sPrefix );
877 : : // reminder: Point is default Postfix
878 [ + - ]: 5340 : rNumFmt.SetSuffix( sPostfix );
879 : 5340 : rNumFmt.SetIncludeUpperLevels( nUpperLevel );
880 : : }
881 : :
882 : : // #i89181#
883 [ + - ][ - + ]: 5877 : if ( rNumFmt.GetPositionAndSpaceMode() ==
884 : : SvxNumberFormat::LABEL_WIDTH_AND_POSITION )
885 : : {
886 [ # # ]: 0 : if (eAdj == SVX_ADJUST_RIGHT)
887 : : {
888 : 0 : rNumFmt.SetAbsLSpace(aLVL.nDxaLeft);
889 : 0 : rNumFmt.SetFirstLineOffset(-aLVL.nDxaLeft);
890 : 0 : rNumFmt.SetCharTextDistance(-aLVL.nDxaLeft1);
891 : : }
892 : : else
893 : : {
894 : 0 : rNumFmt.SetAbsLSpace( aLVL.nDxaLeft );
895 : 0 : rNumFmt.SetFirstLineOffset(aLVL.nDxaLeft1);
896 : : }
897 : : }
898 : : else
899 : : {
900 [ + - ]: 5877 : rNumFmt.SetIndentAt( aLVL.nDxaLeft );
901 [ + - ]: 5877 : rNumFmt.SetFirstLineIndent(aLVL.nDxaLeft1);
902 [ + - ]: 5877 : if ( !aLVL.bV6 )
903 [ + - ]: 5877 : rNumFmt.SetListtabPos( nTabPos );
904 : : else
905 [ # # ]: 0 : rNumFmt.SetListtabPos( aLVL.nV6Indent );
906 : 5877 : SvxNumberFormat::LabelFollowedBy eNumLabelFollowedBy = SvxNumberFormat::LISTTAB;
907 [ + - + + ]: 5877 : switch ( ixchFollow )
908 : : {
909 : : case 0:
910 : : {
911 : 5847 : eNumLabelFollowedBy = SvxNumberFormat::LISTTAB;
912 : : }
913 : 5847 : break;
914 : : case 1:
915 : : {
916 : 0 : eNumLabelFollowedBy = SvxNumberFormat::SPACE;
917 : : }
918 : 0 : break;
919 : : case 2:
920 : : {
921 : 27 : eNumLabelFollowedBy = SvxNumberFormat::NOTHING;
922 : : }
923 : 27 : break;
924 : : }
925 [ + - ]: 5877 : rNumFmt.SetLabelFollowedBy( eNumLabelFollowedBy );
926 : : }
927 : :
928 [ + - ][ + - ]: 5877 : return true;
[ + - ]
929 : : }
930 : :
931 : 5901 : void WW8ListManager::AdjustLVL( sal_uInt8 nLevel, SwNumRule& rNumRule,
932 : : WW8aISet& rListItemSet, WW8aCFmt& rCharFmt, bool& bNewCharFmtCreated,
933 : : String sPrefix )
934 : : {
935 : 5901 : bNewCharFmtCreated = false;
936 : : SfxItemSet* pThisLevelItemSet;
937 : : SfxItemSet* pLowerLevelItemSet;
938 : : sal_uInt8 nIdenticalItemSetLevel;
939 : : const SfxPoolItem* pItem;
940 : :
941 [ + - ][ + - ]: 5901 : SwNumFmt aNumFmt = rNumRule.Get( nLevel );
942 : :
943 : 5901 : pThisLevelItemSet = rListItemSet[ nLevel ];
944 : :
945 [ + + ][ + + ]: 5901 : if( pThisLevelItemSet && pThisLevelItemSet->Count())
[ + + ]
946 : : {
947 : 579 : nIdenticalItemSetLevel = nMaxLevel;
948 [ + - ]: 579 : SfxItemIter aIter( *pThisLevelItemSet );
949 [ + + ]: 996 : for (sal_uInt8 nLowerLevel = 0; nLowerLevel < nLevel; ++nLowerLevel)
950 : : {
951 : 786 : pLowerLevelItemSet = rListItemSet[ nLowerLevel ];
952 [ + - + + ]: 1572 : if( pLowerLevelItemSet
[ + + ]
953 : 786 : && (pLowerLevelItemSet->Count() == pThisLevelItemSet->Count()) )
954 : : {
955 : 714 : nIdenticalItemSetLevel = nLowerLevel;
956 : 714 : sal_uInt16 nWhich = aIter.GetCurItem()->Which();
957 : 369 : while (true)
958 : : {
959 [ + - ][ + + ]: 2166 : if( // ggfs. passenden pItem im pLowerLevelItemSet finden
[ + + ]
960 : : (SFX_ITEM_SET != pLowerLevelItemSet->GetItemState(
961 [ + - ]: 1083 : nWhich, false, &pItem ) )
962 : : || // virtuellen "!=" Operator anwenden
963 [ + - ]: 1083 : (*pItem != *aIter.GetCurItem() ) )
964 : : // falls kein Item mit gleicher nWhich gefunden oder Werte
965 : : // der Items ungleich, Ungleichheit merken und abbrechen!
966 : : {
967 : 345 : nIdenticalItemSetLevel = nMaxLevel;
968 : 345 : break;
969 : : }
970 [ + + ]: 738 : if( aIter.IsAtEnd() )
971 : 369 : break;
972 [ + - ]: 369 : nWhich = aIter.NextItem()->Which();
973 : : }
974 : :
975 [ + + ]: 714 : if( nIdenticalItemSetLevel != nMaxLevel )
976 : 369 : break;
977 : : }
978 : : }
979 : :
980 : : SwCharFmt* pFmt;
981 [ + + ]: 579 : if (nMaxLevel == nIdenticalItemSetLevel)
982 : : {
983 : : // Style definieren
984 [ - + ][ + - ]: 210 : String aName( sPrefix.Len() ? sPrefix : rNumRule.GetName() );
985 [ + - ][ + - ]: 210 : (aName += 'z') += String::CreateFromInt32( nLevel );
[ + - ][ + - ]
986 : :
987 : : // const Wegcasten
988 [ + - ]: 210 : pFmt = rDoc.MakeCharFmt(aName, (SwCharFmt*)rDoc.GetDfltCharFmt());
989 : 210 : bNewCharFmtCreated = true;
990 : : // Attribute reinsetzen
991 [ + - ][ + - ]: 210 : pFmt->SetFmtAttr( *pThisLevelItemSet );
992 : : }
993 : : else
994 : : {
995 : : // passenden Style hier anhaengen
996 : 369 : pFmt = rCharFmt[ nIdenticalItemSetLevel ];
997 : : }
998 : :
999 : : // merken
1000 : 579 : rCharFmt[ nLevel ] = pFmt;
1001 : :
1002 : : //
1003 : : // Style an das NumFormat haengen
1004 : : //
1005 [ + - ][ + - ]: 579 : aNumFmt.SetCharFmt( pFmt );
1006 : : }
1007 : : //
1008 : : // ggfs. Bullet Font an das NumFormat haengen
1009 : : //
1010 [ + + ]: 5901 : if( SVX_NUM_CHAR_SPECIAL == aNumFmt.GetNumberingType() )
1011 : : {
1012 : 561 : SwCharFmt* pFmt = aNumFmt.GetCharFmt();
1013 [ + - ]: 561 : Font aFont;
1014 [ - + ]: 561 : if( !pFmt )
1015 : : {
1016 [ # # ][ # # ]: 0 : aFont = numfunc::GetDefBulletFont();
1017 : : }
1018 : : else
1019 : : {
1020 [ + - ]: 561 : const SvxFontItem& rFontItem = pFmt->GetFont();
1021 [ + - ]: 561 : aFont.SetFamily( rFontItem.GetFamily() );
1022 [ + - ][ + - ]: 561 : aFont.SetName( rFontItem.GetFamilyName() );
1023 [ + - ]: 561 : aFont.SetStyleName( rFontItem.GetStyleName() );
1024 [ + - ]: 561 : aFont.SetPitch( rFontItem.GetPitch() );
1025 [ + - ]: 561 : aFont.SetCharSet( rFontItem.GetCharSet() );
1026 : : }
1027 [ + - ][ + - ]: 561 : aNumFmt.SetBulletFont( &aFont );
1028 : : }
1029 : : //
1030 : : // und wieder rein in die NumRule
1031 : : //
1032 [ + - ][ + - ]: 5901 : rNumRule.Set(nLevel, aNumFmt);
1033 : 5901 : }
1034 : :
1035 : 693 : SwNumRule* WW8ListManager::CreateNextRule(bool bSimple)
1036 : : {
1037 : : // wird erstmal zur Bildung des Style Namens genommen
1038 [ + - ]: 693 : String sPrefix(rtl::OUString("WW8Num"));
1039 [ + - ][ + - ]: 693 : sPrefix += String::CreateFromInt32(nUniqueList++);
[ + - ]
1040 : : // #i86652#
1041 : : sal_uInt16 nRul =
1042 : : rDoc.MakeNumRule( rDoc.GetUniqueNumRuleName(&sPrefix), 0, sal_False,
1043 [ + - ][ + - ]: 693 : SvxNumberFormat::LABEL_ALIGNMENT );
[ + - ]
1044 : 693 : SwNumRule* pMyNumRule = rDoc.GetNumRuleTbl()[nRul];
1045 : 693 : pMyNumRule->SetAutoRule(false);
1046 : 693 : pMyNumRule->SetContinusNum(bSimple);
1047 [ + - ]: 693 : return pMyNumRule;
1048 : : }
1049 : :
1050 : : // oeffentliche Methoden /////////////////////////////////////////////////////
1051 : : //
1052 : 102 : WW8ListManager::WW8ListManager(SvStream& rSt_, SwWW8ImplReader& rReader_)
1053 : 102 : : maSprmParser(rReader_.GetFib().GetFIBVersion()), rReader(rReader_),
1054 : 102 : rDoc(rReader.GetDoc()), rFib(rReader.GetFib()), rSt(rSt_),
1055 [ + - ]: 204 : nUniqueList(1)
1056 : : {
1057 : : // LST und LFO gibts erst ab WW8
1058 [ + - ][ + + ]: 102 : if( ( 8 > rFib.nVersion )
[ + + ][ + - ]
1059 : : || ( rFib.fcPlcfLst == rFib.fcPlfLfo )
1060 : : || ( rFib.lcbPlcfLst < 2 )
1061 : : || ( rFib.lcbPlfLfo < 2) ) return; // offensichtlich keine Listen da
1062 : :
1063 : : // Arrays anlegen
1064 : 39 : bool bLVLOk = true;
1065 : :
1066 : 39 : nLastLFOPosition = USHRT_MAX;
1067 : 39 : long nOriginalPos = rSt.Tell();
1068 : : //
1069 : : // 1. PLCF LST auslesen und die Listen Vorlagen im Writer anlegen
1070 : : //
1071 [ + - ]: 39 : bool bOk = checkSeek(rSt, rFib.fcPlcfLst);
1072 : :
1073 [ + - ]: 39 : if (!bOk)
1074 : : return;
1075 : :
1076 : 39 : sal_uInt32 nRemainingPlcfLst = rFib.lcbPlcfLst;
1077 : :
1078 : 39 : sal_uInt16 nListCount(0);
1079 [ + - ]: 39 : rSt >> nListCount;
1080 : 39 : nRemainingPlcfLst -= 2;
1081 : 39 : bOk = nListCount > 0;
1082 : :
1083 [ + - ]: 39 : if (!bOk)
1084 : : return;
1085 : :
1086 : : //
1087 : : // 1.1 alle LST einlesen
1088 : : //
1089 [ + + ]: 732 : for (sal_uInt16 nList=0; nList < nListCount; ++nList)
1090 : : {
1091 [ + - ]: 693 : if (nRemainingPlcfLst < cbLSTF)
1092 : : break;
1093 : :
1094 : : WW8LST aLST;
1095 : 693 : memset(&aLST, 0, sizeof( aLST ));
1096 : :
1097 : : //
1098 : : // 1.1.1 Daten einlesen
1099 : : //
1100 [ + - ]: 693 : rSt >> aLST.nIdLst;
1101 [ + - ]: 693 : rSt >> aLST.nTplC;
1102 [ + + ]: 6930 : for (sal_uInt16 nLevel = 0; nLevel < nMaxLevel; ++nLevel)
1103 [ + - ]: 6237 : rSt >> aLST.aIdSty[ nLevel ];
1104 : :
1105 : 693 : sal_uInt8 aBits1(0);
1106 [ + - ]: 693 : rSt >> aBits1;
1107 : :
1108 [ + - ]: 693 : rSt.SeekRel( 1 );
1109 : :
1110 [ + + ]: 693 : if( aBits1 & 0x01 )
1111 : 45 : aLST.bSimpleList = true;
1112 [ + + ]: 693 : if( aBits1 & 0x02 )
1113 : 3 : aLST.bRestartHdn = true;
1114 : :
1115 : : // 1.1.2 new NumRule inserted in Doc and WW8LSTInfo marked
1116 : :
1117 : : /*
1118 : : #i1869#
1119 : : In word 2000 microsoft got rid of creating new "simple lists" with
1120 : : only 1 level, all new lists are created with 9 levels. To hack it
1121 : : so that the list types formerly known as simple lists still have
1122 : : their own tab page to themselves one of the reserved bits is used
1123 : : to show that a given list is to be in the simple list tabpage.
1124 : : This has now nothing to do with the actual number of list level a
1125 : : list has, only how many will be shown in the user interface.
1126 : :
1127 : : i.e. create a simple list in 2000 and open it in 97 and 97 will
1128 : : claim (correctly) that it is an outline list. We can set our
1129 : : continous flag in these lists to store this information.
1130 : : */
1131 : : SwNumRule* pMyNumRule = CreateNextRule(
1132 [ + + ][ + + ]: 693 : aLST.bSimpleList || (aBits1 & 0x10));
[ + - ]
1133 : :
1134 [ + - ][ + - ]: 693 : WW8LSTInfo* pLSTInfo = new WW8LSTInfo(pMyNumRule, aLST);
1135 [ + - ]: 693 : maLSTInfos.push_back(pLSTInfo);
1136 : :
1137 : 693 : nRemainingPlcfLst -= cbLSTF;
1138 : : }
1139 : :
1140 : : //
1141 : : // 1.2 alle LVL aller aLST einlesen
1142 : : //
1143 : 39 : sal_uInt16 nLSTInfos = static_cast< sal_uInt16 >(maLSTInfos.size());
1144 [ + + ]: 732 : for (sal_uInt16 nList = 0; nList < nLSTInfos; ++nList)
1145 : : {
1146 : 693 : WW8LSTInfo* pListInfo = maLSTInfos[nList];
1147 [ + - ][ + - ]: 693 : if( !pListInfo || !pListInfo->pNumRule ) break;
1148 : 693 : SwNumRule& rMyNumRule = *pListInfo->pNumRule;
1149 : : //
1150 : : // 1.2.1 betreffende(n) LVL(s) fuer diese aLST einlesen
1151 : : //
1152 [ + + ]: 693 : sal_uInt16 nLvlCount = static_cast< sal_uInt16 >(pListInfo->bSimpleList ? nMinLevel : nMaxLevel);
1153 [ + - ]: 693 : std::deque<bool> aNotReallyThere;
1154 [ + - ]: 693 : aNotReallyThere.resize(nMaxLevel);
1155 [ + - ]: 693 : pListInfo->maParaSprms.resize(nMaxLevel);
1156 [ + + ]: 6570 : for (sal_uInt8 nLevel = 0; nLevel < nLvlCount; ++nLevel)
1157 : : {
1158 [ + - ][ + - ]: 5877 : SwNumFmt aNumFmt( rMyNumRule.Get( nLevel ) );
1159 : : // LVLF einlesen
1160 : 5877 : bLVLOk = ReadLVL( aNumFmt, pListInfo->aItemSet[nLevel],
1161 : 5877 : pListInfo->aIdSty[nLevel], true, aNotReallyThere, nLevel,
1162 [ + - ]: 5877 : pListInfo->maParaSprms[nLevel]);
1163 [ - + ]: 5877 : if( !bLVLOk )
1164 : : break;
1165 : : // und in die rMyNumRule aufnehmen
1166 [ + - ][ + - ]: 11754 : rMyNumRule.Set( nLevel, aNumFmt );
1167 [ + - ]: 5877 : }
1168 [ - + ]: 693 : if( !bLVLOk )
1169 : : break;
1170 : : //
1171 : : // 1.2.2 die ItemPools mit den CHPx Einstellungen der verschiedenen
1172 : : // Level miteinander vergleichen und ggfs. Style(s) erzeugen
1173 : : //
1174 [ + + ]: 6570 : for (sal_uInt8 nLevel = 0; nLevel < nLvlCount; ++nLevel)
1175 : : {
1176 : : bool bDummy;
1177 : : AdjustLVL( nLevel, rMyNumRule, pListInfo->aItemSet,
1178 [ + - ][ + - ]: 5877 : pListInfo->aCharFmt, bDummy );
[ + - ]
1179 : : }
1180 : : //
1181 : : // 1.2.3 ItemPools leeren und loeschen
1182 : : //
1183 [ + + ]: 6570 : for (sal_uInt8 nLevel = 0; nLevel < nLvlCount; ++nLevel)
1184 [ + + ][ + - ]: 5877 : delete pListInfo->aItemSet[ nLevel ];
1185 [ + - ]: 693 : }
1186 : :
1187 : : //
1188 : : // 2. PLF LFO auslesen und speichern
1189 : : //
1190 [ + - ]: 39 : bOk = checkSeek(rSt, rFib.fcPlfLfo);
1191 : :
1192 [ + - ]: 39 : if (!bOk)
1193 : : return;
1194 : :
1195 : 39 : sal_Int32 nLfoCount(0);
1196 [ + - ]: 39 : rSt >> nLfoCount;
1197 : 39 : bOk = nLfoCount > 0;
1198 : :
1199 [ + - ]: 39 : if (!bOk)
1200 : : return;
1201 : :
1202 : : //
1203 : : // 2.1 alle LFO einlesen
1204 : : //
1205 [ + + ]: 741 : for (sal_uInt16 nLfo = 0; nLfo < nLfoCount; ++nLfo)
1206 : : {
1207 : 702 : bOk = false;
1208 : :
1209 [ + - ]: 702 : if (rSt.IsEof())
1210 : : break;
1211 : :
1212 : : WW8LFO aLFO;
1213 : 702 : memset(&aLFO, 0, sizeof( aLFO ));
1214 : :
1215 [ + - ]: 702 : rSt >> aLFO.nIdLst;
1216 [ + - ]: 702 : rSt.SeekRel( 8 );
1217 [ + - ]: 702 : rSt >> aLFO.nLfoLvl;
1218 [ + - ]: 702 : rSt.SeekRel( 3 );
1219 : : // soviele Overrides existieren
1220 [ + + ][ - + ]: 702 : if ((nMaxLevel < aLFO.nLfoLvl) || rSt.GetError())
[ + + ]
1221 : : break;
1222 : :
1223 : : // die Parent NumRule der entsprechenden Liste ermitteln
1224 [ + - ]: 699 : WW8LSTInfo* pParentListInfo = GetLSTByListId(aLFO.nIdLst);
1225 [ + - ]: 699 : if (pParentListInfo)
1226 : : {
1227 : : // hier, im ersten Schritt, erst mal diese NumRule festhalten
1228 : 699 : aLFO.pNumRule = pParentListInfo->pNumRule;
1229 : :
1230 : : // hat die Liste mehrere Level ?
1231 : 699 : aLFO.bSimpleList = pParentListInfo->bSimpleList;
1232 : : }
1233 : : // und rein ins Merk-Array mit dem Teil
1234 [ + - ][ + - ]: 699 : WW8LFOInfo* pLFOInfo = new WW8LFOInfo(aLFO);
1235 [ + - ]: 699 : if (pParentListInfo)
1236 : : {
1237 : : //Copy the basic paragraph properties for each level from the
1238 : : //original list into the list format override levels.
1239 : 699 : int nMaxSize = pParentListInfo->maParaSprms.size();
1240 [ + - ]: 699 : pLFOInfo->maParaSprms.resize(nMaxSize);
1241 [ + + ]: 6990 : for (int i = 0; i < nMaxSize; ++i)
1242 [ + - ]: 6291 : pLFOInfo->maParaSprms[i] = pParentListInfo->maParaSprms[i];
1243 : : }
1244 [ + - ]: 699 : pLFOInfos.push_back(pLFOInfo);
1245 : 699 : bOk = true;
1246 : : }
1247 : :
1248 [ + + ]: 39 : if( bOk )
1249 : : {
1250 : : //
1251 : : // 2.2 fuer alle LFO die zugehoerigen LFOLVL einlesen
1252 : : //
1253 : 36 : size_t nLFOInfos = pLFOInfos.size();
1254 [ + + ]: 735 : for (size_t nLfo = 0; nLfo < nLFOInfos; ++nLfo)
1255 : : {
1256 : 699 : bOk = false;
1257 [ + - ]: 699 : WW8LFOInfo& rLFOInfo = pLFOInfos[nLfo];
1258 : : // stehen hierfuer ueberhaupt LFOLVL an ?
1259 [ + + ]: 699 : if( rLFOInfo.bOverride )
1260 : : {
1261 [ + - ]: 3 : WW8LSTInfo* pParentListInfo = GetLSTByListId(rLFOInfo.nIdLst);
1262 [ + - ]: 3 : if (!pParentListInfo)
1263 : : break;
1264 : : //
1265 : : // 2.2.1 eine neue NumRule fuer diese Liste anlegen
1266 : : //
1267 : 3 : SwNumRule* pParentNumRule = rLFOInfo.pNumRule;
1268 : : OSL_ENSURE(pParentNumRule, "ww: Impossible lists, please report");
1269 [ + - ]: 3 : if( !pParentNumRule )
1270 : : break;
1271 : : // Nauemsprefix aufbauen: fuer NumRule-Name (eventuell)
1272 : : // und (falls vorhanden) fuer Style-Name (dann auf jeden Fall)
1273 [ + - ]: 3 : String sPrefix(rtl::OUString("WW8NumSt"));
1274 [ + - ][ + - ]: 3 : sPrefix += String::CreateFromInt32( nLfo + 1 );
[ + - ]
1275 : : // jetzt dem pNumRule seinen RICHTIGEN Wert zuweisen !!!
1276 : : // (bis dahin war hier die Parent NumRule vermerkt )
1277 : : //
1278 : : // Dazu erst mal nachsehen, ob ein Style diesen LFO
1279 : : // referenziert:
1280 [ + - ][ - + ]: 3 : if( USHRT_MAX > rReader.StyleUsingLFO( nLfo ) )
1281 : : {
1282 : : sal_uInt16 nRul = rDoc.MakeNumRule(
1283 [ # # ][ # # ]: 0 : rDoc.GetUniqueNumRuleName( &sPrefix ), pParentNumRule);
[ # # ]
1284 : 0 : rLFOInfo.pNumRule = rDoc.GetNumRuleTbl()[ nRul ];
1285 : 0 : rLFOInfo.pNumRule->SetAutoRule(false);
1286 : : }
1287 : : else
1288 : : {
1289 : : sal_uInt16 nRul = rDoc.MakeNumRule(
1290 [ + - ][ + - ]: 3 : rDoc.GetUniqueNumRuleName(), pParentNumRule);
[ + - ]
1291 : 3 : rLFOInfo.pNumRule = rDoc.GetNumRuleTbl()[ nRul ];
1292 : 3 : rLFOInfo.pNumRule->SetAutoRule(true); // = default
1293 : : }
1294 : : //
1295 : : // 2.2.2 alle LFOLVL (und ggfs. LVL) fuer die neue NumRule
1296 : : // einlesen
1297 : : //
1298 : : WW8aISet aItemSet; // Zeichenattribute aus GrpprlChpx
1299 : : WW8aCFmt aCharFmt; // Zeichen Style Pointer
1300 : 3 : memset(&aItemSet, 0, sizeof( aItemSet ));
1301 : 3 : memset(&aCharFmt, 0, sizeof( aCharFmt ));
1302 : :
1303 : : //2.2.2.0 skip inter-group of override header ?
1304 : : //See #i25438# for why I moved this here, compare
1305 : : //that original bugdoc's binary to what it looks like
1306 : : //when resaved with word, i.e. there is always a
1307 : : //4 byte header, there might be more than one if
1308 : : //that header was 0xFFFFFFFF, e.g. #114412# ?
1309 : : sal_uInt32 nTest;
1310 [ + - ]: 3 : rSt >> nTest;
1311 [ + + ]: 36 : do
1312 : : {
1313 : 36 : nTest = 0;
1314 [ + - ]: 36 : rSt >> nTest;
1315 : : }
1316 : : while (nTest == 0xFFFFFFFF);
1317 [ + - ]: 3 : rSt.SeekRel(-4);
1318 : :
1319 [ + - ]: 3 : std::deque<bool> aNotReallyThere(WW8ListManager::nMaxLevel);
1320 [ + + ]: 27 : for (sal_uInt8 nLevel = 0; nLevel < rLFOInfo.nLfoLvl; ++nLevel)
1321 : : {
1322 : 24 : WW8LFOLVL aLFOLVL;
1323 : 24 : bLVLOk = false;
1324 : :
1325 : : //
1326 : : // 2.2.2.1 den LFOLVL einlesen
1327 : : //
1328 [ + - ]: 24 : rSt >> aLFOLVL.nStartAt;
1329 : 24 : sal_uInt8 aBits1(0);
1330 [ + - ]: 24 : rSt >> aBits1;
1331 [ + - ]: 24 : rSt.SeekRel( 3 );
1332 [ + - ]: 24 : if (rSt.GetError())
1333 : : break;
1334 : :
1335 : : // beachte: Die Witzbolde bei MS quetschen die
1336 : : // Override-Level-Nummer in vier Bits hinein, damit sie
1337 : : // wieder einen Grund haben, ihr Dateiformat zu aendern,
1338 : : // falls ihnen einfaellt, dass sie eigentlich doch gerne
1339 : : // bis zu 16 Listen-Level haetten. Wir tun das *nicht*
1340 : : // (siehe Kommentar oben bei "struct
1341 : : // WW8LFOInfo")
1342 : 24 : aLFOLVL.nLevel = aBits1 & 0x0F;
1343 [ + + ][ + - ]: 24 : if( (0xFF > aBits1) &&
1344 : : (nMaxLevel > aLFOLVL.nLevel) )
1345 : : {
1346 [ - + ]: 15 : if (aBits1 & 0x10)
1347 : 0 : aLFOLVL.bStartAt = true;
1348 : : else
1349 : 15 : aLFOLVL.bStartAt = false;
1350 : : //
1351 : : // 2.2.2.2 eventuell auch den zugehoerigen LVL einlesen
1352 : : //
1353 : : SwNumFmt aNumFmt(
1354 [ + - ][ + - ]: 15 : rLFOInfo.pNumRule->Get(aLFOLVL.nLevel));
1355 [ - + ]: 15 : if (aBits1 & 0x20)
1356 : : {
1357 : 0 : aLFOLVL.bFormat = true;
1358 : : // falls bStartup true, hier den Startup-Level
1359 : : // durch den im LVL vermerkten ersetzen LVLF
1360 : : // einlesen
1361 : 0 : bLVLOk = ReadLVL(aNumFmt, aItemSet[nLevel],
1362 : 0 : pParentListInfo->aIdSty[nLevel],
1363 : : aLFOLVL.bStartAt, aNotReallyThere, nLevel,
1364 [ # # ]: 0 : rLFOInfo.maParaSprms[nLevel]);
1365 : :
1366 [ # # ]: 0 : if (!bLVLOk)
1367 : : break;
1368 : : }
1369 [ - + ]: 15 : else if (aLFOLVL.bStartAt)
1370 : : {
1371 : : aNumFmt.SetStart(
1372 [ # # ]: 0 : writer_cast<sal_uInt16>(aLFOLVL.nStartAt));
1373 : : }
1374 : : //
1375 : : // 2.2.2.3 das NumFmt in die NumRule aufnehmen
1376 : : //
1377 [ + - ][ + - ]: 15 : rLFOInfo.pNumRule->Set(aLFOLVL.nLevel, aNumFmt);
[ + - ]
1378 : : }
1379 : 24 : bLVLOk = true;
1380 : :
1381 [ + + ]: 24 : if (nMaxLevel > aLFOLVL.nLevel)
1382 : 15 : rLFOInfo.maOverrides[aLFOLVL.nLevel] = aLFOLVL;
1383 : : }
1384 [ - + ]: 3 : if( !bLVLOk )
1385 : : break;
1386 : : //
1387 : : // 2.2.3 die LVL der neuen NumRule anpassen
1388 : : //
1389 : 3 : sal_uInt16 aFlagsNewCharFmt = 0;
1390 : 3 : bool bNewCharFmtCreated = false;
1391 [ + + ]: 27 : for (sal_uInt8 nLevel = 0; nLevel < rLFOInfo.nLfoLvl; ++nLevel)
1392 : : {
1393 : : AdjustLVL( nLevel, *rLFOInfo.pNumRule, aItemSet, aCharFmt,
1394 [ + - ][ + - ]: 24 : bNewCharFmtCreated, sPrefix );
[ + - ]
1395 [ - + ]: 24 : if( bNewCharFmtCreated )
1396 : 0 : aFlagsNewCharFmt += (1 << nLevel);
1397 : : }
1398 : : //
1399 : : // 2.2.4 ItemPools leeren und loeschen
1400 : : //
1401 [ + + ]: 27 : for (sal_uInt8 nLevel = 0; nLevel < rLFOInfo.nLfoLvl; ++nLevel)
1402 [ - + ][ # # ]: 24 : delete aItemSet[ nLevel ];
1403 [ - + ][ + - ]: 3 : bOk = true;
[ + - ]
1404 : : }
1405 : : }
1406 : : }
1407 : : // und schon sind wir fertig!
1408 [ + - ]: 102 : rSt.Seek( nOriginalPos );
1409 : : }
1410 : :
1411 [ + - ]: 102 : WW8ListManager::~WW8ListManager()
1412 : : {
1413 : : /*
1414 : : named lists remain in document
1415 : : unused automatic lists are removed from document (DelNumRule)
1416 : : */
1417 [ + - ][ + + ]: 1590 : for(std::vector<WW8LSTInfo *>::iterator aIter = maLSTInfos.begin();
1418 : 795 : aIter != maLSTInfos.end(); ++aIter)
1419 : : {
1420 [ + - ]: 1245 : if ((*aIter)->pNumRule && !(*aIter)->bUsedInDoc &&
[ + + - + ]
[ - + ]
1421 : 552 : (*aIter)->pNumRule->IsAutoRule())
1422 : : {
1423 [ # # ]: 0 : rDoc.DelNumRule((*aIter)->pNumRule->GetName());
1424 : : }
1425 [ + - ]: 693 : delete *aIter;
1426 : : }
1427 [ + - ]: 102 : boost::ptr_vector<WW8LFOInfo >::reverse_iterator aIter;
1428 [ + - ][ + - ]: 1602 : for (aIter = pLFOInfos.rbegin() ;
[ + - ][ + + ]
1429 [ + - ]: 801 : aIter < pLFOInfos.rend();
1430 : : ++aIter )
1431 : : {
1432 [ + - ][ + + ]: 708 : if (aIter->bOverride
[ + - ]
[ + - + - ]
[ + + ]
1433 [ + - ]: 3 : && aIter->pNumRule
1434 [ + - ]: 3 : && !aIter->bUsedInDoc
1435 [ + - ]: 3 : && aIter->pNumRule->IsAutoRule())
1436 : : {
1437 [ + - ][ + - ]: 3 : rDoc.DelNumRule( aIter->pNumRule->GetName() );
1438 : : }
1439 : : }
1440 : 102 : }
1441 : :
1442 : 0 : bool IsEqualFormatting(const SwNumRule &rOne, const SwNumRule &rTwo)
1443 : : {
1444 : : bool bRet =
1445 : : (
1446 : 0 : rOne.GetRuleType() == rTwo.GetRuleType() &&
1447 : 0 : rOne.IsContinusNum() == rTwo.IsContinusNum() &&
1448 : 0 : rOne.IsAbsSpaces() == rTwo.IsAbsSpaces() &&
1449 : 0 : rOne.GetPoolFmtId() == rTwo.GetPoolFmtId() &&
1450 : 0 : rOne.GetPoolHelpId() == rTwo.GetPoolHelpId() &&
1451 : 0 : rTwo.GetPoolHlpFileId() == rTwo.GetPoolHlpFileId()
1452 [ # # # # : 0 : );
# # # # #
# # # ]
1453 : :
1454 [ # # ]: 0 : if (bRet)
1455 : : {
1456 [ # # ]: 0 : for (sal_uInt8 n = 0; n < MAXLEVEL; ++n )
1457 : : {
1458 : : //The SvxNumberFormat compare, not the SwNumFmt compare
1459 : 0 : const SvxNumberFormat &rO = rOne.Get(n);
1460 : 0 : const SvxNumberFormat &rT = rTwo.Get(n);
1461 [ # # ]: 0 : if (!(rO == rT))
1462 : : {
1463 : 0 : bRet = false;
1464 : 0 : break;
1465 : : }
1466 : : }
1467 : : }
1468 : 0 : return bRet;
1469 : : }
1470 : :
1471 : 738 : SwNumRule* WW8ListManager::GetNumRuleForActivation(sal_uInt16 nLFOPosition,
1472 : : const sal_uInt8 nLevel, std::vector<sal_uInt8> &rParaSprms, SwTxtNode *pNode)
1473 : : {
1474 [ + + ]: 738 : if (pLFOInfos.size() <= nLFOPosition)
1475 : 24 : return 0;
1476 : :
1477 [ + - ]: 714 : WW8LFOInfo& rLFOInfo = pLFOInfos[nLFOPosition];
1478 : :
1479 : 714 : bool bFirstUse = !rLFOInfo.bUsedInDoc;
1480 : 714 : rLFOInfo.bUsedInDoc = true;
1481 : :
1482 [ - + ]: 714 : if( !rLFOInfo.pNumRule )
1483 : 0 : return 0;
1484 : :
1485 : : // #i25545#
1486 : : // #i100132# - a number format does not have to exist on given list level
1487 [ + - ][ + - ]: 714 : SwNumFmt pFmt(rLFOInfo.pNumRule->Get(nLevel));
1488 : :
1489 [ + - ][ - + ]: 714 : if (rReader.IsRightToLeft() && nLastLFOPosition != nLFOPosition) {
[ # # ][ - + ]
1490 [ # # ]: 0 : if ( pFmt.GetNumAdjust() == SVX_ADJUST_RIGHT)
1491 : 0 : pFmt.SetNumAdjust(SVX_ADJUST_LEFT);
1492 [ # # ]: 0 : else if ( pFmt.GetNumAdjust() == SVX_ADJUST_LEFT)
1493 : 0 : pFmt.SetNumAdjust(SVX_ADJUST_RIGHT);
1494 [ # # ]: 0 : rLFOInfo.pNumRule->Set(nLevel, pFmt);
1495 : : }
1496 : 714 : nLastLFOPosition = nLFOPosition;
1497 : : /*
1498 : : #i1869#
1499 : : If this list has had its bits set in word 2000 to pretend that it is a
1500 : : simple list from the point of view of the user, then it is almost
1501 : : certainly a simple continous list, and we will try to keep it like that.
1502 : : Otherwise when we save again it will be shown as the true outline list
1503 : : that it is, confusing the user that just wanted what they thought was a
1504 : : simple list. On the otherhand it is possible that some of the other levels
1505 : : were used by the user, in which case we will not pretend anymore that it
1506 : : is a simple list. Something that word 2000 does anyway, that 97 didn't, to
1507 : : my bewilderment.
1508 : : */
1509 [ + + ][ - + ]: 714 : if (nLevel && rLFOInfo.pNumRule->IsContinusNum())
[ - + ]
1510 : 0 : rLFOInfo.pNumRule->SetContinusNum(false);
1511 : :
1512 [ + - ][ + + ]: 714 : if( (!rLFOInfo.bOverride) && (!rLFOInfo.bLSTbUIDSet) )
1513 : : {
1514 [ + - ]: 141 : WW8LSTInfo* pParentListInfo = GetLSTByListId( rLFOInfo.nIdLst );
1515 [ + - ]: 141 : if( pParentListInfo )
1516 : 141 : pParentListInfo->bUsedInDoc = true;
1517 : 141 : rLFOInfo.bLSTbUIDSet = true;
1518 : : }
1519 : :
1520 [ + - ]: 714 : if (rLFOInfo.maParaSprms.size() > nLevel)
1521 [ + - ]: 714 : rParaSprms = rLFOInfo.maParaSprms[nLevel];
1522 : :
1523 : 714 : SwNumRule *pRet = rLFOInfo.pNumRule;
1524 : :
1525 : 714 : bool bRestart(false);
1526 : 714 : sal_uInt16 nStart(0);
1527 : 714 : bool bNewstart(false);
1528 : : /*
1529 : : Note: If you fiddle with this then you have to make sure that #i18322#
1530 : : #i13833#, #i20095# and #112466# continue to work
1531 : :
1532 : : Check if there were overrides for this level
1533 : : */
1534 [ - + ][ # # ]: 714 : if (rLFOInfo.bOverride && nLevel < rLFOInfo.nLfoLvl)
1535 : : {
1536 [ # # ]: 0 : WW8LSTInfo* pParentListInfo = GetLSTByListId(rLFOInfo.nIdLst);
1537 : : OSL_ENSURE(pParentListInfo, "ww: Impossible lists, please report");
1538 [ # # ][ # # ]: 0 : if (pParentListInfo && pParentListInfo->pNumRule)
1539 : : {
1540 : 0 : const WW8LFOLVL &rOverride = rLFOInfo.maOverrides[nLevel];
1541 : : bool bNoChangeFromParent =
1542 [ # # ]: 0 : IsEqualFormatting(*pRet, *(pParentListInfo->pNumRule));
1543 : :
1544 : : //If so then I think word still uses the parent (maybe)
1545 [ # # ]: 0 : if (bNoChangeFromParent)
1546 : : {
1547 : 0 : pRet = pParentListInfo->pNumRule;
1548 : :
1549 : : //did it not affect start at value ?
1550 [ # # ]: 0 : if (bFirstUse)
1551 : : {
1552 [ # # ]: 0 : if (rOverride.bStartAt)
1553 : : {
1554 : : const SwNumFmt &rFmt =
1555 [ # # ]: 0 : pParentListInfo->pNumRule->Get(nLevel);
1556 [ # # ]: 0 : if (
1557 : 0 : rFmt.GetStart() ==
1558 : 0 : rLFOInfo.maOverrides[nLevel].nStartAt
1559 : : )
1560 : : {
1561 : 0 : bRestart = true;
1562 : : }
1563 : : else
1564 : : {
1565 : 0 : bNewstart = true;
1566 : : nStart = writer_cast<sal_uInt16>
1567 [ # # ]: 0 : (rLFOInfo.maOverrides[nLevel].nStartAt);
1568 : : }
1569 : : }
1570 : : }
1571 : :
1572 : 0 : pParentListInfo->bUsedInDoc = true;
1573 : : }
1574 : : }
1575 : : }
1576 : :
1577 [ + + ]: 714 : if (pNode)
1578 : : {
1579 [ + - ]: 627 : pNode->SetAttrListLevel(nLevel);
1580 : :
1581 [ + - ][ - + ]: 627 : if (bRestart || bNewstart)
1582 [ # # ]: 0 : pNode->SetListRestart(true);
1583 [ - + ]: 627 : if (bNewstart)
1584 [ # # ]: 0 : pNode->SetAttrListRestartValue(nStart);
1585 : : }
1586 [ + - ]: 738 : return pRet;
1587 : : }
1588 : :
1589 : : //----------------------------------------------------------------------------
1590 : : // SwWW8ImplReader: anhaengen einer Liste an einen Style oder Absatz
1591 : : //----------------------------------------------------------------------------
1592 : 10962 : bool SwWW8ImplReader::SetTxtFmtCollAndListLevel(const SwPaM& rRg,
1593 : : SwWW8StyInf& rStyleInfo)
1594 : : {
1595 : 10962 : bool bRes = true;
1596 [ + - ][ + - ]: 10962 : if( rStyleInfo.pFmt && rStyleInfo.bColl )
1597 : : {
1598 : 10962 : bRes = rDoc.SetTxtFmtColl(rRg, (SwTxtFmtColl*)rStyleInfo.pFmt)
1599 : 10962 : ? true : false;
1600 : 10962 : SwTxtNode* pTxtNode = pPaM->GetNode()->GetTxtNode();
1601 : : OSL_ENSURE( pTxtNode, "No Text-Node at PaM-Position" );
1602 : : // make code robust
1603 [ - + ]: 10962 : if ( !pTxtNode )
1604 : : {
1605 : 0 : return bRes;
1606 : : }
1607 : :
1608 : 10962 : SwNumRule * pNumRule = pTxtNode->GetNumRule(); // #i27610#
1609 : :
1610 [ + + ][ + + ]: 12207 : if( !IsInvalidOrToBeMergedTabCell() &&
[ + + ]
1611 [ + + ]: 1245 : ! (pNumRule && pNumRule->IsOutlineRule()) ) // #i27610#
1612 : 10746 : pTxtNode->ResetAttr( RES_PARATR_NUMRULE );
1613 : :
1614 [ + + ]: 10962 : if( !rStyleInfo.pOutlineNumrule )
1615 : : {
1616 [ + + ][ + - ]: 10836 : if (
1617 : : (USHRT_MAX > rStyleInfo.nLFOIndex) &&
1618 : : (WW8ListManager::nMaxLevel > rStyleInfo.nListLevel)
1619 : : )
1620 : : {
1621 : : RegisterNumFmtOnTxtNode(rStyleInfo.nLFOIndex,
1622 : 738 : rStyleInfo.nListLevel, false);
1623 : : }
1624 : : }
1625 : : else
1626 : : {
1627 : : // Use outline level set at the style info <rStyleInfo> instead of
1628 : : // the outline level at the text format, because the WW8 document
1629 : : // could contain more than one outline numbering rule and the one
1630 : : // of the text format isn't the one, which a chosen as the Writer
1631 : : // outline rule.
1632 : 126 : pTxtNode->SetAttrListLevel( rStyleInfo.nOutlineLevel );
1633 : : }
1634 : : }
1635 : 10962 : return bRes;
1636 : : }
1637 : :
1638 : 48 : void UseListIndent(SwWW8StyInf &rStyle, const SwNumFmt &rFmt)
1639 : : {
1640 : : // #i86652#
1641 [ - + ]: 48 : if ( rFmt.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_WIDTH_AND_POSITION )
1642 : : {
1643 [ # # ]: 0 : const long nAbsLSpace = rFmt.GetAbsLSpace();
1644 [ # # ]: 0 : const long nListFirstLineIndent = GetListFirstLineIndent(rFmt);
1645 [ # # ][ # # ]: 0 : SvxLRSpaceItem aLR(ItemGet<SvxLRSpaceItem>(*rStyle.pFmt, RES_LR_SPACE));
1646 [ # # ]: 0 : aLR.SetTxtLeft(nAbsLSpace);
1647 [ # # ][ # # ]: 0 : aLR.SetTxtFirstLineOfst(writer_cast<short>(nListFirstLineIndent));
1648 [ # # ]: 0 : rStyle.pFmt->SetFmtAttr(aLR);
1649 [ # # ]: 0 : rStyle.bListReleventIndentSet = true;
1650 : : }
1651 : 48 : }
1652 : :
1653 : 39 : void SetStyleIndent(SwWW8StyInf &rStyle, const SwNumFmt &rFmt)
1654 : : {
1655 [ - + ]: 39 : if ( rFmt.GetPositionAndSpaceMode() == SvxNumberFormat::LABEL_WIDTH_AND_POSITION ) // #i86652#
1656 : : {
1657 [ # # ][ # # ]: 0 : SvxLRSpaceItem aLR(ItemGet<SvxLRSpaceItem>(*rStyle.pFmt, RES_LR_SPACE));
1658 [ # # ]: 0 : if (rStyle.bListReleventIndentSet)
1659 : : {
1660 : :
1661 [ # # ]: 0 : SyncIndentWithList( aLR, rFmt, false, false ); // #i103711#, #i105414#
1662 : : }
1663 : : else
1664 : : {
1665 [ # # ]: 0 : aLR.SetTxtLeft(0);
1666 [ # # ]: 0 : aLR.SetTxtFirstLineOfst(0);
1667 : : }
1668 [ # # ][ # # ]: 0 : rStyle.pFmt->SetFmtAttr(aLR);
1669 : : }
1670 : 39 : }
1671 : :
1672 : 54 : void SwWW8ImplReader::SetStylesList(sal_uInt16 nStyle, sal_uInt16 nActLFO,
1673 : : sal_uInt8 nActLevel)
1674 : : {
1675 [ - + ]: 54 : if (nStyle >= vColl.size())
1676 : 54 : return;
1677 : :
1678 : 54 : SwWW8StyInf &rStyleInf = vColl[nStyle];
1679 [ + - ]: 54 : if (rStyleInf.bValid)
1680 : : {
1681 : : OSL_ENSURE(pAktColl, "Cannot be called outside of style import");
1682 : : // Phase 1: Nummerierungsattribute beim Einlesen einer StyleDef
1683 [ + - ]: 54 : if( pAktColl )
1684 : : {
1685 : : // jetzt nur die Parameter vermerken: die tatsaechliche Liste wird
1686 : : // spaeter drangehaengt, wenn die Listendefinitionen gelesen sind...
1687 [ + - ][ + - ]: 54 : if (
1688 : : (USHRT_MAX > nActLFO) &&
1689 : : (WW8ListManager::nMaxLevel > nActLevel)
1690 : : )
1691 : : {
1692 : 54 : rStyleInf.nLFOIndex = nActLFO;
1693 : 54 : rStyleInf.nListLevel = nActLevel;
1694 [ + + ]: 54 : if (nActLevel > 0) // it must be an outline list
1695 : 24 : rStyleInf.nOutlineLevel = nActLevel;
1696 : :
1697 [ + - ][ + - ]: 54 : if (
1698 : : (USHRT_MAX > nActLFO) &&
1699 : : (WW8ListManager::nMaxLevel > nActLevel)
1700 : : )
1701 : : {
1702 [ + - ]: 54 : std::vector<sal_uInt8> aParaSprms;
1703 : : SwNumRule *pNmRule =
1704 : : pLstManager->GetNumRuleForActivation(nActLFO,
1705 [ + - ]: 54 : nActLevel, aParaSprms);
1706 [ + + ]: 54 : if (pNmRule)
1707 [ + - ][ + - ]: 54 : UseListIndent(rStyleInf, pNmRule->Get(nActLevel));
1708 : : }
1709 : : }
1710 : : }
1711 : : }
1712 : : }
1713 : :
1714 : 1110 : void SwWW8ImplReader::RegisterNumFmtOnStyle(sal_uInt16 nStyle)
1715 : : {
1716 : :
1717 [ - + ]: 1110 : if (nStyle >= vColl.size())
1718 : 1110 : return;
1719 : :
1720 : 1110 : SwWW8StyInf &rStyleInf = vColl[nStyle];
1721 [ + + ][ + - ]: 1110 : if (rStyleInf.bValid && rStyleInf.pFmt)
1722 : : {
1723 : : //Save old pre-list modified indent, which are the word indent values
1724 : : rStyleInf.maWordLR =
1725 : 996 : ItemGet<SvxLRSpaceItem>(*rStyleInf.pFmt, RES_LR_SPACE);
1726 : :
1727 : : // Phase 2: aktualisieren der StyleDef nach einlesen aller Listen
1728 : 996 : SwNumRule* pNmRule = 0;
1729 : 996 : sal_uInt16 nLFO = rStyleInf.nLFOIndex;
1730 : 996 : sal_uInt8 nLevel = rStyleInf.nListLevel;
1731 [ + - ][ + + ]: 996 : if (
1732 : : (USHRT_MAX > nLFO) &&
1733 : : (WW8ListManager::nMaxLevel > nLevel)
1734 : : )
1735 : : {
1736 [ + - ]: 45 : std::vector<sal_uInt8> aParaSprms;
1737 : : pNmRule = pLstManager->GetNumRuleForActivation(nLFO, nLevel,
1738 [ + - ]: 45 : aParaSprms);
1739 : :
1740 [ + + ]: 45 : if (pNmRule)
1741 : : {
1742 [ + + ]: 39 : if( MAXLEVEL > rStyleInf.nOutlineLevel )
1743 : 33 : rStyleInf.pOutlineNumrule = pNmRule;
1744 : : else
1745 : : {
1746 : : rStyleInf.pFmt->SetFmtAttr(
1747 [ + - ][ + - ]: 6 : SwNumRuleItem( pNmRule->GetName() ) );
[ + - ]
1748 : 6 : rStyleInf.bHasStyNumRule = true;
1749 : : }
1750 : 45 : }
1751 : : }
1752 : :
1753 [ + + ]: 996 : if (pNmRule)
1754 : 39 : SetStyleIndent(rStyleInf, pNmRule->Get(nLevel));
1755 : : }
1756 : : }
1757 : :
1758 : 1377 : void SwWW8ImplReader::RegisterNumFmtOnTxtNode(sal_uInt16 nActLFO,
1759 : : sal_uInt8 nActLevel, bool bSetAttr)
1760 : : {
1761 : : // beachte: die Methode haengt die NumRule an den Text Node, falls
1762 : : // bSetAttr (dann muessen natuerlich vorher die Listen gelesen sein)
1763 : : // stellt sie NUR den Level ein, im Vertrauen darauf, dass am STYLE eine
1764 : : // NumRule haengt - dies wird NICHT ueberprueft !!!
1765 : :
1766 [ + - ]: 1377 : if (pLstManager) // sind die Listendeklarationen gelesen?
1767 : : {
1768 : 1377 : SwTxtNode* pTxtNd = pPaM->GetNode()->GetTxtNode();
1769 : : OSL_ENSURE(pTxtNd, "No Text-Node at PaM-Position");
1770 [ + - ]: 1377 : if (!pTxtNd)
1771 : 1377 : return;
1772 : :
1773 [ + - ]: 1377 : std::vector<sal_uInt8> aParaSprms;
1774 : : const SwNumRule* pRule = bSetAttr ?
1775 : : pLstManager->GetNumRuleForActivation( nActLFO, nActLevel,
1776 [ + + ][ + - ]: 1377 : aParaSprms, pTxtNd) : 0;
1777 : :
1778 [ + + ][ + + ]: 1377 : if (pRule || !bSetAttr)
1779 : : {
1780 : : //#i24136# old is the same as new, and its the outline numbering,
1781 : : //then we don't set the numrule again, and we just take the num node
1782 : : //(the actual outline numbering gets set in SetOutlineNum)
1783 : : using namespace sw::util;
1784 : 1365 : bool bUnchangedOutlineNumbering = false;
1785 : : /*
1786 : : If the node is outline numbered, and the new numbering to apply
1787 : : is the one that was chosen to be the outline numbering then all
1788 : : is unchanged
1789 : : */
1790 : : // correct condition according to the above given comment.
1791 [ + - ][ - + ]: 1365 : if ( pTxtNd->GetNumRule() == rDoc.GetOutlineNumRule() &&
[ # # ][ - + ]
1792 : : pRule == mpChosenOutlineNumRule )
1793 : : {
1794 : 0 : bUnchangedOutlineNumbering = true;
1795 : : }
1796 [ + - ]: 1365 : if (!bUnchangedOutlineNumbering)
1797 : : {
1798 : : //If its normal numbering, see if its the same as it already
1799 : : //was, if its not, and we have been asked to set it, then set
1800 : : //it to the new one
1801 [ + + ]: 1365 : if (bSetAttr)
1802 : : {
1803 [ + - ]: 627 : const SwNumRule *pNormal = pTxtNd->GetNumRule();
1804 [ + - ]: 627 : if (pNormal != pRule)
1805 : : {
1806 : : pTxtNd->SetAttr
1807 [ + - ][ + - ]: 627 : (SwNumRuleItem(pRule->GetName()));
[ + - ]
1808 : : }
1809 : : }
1810 : : }
1811 [ + - ]: 1365 : pTxtNd->SetAttrListLevel(nActLevel);
1812 : :
1813 : : // <IsCounted()> state of text node has to be adjusted accordingly.
1814 [ + - ]: 1365 : if ( /*nActLevel >= 0 &&*/ nActLevel < MAXLEVEL )
1815 : : {
1816 [ + - ]: 1365 : pTxtNd->SetCountedInList( true );
1817 : : }
1818 : :
1819 : : // #i99822#
1820 : : // Direct application of the list level formatting no longer
1821 : : // needed for list levels of mode LABEL_ALIGNMENT
1822 : 1365 : bool bApplyListLevelIndentDirectlyAtPara( true );
1823 [ + - ][ + + ]: 1365 : if ( pTxtNd->GetNumRule() && nActLevel < MAXLEVEL )
[ + - ][ + + ]
1824 : : {
1825 [ + - ][ + - ]: 1119 : const SwNumFmt& rFmt = pTxtNd->GetNumRule()->Get( nActLevel );
1826 [ + - ][ + - ]: 1119 : if ( rFmt.GetPositionAndSpaceMode() ==
1827 : : SvxNumberFormat::LABEL_ALIGNMENT )
1828 : : {
1829 : 1119 : bApplyListLevelIndentDirectlyAtPara = false;
1830 : : }
1831 : : }
1832 : :
1833 [ + + ]: 1365 : if ( bApplyListLevelIndentDirectlyAtPara )
1834 : : {
1835 : 246 : SfxItemSet aListIndent(rDoc.GetAttrPool(), RES_LR_SPACE,
1836 [ + - ]: 246 : RES_LR_SPACE);
1837 : : const SvxLRSpaceItem *pItem = (const SvxLRSpaceItem*)(
1838 [ + - ]: 246 : GetFmtAttr(RES_LR_SPACE));
1839 : : OSL_ENSURE(pItem, "impossible");
1840 [ + - ]: 246 : if (pItem)
1841 [ + - ]: 246 : aListIndent.Put(*pItem);
1842 : :
1843 : : /*
1844 : : Take the original paragraph sprms attached to this list level
1845 : : formatting and apply them to the paragraph. I'm convinced that
1846 : : this is exactly what word does.
1847 : : */
1848 [ - + ]: 246 : if (short nLen = static_cast< short >(aParaSprms.size()))
1849 : : {
1850 : 0 : SfxItemSet* pOldAktItemSet = pAktItemSet;
1851 : 0 : SetAktItemSet(&aListIndent);
1852 : :
1853 [ # # ]: 0 : sal_uInt8* pSprms1 = &aParaSprms[0];
1854 [ # # ]: 0 : while (0 < nLen)
1855 : : {
1856 [ # # ]: 0 : sal_uInt16 nL1 = ImportSprm(pSprms1);
1857 : 0 : nLen = nLen - nL1;
1858 : 0 : pSprms1 += nL1;
1859 : : }
1860 : :
1861 : 0 : SetAktItemSet(pOldAktItemSet);
1862 : : }
1863 : :
1864 : : const SvxLRSpaceItem *pLR =
1865 [ + - ]: 246 : HasItem<SvxLRSpaceItem>(aListIndent, RES_LR_SPACE);
1866 : : OSL_ENSURE(pLR, "Impossible");
1867 [ + - ]: 246 : if (pLR)
1868 : : {
1869 [ + - ]: 246 : pCtrlStck->NewAttr(*pPaM->GetPoint(), *pLR);
1870 [ + - ]: 246 : pCtrlStck->SetAttr(*pPaM->GetPoint(), RES_LR_SPACE);
1871 [ + - ]: 246 : }
1872 : : }
1873 : 1377 : }
1874 : : }
1875 : : }
1876 : :
1877 : 693 : void SwWW8ImplReader::RegisterNumFmt(sal_uInt16 nActLFO, sal_uInt8 nActLevel)
1878 : : {
1879 : : // sind wir erst beim Einlesen der StyleDef ?
1880 [ + + ]: 693 : if (pAktColl)
1881 : 54 : SetStylesList( nAktColl , nActLFO, nActLevel);
1882 : : else
1883 : 639 : RegisterNumFmtOnTxtNode(nActLFO, nActLevel);
1884 : 693 : }
1885 : :
1886 : 1566 : void SwWW8ImplReader::Read_ListLevel(sal_uInt16, const sal_uInt8* pData,
1887 : : short nLen)
1888 : : {
1889 [ + + ][ - + ]: 1566 : if (pPlcxMan && pPlcxMan->GetDoingDrawTextBox())
[ - + ]
1890 : 0 : return;
1891 : :
1892 [ + + ]: 1566 : if( nLen < 0 )
1893 : : {
1894 : : // aktuelle Liste ist hier zu Ende, was ist zu tun ???
1895 : 756 : nListLevel = WW8ListManager::nMaxLevel;
1896 [ + - ][ + - ]: 756 : if (pStyles && !bVer67)
1897 : 756 : pStyles->nWwNumLevel = 0;
1898 : : }
1899 : : else
1900 : : {
1901 : : // Sicherheitspruefung auf NIL Pointer
1902 [ - + ]: 810 : if( !pData ) return;
1903 : : // die Streamdaten sind hier Null basiert, so wie wir es brauchen
1904 : 810 : nListLevel = *pData;
1905 : :
1906 [ + - ][ + - ]: 810 : if (pStyles && !bVer67)
1907 : : {
1908 : : /*
1909 : : if this is the case, then if the numbering is actually stored in
1910 : : winword 6 format, and its likely that sprmPIlvl has been abused
1911 : : to set the ww6 list level information which we will need when we
1912 : : reach the true ww6 list def. So set it now
1913 : : */
1914 : 810 : pStyles->nWwNumLevel = nListLevel;
1915 : : }
1916 : :
1917 [ - + ]: 810 : if (WW8ListManager::nMaxLevel <= nListLevel )
1918 : 0 : nListLevel = WW8ListManager::nMaxLevel;
1919 [ - + ][ # # ]: 810 : else if
1920 : : (
1921 : : (USHRT_MAX > nLFOPosition) &&
1922 : : (WW8ListManager::nMaxLevel > nListLevel)
1923 : : )
1924 : : {
1925 : 0 : RegisterNumFmt(nLFOPosition, nListLevel);
1926 : 0 : nLFOPosition = USHRT_MAX;
1927 : 1566 : nListLevel = WW8ListManager::nMaxLevel;
1928 : : }
1929 : : }
1930 : : }
1931 : :
1932 : 1566 : void SwWW8ImplReader::Read_LFOPosition(sal_uInt16, const sal_uInt8* pData,
1933 : : short nLen)
1934 : : {
1935 [ + + ][ - + ]: 1566 : if (pPlcxMan && pPlcxMan->GetDoingDrawTextBox())
[ - + ]
1936 : 0 : return;
1937 : :
1938 [ + + ]: 1566 : if( nLen < 0 )
1939 : : {
1940 : : // aktueller Level ist hier zu Ende, was ist zu tun ???
1941 : 756 : nLFOPosition = USHRT_MAX;
1942 : 756 : nListLevel = WW8ListManager::nMaxLevel;
1943 : : }
1944 : : else
1945 : : {
1946 : : // Sicherheitspruefung auf NIL Pointer
1947 [ - + ]: 810 : if( !pData )
1948 : 0 : return;
1949 : 810 : short nData = SVBT16ToShort( pData );
1950 [ + + ]: 810 : if( 0 >= nData )
1951 : : {
1952 : : /*
1953 : : If you have a paragraph in word with left and/or hanging indent
1954 : : and remove its numbering, then the indentation appears to get
1955 : : reset, but not back to the base style, instead its goes to a blank
1956 : : setting.
1957 : : Unless its a broken ww6 list in 97 in which case more hackery is
1958 : : required, some more details about that in
1959 : : ww8par6.cxx#SwWW8ImplReader::Read_LR
1960 : : */
1961 : :
1962 [ - + ]: 117 : if (pAktColl)
1963 : : {
1964 : 0 : pAktColl->SetFmtAttr(*GetDfltAttr( RES_PARATR_NUMRULE));
1965 [ # # ]: 0 : pAktColl->SetFmtAttr(SvxLRSpaceItem(RES_LR_SPACE));
1966 : : }
1967 [ + - ]: 117 : else if (SwTxtNode* pTxtNode = pPaM->GetNode()->GetTxtNode())
1968 : : {
1969 : 117 : pTxtNode->ResetAttr( RES_PARATR_NUMRULE ); // #i54393#
1970 : 117 : pTxtNode->SetCountedInList(false);
1971 : :
1972 : : /*
1973 : : #i24553#
1974 : : Hmm, I can't remove outline numbering on a per txtnode basis,
1975 : : but I can set some normal numbering, and that overrides outline
1976 : : numbering, and then I can say when I come to say that I want no
1977 : : number on the normal numbering rule, that should all work out
1978 : :
1979 : : No special outline number in textnode any more
1980 : : */
1981 [ + + ]: 117 : if (pTxtNode->IsOutline())
1982 : : {
1983 : : // #i54393#
1984 : : // It's not needed to call <SetCounted( false )> again - see above.
1985 : : // #i54393#
1986 : : // Assure that the numbering rule, which is retrieved at
1987 : : // the paragraph is the outline numbering rule, instead of
1988 : : // incorrectly setting the chosen outline rule.
1989 : : // Note: The chosen outline rule doesn't have to correspond
1990 : : // to the outline rule
1991 [ - + ]: 45 : if ( pTxtNode->GetNumRule() != rDoc.GetOutlineNumRule() )
1992 : : {
1993 : : pTxtNode->SetAttr(
1994 [ # # ]: 0 : SwNumRuleItem( rDoc.GetOutlineNumRule()->GetName() ) );
1995 : : }
1996 : : }
1997 : :
1998 [ + - ]: 117 : pCtrlStck->NewAttr(*pPaM->GetPoint(), SvxLRSpaceItem(RES_LR_SPACE));
1999 : 117 : pCtrlStck->SetAttr(*pPaM->GetPoint(), RES_LR_SPACE);
2000 : : }
2001 : 117 : nLFOPosition = USHRT_MAX;
2002 : : }
2003 : : else
2004 : : {
2005 : 693 : nLFOPosition = (sal_uInt16)nData-1;
2006 : : /*
2007 : : If we are a ww8+ style with ww7- style lists then there is a
2008 : : bizarre broken word bug where when the list is removed from a para
2009 : : the ww6 list first line indent still affects the first line
2010 : : indentation. Setting this flag will allow us to recover from this
2011 : : braindeadness
2012 : : */
2013 [ + + ][ - + ]: 693 : if (pAktColl && (nLFOPosition == 2047-1) && nAktColl < vColl.size())
[ # # ][ - + ]
2014 : 0 : vColl[nAktColl].bHasBrokenWW6List = true;
2015 : :
2016 : : // die Streamdaten sind hier 1 basiert, wir ziehen EINS ab
2017 [ + - ]: 693 : if (USHRT_MAX > nLFOPosition)
2018 : : {
2019 [ + - ]: 693 : if (nLFOPosition != 2047-1) //Normal ww8+ list behaviour
2020 : : {
2021 [ - + ]: 693 : if (WW8ListManager::nMaxLevel == nListLevel)
2022 : 0 : nListLevel = 0;
2023 [ + - ]: 693 : else if (WW8ListManager::nMaxLevel > nListLevel)
2024 : : {
2025 : 693 : RegisterNumFmt(nLFOPosition, nListLevel);
2026 : 693 : nLFOPosition = USHRT_MAX;
2027 : 693 : nListLevel = WW8ListManager::nMaxLevel;
2028 : : }
2029 : : }
2030 [ # # ][ # # ]: 0 : else if (pPlcxMan && pPlcxMan->HasParaSprm(0xC63E))
[ # # ]
2031 : : {
2032 : : /*
2033 : : #i8114# Horrific backwards compatible ww7- lists in ww8+
2034 : : docs
2035 : : */
2036 : 1566 : Read_ANLevelNo(13 /*equiv ww7- sprm no*/, &nListLevel, 1);
2037 : : }
2038 : : }
2039 : : }
2040 : : }
2041 : : }
2042 : :
2043 : : // -------------------------------------------------------------------
2044 : : // ------------------------- Reading Controls ------------------------
2045 : : // -------------------------------------------------------------------
2046 : :
2047 : 0 : bool SwWW8ImplReader::ImportFormulaControl(WW8FormulaControl &aFormula,
2048 : : WW8_CP nStart, SwWw8ControlType nWhich )
2049 : : {
2050 : 0 : bool bRet=false;
2051 : : /*
2052 : : * Save the reader state and process the sprms for this anchor cp.
2053 : : * Doing so will set the nPicLocFc to the offset to find the hypertext
2054 : : * data in the data stream.
2055 : : */
2056 : 0 : WW8_CP nEndCp = nStart+1; //Only interested in the single 0x01 character
2057 : :
2058 [ # # ]: 0 : WW8ReaderSave aSave(this,nStart);
2059 : :
2060 : : WW8PLCFManResult aRes;
2061 [ # # ]: 0 : nStart = pPlcxMan->Where();
2062 [ # # ]: 0 : while(nStart <= nEndCp)
2063 : : {
2064 [ # # ][ # # ]: 0 : if ( pPlcxMan->Get(&aRes)
[ # # ][ # # ]
[ # # ]
2065 : : && aRes.pMemPos && aRes.nSprmId )
2066 : : {
2067 : : //only interested in sprms which would set nPicLocFc
2068 [ # # ][ # # ]: 0 : if ( (68 == aRes.nSprmId) || (0x6A03 == aRes.nSprmId) )
2069 : : {
2070 : : Read_PicLoc( aRes.nSprmId, aRes.pMemPos +
2071 [ # # ][ # # ]: 0 : mpSprmParser->DistanceToData(aRes.nSprmId), 4);
2072 : 0 : break;
2073 : : }
2074 : : }
2075 [ # # ]: 0 : pPlcxMan->advance();
2076 [ # # ]: 0 : nStart = pPlcxMan->Where();
2077 : : }
2078 : 0 : sal_uLong nOffset = nPicLocFc;
2079 [ # # ]: 0 : aSave.Restore(this);
2080 : :
2081 : 0 : sal_uLong nOldPos = pDataStream->Tell();
2082 : 0 : WW8_PIC aPic;
2083 [ # # ]: 0 : pDataStream->Seek( nOffset);
2084 [ # # ]: 0 : PicRead( pDataStream, &aPic, bVer67);
2085 : :
2086 [ # # ][ # # ]: 0 : if((aPic.lcb > 0x3A) && !pDataStream->GetError() )
[ # # ]
2087 : : {
2088 [ # # ]: 0 : aFormula.FormulaRead(nWhich,pDataStream);
2089 : 0 : bRet = true;
2090 : : }
2091 : :
2092 : : /*
2093 : : There is a problem with aPic, the WW8_PIC is always used even though it
2094 : : is too big for the WW95 files, it needs to be modified to check the
2095 : : version C.
2096 : : */
2097 [ # # ]: 0 : pDataStream->Seek( nOldPos );
2098 [ # # ]: 0 : return(bRet);
2099 : : }
2100 : :
2101 : 0 : sal_Bool SwMSConvertControls::InsertFormula(WW8FormulaControl &rFormula)
2102 : : {
2103 : 0 : sal_Bool bRet = sal_False;
2104 : :
2105 : : const uno::Reference< lang::XMultiServiceFactory > & rServiceFactory =
2106 [ # # ]: 0 : GetServiceFactory();
2107 : :
2108 [ # # ]: 0 : if(!rServiceFactory.is())
2109 : 0 : return sal_False;
2110 : :
2111 : 0 : awt::Size aSz;
2112 : 0 : uno::Reference< form::XFormComponent> xFComp;
2113 : :
2114 [ # # ][ # # ]: 0 : if (sal_True == (bRet = rFormula.Import(rServiceFactory, xFComp, aSz)))
2115 : : {
2116 : 0 : uno::Reference <drawing::XShape> xShapeRef;
2117 [ # # ][ # # ]: 0 : if (sal_True == (bRet = InsertControl(xFComp, aSz, &xShapeRef, false)))
2118 [ # # ][ # # ]: 0 : GetShapes()->add(xShapeRef);
[ # # ]
2119 : : }
2120 : 0 : return bRet;
2121 : : }
2122 : :
2123 : 0 : void WW8FormulaControl::FormulaRead(SwWw8ControlType nWhich,
2124 : : SvStream *pDataStream)
2125 : : {
2126 : : sal_uInt8 nField;
2127 : : // nHeaderBype == version
2128 : : sal_uInt32 nHeaderByte;
2129 : :
2130 : : // The following is a FFData structure as described in
2131 : : // Microsoft's DOC specification (chapter 2.9.78)
2132 : :
2133 [ # # ]: 0 : *pDataStream >> nHeaderByte;
2134 : :
2135 : : // might be better to read the bits as a 16 bit word
2136 : : // ( like it is in the spec. )
2137 : : sal_uInt8 bits1;
2138 [ # # ]: 0 : *pDataStream >> bits1;
2139 : : sal_uInt8 bits2;
2140 [ # # ]: 0 : *pDataStream >> bits2;
2141 : :
2142 : 0 : sal_uInt8 iType = ( bits1 & 0x3 );
2143 : :
2144 : : // we should verify that bits.iType & nWhich concur
2145 : : OSL_ENSURE( iType == nWhich, "something wrong, expect control type read from stream doesn't match nWhich passed in");
2146 [ # # ]: 0 : if ( !( iType == nWhich ) )
2147 : 0 : return; // bail out
2148 : :
2149 : 0 : sal_uInt8 iRes = (bits1 & 0x7C) >> 2;
2150 : :
2151 : : sal_uInt16 cch;
2152 [ # # ]: 0 : *pDataStream >> cch;
2153 : :
2154 : : sal_uInt16 hps;
2155 [ # # ]: 0 : *pDataStream >> hps;
2156 : :
2157 : : // xstzName
2158 [ # # ][ # # ]: 0 : sTitle = read_uInt16_BeltAndBracesString(*pDataStream);
[ # # ]
2159 : :
2160 [ # # ]: 0 : if (nWhich == WW8_CT_EDIT)
2161 : : { // Field is a textbox
2162 : : // Default text
2163 : : // xstzTextDef
2164 [ # # ][ # # ]: 0 : sDefault = read_uInt16_BeltAndBracesString(*pDataStream);
[ # # ]
2165 : : }
2166 : : else
2167 : : {
2168 : : // CheckBox or ComboBox
2169 : 0 : sal_uInt16 wDef = 0;
2170 [ # # ]: 0 : *pDataStream >> wDef;
2171 : 0 : nChecked = wDef; // default
2172 [ # # ]: 0 : if (nWhich == WW8_CT_CHECKBOX)
2173 : : {
2174 [ # # ]: 0 : if ( iRes != 25 )
2175 : 0 : nChecked = iRes;
2176 [ # # ][ # # ]: 0 : sDefault = ( wDef == 0 ) ? rtl::OUString( "0" ) : rtl::OUString( "1" );
[ # # ]
2177 : : }
2178 : : }
2179 : : // xstzTextFormat
2180 [ # # ][ # # ]: 0 : sFormatting = read_uInt16_BeltAndBracesString(*pDataStream);
[ # # ]
2181 : : // xstzHelpText
2182 [ # # ][ # # ]: 0 : sHelp = read_uInt16_BeltAndBracesString(*pDataStream);
[ # # ]
2183 : : // xstzStatText
2184 [ # # ][ # # ]: 0 : sToolTip = read_uInt16_BeltAndBracesString(*pDataStream);
[ # # ]
2185 : :
2186 [ # # ]: 0 : String sEntryMacro = read_uInt16_BeltAndBracesString(*pDataStream);
2187 [ # # ]: 0 : String sExitMcr = read_uInt16_BeltAndBracesString(*pDataStream);
2188 : :
2189 [ # # ]: 0 : if (nWhich == WW8_CT_DROPDOWN)
2190 : : {
2191 : 0 : bool bAllOk = true;
2192 : : // SSTB (see Spec. 2.2.4)
2193 : : sal_uInt16 fExtend;
2194 [ # # ]: 0 : *pDataStream >> fExtend;
2195 : : sal_uInt16 nNoStrings;
2196 : :
2197 : : // Isn't it that if fExtend isn't 0xFFFF then fExtend actually
2198 : : // doesn't exist and we really have just read nNoStrings ( or cData )?
2199 [ # # ]: 0 : if (fExtend != 0xFFFF)
2200 : 0 : bAllOk = false;
2201 [ # # ]: 0 : *pDataStream >> nNoStrings;
2202 : :
2203 : : // I guess this should be zero ( and we should ensure that )
2204 : : sal_uInt16 cbExtra;
2205 [ # # ]: 0 : *pDataStream >> cbExtra;
2206 : :
2207 : : OSL_ENSURE(bAllOk,
2208 : : "Unknown formfield dropdown list structure. Report to cmc");
2209 [ # # ]: 0 : if (!bAllOk) //Not as expected, don't risk it at all.
2210 : 0 : nNoStrings = 0;
2211 [ # # ]: 0 : maListEntries.reserve(nNoStrings);
2212 [ # # ]: 0 : for (sal_uInt32 nI = 0; nI < nNoStrings; ++nI)
2213 : : {
2214 [ # # ]: 0 : String sEntry = read_uInt16_PascalString(*pDataStream);
2215 [ # # ][ # # ]: 0 : maListEntries.push_back(sEntry);
2216 [ # # ]: 0 : }
2217 : : }
2218 : 0 : fDropdownIndex = iRes;
2219 : :
2220 : 0 : nField = bits2;
2221 : 0 : fToolTip = nField & 0x01;
2222 : 0 : fNoMark = (nField & 0x02)>>1;
2223 : 0 : fUseSize = (nField & 0x04)>>2;
2224 : 0 : fNumbersOnly= (nField & 0x08)>>3;
2225 : 0 : fDateOnly = (nField & 0x10)>>4;
2226 [ # # ][ # # ]: 0 : fUnused = (nField & 0xE0)>>5;
2227 : : }
2228 : :
2229 : 0 : WW8FormulaListBox::WW8FormulaListBox(SwWW8ImplReader &rR)
2230 [ # # ]: 0 : : WW8FormulaControl(rtl::OUString(SL::aListBox), rR)
2231 : : {
2232 : 0 : }
2233 : :
2234 : : //Miserable hack to get a hardcoded guesstimate of the size of a list dropdown
2235 : : //box's first entry to set as the lists default size
2236 : 0 : awt::Size SwWW8ImplReader::MiserableDropDownFormHack(const String &rString,
2237 : : uno::Reference<beans::XPropertySet>& rPropSet)
2238 : : {
2239 : 0 : awt::Size aRet;
2240 : : struct CtrlFontMapEntry
2241 : : {
2242 : : sal_uInt16 nWhichId;
2243 : : const sal_Char* pPropNm;
2244 : : };
2245 : : const CtrlFontMapEntry aMapTable[] =
2246 : : {
2247 : : { RES_CHRATR_COLOR, "TextColor" },
2248 : : { RES_CHRATR_FONT, "FontName" },
2249 : : { RES_CHRATR_FONTSIZE, "FontHeight" },
2250 : : { RES_CHRATR_WEIGHT, "FontWeight" },
2251 : : { RES_CHRATR_UNDERLINE, "FontUnderline" },
2252 : : { RES_CHRATR_CROSSEDOUT, "FontStrikeout" },
2253 : : { RES_CHRATR_POSTURE, "FontSlant" },
2254 : : { 0, 0 }
2255 : 0 : };
2256 : :
2257 [ # # ]: 0 : Font aFont;
2258 : : uno::Reference< beans::XPropertySetInfo > xPropSetInfo =
2259 [ # # ][ # # ]: 0 : rPropSet->getPropertySetInfo();
2260 : :
2261 : 0 : uno::Any aTmp;
2262 [ # # ]: 0 : for (const CtrlFontMapEntry* pMap = aMapTable; pMap->nWhichId; ++pMap)
2263 : : {
2264 : 0 : bool bSet = true;
2265 [ # # ]: 0 : const SfxPoolItem* pItem = GetFmtAttr( pMap->nWhichId );
2266 : : OSL_ENSURE(pItem, "Impossible");
2267 [ # # ]: 0 : if (!pItem)
2268 : 0 : continue;
2269 : :
2270 [ # # # # : 0 : switch ( pMap->nWhichId )
# # # # ]
2271 : : {
2272 : : case RES_CHRATR_COLOR:
2273 : : {
2274 [ # # ]: 0 : String pNm;
2275 [ # # ][ # # ]: 0 : if (xPropSetInfo->hasPropertyByName(pNm = C2U("TextColor")))
[ # # ][ # # ]
[ # # ][ # # ]
2276 : : {
2277 [ # # ]: 0 : aTmp <<= (sal_Int32)((SvxColorItem*)pItem)->GetValue().GetColor();
2278 [ # # ][ # # ]: 0 : rPropSet->setPropertyValue(pNm, aTmp);
[ # # ]
2279 [ # # ]: 0 : }
2280 : : }
2281 [ # # ]: 0 : aFont.SetColor(((SvxColorItem*)pItem)->GetValue());
2282 : 0 : break;
2283 : : case RES_CHRATR_FONT:
2284 : : {
2285 : 0 : const SvxFontItem *pFontItem = (SvxFontItem *)pItem;
2286 [ # # ]: 0 : String pNm;
2287 [ # # ][ # # ]: 0 : if (xPropSetInfo->hasPropertyByName(pNm = C2U("FontStyleName")))
[ # # ][ # # ]
[ # # ][ # # ]
2288 : : {
2289 [ # # ][ # # ]: 0 : aTmp <<= rtl::OUString( pFontItem->GetStyleName());
2290 [ # # ][ # # ]: 0 : rPropSet->setPropertyValue( pNm, aTmp );
[ # # ]
2291 : : }
2292 [ # # ][ # # ]: 0 : if (xPropSetInfo->hasPropertyByName(pNm = C2U("FontFamily")))
[ # # ][ # # ]
[ # # ][ # # ]
2293 : : {
2294 [ # # ]: 0 : aTmp <<= (sal_Int16)pFontItem->GetFamily();
2295 [ # # ][ # # ]: 0 : rPropSet->setPropertyValue( pNm, aTmp );
[ # # ]
2296 : : }
2297 [ # # ][ # # ]: 0 : if (xPropSetInfo->hasPropertyByName(pNm = C2U("FontCharset")))
[ # # ][ # # ]
[ # # ][ # # ]
2298 : : {
2299 [ # # ]: 0 : aTmp <<= (sal_Int16)pFontItem->GetCharSet();
2300 [ # # ][ # # ]: 0 : rPropSet->setPropertyValue( pNm, aTmp );
[ # # ]
2301 : : }
2302 [ # # ][ # # ]: 0 : if (xPropSetInfo->hasPropertyByName(pNm = C2U("FontPitch")))
[ # # ][ # # ]
[ # # ][ # # ]
2303 : : {
2304 [ # # ]: 0 : aTmp <<= (sal_Int16)pFontItem->GetPitch();
2305 [ # # ][ # # ]: 0 : rPropSet->setPropertyValue( pNm, aTmp );
[ # # ]
2306 : : }
2307 : :
2308 [ # # ][ # # ]: 0 : aTmp <<= rtl::OUString( pFontItem->GetFamilyName());
2309 [ # # ][ # # ]: 0 : aFont.SetName( pFontItem->GetFamilyName() );
2310 [ # # ]: 0 : aFont.SetStyleName( pFontItem->GetStyleName() );
2311 [ # # ]: 0 : aFont.SetFamily( pFontItem->GetFamily() );
2312 [ # # ]: 0 : aFont.SetCharSet( pFontItem->GetCharSet() );
2313 [ # # ][ # # ]: 0 : aFont.SetPitch( pFontItem->GetPitch() );
2314 : : }
2315 : 0 : break;
2316 : :
2317 : : case RES_CHRATR_FONTSIZE:
2318 : : {
2319 [ # # ]: 0 : Size aSize( aFont.GetSize().Width(),
2320 : 0 : ((SvxFontHeightItem*)pItem)->GetHeight() );
2321 [ # # ]: 0 : aTmp <<= ((float)aSize.Height()) / 20.0;
2322 : :
2323 : : aFont.SetSize(OutputDevice::LogicToLogic(aSize, MAP_TWIP,
2324 [ # # ][ # # ]: 0 : MAP_100TH_MM));
[ # # ][ # # ]
[ # # ][ # # ]
2325 : : }
2326 : 0 : break;
2327 : :
2328 : : case RES_CHRATR_WEIGHT:
2329 : : aTmp <<= (float)VCLUnoHelper::ConvertFontWeight(
2330 [ # # ][ # # ]: 0 : ((SvxWeightItem*)pItem)->GetWeight() );
2331 [ # # ]: 0 : aFont.SetWeight( ((SvxWeightItem*)pItem)->GetWeight() );
2332 : 0 : break;
2333 : :
2334 : : case RES_CHRATR_UNDERLINE:
2335 [ # # ]: 0 : aTmp <<= (sal_Int16)(((SvxUnderlineItem*)pItem)->GetLineStyle());
2336 [ # # ]: 0 : aFont.SetUnderline(((SvxUnderlineItem*)pItem)->GetLineStyle());
2337 : 0 : break;
2338 : :
2339 : : case RES_CHRATR_CROSSEDOUT:
2340 [ # # ]: 0 : aTmp <<= (sal_Int16)( ((SvxCrossedOutItem*)pItem)->GetStrikeout() );
2341 [ # # ]: 0 : aFont.SetStrikeout( ((SvxCrossedOutItem*)pItem)->GetStrikeout() );
2342 : 0 : break;
2343 : :
2344 : : case RES_CHRATR_POSTURE:
2345 [ # # ]: 0 : aTmp <<= (sal_Int16)( ((SvxPostureItem*)pItem)->GetPosture() );
2346 [ # # ]: 0 : aFont.SetItalic( ((SvxPostureItem*)pItem)->GetPosture() );
2347 : 0 : break;
2348 : :
2349 : : default:
2350 : 0 : bSet = false;
2351 : 0 : break;
2352 : : }
2353 : :
2354 [ # # ][ # # ]: 0 : if (bSet && xPropSetInfo->hasPropertyByName(rtl::OUString::createFromAscii(pMap->pPropNm)))
[ # # ][ # # ]
[ # # ]
[ # # # # ]
2355 [ # # ][ # # ]: 0 : rPropSet->setPropertyValue(rtl::OUString::createFromAscii(pMap->pPropNm), aTmp);
2356 : : }
2357 : : // now calculate the size of the control
2358 [ # # ]: 0 : OutputDevice* pOut = Application::GetDefaultDevice();
2359 : : OSL_ENSURE(pOut, "Impossible");
2360 [ # # ]: 0 : if (pOut)
2361 : : {
2362 [ # # ]: 0 : pOut->Push( PUSH_FONT | PUSH_MAPMODE );
2363 [ # # ][ # # ]: 0 : pOut->SetMapMode( MapMode( MAP_100TH_MM ));
[ # # ]
2364 [ # # ]: 0 : pOut->SetFont( aFont );
2365 [ # # ]: 0 : aRet.Width = pOut->GetTextWidth(rString);
2366 : 0 : aRet.Width += 500; //plus size of button, total hack territory
2367 [ # # ]: 0 : aRet.Height = pOut->GetTextHeight();
2368 [ # # ]: 0 : pOut->Pop();
2369 : : }
2370 [ # # ]: 0 : return aRet;
2371 : : }
2372 : :
2373 : 0 : sal_Bool WW8FormulaListBox::Import(const uno::Reference <
2374 : : lang::XMultiServiceFactory> &rServiceFactory,
2375 : : uno::Reference <form::XFormComponent> &rFComp,awt::Size &rSz )
2376 : : {
2377 [ # # ]: 0 : uno::Reference<uno::XInterface> xCreate = rServiceFactory->createInstance(
2378 [ # # ][ # # ]: 0 : C2U("com.sun.star.form.component.ComboBox"));
2379 [ # # ]: 0 : if( !xCreate.is() )
2380 : 0 : return sal_False;
2381 : :
2382 [ # # ][ # # ]: 0 : rFComp = uno::Reference<form::XFormComponent>(xCreate, uno::UNO_QUERY);
2383 [ # # ]: 0 : if( !rFComp.is() )
2384 : 0 : return sal_False;
2385 : :
2386 [ # # ]: 0 : uno::Reference<beans::XPropertySet> xPropSet(xCreate, uno::UNO_QUERY);
2387 : :
2388 : 0 : uno::Any aTmp;
2389 [ # # ]: 0 : if (!sTitle.isEmpty())
2390 [ # # ]: 0 : aTmp <<= sTitle;
2391 : : else
2392 [ # # ]: 0 : aTmp <<= sName;
2393 [ # # ][ # # ]: 0 : xPropSet->setPropertyValue(C2U("Name"), aTmp );
[ # # ]
2394 : :
2395 [ # # ]: 0 : if (!sToolTip.isEmpty())
2396 : : {
2397 [ # # ]: 0 : aTmp <<= sToolTip;
2398 [ # # ][ # # ]: 0 : xPropSet->setPropertyValue(C2U("HelpText"), aTmp );
[ # # ]
2399 : : }
2400 : :
2401 : 0 : sal_Bool bDropDown(sal_True);
2402 [ # # ][ # # ]: 0 : xPropSet->setPropertyValue(C2U("Dropdown"), cppu::bool2any(bDropDown));
[ # # ][ # # ]
2403 : :
2404 [ # # ]: 0 : if (!maListEntries.empty())
2405 : : {
2406 : 0 : sal_uInt32 nLen = maListEntries.size();
2407 [ # # ]: 0 : uno::Sequence< ::rtl::OUString > aListSource(nLen);
2408 [ # # ]: 0 : for (sal_uInt32 nI = 0; nI < nLen; ++nI)
2409 [ # # ]: 0 : aListSource[nI] = rtl::OUString(maListEntries[nI]);
2410 [ # # ]: 0 : aTmp <<= aListSource;
2411 [ # # ][ # # ]: 0 : xPropSet->setPropertyValue(C2U("StringItemList"), aTmp );
[ # # ]
2412 : :
2413 [ # # ]: 0 : if (fDropdownIndex < nLen)
2414 : : {
2415 [ # # ][ # # ]: 0 : aTmp <<= aListSource[fDropdownIndex];
2416 : : }
2417 : : else
2418 : : {
2419 [ # # ][ # # ]: 0 : aTmp <<= aListSource[0];
2420 : : }
2421 : :
2422 [ # # ][ # # ]: 0 : xPropSet->setPropertyValue(C2U("DefaultText"), aTmp );
[ # # ]
2423 : :
2424 [ # # ][ # # ]: 0 : rSz = rRdr.MiserableDropDownFormHack(maListEntries[0], xPropSet);
[ # # ][ # # ]
2425 : : }
2426 : : else
2427 : : {
2428 : : static const sal_Unicode aBlank[] =
2429 : : {
2430 : : 0x2002,0x2002,0x2002,0x2002,0x2002
2431 : : };
2432 [ # # ][ # # ]: 0 : rSz = rRdr.MiserableDropDownFormHack(rtl::OUString(aBlank, SAL_N_ELEMENTS(aBlank)), xPropSet);
[ # # ]
2433 : : }
2434 : :
2435 : 0 : return sal_True;
2436 : : }
2437 : :
2438 : 0 : WW8FormulaCheckBox::WW8FormulaCheckBox(SwWW8ImplReader &rR)
2439 [ # # ]: 0 : : WW8FormulaControl(rtl::OUString(SL::aCheckBox), rR)
2440 : : {
2441 : 0 : }
2442 : :
2443 : 0 : static void lcl_AddToPropertyContainer
2444 : : (uno::Reference<beans::XPropertySet> xPropSet,
2445 : : const rtl::OUString & rPropertyName, const rtl::OUString & rValue)
2446 : : {
2447 : : uno::Reference<beans::XPropertySetInfo> xPropSetInfo =
2448 [ # # ][ # # ]: 0 : xPropSet->getPropertySetInfo();
2449 [ # # ][ # # ]: 0 : if (xPropSetInfo.is() &&
[ # # ]
2450 [ # # ][ # # ]: 0 : ! xPropSetInfo->hasPropertyByName(rPropertyName))
2451 : : {
2452 : : uno::Reference<beans::XPropertyContainer>
2453 [ # # ]: 0 : xPropContainer(xPropSet, uno::UNO_QUERY);
2454 [ # # ][ # # ]: 0 : uno::Any aAny(C2U(""));
2455 [ # # ]: 0 : xPropContainer->addProperty
2456 : : (rPropertyName,
2457 : : static_cast<sal_Int16>(beans::PropertyAttribute::BOUND |
2458 : : beans::PropertyAttribute::REMOVABLE),
2459 [ # # ]: 0 : aAny);
2460 : : }
2461 : :
2462 [ # # ]: 0 : uno::Any aAnyValue(rValue);
2463 [ # # ][ # # ]: 0 : xPropSet->setPropertyValue(rPropertyName, aAnyValue );
2464 : 0 : }
2465 : :
2466 : 0 : sal_Bool WW8FormulaCheckBox::Import(const uno::Reference <
2467 : : lang::XMultiServiceFactory> &rServiceFactory,
2468 : : uno::Reference <form::XFormComponent> &rFComp,awt::Size &rSz )
2469 : : {
2470 [ # # ]: 0 : uno::Reference< uno::XInterface > xCreate = rServiceFactory->createInstance(
2471 [ # # ][ # # ]: 0 : C2U("com.sun.star.form.component.CheckBox"));
2472 [ # # ]: 0 : if( !xCreate.is() )
2473 : 0 : return sal_False;
2474 : :
2475 [ # # ][ # # ]: 0 : rFComp = uno::Reference< form::XFormComponent >( xCreate, uno::UNO_QUERY );
2476 [ # # ]: 0 : if( !rFComp.is() )
2477 : 0 : return sal_False;
2478 : :
2479 [ # # ]: 0 : uno::Reference< beans::XPropertySet > xPropSet( xCreate, uno::UNO_QUERY );
2480 : :
2481 : 0 : rSz.Width = 16 * hpsCheckBox;
2482 : 0 : rSz.Height = 16 * hpsCheckBox;
2483 : :
2484 : 0 : uno::Any aTmp;
2485 [ # # ]: 0 : if (!sTitle.isEmpty())
2486 [ # # ]: 0 : aTmp <<= sTitle;
2487 : : else
2488 [ # # ]: 0 : aTmp <<= sName;
2489 [ # # ][ # # ]: 0 : xPropSet->setPropertyValue(C2U("Name"), aTmp );
[ # # ]
2490 : :
2491 [ # # ]: 0 : aTmp <<= (sal_Int16)nChecked;
2492 [ # # ][ # # ]: 0 : xPropSet->setPropertyValue(C2U("DefaultState"), aTmp);
[ # # ]
2493 : :
2494 [ # # ]: 0 : if (!sToolTip.isEmpty())
2495 [ # # ][ # # ]: 0 : lcl_AddToPropertyContainer(xPropSet, C2U("HelpText"), sToolTip);
2496 : :
2497 [ # # ]: 0 : if (!sHelp.isEmpty())
2498 [ # # ][ # # ]: 0 : lcl_AddToPropertyContainer(xPropSet, C2U("HelpF1Text"), sHelp);
2499 : :
2500 : 0 : return sal_True;
2501 : :
2502 : : }
2503 : :
2504 : 0 : WW8FormulaEditBox::WW8FormulaEditBox(SwWW8ImplReader &rR)
2505 [ # # ]: 0 : : WW8FormulaControl(rtl::OUString(SL::aTextField) ,rR)
2506 : : {
2507 : 0 : }
2508 : :
2509 : 3 : sal_Bool SwMSConvertControls::InsertControl(
2510 : : const uno::Reference< form::XFormComponent > & rFComp,
2511 : : const awt::Size& rSize, uno::Reference< drawing::XShape > *pShape,
2512 : : sal_Bool bFloatingCtrl)
2513 : : {
2514 [ + - ]: 3 : const uno::Reference< container::XIndexContainer > &rComps = GetFormComps();
2515 : : uno::Any aTmp( &rFComp, ::getCppuType((const uno::Reference<
2516 [ + - ]: 3 : form::XFormComponent >*)0) );
2517 [ + - ][ + - ]: 3 : rComps->insertByIndex( rComps->getCount(), aTmp );
[ + - ][ + - ]
2518 : :
2519 : : const uno::Reference< lang::XMultiServiceFactory > &rServiceFactory =
2520 [ + - ]: 3 : GetServiceFactory();
2521 [ - + ]: 3 : if( !rServiceFactory.is() )
2522 : 0 : return sal_False;
2523 : :
2524 [ + - ]: 3 : uno::Reference< uno::XInterface > xCreate = rServiceFactory->createInstance(
2525 [ + - ][ + - ]: 3 : C2U("com.sun.star.drawing.ControlShape"));
2526 [ - + ]: 3 : if( !xCreate.is() )
2527 : 0 : return sal_False;
2528 : :
2529 : : uno::Reference< drawing::XShape > xShape =
2530 [ + - ]: 3 : uno::Reference< drawing::XShape >(xCreate, uno::UNO_QUERY);
2531 : :
2532 : : OSL_ENSURE(xShape.is(), "XShape nicht erhalten");
2533 [ + - ][ + - ]: 3 : xShape->setSize(rSize);
2534 : :
2535 : : uno::Reference< beans::XPropertySet > xShapePropSet(
2536 [ + - ]: 3 : xCreate, uno::UNO_QUERY );
2537 : :
2538 : : //I lay a small bet that this will change to
2539 : : //sal_Int16 nTemp=TextContentAnchorType::AS_CHARACTER;
2540 : : sal_Int16 nTemp;
2541 [ + - ]: 3 : if (bFloatingCtrl)
2542 : 3 : nTemp= text::TextContentAnchorType_AT_PARAGRAPH;
2543 : : else
2544 : 0 : nTemp= text::TextContentAnchorType_AS_CHARACTER;
2545 : :
2546 [ + - ]: 3 : aTmp <<= nTemp;
2547 [ + - ][ + - ]: 3 : xShapePropSet->setPropertyValue(C2U("AnchorType"), aTmp );
[ + - ]
2548 : :
2549 : 3 : nTemp= text::VertOrientation::TOP;
2550 [ + - ]: 3 : aTmp <<= nTemp;
2551 [ + - ][ + - ]: 3 : xShapePropSet->setPropertyValue(C2U("VertOrient"), aTmp );
[ + - ]
2552 : :
2553 : 3 : uno::Reference< text::XText > xDummyTxtRef;
2554 : : uno::Reference< text::XTextRange > xTxtRg =
2555 [ + - ][ + - ]: 3 : new SwXTextRange( *pPaM, xDummyTxtRef );
[ + - ]
2556 : :
2557 : : aTmp.setValue(&xTxtRg,::getCppuType((
2558 [ + - ]: 3 : uno::Reference< text::XTextRange >*)0));
2559 [ + - ][ + - ]: 3 : xShapePropSet->setPropertyValue(C2U("TextRange"), aTmp );
[ + - ]
2560 : :
2561 : : // Das Control-Model am Control-Shape setzen
2562 : : uno::Reference< drawing::XControlShape > xControlShape( xShape,
2563 [ + - ]: 3 : uno::UNO_QUERY );
2564 : : uno::Reference< awt::XControlModel > xControlModel( rFComp,
2565 [ + - ]: 3 : uno::UNO_QUERY );
2566 [ + - ][ + - ]: 3 : xControlShape->setControl( xControlModel );
2567 : :
2568 [ + - ]: 3 : if (pShape)
2569 [ + - ]: 3 : *pShape = xShape;
2570 : :
2571 : 3 : return sal_True;
2572 [ + - ][ + - ]: 54 : }
2573 : :
2574 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|