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