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 : #include <hintids.hxx>
21 : #include <poolfmt.hxx>
22 : #include "unomid.h"
23 :
24 : #include <basic/sbxvar.hxx>
25 : #include <svl/macitem.hxx>
26 : #include <svl/stritem.hxx>
27 : #include <svl/stylepool.hxx>
28 : #include <fmtautofmt.hxx>
29 : #include <fchrfmt.hxx>
30 : #include <fmtinfmt.hxx>
31 : #include <txtatr.hxx>
32 : #include <fmtruby.hxx>
33 : #include <charfmt.hxx>
34 : #include <hints.hxx>
35 : #include <unostyle.hxx>
36 : #include <unoevent.hxx>
37 : #include <com/sun/star/text/RubyAdjust.hpp>
38 :
39 : #include <cmdid.h>
40 : #include <com/sun/star/uno/Any.h>
41 : #include <SwStyleNameMapper.hxx>
42 :
43 : #include <fmtmeta.hxx>
44 : #include <ndtxt.hxx>
45 : #include <doc.hxx>
46 : #include <unometa.hxx>
47 : #include <docsh.hxx>
48 : #include <svl/zforlist.hxx>
49 :
50 : #include <boost/bind.hpp>
51 : #include <algorithm>
52 :
53 : using namespace ::com::sun::star;
54 :
55 23393 : TYPEINIT1_AUTOFACTORY(SwFmtINetFmt, SfxPoolItem);
56 43076 : TYPEINIT1_AUTOFACTORY(SwFmtAutoFmt, SfxPoolItem);
57 :
58 15753 : SwFmtCharFmt::SwFmtCharFmt( SwCharFmt *pFmt )
59 : : SfxPoolItem( RES_TXTATR_CHARFMT ),
60 : SwClient(pFmt),
61 15753 : pTxtAttr( 0 )
62 : {
63 15753 : }
64 :
65 239143 : SwFmtCharFmt::SwFmtCharFmt( const SwFmtCharFmt& rAttr )
66 : : SfxPoolItem( RES_TXTATR_CHARFMT ),
67 239143 : SwClient( rAttr.GetCharFmt() ),
68 478286 : pTxtAttr( 0 )
69 : {
70 239143 : }
71 :
72 494133 : SwFmtCharFmt::~SwFmtCharFmt() {}
73 :
74 15786 : bool SwFmtCharFmt::operator==( const SfxPoolItem& rAttr ) const
75 : {
76 : assert(SfxPoolItem::operator==(rAttr));
77 15786 : return GetCharFmt() == ((SwFmtCharFmt&)rAttr).GetCharFmt();
78 : }
79 :
80 239143 : SfxPoolItem* SwFmtCharFmt::Clone( SfxItemPool* ) const
81 : {
82 239143 : return new SwFmtCharFmt( *this );
83 : }
84 :
85 : // weiterleiten an das TextAttribut
86 9162 : void SwFmtCharFmt::Modify( const SfxPoolItem* pOld, const SfxPoolItem* pNew )
87 : {
88 9162 : if( pTxtAttr )
89 8944 : pTxtAttr->ModifyNotification( pOld, pNew );
90 9162 : }
91 :
92 : // weiterleiten an das TextAttribut
93 12 : bool SwFmtCharFmt::GetInfo( SfxPoolItem& rInfo ) const
94 : {
95 12 : return pTxtAttr && pTxtAttr->GetInfo( rInfo );
96 : }
97 24 : bool SwFmtCharFmt::QueryValue( uno::Any& rVal, sal_uInt8 ) const
98 : {
99 24 : OUString sCharFmtName;
100 24 : if(GetCharFmt())
101 14 : SwStyleNameMapper::FillProgName(GetCharFmt()->GetName(), sCharFmtName, nsSwGetPoolIdFromName::GET_POOLID_CHRFMT, true );
102 24 : rVal <<= sCharFmtName;
103 24 : return true;
104 : }
105 0 : bool SwFmtCharFmt::PutValue( const uno::Any& , sal_uInt8 )
106 : {
107 : OSL_FAIL("Zeichenvorlage kann mit PutValue nicht gesetzt werden!");
108 0 : return false;
109 : }
110 :
111 183394 : SwFmtAutoFmt::SwFmtAutoFmt( sal_uInt16 nInitWhich )
112 183394 : : SfxPoolItem( nInitWhich )
113 : {
114 183394 : }
115 :
116 58576 : SwFmtAutoFmt::SwFmtAutoFmt( const SwFmtAutoFmt& rAttr )
117 58576 : : SfxPoolItem( rAttr.Which() ), mpHandle( rAttr.mpHandle )
118 : {
119 58576 : }
120 :
121 300718 : SwFmtAutoFmt::~SwFmtAutoFmt()
122 : {
123 300718 : }
124 :
125 4328296 : bool SwFmtAutoFmt::operator==( const SfxPoolItem& rAttr ) const
126 : {
127 : assert(SfxPoolItem::operator==(rAttr));
128 4328296 : return mpHandle == ((SwFmtAutoFmt&)rAttr).mpHandle;
129 : }
130 :
131 58576 : SfxPoolItem* SwFmtAutoFmt::Clone( SfxItemPool* ) const
132 : {
133 58576 : return new SwFmtAutoFmt( *this );
134 : }
135 :
136 12 : bool SwFmtAutoFmt::QueryValue( uno::Any& rVal, sal_uInt8 ) const
137 : {
138 12 : OUString sCharFmtName = StylePool::nameOf( mpHandle );
139 12 : rVal <<= OUString( sCharFmtName );
140 12 : return true;
141 : }
142 :
143 0 : bool SwFmtAutoFmt::PutValue( const uno::Any& , sal_uInt8 )
144 : {
145 : //the format is not renameable via API
146 0 : return false;
147 : }
148 :
149 0 : SwFmtINetFmt::SwFmtINetFmt()
150 : : SfxPoolItem( RES_TXTATR_INETFMT )
151 : , msURL()
152 : , msTargetFrame()
153 : , msINetFmtName()
154 : , msVisitedFmtName()
155 : , msHyperlinkName()
156 : , mpMacroTbl( 0 )
157 : , mpTxtAttr( 0 )
158 : , mnINetFmtId( 0 )
159 0 : , mnVisitedFmtId( 0 )
160 0 : {}
161 :
162 130 : SwFmtINetFmt::SwFmtINetFmt( const OUString& rURL, const OUString& rTarget )
163 : : SfxPoolItem( RES_TXTATR_INETFMT )
164 : , msURL( rURL )
165 : , msTargetFrame( rTarget )
166 : , msINetFmtName()
167 : , msVisitedFmtName()
168 : , msHyperlinkName()
169 : , mpMacroTbl( 0 )
170 : , mpTxtAttr( 0 )
171 : , mnINetFmtId( RES_POOLCHR_INET_NORMAL )
172 130 : , mnVisitedFmtId( RES_POOLCHR_INET_VISIT )
173 : {
174 130 : SwStyleNameMapper::FillUIName( mnINetFmtId, msINetFmtName );
175 130 : SwStyleNameMapper::FillUIName( mnVisitedFmtId, msVisitedFmtName );
176 130 : }
177 :
178 13200 : SwFmtINetFmt::SwFmtINetFmt( const SwFmtINetFmt& rAttr )
179 : : SfxPoolItem( RES_TXTATR_INETFMT )
180 13200 : , msURL( rAttr.GetValue() )
181 : , msTargetFrame( rAttr.msTargetFrame )
182 : , msINetFmtName( rAttr.msINetFmtName )
183 : , msVisitedFmtName( rAttr.msVisitedFmtName )
184 : , msHyperlinkName( rAttr.msHyperlinkName )
185 : , mpMacroTbl( 0 )
186 : , mpTxtAttr( 0 )
187 : , mnINetFmtId( rAttr.mnINetFmtId )
188 26400 : , mnVisitedFmtId( rAttr.mnVisitedFmtId )
189 : {
190 13200 : if ( rAttr.GetMacroTbl() )
191 0 : mpMacroTbl = new SvxMacroTableDtor( *rAttr.GetMacroTbl() );
192 13200 : }
193 :
194 39950 : SwFmtINetFmt::~SwFmtINetFmt()
195 : {
196 13330 : delete mpMacroTbl;
197 26620 : }
198 :
199 1538 : bool SwFmtINetFmt::operator==( const SfxPoolItem& rAttr ) const
200 : {
201 : assert(SfxPoolItem::operator==(rAttr));
202 1538 : bool bRet = SfxPoolItem::operator==( (SfxPoolItem&) rAttr )
203 1538 : && msURL == ((SwFmtINetFmt&)rAttr).msURL
204 1272 : && msHyperlinkName == ((SwFmtINetFmt&)rAttr).msHyperlinkName
205 1268 : && msTargetFrame == ((SwFmtINetFmt&)rAttr).msTargetFrame
206 1264 : && msINetFmtName == ((SwFmtINetFmt&)rAttr).msINetFmtName
207 640 : && msVisitedFmtName == ((SwFmtINetFmt&)rAttr).msVisitedFmtName
208 16 : && mnINetFmtId == ((SwFmtINetFmt&)rAttr).mnINetFmtId
209 1554 : && mnVisitedFmtId == ((SwFmtINetFmt&)rAttr).mnVisitedFmtId;
210 :
211 1538 : if( !bRet )
212 1522 : return false;
213 :
214 16 : const SvxMacroTableDtor* pOther = ((SwFmtINetFmt&)rAttr).mpMacroTbl;
215 16 : if( !mpMacroTbl )
216 16 : return ( !pOther || pOther->empty() );
217 0 : if( !pOther )
218 0 : return mpMacroTbl->empty();
219 :
220 0 : const SvxMacroTableDtor& rOwn = *mpMacroTbl;
221 0 : const SvxMacroTableDtor& rOther = *pOther;
222 :
223 0 : return rOwn == rOther;
224 : }
225 :
226 13200 : SfxPoolItem* SwFmtINetFmt::Clone( SfxItemPool* ) const
227 : {
228 13200 : return new SwFmtINetFmt( *this );
229 : }
230 :
231 0 : void SwFmtINetFmt::SetMacroTbl( const SvxMacroTableDtor* pNewTbl )
232 : {
233 0 : if( pNewTbl )
234 : {
235 0 : if( mpMacroTbl )
236 0 : *mpMacroTbl = *pNewTbl;
237 : else
238 0 : mpMacroTbl = new SvxMacroTableDtor( *pNewTbl );
239 : }
240 : else
241 0 : delete mpMacroTbl, mpMacroTbl = 0;
242 0 : }
243 :
244 0 : void SwFmtINetFmt::SetMacro( sal_uInt16 nEvent, const SvxMacro& rMacro )
245 : {
246 0 : if( !mpMacroTbl )
247 0 : mpMacroTbl = new SvxMacroTableDtor;
248 :
249 0 : mpMacroTbl->Insert( nEvent, rMacro );
250 0 : }
251 :
252 36 : const SvxMacro* SwFmtINetFmt::GetMacro( sal_uInt16 nEvent ) const
253 : {
254 36 : const SvxMacro* pRet = 0;
255 36 : if( mpMacroTbl && mpMacroTbl->IsKeyValid( nEvent ) )
256 0 : pRet = mpMacroTbl->Get( nEvent );
257 36 : return pRet;
258 : }
259 :
260 1056 : bool SwFmtINetFmt::QueryValue( uno::Any& rVal, sal_uInt8 nMemberId ) const
261 : {
262 1056 : nMemberId &= ~CONVERT_TWIPS;
263 1056 : switch(nMemberId)
264 : {
265 : case MID_URL_URL:
266 994 : rVal <<= msURL;
267 994 : break;
268 : case MID_URL_TARGET:
269 14 : rVal <<= msTargetFrame;
270 14 : break;
271 : case MID_URL_HYPERLINKNAME:
272 14 : rVal <<= msHyperlinkName;
273 14 : break;
274 : case MID_URL_VISITED_FMT:
275 : {
276 14 : OUString sVal = msVisitedFmtName;
277 14 : if (sVal.isEmpty() && mnVisitedFmtId != 0)
278 0 : SwStyleNameMapper::FillUIName(mnVisitedFmtId, sVal);
279 14 : if (!sVal.isEmpty())
280 : SwStyleNameMapper::FillProgName(sVal, sVal,
281 14 : nsSwGetPoolIdFromName::GET_POOLID_CHRFMT, true);
282 14 : rVal <<= sVal;
283 : }
284 14 : break;
285 : case MID_URL_UNVISITED_FMT:
286 : {
287 14 : OUString sVal = msINetFmtName;
288 14 : if (sVal.isEmpty() && mnINetFmtId != 0)
289 0 : SwStyleNameMapper::FillUIName(mnINetFmtId, sVal);
290 14 : if (!sVal.isEmpty())
291 : SwStyleNameMapper::FillProgName(sVal, sVal,
292 14 : nsSwGetPoolIdFromName::GET_POOLID_CHRFMT, true);
293 14 : rVal <<= sVal;
294 : }
295 14 : break;
296 : case MID_URL_HYPERLINKEVENTS:
297 : {
298 : // create (and return) event descriptor
299 : SwHyperlinkEventDescriptor* pEvents =
300 6 : new SwHyperlinkEventDescriptor();
301 6 : pEvents->copyMacrosFromINetFmt(*this);
302 6 : uno::Reference<container::XNameReplace> xNameReplace(pEvents);
303 :
304 : // all others return a string; so we just set rVal here and exit
305 6 : rVal <<= xNameReplace;
306 : }
307 6 : break;
308 : default:
309 0 : rVal <<= OUString();
310 0 : break;
311 : }
312 1056 : return true;
313 : }
314 2756 : bool SwFmtINetFmt::PutValue( const uno::Any& rVal, sal_uInt8 nMemberId )
315 : {
316 2756 : bool bRet = true;
317 2756 : nMemberId &= ~CONVERT_TWIPS;
318 :
319 : // all properties except HyperlinkEvents are of type string, hence
320 : // we treat HyperlinkEvents specially
321 2756 : if (MID_URL_HYPERLINKEVENTS == nMemberId)
322 : {
323 0 : uno::Reference<container::XNameReplace> xReplace;
324 0 : rVal >>= xReplace;
325 0 : if (xReplace.is())
326 : {
327 : // Create hyperlink event descriptor. Then copy events
328 : // from argument into descriptor. Then copy events from
329 : // the descriptor into the format.
330 0 : SwHyperlinkEventDescriptor* pEvents = new SwHyperlinkEventDescriptor();
331 0 : uno::Reference< lang::XServiceInfo> xHold = pEvents;
332 0 : pEvents->copyMacrosFromNameReplace(xReplace);
333 0 : pEvents->copyMacrosIntoINetFmt(*this);
334 : }
335 : else
336 : {
337 : // wrong type!
338 0 : bRet = false;
339 0 : }
340 : }
341 : else
342 : {
343 : // all string properties:
344 2756 : if(rVal.getValueType() != ::cppu::UnoType<OUString>::get())
345 0 : return false;
346 :
347 2756 : switch(nMemberId)
348 : {
349 : case MID_URL_URL:
350 1484 : rVal >>= msURL;
351 1484 : break;
352 : case MID_URL_TARGET:
353 12 : rVal >>= msTargetFrame;
354 12 : break;
355 : case MID_URL_HYPERLINKNAME:
356 12 : rVal >>= msHyperlinkName;
357 12 : break;
358 : case MID_URL_VISITED_FMT:
359 : {
360 624 : OUString sVal;
361 624 : rVal >>= sVal;
362 1248 : OUString aString;
363 624 : SwStyleNameMapper::FillUIName( sVal, aString, nsSwGetPoolIdFromName::GET_POOLID_CHRFMT, true );
364 624 : msVisitedFmtName = aString;
365 : mnVisitedFmtId = SwStyleNameMapper::GetPoolIdFromUIName( msVisitedFmtName,
366 1248 : nsSwGetPoolIdFromName::GET_POOLID_CHRFMT );
367 : }
368 624 : break;
369 : case MID_URL_UNVISITED_FMT:
370 : {
371 624 : OUString sVal;
372 624 : rVal >>= sVal;
373 1248 : OUString aString;
374 624 : SwStyleNameMapper::FillUIName( sVal, aString, nsSwGetPoolIdFromName::GET_POOLID_CHRFMT, true );
375 624 : msINetFmtName = aString;
376 1248 : mnINetFmtId = SwStyleNameMapper::GetPoolIdFromUIName( msINetFmtName, nsSwGetPoolIdFromName::GET_POOLID_CHRFMT );
377 : }
378 624 : break;
379 : default:
380 0 : bRet = false;
381 : }
382 : }
383 2756 : return bRet;
384 : }
385 :
386 90 : SwFmtRuby::SwFmtRuby( const OUString& rRubyTxt )
387 : : SfxPoolItem( RES_TXTATR_CJK_RUBY ),
388 : sRubyTxt( rRubyTxt ),
389 : pTxtAttr( 0 ),
390 : nCharFmtId( 0 ),
391 : nPosition( 0 ),
392 90 : nAdjustment( 0 )
393 : {
394 90 : }
395 :
396 4824 : SwFmtRuby::SwFmtRuby( const SwFmtRuby& rAttr )
397 : : SfxPoolItem( RES_TXTATR_CJK_RUBY ),
398 : sRubyTxt( rAttr.sRubyTxt ),
399 : sCharFmtName( rAttr.sCharFmtName ),
400 : pTxtAttr( 0 ),
401 : nCharFmtId( rAttr.nCharFmtId),
402 : nPosition( rAttr.nPosition ),
403 4824 : nAdjustment( rAttr.nAdjustment )
404 : {
405 4824 : }
406 :
407 9828 : SwFmtRuby::~SwFmtRuby()
408 : {
409 9828 : }
410 :
411 0 : SwFmtRuby& SwFmtRuby::operator=( const SwFmtRuby& rAttr )
412 : {
413 0 : sRubyTxt = rAttr.sRubyTxt;
414 0 : sCharFmtName = rAttr.sCharFmtName;
415 0 : nCharFmtId = rAttr.nCharFmtId;
416 0 : nPosition = rAttr.nPosition;
417 0 : nAdjustment = rAttr.nAdjustment;
418 0 : pTxtAttr = 0;
419 0 : return *this;
420 : }
421 :
422 1926 : bool SwFmtRuby::operator==( const SfxPoolItem& rAttr ) const
423 : {
424 : assert(SfxPoolItem::operator==(rAttr));
425 3822 : return sRubyTxt == ((SwFmtRuby&)rAttr).sRubyTxt &&
426 3784 : sCharFmtName == ((SwFmtRuby&)rAttr).sCharFmtName &&
427 3776 : nCharFmtId == ((SwFmtRuby&)rAttr).nCharFmtId &&
428 5694 : nPosition == ((SwFmtRuby&)rAttr).nPosition &&
429 3806 : nAdjustment == ((SwFmtRuby&)rAttr).nAdjustment;
430 : }
431 :
432 4816 : SfxPoolItem* SwFmtRuby::Clone( SfxItemPool* ) const
433 : {
434 4816 : return new SwFmtRuby( *this );
435 : }
436 :
437 1068 : bool SwFmtRuby::QueryValue( uno::Any& rVal,
438 : sal_uInt8 nMemberId ) const
439 : {
440 1068 : bool bRet = true;
441 1068 : nMemberId &= ~CONVERT_TWIPS;
442 1068 : switch( nMemberId )
443 : {
444 266 : case MID_RUBY_TEXT: rVal <<= (OUString)sRubyTxt; break;
445 268 : case MID_RUBY_ADJUST: rVal <<= (sal_Int16)nAdjustment; break;
446 : case MID_RUBY_CHARSTYLE:
447 : {
448 266 : OUString aString;
449 266 : SwStyleNameMapper::FillProgName(sCharFmtName, aString, nsSwGetPoolIdFromName::GET_POOLID_CHRFMT, true );
450 266 : rVal <<= aString;
451 : }
452 266 : break;
453 : case MID_RUBY_ABOVE:
454 : {
455 268 : sal_Bool bAbove = !nPosition;
456 268 : rVal.setValue(&bAbove, ::getBooleanCppuType());
457 : }
458 268 : break;
459 : default:
460 0 : bRet = false;
461 : }
462 1068 : return bRet;
463 : }
464 168 : bool SwFmtRuby::PutValue( const uno::Any& rVal,
465 : sal_uInt8 nMemberId )
466 : {
467 168 : bool bRet = true;
468 168 : nMemberId &= ~CONVERT_TWIPS;
469 168 : switch( nMemberId )
470 : {
471 : case MID_RUBY_TEXT:
472 : {
473 104 : OUString sTmp;
474 104 : bRet = rVal >>= sTmp;
475 104 : sRubyTxt = sTmp;
476 : }
477 104 : break;
478 : case MID_RUBY_ADJUST:
479 : {
480 32 : sal_Int16 nSet = 0;
481 32 : rVal >>= nSet;
482 32 : if(nSet >= 0 && nSet <= text::RubyAdjust_INDENT_BLOCK)
483 32 : nAdjustment = nSet;
484 : else
485 0 : bRet = false;
486 : }
487 32 : break;
488 : case MID_RUBY_ABOVE:
489 : {
490 32 : const uno::Type& rType = ::getBooleanCppuType();
491 32 : if(rVal.hasValue() && rVal.getValueType() == rType)
492 : {
493 32 : bool bAbove = *(sal_Bool*)rVal.getValue();
494 32 : nPosition = bAbove ? 0 : 1;
495 : }
496 : }
497 32 : break;
498 : case MID_RUBY_CHARSTYLE:
499 : {
500 0 : OUString sTmp;
501 0 : bRet = rVal >>= sTmp;
502 0 : if(bRet)
503 0 : sCharFmtName = SwStyleNameMapper::GetUIName(sTmp, nsSwGetPoolIdFromName::GET_POOLID_CHRFMT );
504 : }
505 0 : break;
506 : default:
507 0 : bRet = false;
508 : }
509 168 : return bRet;
510 : }
511 :
512 180 : SwFmtMeta * SwFmtMeta::CreatePoolDefault(const sal_uInt16 i_nWhich)
513 : {
514 180 : return new SwFmtMeta(i_nWhich);
515 : }
516 :
517 180 : SwFmtMeta::SwFmtMeta(const sal_uInt16 i_nWhich)
518 : : SfxPoolItem( i_nWhich )
519 : , m_pMeta()
520 180 : , m_pTxtAttr( 0 )
521 : {
522 : OSL_ENSURE((RES_TXTATR_META == i_nWhich) || (RES_TXTATR_METAFIELD == i_nWhich),
523 : "ERROR: SwFmtMeta: invalid which id!");
524 180 : }
525 :
526 1994 : SwFmtMeta::SwFmtMeta( ::boost::shared_ptr< ::sw::Meta > const & i_pMeta,
527 : const sal_uInt16 i_nWhich )
528 : : SfxPoolItem( i_nWhich )
529 : , m_pMeta( i_pMeta )
530 1994 : , m_pTxtAttr( 0 )
531 : {
532 : OSL_ENSURE((RES_TXTATR_META == i_nWhich) || (RES_TXTATR_METAFIELD == i_nWhich),
533 : "ERROR: SwFmtMeta: invalid which id!");
534 : OSL_ENSURE(m_pMeta, "SwFmtMeta: no Meta ?");
535 : // DO NOT call m_pMeta->SetFmtMeta(this) here; only from SetTxtAttr!
536 1994 : }
537 :
538 6328 : SwFmtMeta::~SwFmtMeta()
539 : {
540 2174 : if (m_pMeta && (m_pMeta->GetFmtMeta() == this))
541 : {
542 0 : NotifyChangeTxtNode(0);
543 0 : m_pMeta->SetFmtMeta(0);
544 : }
545 4154 : }
546 :
547 138 : bool SwFmtMeta::operator==( const SfxPoolItem & i_rOther ) const
548 : {
549 : assert(SfxPoolItem::operator==(i_rOther));
550 138 : return SfxPoolItem::operator==( i_rOther )
551 138 : && (m_pMeta == static_cast<SwFmtMeta const &>( i_rOther ).m_pMeta);
552 : }
553 :
554 1800 : SfxPoolItem * SwFmtMeta::Clone( SfxItemPool * /*pPool*/ ) const
555 : {
556 : // if this is indeed a copy, then DoCopy must be called later!
557 : return (m_pMeta) // #i105148# pool default may be cloned also!
558 1800 : ? new SwFmtMeta( m_pMeta, Which() ) : new SwFmtMeta( Which() );
559 : }
560 :
561 388 : void SwFmtMeta::SetTxtAttr(SwTxtMeta * const i_pTxtAttr)
562 : {
563 : OSL_ENSURE(!(m_pTxtAttr && i_pTxtAttr),
564 : "SwFmtMeta::SetTxtAttr: already has text attribute?");
565 : OSL_ENSURE( m_pTxtAttr || i_pTxtAttr ,
566 : "SwFmtMeta::SetTxtAttr: no attribute to remove?");
567 388 : m_pTxtAttr = i_pTxtAttr;
568 : OSL_ENSURE(m_pMeta, "inserted SwFmtMeta has no sw::Meta?");
569 : // the sw::Meta must be able to find the current text attribute!
570 388 : if (m_pMeta)
571 : {
572 388 : if (i_pTxtAttr)
573 : {
574 194 : m_pMeta->SetFmtMeta(this);
575 : }
576 194 : else if (m_pMeta->GetFmtMeta() == this)
577 : { // text attribute gone => de-register from text node!
578 194 : NotifyChangeTxtNode(0);
579 194 : m_pMeta->SetFmtMeta(0);
580 : }
581 : }
582 388 : }
583 :
584 582 : void SwFmtMeta::NotifyChangeTxtNode(SwTxtNode *const pTxtNode)
585 : {
586 : // N.B.: do not reset m_pTxtAttr here: see call in nodes.cxx,
587 : // where the hint is not deleted!
588 : OSL_ENSURE(m_pMeta, "SwFmtMeta::NotifyChangeTxtNode: no Meta?");
589 582 : if (m_pMeta && (m_pMeta->GetFmtMeta() == this))
590 : { // do not call Modify, that would call SwXMeta::Modify!
591 582 : m_pMeta->NotifyChangeTxtNode(pTxtNode);
592 : }
593 582 : }
594 :
595 : // this SwFmtMeta has been cloned and points at the same sw::Meta as the source
596 : // this method copies the sw::Meta
597 0 : void SwFmtMeta::DoCopy(::sw::MetaFieldManager & i_rTargetDocManager,
598 : SwTxtNode & i_rTargetTxtNode)
599 : {
600 : OSL_ENSURE(m_pMeta, "DoCopy called for SwFmtMeta with no sw::Meta?");
601 0 : if (m_pMeta)
602 : {
603 0 : const ::boost::shared_ptr< ::sw::Meta> pOriginal( m_pMeta );
604 0 : if (RES_TXTATR_META == Which())
605 : {
606 0 : m_pMeta.reset( new ::sw::Meta(this) );
607 : }
608 : else
609 : {
610 : ::sw::MetaField *const pMetaField(
611 0 : static_cast< ::sw::MetaField* >(pOriginal.get()));
612 0 : m_pMeta = i_rTargetDocManager.makeMetaField( this,
613 0 : pMetaField->m_nNumberFormat, pMetaField->IsFixedLanguage() );
614 : }
615 : // Meta must have a text node before calling RegisterAsCopyOf
616 0 : m_pMeta->NotifyChangeTxtNode(& i_rTargetTxtNode);
617 : // this cannot be done in Clone: a Clone is not necessarily a copy!
618 0 : m_pMeta->RegisterAsCopyOf(*pOriginal);
619 : }
620 0 : }
621 :
622 : namespace sw {
623 :
624 194 : Meta::Meta(SwFmtMeta * const i_pFmt)
625 : : ::sfx2::Metadatable()
626 : , SwModify()
627 : , m_pFmt(i_pFmt)
628 194 : , m_pTxtNode(0)
629 : {
630 194 : }
631 :
632 336 : Meta::~Meta()
633 : {
634 336 : }
635 :
636 1616 : SwTxtMeta * Meta::GetTxtAttr() const
637 : {
638 1616 : return (m_pFmt) ? m_pFmt->GetTxtAttr() : 0;
639 : }
640 :
641 :
642 582 : void Meta::NotifyChangeTxtNodeImpl()
643 : {
644 582 : if (m_pTxtNode && (GetRegisteredIn() != m_pTxtNode))
645 : {
646 194 : m_pTxtNode->Add(this);
647 : }
648 388 : else if (!m_pTxtNode && GetRegisteredIn())
649 : {
650 194 : GetRegisteredInNonConst()->Remove(this);
651 : }
652 582 : }
653 :
654 582 : void Meta::NotifyChangeTxtNode(SwTxtNode *const pTxtNode)
655 : {
656 582 : m_pTxtNode = pTxtNode;
657 582 : NotifyChangeTxtNodeImpl();
658 582 : if (!pTxtNode) // text node gone? invalidate UNO object!
659 : {
660 : SwPtrMsgPoolItem aMsgHint( RES_REMOVE_UNO_OBJECT,
661 388 : &static_cast<SwModify&>(*this) ); // cast to base class!
662 388 : this->Modify(&aMsgHint, &aMsgHint);
663 : }
664 582 : }
665 :
666 : // SwClient
667 4144 : void Meta::Modify( const SfxPoolItem *pOld, const SfxPoolItem *pNew )
668 : {
669 4144 : NotifyClients(pOld, pNew);
670 4144 : if (pOld && (RES_REMOVE_UNO_OBJECT == pOld->Which()))
671 : { // invalidate cached uno object
672 388 : SetXMeta(uno::Reference<rdf::XMetadatable>(0));
673 : }
674 4144 : }
675 :
676 : // sfx2::Metadatable
677 188 : ::sfx2::IXmlIdRegistry& Meta::GetRegistry()
678 : {
679 188 : SwTxtNode * const pTxtNode( GetTxtNode() );
680 : // GetRegistry may only be called on a meta that is actually in the
681 : // document, which means it has a pointer to its text node
682 : OSL_ENSURE(pTxtNode, "ERROR: GetRegistry: no text node?");
683 188 : if (!pTxtNode)
684 0 : throw uno::RuntimeException();
685 188 : return pTxtNode->GetRegistry();
686 : }
687 :
688 846 : bool Meta::IsInClipboard() const
689 : {
690 846 : const SwTxtNode * const pTxtNode( GetTxtNode() );
691 : // no text node: in UNDO OSL_ENSURE(pTxtNode, "IsInClipboard: no text node?");
692 846 : return pTxtNode && pTxtNode->IsInClipboard();
693 : }
694 :
695 866 : bool Meta::IsInUndo() const
696 : {
697 866 : const SwTxtNode * const pTxtNode( GetTxtNode() );
698 : // no text node: in UNDO OSL_ENSURE(pTxtNode, "IsInUndo: no text node?");
699 866 : return (pTxtNode) ? pTxtNode->IsInUndo() : true;
700 : }
701 :
702 228 : bool Meta::IsInContent() const
703 : {
704 228 : const SwTxtNode * const pTxtNode( GetTxtNode() );
705 : OSL_ENSURE(pTxtNode, "IsInContent: no text node?");
706 228 : return (pTxtNode) ? pTxtNode->IsInContent() : true;
707 : }
708 :
709 : ::com::sun::star::uno::Reference< ::com::sun::star::rdf::XMetadatable >
710 132 : Meta::MakeUnoObject()
711 : {
712 132 : return SwXMeta::CreateXMeta(*this);
713 : }
714 :
715 52 : MetaField::MetaField(SwFmtMeta * const i_pFmt,
716 : const sal_uInt32 nNumberFormat, const bool bIsFixedLanguage)
717 : : Meta(i_pFmt)
718 : , m_nNumberFormat( nNumberFormat )
719 52 : , m_bIsFixedLanguage( bIsFixedLanguage )
720 : {
721 52 : }
722 :
723 80 : void MetaField::GetPrefixAndSuffix(
724 : OUString *const o_pPrefix, OUString *const o_pSuffix)
725 : {
726 : try
727 : {
728 80 : const uno::Reference<rdf::XMetadatable> xMetaField( MakeUnoObject() );
729 : OSL_ENSURE(dynamic_cast<SwXMetaField*>(xMetaField.get()),
730 : "GetPrefixAndSuffix: no SwXMetaField?");
731 80 : if (xMetaField.is())
732 : {
733 80 : SwTxtNode * const pTxtNode( GetTxtNode() );
734 80 : SwDocShell const * const pShell(pTxtNode->GetDoc()->GetDocShell());
735 : const uno::Reference<frame::XModel> xModel(
736 80 : (pShell) ? pShell->GetModel() : 0, uno::UNO_SET_THROW);
737 80 : getPrefixAndSuffix(xModel, xMetaField, o_pPrefix, o_pSuffix);
738 80 : }
739 : }
740 0 : catch (const uno::Exception&)
741 : {
742 : OSL_FAIL("exception?");
743 : }
744 80 : }
745 :
746 48 : sal_uInt32 MetaField::GetNumberFormat(OUString const & rContent) const
747 : {
748 : //TODO: this probably lacks treatment for some special cases
749 48 : sal_uInt32 nNumberFormat( m_nNumberFormat );
750 48 : SwTxtNode * const pTxtNode( GetTxtNode() );
751 48 : if (pTxtNode)
752 : {
753 : SvNumberFormatter *const pNumberFormatter(
754 48 : pTxtNode->GetDoc()->GetNumberFormatter() );
755 : double number;
756 : (void) pNumberFormatter->IsNumberFormat(
757 48 : rContent, nNumberFormat, number );
758 : }
759 48 : return nNumberFormat;
760 : }
761 :
762 10 : void MetaField::SetNumberFormat(sal_uInt32 nNumberFormat)
763 : {
764 : // effectively, the member is only a default:
765 : // GetNumberFormat checks if the text actually conforms
766 10 : m_nNumberFormat = nNumberFormat;
767 10 : }
768 :
769 5052 : MetaFieldManager::MetaFieldManager()
770 : {
771 5052 : }
772 :
773 : ::boost::shared_ptr<MetaField>
774 52 : MetaFieldManager::makeMetaField(SwFmtMeta * const i_pFmt,
775 : const sal_uInt32 nNumberFormat, const bool bIsFixedLanguage)
776 : {
777 : const ::boost::shared_ptr<MetaField> pMetaField(
778 52 : new MetaField(i_pFmt, nNumberFormat, bIsFixedLanguage) );
779 52 : m_MetaFields.push_back(pMetaField);
780 52 : return pMetaField;
781 : }
782 :
783 : struct IsInUndo
784 : {
785 20 : bool operator()(::boost::weak_ptr<MetaField> const & pMetaField) {
786 20 : return pMetaField.lock()->IsInUndo();
787 : }
788 : };
789 :
790 : struct MakeUnoObject
791 : {
792 : uno::Reference<text::XTextField>
793 20 : operator()(::boost::weak_ptr<MetaField> const & pMetaField) {
794 : return uno::Reference<text::XTextField>(
795 20 : pMetaField.lock()->MakeUnoObject(), uno::UNO_QUERY);
796 : }
797 : };
798 :
799 : ::std::vector< uno::Reference<text::XTextField> >
800 4156 : MetaFieldManager::getMetaFields()
801 : {
802 : // erase deleted fields
803 : const MetaFieldList_t::iterator iter(
804 : ::std::remove_if(m_MetaFields.begin(), m_MetaFields.end(),
805 4156 : ::boost::bind(&::boost::weak_ptr<MetaField>::expired, _1)));
806 4156 : m_MetaFields.erase(iter, m_MetaFields.end());
807 : // filter out fields in UNDO
808 4156 : MetaFieldList_t filtered(m_MetaFields.size());
809 : const MetaFieldList_t::iterator iter2(
810 : ::std::remove_copy_if(m_MetaFields.begin(), m_MetaFields.end(),
811 4156 : filtered.begin(), IsInUndo()));
812 4156 : filtered.erase(iter2, filtered.end());
813 : // create uno objects
814 4156 : ::std::vector< uno::Reference<text::XTextField> > ret(filtered.size());
815 : ::std::transform(filtered.begin(), filtered.end(), ret.begin(),
816 4156 : MakeUnoObject());
817 4156 : return ret;
818 : }
819 :
820 270 : } // namespace sw
821 :
822 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|