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