Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 :
21 : #include <hintids.hxx>
22 : #include <svl/urihelper.hxx>
23 : #include <unotools/pathoptions.hxx>
24 : #include <tools/stream.hxx>
25 : #include <sfx2/docfile.hxx>
26 : #include <svl/itemiter.hxx>
27 : #include <editeng/brushitem.hxx>
28 :
29 : #include <tools/resid.hxx>
30 : #include <fmtornt.hxx>
31 : #include <swtypes.hxx> // empty string
32 : #include <wrtsh.hxx>
33 : #include <uinums.hxx>
34 : #include <poolfmt.hxx>
35 : #include <charfmt.hxx>
36 : #include <frmatr.hxx>
37 :
38 : #include <unomid.h>
39 :
40 : using namespace ::com::sun::star;
41 :
42 :
43 : #define VERSION_30B ((sal_uInt16)250)
44 : #define VERSION_31B ((sal_uInt16)326)
45 : #define VERSION_40A ((sal_uInt16)364)
46 : #define VERSION_53A ((sal_uInt16)596)
47 : #define ACT_NUM_VERSION VERSION_53A
48 :
49 : #define CHAPTER_FILENAME "chapter.cfg"
50 :
51 :
52 : // SwNumRulesWithName ----------------------------------------------------
53 : // PUBLIC METHODES -------------------------------------------------------
54 : /*------------------------------------------------------------------------
55 : Description: Saving a rule
56 : Parameter: rCopy -- the rule to save
57 : nIdx -- position, where the rule is to be saved.
58 : An old rule at that position will be overwritten.
59 : ------------------------------------------------------------------------*/
60 :
61 0 : SwBaseNumRules::SwBaseNumRules( const String& rFileName )
62 : :
63 : sFileName( rFileName ),
64 : nVersion(0),
65 0 : bModified( sal_False )
66 : {
67 0 : Init();
68 0 : }
69 :
70 0 : SwBaseNumRules::~SwBaseNumRules()
71 : {
72 0 : if( bModified )
73 : {
74 0 : SvtPathOptions aPathOpt;
75 0 : String sNm( aPathOpt.GetUserConfigPath() );
76 0 : sNm += INET_PATH_TOKEN;
77 0 : sNm += sFileName;
78 0 : INetURLObject aTempObj(sNm);
79 0 : sNm = aTempObj.GetFull();
80 : SfxMedium aStrm( sNm, STREAM_WRITE | STREAM_TRUNC |
81 0 : STREAM_SHARE_DENYALL );
82 0 : Store( *aStrm.GetOutStream() );
83 : }
84 :
85 0 : for( sal_uInt16 i = 0; i < nMaxRules; ++i )
86 0 : delete pNumRules[i];
87 0 : }
88 :
89 0 : void SwBaseNumRules::Init()
90 : {
91 0 : for(sal_uInt16 i = 0; i < nMaxRules; ++i )
92 0 : pNumRules[i] = 0;
93 :
94 0 : OUString sNm( sFileName );
95 0 : SvtPathOptions aOpt;
96 0 : if( aOpt.SearchFile( sNm, SvtPathOptions::PATH_USERCONFIG ))
97 : {
98 0 : SfxMedium aStrm( sNm, STREAM_STD_READ );
99 0 : Load( *aStrm.GetInStream() );
100 0 : }
101 0 : }
102 :
103 0 : void SwBaseNumRules::ApplyNumRules(const SwNumRulesWithName &rCopy, sal_uInt16 nIdx)
104 : {
105 : OSL_ENSURE(nIdx < nMaxRules, "Array der NumRules ueberindiziert.");
106 0 : if( !pNumRules[nIdx] )
107 0 : pNumRules[nIdx] = new SwNumRulesWithName( rCopy );
108 : else
109 0 : *pNumRules[nIdx] = rCopy;
110 0 : }
111 :
112 : // PROTECTED METHODS ----------------------------------------------------
113 0 : sal_Bool SwBaseNumRules::Store(SvStream &rStream)
114 : {
115 0 : rStream << ACT_NUM_VERSION;
116 : // Write, what positions are occupied by a rule
117 : // Then write each of the rules
118 0 : for(sal_uInt16 i = 0; i < nMaxRules; ++i)
119 : {
120 0 : if(pNumRules[i])
121 : {
122 0 : rStream << (unsigned char) sal_True;
123 0 : pNumRules[i]->Store( rStream );
124 : }
125 : else
126 0 : rStream << (unsigned char) sal_False;
127 : }
128 0 : return sal_True;
129 : }
130 :
131 0 : int SwBaseNumRules::Load(SvStream &rStream)
132 : {
133 0 : int rc = 0;
134 :
135 0 : rStream >> nVersion;
136 :
137 : // due to a small but serious mistake, PreFinal writes the same VERION_40A as SP2
138 : // #55402#
139 0 : if(VERSION_40A == nVersion)
140 : {
141 : OSL_FAIL("Version 364 is not clear #55402#");
142 : }
143 0 : else if( VERSION_30B == nVersion || VERSION_31B == nVersion ||
144 0 : ACT_NUM_VERSION >= nVersion )
145 : {
146 0 : unsigned char bRule = sal_False;
147 0 : for(sal_uInt16 i = 0; i < nMaxRules; ++i)
148 : {
149 0 : rStream >> bRule;
150 0 : if(bRule)
151 0 : pNumRules[i] = new SwNumRulesWithName( rStream, nVersion );
152 0 : }
153 : }
154 : else
155 : {
156 0 : rc = 1;
157 : }
158 :
159 0 : return rc;
160 : }
161 :
162 0 : SwChapterNumRules::SwChapterNumRules() :
163 0 : SwBaseNumRules(OUString(CHAPTER_FILENAME))
164 : {
165 0 : }
166 :
167 0 : SwChapterNumRules::~SwChapterNumRules()
168 : {
169 0 : }
170 :
171 0 : void SwChapterNumRules::ApplyNumRules(const SwNumRulesWithName &rCopy, sal_uInt16 nIdx)
172 : {
173 0 : bModified = sal_True;
174 0 : SwBaseNumRules::ApplyNumRules(rCopy, nIdx);
175 0 : }
176 :
177 0 : SwNumRulesWithName::SwNumRulesWithName( const SwNumRule &rCopy,
178 : const String &rName )
179 0 : : maName(rName)
180 : {
181 0 : for( sal_uInt16 n = 0; n < MAXLEVEL; ++n )
182 : {
183 0 : const SwNumFmt* pFmt = rCopy.GetNumFmt( n );
184 0 : if( pFmt )
185 0 : aFmts[ n ] = new _SwNumFmtGlobal( *pFmt );
186 : else
187 0 : aFmts[ n ] = 0;
188 : }
189 0 : }
190 :
191 0 : SwNumRulesWithName::SwNumRulesWithName( const SwNumRulesWithName& rCopy )
192 : {
193 0 : memset( aFmts, 0, sizeof( aFmts ));
194 0 : *this = rCopy;
195 0 : }
196 :
197 0 : SwNumRulesWithName::~SwNumRulesWithName()
198 : {
199 0 : for( int n = 0; n < MAXLEVEL; ++n )
200 0 : delete aFmts[ n ];
201 0 : }
202 :
203 0 : const SwNumRulesWithName& SwNumRulesWithName::operator=(const SwNumRulesWithName &rCopy)
204 : {
205 0 : if( this != &rCopy )
206 : {
207 0 : maName = rCopy.maName;
208 0 : for( int n = 0; n < MAXLEVEL; ++n )
209 : {
210 0 : delete aFmts[ n ];
211 :
212 0 : _SwNumFmtGlobal* pFmt = rCopy.aFmts[ n ];
213 0 : if( pFmt )
214 0 : aFmts[ n ] = new _SwNumFmtGlobal( *pFmt );
215 : else
216 0 : aFmts[ n ] = 0;
217 : }
218 : }
219 0 : return *this;
220 : }
221 :
222 0 : SwNumRulesWithName::SwNumRulesWithName( SvStream &rStream, sal_uInt16 nVersion )
223 : {
224 0 : CharSet eEncoding = osl_getThreadTextEncoding();
225 0 : maName = rStream.ReadUniOrByteString(eEncoding);
226 :
227 : char c;
228 0 : for(sal_uInt16 n = 0; n < MAXLEVEL; ++n )
229 : {
230 0 : if( VERSION_30B == nVersion )
231 0 : c = 1;
232 : // due to a small but serious mistake, PreFinal writes the same VERION_40A as SP2
233 : // #55402#
234 0 : else if(nVersion < VERSION_40A && n > 5)
235 0 : c = 0;
236 : else
237 0 : rStream >> c;
238 :
239 0 : if( c )
240 0 : aFmts[ n ] = new _SwNumFmtGlobal( rStream, nVersion );
241 : else
242 0 : aFmts[ n ] = 0;
243 : }
244 0 : }
245 :
246 0 : void SwNumRulesWithName::MakeNumRule( SwWrtShell& rSh, SwNumRule& rChg ) const
247 : {
248 : // #i89178#
249 0 : rChg = SwNumRule( maName, numfunc::GetDefaultPositionAndSpaceMode() );
250 0 : rChg.SetAutoRule( sal_False );
251 : _SwNumFmtGlobal* pFmt;
252 0 : for( sal_uInt16 n = 0; n < MAXLEVEL; ++n )
253 0 : if( 0 != ( pFmt = aFmts[ n ] ) )
254 : {
255 0 : SwNumFmt aNew;
256 0 : pFmt->ChgNumFmt( rSh, aNew );
257 0 : rChg.Set( n, aNew );
258 : }
259 0 : }
260 :
261 0 : void SwNumRulesWithName::Store( SvStream &rStream )
262 : {
263 0 : CharSet eEncoding = osl_getThreadTextEncoding();
264 0 : rStream.WriteUniOrByteString(maName, eEncoding);
265 :
266 0 : for( sal_uInt16 n = 0; n < MAXLEVEL; ++n )
267 : {
268 0 : _SwNumFmtGlobal* pFmt = aFmts[ n ];
269 0 : if( pFmt )
270 : {
271 0 : rStream << (char)1;
272 0 : pFmt->Store( rStream );
273 : }
274 : else
275 0 : rStream << (char)0;
276 : }
277 0 : }
278 :
279 0 : SwNumRulesWithName::_SwNumFmtGlobal::_SwNumFmtGlobal( const SwNumFmt& rFmt )
280 0 : : aFmt( rFmt ), nCharPoolId( USHRT_MAX )
281 : {
282 : // relative gaps?????
283 :
284 0 : SwCharFmt* pFmt = rFmt.GetCharFmt();
285 0 : if( pFmt )
286 : {
287 0 : sCharFmtName = pFmt->GetName();
288 0 : nCharPoolId = pFmt->GetPoolFmtId();
289 0 : if( pFmt->GetAttrSet().Count() )
290 : {
291 0 : SfxItemIter aIter( pFmt->GetAttrSet() );
292 0 : const SfxPoolItem *pCurr = aIter.GetCurItem();
293 : while( true )
294 : {
295 0 : aItems.push_back( pCurr->Clone() );
296 0 : if( aIter.IsAtEnd() )
297 0 : break;
298 0 : pCurr = aIter.NextItem();
299 0 : }
300 : }
301 :
302 0 : aFmt.SetCharFmt( 0 );
303 : }
304 0 : }
305 :
306 0 : SwNumRulesWithName::_SwNumFmtGlobal::_SwNumFmtGlobal( const _SwNumFmtGlobal& rFmt )
307 : :
308 : aFmt( rFmt.aFmt ),
309 : sCharFmtName( rFmt.sCharFmtName ),
310 0 : nCharPoolId( rFmt.nCharPoolId )
311 : {
312 0 : for( sal_uInt16 n = rFmt.aItems.size(); n; )
313 0 : aItems.push_back( rFmt.aItems[ --n ].Clone() );
314 0 : }
315 :
316 0 : SwNumRulesWithName::_SwNumFmtGlobal::_SwNumFmtGlobal( SvStream& rStream,
317 : sal_uInt16 nVersion )
318 0 : : nCharPoolId( USHRT_MAX )
319 : {
320 0 : CharSet eEncoding = osl_getThreadTextEncoding();
321 : {
322 : sal_uInt16 nUS;
323 : short nShort;
324 : sal_Char cChar;
325 : sal_Bool bFlag;
326 0 : String sStr;
327 :
328 0 : rStream >> nUS; aFmt.SetNumberingType((sal_Int16)nUS );
329 0 : if( VERSION_53A > nVersion )
330 : {
331 0 : rStream >> cChar; aFmt.SetBulletChar( cChar );
332 : }
333 : else
334 : {
335 0 : rStream >> nUS; aFmt.SetBulletChar( nUS );
336 : }
337 :
338 0 : rStream >> bFlag; aFmt.SetIncludeUpperLevels( bFlag );
339 :
340 0 : if( VERSION_30B == nVersion )
341 : {
342 : sal_Int32 nL;
343 0 : rStream >> cChar; aFmt.SetStart( (sal_uInt16)cChar );
344 :
345 0 : sStr = rStream.ReadUniOrByteString(eEncoding);
346 0 : aFmt.SetPrefix( sStr );
347 0 : sStr = rStream.ReadUniOrByteString(eEncoding);
348 0 : aFmt.SetSuffix( sStr );
349 0 : rStream >> nUS; aFmt.SetNumAdjust( SvxAdjust( nUS ) );
350 0 : rStream >> nL; aFmt.SetLSpace( lNumIndent );
351 0 : rStream >> nL; aFmt.SetFirstLineOffset( (short)nL );
352 : }
353 : else // old start-value was a Byte
354 : {
355 0 : rStream >> nUS; aFmt.SetStart( nUS );
356 0 : sStr = rStream.ReadUniOrByteString(eEncoding);
357 0 : aFmt.SetPrefix( sStr );
358 0 : sStr = rStream.ReadUniOrByteString(eEncoding);
359 0 : aFmt.SetSuffix( sStr );
360 0 : rStream >> nUS; aFmt.SetNumAdjust( SvxAdjust( nUS ) );
361 0 : rStream >> nUS; aFmt.SetAbsLSpace( nUS );
362 0 : rStream >> nShort; aFmt.SetFirstLineOffset( nShort );
363 0 : rStream >> nUS; aFmt.SetCharTextDistance( nUS );
364 0 : rStream >> nShort; aFmt.SetLSpace( nShort );
365 0 : rStream >> bFlag;
366 : }
367 :
368 : sal_uInt16 nFamily;
369 : sal_uInt16 nCharSet;
370 : short nWidth;
371 : short nHeight;
372 : sal_uInt16 nPitch;
373 0 : String aName;
374 :
375 0 : aName = rStream.ReadUniOrByteString(eEncoding);
376 0 : rStream >> nFamily >> nCharSet >> nWidth >> nHeight >> nPitch;
377 :
378 0 : if( aName.Len() )
379 : {
380 0 : Font aFont( static_cast<FontFamily>(nFamily), Size( nWidth, nHeight ) );
381 0 : aFont.SetName( aName );
382 0 : aFont.SetCharSet( (CharSet)nCharSet );
383 0 : aFont.SetPitch( (FontPitch)nPitch );
384 :
385 0 : aFmt.SetBulletFont( &aFont );
386 : }
387 : else
388 0 : nCharSet = RTL_TEXTENCODING_SYMBOL;
389 :
390 0 : if( VERSION_53A > nVersion )
391 : {
392 0 : sal_Char cEncoded(aFmt.GetBulletChar());
393 0 : aFmt.SetBulletChar(OUString(&cEncoded, 1, nCharSet).toChar());
394 0 : }
395 : }
396 :
397 0 : if( VERSION_30B != nVersion )
398 : {
399 : sal_uInt16 nItemCount;
400 0 : rStream >> nCharPoolId;
401 0 : sCharFmtName = rStream.ReadUniOrByteString(eEncoding);
402 0 : rStream >> nItemCount;
403 :
404 0 : while( nItemCount-- )
405 : {
406 : sal_uInt16 nWhich, nVers;
407 0 : rStream >> nWhich >> nVers;
408 0 : aItems.push_back( GetDfltAttr( nWhich )->Create( rStream, nVers ) );
409 : }
410 : }
411 :
412 0 : if( VERSION_40A == nVersion && SVX_NUM_BITMAP == aFmt.GetNumberingType() )
413 : {
414 : sal_uInt8 cF;
415 0 : sal_Int32 nWidth(0), nHeight(0);
416 :
417 0 : rStream >> nWidth >> nHeight;
418 :
419 0 : Size aSz(nWidth, nHeight);
420 :
421 0 : rStream >> cF;
422 0 : if( cF )
423 : {
424 0 : SvxBrushItem* pBrush = 0;
425 0 : SwFmtVertOrient* pVOrient = 0;
426 : sal_uInt16 nVer;
427 :
428 0 : if( cF & 1 )
429 : {
430 0 : rStream >> nVer;
431 0 : pBrush = (SvxBrushItem*)GetDfltAttr( RES_BACKGROUND )
432 0 : ->Create( rStream, nVer );
433 : }
434 :
435 0 : if( cF & 2 )
436 : {
437 0 : rStream >> nVer;
438 0 : pVOrient = (SwFmtVertOrient*)GetDfltAttr( RES_VERT_ORIENT )
439 0 : ->Create( rStream, nVer );
440 : }
441 0 : sal_Int16 eOrient = text::VertOrientation::NONE;
442 0 : if(pVOrient)
443 0 : eOrient = (sal_Int16)pVOrient->GetVertOrient();
444 0 : aFmt.SetGraphicBrush( pBrush, &aSz, pVOrient ? &eOrient : 0 );
445 : }
446 : }
447 0 : }
448 :
449 0 : SwNumRulesWithName::_SwNumFmtGlobal::~_SwNumFmtGlobal()
450 : {
451 0 : }
452 :
453 0 : void SwNumRulesWithName::_SwNumFmtGlobal::Store( SvStream& rStream )
454 : {
455 0 : CharSet eEncoding = osl_getThreadTextEncoding();
456 : {
457 0 : String aName;
458 0 : sal_uInt16 nFamily = FAMILY_DONTKNOW, nCharSet = 0, nPitch = 0;
459 0 : short nWidth = 0, nHeight = 0;
460 :
461 0 : const Font* pFnt = aFmt.GetBulletFont();
462 0 : if( pFnt )
463 : {
464 0 : aName = pFnt->GetName();
465 0 : nFamily = (sal_uInt16)pFnt->GetFamily();
466 0 : nCharSet = (sal_uInt16)pFnt->GetCharSet();
467 0 : nWidth = (short)pFnt->GetSize().Width();
468 0 : nHeight = (short)pFnt->GetSize().Height();
469 0 : nPitch = (sal_uInt16)pFnt->GetPitch();
470 : }
471 :
472 0 : rStream << sal_uInt16(aFmt.GetNumberingType())
473 0 : << aFmt.GetBulletChar()
474 0 : << static_cast<sal_Bool>(aFmt.GetIncludeUpperLevels() > 0)
475 0 : << aFmt.GetStart();
476 0 : rStream.WriteUniOrByteString( aFmt.GetPrefix(), eEncoding );
477 0 : rStream.WriteUniOrByteString( aFmt.GetSuffix(), eEncoding );
478 0 : rStream << sal_uInt16( aFmt.GetNumAdjust() )
479 0 : << aFmt.GetAbsLSpace()
480 0 : << aFmt.GetFirstLineOffset()
481 0 : << aFmt.GetCharTextDistance()
482 0 : << aFmt.GetLSpace()
483 0 : << sal_False;//aFmt.IsRelLSpace();
484 0 : rStream.WriteUniOrByteString( aName, eEncoding );
485 0 : rStream << nFamily
486 0 : << nCharSet
487 0 : << nWidth
488 0 : << nHeight
489 0 : << nPitch;
490 : }
491 0 : rStream << nCharPoolId;
492 0 : rStream.WriteUniOrByteString( sCharFmtName, eEncoding );
493 0 : rStream << static_cast<sal_uInt16>(aItems.size());
494 :
495 0 : for( sal_uInt16 n = aItems.size(); n; )
496 : {
497 0 : SfxPoolItem* pItem = &aItems[ --n ];
498 0 : sal_uInt16 nIVers = pItem->GetVersion( SOFFICE_FILEFORMAT_50 );
499 : OSL_ENSURE( nIVers != USHRT_MAX,
500 : "Was'n das: Item-Version USHRT_MAX in der aktuellen Version" );
501 0 : rStream << pItem->Which()
502 0 : << nIVers;
503 0 : pItem->Store( rStream, nIVers );
504 : }
505 :
506 : // Extensions for 40A
507 :
508 0 : if( SVX_NUM_BITMAP == aFmt.GetNumberingType() )
509 : {
510 0 : rStream << (sal_Int32)aFmt.GetGraphicSize().Width()
511 0 : << (sal_Int32)aFmt.GetGraphicSize().Height();
512 0 : sal_uInt8 cFlg = ( 0 != aFmt.GetBrush() ? 1 : 0 ) +
513 0 : ( 0 != aFmt.GetGraphicOrientation() ? 2 : 0 );
514 0 : rStream << cFlg;
515 :
516 0 : if( aFmt.GetBrush() )
517 : {
518 0 : sal_uInt16 nVersion = aFmt.GetBrush()->GetVersion( SOFFICE_FILEFORMAT_50 );
519 0 : rStream << nVersion;
520 0 : aFmt.GetBrush()->Store( rStream, nVersion );
521 : }
522 0 : if( aFmt.GetGraphicOrientation() )
523 : {
524 0 : sal_uInt16 nVersion = aFmt.GetGraphicOrientation()->GetVersion( SOFFICE_FILEFORMAT_50 );
525 0 : rStream << nVersion;
526 0 : aFmt.GetGraphicOrientation()->Store( rStream, nVersion );
527 : }
528 : }
529 0 : }
530 :
531 0 : void SwNumRulesWithName::_SwNumFmtGlobal::ChgNumFmt( SwWrtShell& rSh,
532 : SwNumFmt& rNew ) const
533 : {
534 0 : SwCharFmt* pFmt = 0;
535 0 : if( sCharFmtName.Len() )
536 : {
537 : // at first, look for the name
538 0 : sal_uInt16 nArrLen = rSh.GetCharFmtCount();
539 0 : for( sal_uInt16 i = 1; i < nArrLen; ++i )
540 : {
541 0 : pFmt = &rSh.GetCharFmt( i );
542 0 : if( COMPARE_EQUAL == pFmt->GetName().CompareTo( sCharFmtName ))
543 : // exists, so leave attributes as they are!
544 0 : break;
545 0 : pFmt = 0;
546 : }
547 :
548 0 : if( !pFmt )
549 : {
550 0 : if( IsPoolUserFmt( nCharPoolId ) )
551 : {
552 0 : pFmt = rSh.MakeCharFmt( sCharFmtName );
553 0 : pFmt->SetAuto( false );
554 : }
555 : else
556 0 : pFmt = rSh.GetCharFmtFromPool( nCharPoolId );
557 :
558 0 : if( !pFmt->GetDepends() ) // set attributes
559 0 : for( sal_uInt16 n = aItems.size(); n; )
560 0 : pFmt->SetFmtAttr( aItems[ --n ] );
561 : }
562 : }
563 0 : ((SwNumFmt&)aFmt).SetCharFmt( pFmt );
564 0 : rNew = aFmt;
565 0 : if( pFmt )
566 0 : ((SwNumFmt&)aFmt).SetCharFmt( 0 );
567 99 : }
568 :
569 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|