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