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