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