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_sc.hxx"
26
27
28
29 #include "scitems.hxx"
30 #include <editeng/eeitem.hxx>
31 #include <svx/svdpool.hxx>
32 #include <svx/svdobj.hxx>
33 #include <editeng/editeng.hxx>
34 #include <editeng/editobj.hxx>
35 #include <editeng/flditem.hxx>
36 #include <svx/unomid.hxx>
37 #include <editeng/unoprnms.hxx>
38 #include <editeng/unofored.hxx>
39 #include <rtl/uuid.h>
40 #include <vcl/virdev.hxx>
41 #include <com/sun/star/awt/FontSlant.hpp>
42
43 #include <com/sun/star/beans/PropertyAttribute.hpp>
44 #include <editeng/unoipset.hxx>
45 #include "textuno.hxx"
46 #include "fielduno.hxx"
47 #include "servuno.hxx"
48 #include "editsrc.hxx"
49 #include "docsh.hxx"
50 #include "editutil.hxx"
51 #include "unoguard.hxx"
52 #include "miscuno.hxx"
53 #include "cellsuno.hxx"
54 #include "hints.hxx"
55 #include "patattr.hxx"
56 #include "cell.hxx"
57 #include "docfunc.hxx"
58 #include "scmod.hxx"
59
60 using namespace com::sun::star;
61
62 //------------------------------------------------------------------------
63
lcl_GetHdFtPropertySet()64 const SvxItemPropertySet * lcl_GetHdFtPropertySet()
65 {
66 static SfxItemPropertyMapEntry aHdFtPropertyMap_Impl[] =
67 {
68 SVX_UNOEDIT_CHAR_PROPERTIES,
69 SVX_UNOEDIT_FONT_PROPERTIES,
70 SVX_UNOEDIT_PARA_PROPERTIES,
71 SVX_UNOEDIT_NUMBERING_PROPERTIE, // for completeness of service ParagraphProperties
72 {0,0,0,0,0,0}
73 };
74 static sal_Bool bTwipsSet = sal_False;
75
76 if (!bTwipsSet)
77 {
78 // modify PropertyMap to include CONVERT_TWIPS flag for font height
79 // (headers/footers are in twips)
80
81 SfxItemPropertyMapEntry* pEntry = aHdFtPropertyMap_Impl;
82 while (pEntry->pName)
83 {
84 if ( ( pEntry->nWID == EE_CHAR_FONTHEIGHT ||
85 pEntry->nWID == EE_CHAR_FONTHEIGHT_CJK ||
86 pEntry->nWID == EE_CHAR_FONTHEIGHT_CTL ) &&
87 pEntry->nMemberId == MID_FONTHEIGHT )
88 {
89 pEntry->nMemberId |= CONVERT_TWIPS;
90 }
91
92 ++pEntry;
93 }
94 bTwipsSet = sal_True;
95 }
96 static SvxItemPropertySet aHdFtPropertySet_Impl( aHdFtPropertyMap_Impl, SdrObject::GetGlobalDrawObjectItemPool() );
97 return &aHdFtPropertySet_Impl;
98 }
99
100 //------------------------------------------------------------------------
101
102 SC_SIMPLE_SERVICE_INFO( ScHeaderFooterContentObj, "ScHeaderFooterContentObj", "com.sun.star.sheet.HeaderFooterContent" )
103 SC_SIMPLE_SERVICE_INFO( ScHeaderFooterTextObj, "ScHeaderFooterTextObj", "stardiv.one.Text.Text" )
104
105 //------------------------------------------------------------------------
106
ScHeaderFooterContentObj(const EditTextObject * pLeft,const EditTextObject * pCenter,const EditTextObject * pRight)107 ScHeaderFooterContentObj::ScHeaderFooterContentObj( const EditTextObject* pLeft,
108 const EditTextObject* pCenter,
109 const EditTextObject* pRight ) :
110 pLeftText ( NULL ),
111 pCenterText ( NULL ),
112 pRightText ( NULL )
113 {
114 if ( pLeft )
115 pLeftText = pLeft->Clone();
116 if ( pCenter )
117 pCenterText = pCenter->Clone();
118 if ( pRight )
119 pRightText = pRight->Clone();
120 }
121
~ScHeaderFooterContentObj()122 ScHeaderFooterContentObj::~ScHeaderFooterContentObj()
123 {
124 delete pLeftText;
125 delete pCenterText;
126 delete pRightText;
127 }
128
AddListener(SfxListener & rListener)129 void ScHeaderFooterContentObj::AddListener( SfxListener& rListener )
130 {
131 rListener.StartListening( aBC );
132 }
133
RemoveListener(SfxListener & rListener)134 void ScHeaderFooterContentObj::RemoveListener( SfxListener& rListener )
135 {
136 rListener.EndListening( aBC );
137 }
138
UpdateText(sal_uInt16 nPart,EditEngine & rSource)139 void ScHeaderFooterContentObj::UpdateText( sal_uInt16 nPart, EditEngine& rSource )
140 {
141 EditTextObject* pNew = rSource.CreateTextObject();
142 switch (nPart)
143 {
144 case SC_HDFT_LEFT:
145 delete pLeftText;
146 pLeftText = pNew;
147 break;
148 case SC_HDFT_CENTER:
149 delete pCenterText;
150 pCenterText = pNew;
151 break;
152 default: // SC_HDFT_RIGHT
153 delete pRightText;
154 pRightText = pNew;
155 break;
156 }
157
158 aBC.Broadcast( ScHeaderFooterChangedHint( nPart ) );
159 }
160
161 // XHeaderFooterContent
162
getLeftText()163 uno::Reference<text::XText> SAL_CALL ScHeaderFooterContentObj::getLeftText()
164 throw(uno::RuntimeException)
165 {
166 ScUnoGuard aGuard;
167 return new ScHeaderFooterTextObj( *this, SC_HDFT_LEFT );
168 }
169
getCenterText()170 uno::Reference<text::XText> SAL_CALL ScHeaderFooterContentObj::getCenterText()
171 throw(uno::RuntimeException)
172 {
173 ScUnoGuard aGuard;
174 return new ScHeaderFooterTextObj( *this, SC_HDFT_CENTER );
175 }
176
getRightText()177 uno::Reference<text::XText> SAL_CALL ScHeaderFooterContentObj::getRightText()
178 throw(uno::RuntimeException)
179 {
180 ScUnoGuard aGuard;
181 return new ScHeaderFooterTextObj( *this, SC_HDFT_RIGHT );
182 }
183
184 // XUnoTunnel
185
getSomething(const uno::Sequence<sal_Int8> & rId)186 sal_Int64 SAL_CALL ScHeaderFooterContentObj::getSomething(
187 const uno::Sequence<sal_Int8 >& rId ) throw(uno::RuntimeException)
188 {
189 if ( rId.getLength() == 16 &&
190 0 == rtl_compareMemory( getUnoTunnelId().getConstArray(),
191 rId.getConstArray(), 16 ) )
192 {
193 return sal::static_int_cast<sal_Int64>(reinterpret_cast<sal_IntPtr>(this));
194 }
195 return 0;
196 }
197
198 // static
getUnoTunnelId()199 const uno::Sequence<sal_Int8>& ScHeaderFooterContentObj::getUnoTunnelId()
200 {
201 static uno::Sequence<sal_Int8> * pSeq = 0;
202 if( !pSeq )
203 {
204 osl::Guard< osl::Mutex > aGuard( osl::Mutex::getGlobalMutex() );
205 if( !pSeq )
206 {
207 static uno::Sequence< sal_Int8 > aSeq( 16 );
208 rtl_createUuid( (sal_uInt8*)aSeq.getArray(), 0, sal_True );
209 pSeq = &aSeq;
210 }
211 }
212 return *pSeq;
213 }
214
215 // static
getImplementation(const uno::Reference<sheet::XHeaderFooterContent> xObj)216 ScHeaderFooterContentObj* ScHeaderFooterContentObj::getImplementation(
217 const uno::Reference<sheet::XHeaderFooterContent> xObj )
218 {
219 ScHeaderFooterContentObj* pRet = NULL;
220 uno::Reference<lang::XUnoTunnel> xUT( xObj, uno::UNO_QUERY );
221 if (xUT.is())
222 pRet = reinterpret_cast<ScHeaderFooterContentObj*>(sal::static_int_cast<sal_IntPtr>(xUT->getSomething(getUnoTunnelId())));
223 return pRet;
224 }
225
226
227 //------------------------------------------------------------------------
228
ScHeaderFooterTextData(ScHeaderFooterContentObj & rContent,sal_uInt16 nP)229 ScHeaderFooterTextData::ScHeaderFooterTextData( ScHeaderFooterContentObj& rContent,
230 sal_uInt16 nP ) :
231 rContentObj( rContent ),
232 nPart( nP ),
233 pEditEngine( NULL ),
234 pForwarder( NULL ),
235 bDataValid( sal_False ),
236 bInUpdate( sal_False )
237 {
238 rContentObj.acquire(); // must not go away
239 rContentObj.AddListener( *this );
240 }
241
~ScHeaderFooterTextData()242 ScHeaderFooterTextData::~ScHeaderFooterTextData()
243 {
244 ScUnoGuard aGuard; // needed for EditEngine dtor
245
246 rContentObj.RemoveListener( *this );
247
248 delete pForwarder;
249 delete pEditEngine;
250
251 rContentObj.release();
252 }
253
Notify(SfxBroadcaster &,const SfxHint & rHint)254 void ScHeaderFooterTextData::Notify( SfxBroadcaster&, const SfxHint& rHint )
255 {
256 if ( rHint.ISA( ScHeaderFooterChangedHint ) )
257 {
258 if ( ((const ScHeaderFooterChangedHint&)rHint).GetPart() == nPart )
259 {
260 if (!bInUpdate) // not for own updates
261 bDataValid = sal_False; // text has to be fetched again
262 }
263 }
264 }
265
GetTextForwarder()266 SvxTextForwarder* ScHeaderFooterTextData::GetTextForwarder()
267 {
268 if (!pEditEngine)
269 {
270 SfxItemPool* pEnginePool = EditEngine::CreatePool();
271 pEnginePool->FreezeIdRanges();
272 ScHeaderEditEngine* pHdrEngine = new ScHeaderEditEngine( pEnginePool, sal_True );
273
274 pHdrEngine->EnableUndo( sal_False );
275 pHdrEngine->SetRefMapMode( MAP_TWIP );
276
277 // default font must be set, independently of document
278 // -> use global pool from module
279
280 SfxItemSet aDefaults( pHdrEngine->GetEmptyItemSet() );
281 const ScPatternAttr& rPattern = (const ScPatternAttr&)SC_MOD()->GetPool().GetDefaultItem(ATTR_PATTERN);
282 rPattern.FillEditItemSet( &aDefaults );
283 // FillEditItemSet adjusts font height to 1/100th mm,
284 // but for header/footer twips is needed, as in the PatternAttr:
285 aDefaults.Put( rPattern.GetItem(ATTR_FONT_HEIGHT), EE_CHAR_FONTHEIGHT );
286 aDefaults.Put( rPattern.GetItem(ATTR_CJK_FONT_HEIGHT), EE_CHAR_FONTHEIGHT_CJK );
287 aDefaults.Put( rPattern.GetItem(ATTR_CTL_FONT_HEIGHT), EE_CHAR_FONTHEIGHT_CTL );
288 pHdrEngine->SetDefaults( aDefaults );
289
290 ScHeaderFieldData aData;
291 ScHeaderFooterTextObj::FillDummyFieldData( aData );
292 pHdrEngine->SetData( aData );
293
294 pEditEngine = pHdrEngine;
295 pForwarder = new SvxEditEngineForwarder(*pEditEngine);
296 }
297
298 if (bDataValid)
299 return pForwarder;
300
301 const EditTextObject* pData;
302 if (nPart == SC_HDFT_LEFT)
303 pData = rContentObj.GetLeftEditObject();
304 else if (nPart == SC_HDFT_CENTER)
305 pData = rContentObj.GetCenterEditObject();
306 else
307 pData = rContentObj.GetRightEditObject();
308
309 if (pData)
310 pEditEngine->SetText(*pData);
311
312 bDataValid = sal_True;
313 return pForwarder;
314 }
315
UpdateData()316 void ScHeaderFooterTextData::UpdateData()
317 {
318 if ( pEditEngine )
319 {
320 bInUpdate = sal_True; // don't reset bDataValid during UpdateText
321
322 rContentObj.UpdateText( nPart, *pEditEngine );
323
324 bInUpdate = sal_False;
325 }
326 }
327
328 //------------------------------------------------------------------------
329
ScHeaderFooterTextObj(ScHeaderFooterContentObj & rContent,sal_uInt16 nP)330 ScHeaderFooterTextObj::ScHeaderFooterTextObj( ScHeaderFooterContentObj& rContent,
331 sal_uInt16 nP ) :
332 aTextData( rContent, nP ),
333 pUnoText( NULL )
334 {
335 // ScHeaderFooterTextData acquires rContent
336 // pUnoText is created on demand (getString/setString work without it)
337 }
338
CreateUnoText_Impl()339 void ScHeaderFooterTextObj::CreateUnoText_Impl()
340 {
341 if ( !pUnoText )
342 {
343 // can't be aggregated because getString/setString is handled here
344 ScSharedHeaderFooterEditSource aEditSource( &aTextData );
345 pUnoText = new SvxUnoText( &aEditSource, lcl_GetHdFtPropertySet(), uno::Reference<text::XText>() );
346 pUnoText->acquire();
347 }
348 }
349
~ScHeaderFooterTextObj()350 ScHeaderFooterTextObj::~ScHeaderFooterTextObj()
351 {
352 if (pUnoText)
353 pUnoText->release();
354 }
355
GetUnoText()356 const SvxUnoText& ScHeaderFooterTextObj::GetUnoText()
357 {
358 if (!pUnoText)
359 CreateUnoText_Impl();
360 return *pUnoText;
361 }
362
363 // XText
364
createTextCursor()365 uno::Reference<text::XTextCursor> SAL_CALL ScHeaderFooterTextObj::createTextCursor()
366 throw(uno::RuntimeException)
367 {
368 ScUnoGuard aGuard;
369 return new ScHeaderFooterTextCursor( *this );
370 }
371
createTextCursorByRange(const uno::Reference<text::XTextRange> & aTextPosition)372 uno::Reference<text::XTextCursor> SAL_CALL ScHeaderFooterTextObj::createTextCursorByRange(
373 const uno::Reference<text::XTextRange>& aTextPosition )
374 throw(uno::RuntimeException)
375 {
376 ScUnoGuard aGuard;
377 if (!pUnoText)
378 CreateUnoText_Impl();
379 return pUnoText->createTextCursorByRange(aTextPosition);
380 //! wie ScCellObj::createTextCursorByRange, wenn SvxUnoTextRange_getReflection verfuegbar
381 }
382
FillDummyFieldData(ScHeaderFieldData & rData)383 void ScHeaderFooterTextObj::FillDummyFieldData( ScHeaderFieldData& rData ) // static
384 {
385 String aDummy(String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM( "???" )));
386 rData.aTitle = aDummy;
387 rData.aLongDocName = aDummy;
388 rData.aShortDocName = aDummy;
389 rData.aTabName = aDummy;
390 rData.nPageNo = 1;
391 rData.nTotalPages = 99;
392 }
393
getString()394 rtl::OUString SAL_CALL ScHeaderFooterTextObj::getString() throw(uno::RuntimeException)
395 {
396 ScUnoGuard aGuard;
397 rtl::OUString aRet;
398 const EditTextObject* pData;
399
400 sal_uInt16 nPart = aTextData.GetPart();
401 ScHeaderFooterContentObj& rContentObj = aTextData.GetContentObj();
402
403 if (nPart == SC_HDFT_LEFT)
404 pData = rContentObj.GetLeftEditObject();
405 else if (nPart == SC_HDFT_CENTER)
406 pData = rContentObj.GetCenterEditObject();
407 else
408 pData = rContentObj.GetRightEditObject();
409 if (pData)
410 {
411 // for pure text, no font info is needed in pool defaults
412 ScHeaderEditEngine aEditEngine( EditEngine::CreatePool(), sal_True );
413
414 ScHeaderFieldData aData;
415 FillDummyFieldData( aData );
416 aEditEngine.SetData( aData );
417
418 aEditEngine.SetText(*pData);
419 aRet = ScEditUtil::GetSpaceDelimitedString( aEditEngine );
420 }
421 return aRet;
422 }
423
setString(const rtl::OUString & aText)424 void SAL_CALL ScHeaderFooterTextObj::setString( const rtl::OUString& aText ) throw(uno::RuntimeException)
425 {
426 ScUnoGuard aGuard;
427 String aString(aText);
428
429 // for pure text, no font info is needed in pool defaults
430 ScHeaderEditEngine aEditEngine( EditEngine::CreatePool(), sal_True );
431 aEditEngine.SetText( aString );
432
433 aTextData.GetContentObj().UpdateText( aTextData.GetPart(), aEditEngine );
434 }
435
insertString(const uno::Reference<text::XTextRange> & xRange,const rtl::OUString & aString,sal_Bool bAbsorb)436 void SAL_CALL ScHeaderFooterTextObj::insertString( const uno::Reference<text::XTextRange>& xRange,
437 const rtl::OUString& aString, sal_Bool bAbsorb )
438 throw(uno::RuntimeException)
439 {
440 ScUnoGuard aGuard;
441 if (!pUnoText)
442 CreateUnoText_Impl();
443 pUnoText->insertString( xRange, aString, bAbsorb );
444 }
445
insertControlCharacter(const uno::Reference<text::XTextRange> & xRange,sal_Int16 nControlCharacter,sal_Bool bAbsorb)446 void SAL_CALL ScHeaderFooterTextObj::insertControlCharacter(
447 const uno::Reference<text::XTextRange>& xRange,
448 sal_Int16 nControlCharacter, sal_Bool bAbsorb )
449 throw(lang::IllegalArgumentException, uno::RuntimeException)
450 {
451 ScUnoGuard aGuard;
452 if (!pUnoText)
453 CreateUnoText_Impl();
454 pUnoText->insertControlCharacter( xRange, nControlCharacter, bAbsorb );
455 }
456
insertTextContent(const uno::Reference<text::XTextRange> & xRange,const uno::Reference<text::XTextContent> & xContent,sal_Bool bAbsorb)457 void SAL_CALL ScHeaderFooterTextObj::insertTextContent(
458 const uno::Reference<text::XTextRange >& xRange,
459 const uno::Reference<text::XTextContent >& xContent,
460 sal_Bool bAbsorb )
461 throw(lang::IllegalArgumentException, uno::RuntimeException)
462 {
463 ScUnoGuard aGuard;
464 if ( xContent.is() && xRange.is() )
465 {
466 ScHeaderFieldObj* pHeaderField = ScHeaderFieldObj::getImplementation( xContent );
467
468 SvxUnoTextRangeBase* pTextRange =
469 ScHeaderFooterTextCursor::getImplementation( xRange );
470
471 #if 0
472 if (!pTextRange)
473 pTextRange = (SvxUnoTextRange*)xRange->getImplementation(
474 SvxUnoTextRange_getReflection() );
475 //! bei SvxUnoTextRange testen, ob in passendem Objekt !!!
476 #endif
477
478 if ( pHeaderField && !pHeaderField->IsInserted() && pTextRange )
479 {
480 SvxEditSource* pEditSource = pTextRange->GetEditSource();
481 ESelection aSelection(pTextRange->GetSelection());
482
483 if (!bAbsorb)
484 {
485 // don't replace -> append at end
486 aSelection.Adjust();
487 aSelection.nStartPara = aSelection.nEndPara;
488 aSelection.nStartPos = aSelection.nEndPos;
489 }
490
491 SvxFieldItem aItem(pHeaderField->CreateFieldItem());
492
493 SvxTextForwarder* pForwarder = pEditSource->GetTextForwarder();
494 pForwarder->QuickInsertField( aItem, aSelection );
495 pEditSource->UpdateData();
496
497 // neue Selektion: ein Zeichen
498 aSelection.Adjust();
499 aSelection.nEndPara = aSelection.nStartPara;
500 aSelection.nEndPos = aSelection.nStartPos + 1;
501 pHeaderField->InitDoc( &aTextData.GetContentObj(), aTextData.GetPart(), aSelection );
502
503 // #91431# for bAbsorb=sal_False, the new selection must be behind the inserted content
504 // (the xml filter relies on this)
505 if (!bAbsorb)
506 aSelection.nStartPos = aSelection.nEndPos;
507
508 pTextRange->SetSelection( aSelection );
509
510 return;
511 }
512 }
513
514 if (!pUnoText)
515 CreateUnoText_Impl();
516 pUnoText->insertTextContent( xRange, xContent, bAbsorb );
517 }
518
removeTextContent(const uno::Reference<text::XTextContent> & xContent)519 void SAL_CALL ScHeaderFooterTextObj::removeTextContent(
520 const uno::Reference<text::XTextContent>& xContent )
521 throw(container::NoSuchElementException, uno::RuntimeException)
522 {
523 ScUnoGuard aGuard;
524 if ( xContent.is() )
525 {
526 ScHeaderFieldObj* pHeaderField = ScHeaderFieldObj::getImplementation( xContent );
527 if ( pHeaderField && pHeaderField->IsInserted() )
528 {
529 //! Testen, ob das Feld in dieser Zelle ist
530 pHeaderField->DeleteField();
531 return;
532 }
533 }
534 if (!pUnoText)
535 CreateUnoText_Impl();
536 pUnoText->removeTextContent( xContent );
537 }
538
getText()539 uno::Reference<text::XText> SAL_CALL ScHeaderFooterTextObj::getText() throw(uno::RuntimeException)
540 {
541 ScUnoGuard aGuard;
542 if (!pUnoText)
543 CreateUnoText_Impl();
544 return pUnoText->getText();
545 }
546
getStart()547 uno::Reference<text::XTextRange> SAL_CALL ScHeaderFooterTextObj::getStart() throw(uno::RuntimeException)
548 {
549 ScUnoGuard aGuard;
550 if (!pUnoText)
551 CreateUnoText_Impl();
552 return pUnoText->getStart();
553 }
554
getEnd()555 uno::Reference<text::XTextRange> SAL_CALL ScHeaderFooterTextObj::getEnd() throw(uno::RuntimeException)
556 {
557 ScUnoGuard aGuard;
558 if (!pUnoText)
559 CreateUnoText_Impl();
560 return pUnoText->getEnd();
561 }
562
563 // XTextFieldsSupplier
564
getTextFields()565 uno::Reference<container::XEnumerationAccess> SAL_CALL ScHeaderFooterTextObj::getTextFields()
566 throw(uno::RuntimeException)
567 {
568 ScUnoGuard aGuard;
569 // all fields
570 return new ScHeaderFieldsObj( &aTextData.GetContentObj(), aTextData.GetPart(), SC_SERVICE_INVALID );
571 }
572
getTextFieldMasters()573 uno::Reference<container::XNameAccess> SAL_CALL ScHeaderFooterTextObj::getTextFieldMasters()
574 throw(uno::RuntimeException)
575 {
576 // sowas gibts nicht im Calc (?)
577 return NULL;
578 }
579
580 // XTextRangeMover
581
moveTextRange(const uno::Reference<text::XTextRange> & xRange,sal_Int16 nParagraphs)582 void SAL_CALL ScHeaderFooterTextObj::moveTextRange(
583 const uno::Reference<text::XTextRange>& xRange,
584 sal_Int16 nParagraphs )
585 throw(uno::RuntimeException)
586 {
587 ScUnoGuard aGuard;
588 if (!pUnoText)
589 CreateUnoText_Impl();
590 pUnoText->moveTextRange( xRange, nParagraphs );
591 }
592
593 // XEnumerationAccess
594
createEnumeration()595 uno::Reference<container::XEnumeration> SAL_CALL ScHeaderFooterTextObj::createEnumeration()
596 throw(uno::RuntimeException)
597 {
598 ScUnoGuard aGuard;
599 if (!pUnoText)
600 CreateUnoText_Impl();
601 return pUnoText->createEnumeration();
602 }
603
604 // XElementAccess
605
getElementType()606 uno::Type SAL_CALL ScHeaderFooterTextObj::getElementType() throw(uno::RuntimeException)
607 {
608 ScUnoGuard aGuard;
609 if (!pUnoText)
610 CreateUnoText_Impl();
611 return pUnoText->getElementType();
612 }
613
hasElements()614 sal_Bool SAL_CALL ScHeaderFooterTextObj::hasElements() throw(uno::RuntimeException)
615 {
616 ScUnoGuard aGuard;
617 if (!pUnoText)
618 CreateUnoText_Impl();
619 return pUnoText->hasElements();
620 }
621
622 //------------------------------------------------------------------------
623
ScCellTextCursor(const ScCellTextCursor & rOther)624 ScCellTextCursor::ScCellTextCursor(const ScCellTextCursor& rOther) :
625 SvxUnoTextCursor( rOther ),
626 rTextObj( rOther.rTextObj )
627 {
628 rTextObj.acquire();
629 }
630
ScCellTextCursor(ScCellObj & rText)631 ScCellTextCursor::ScCellTextCursor(ScCellObj& rText) :
632 SvxUnoTextCursor( rText.GetUnoText() ),
633 rTextObj( rText )
634 {
635 rTextObj.acquire();
636 }
637
~ScCellTextCursor()638 ScCellTextCursor::~ScCellTextCursor() throw()
639 {
640 rTextObj.release();
641 }
642
643 // SvxUnoTextCursor methods reimplemented here to return the right objects:
644
getText()645 uno::Reference<text::XText> SAL_CALL ScCellTextCursor::getText() throw(uno::RuntimeException)
646 {
647 ScUnoGuard aGuard;
648 return &rTextObj;
649 }
650
getStart()651 uno::Reference<text::XTextRange> SAL_CALL ScCellTextCursor::getStart() throw(uno::RuntimeException)
652 {
653 ScUnoGuard aGuard;
654
655 //! use other object for range than cursor?
656
657 ScCellTextCursor* pNew = new ScCellTextCursor( *this );
658 uno::Reference<text::XTextRange> xRange( static_cast<SvxUnoTextRangeBase*>(pNew) );
659
660 ESelection aNewSel(GetSelection());
661 aNewSel.nEndPara = aNewSel.nStartPara;
662 aNewSel.nEndPos = aNewSel.nStartPos;
663 pNew->SetSelection( aNewSel );
664
665 return xRange;
666 }
667
getEnd()668 uno::Reference<text::XTextRange> SAL_CALL ScCellTextCursor::getEnd() throw(uno::RuntimeException)
669 {
670 ScUnoGuard aGuard;
671
672 //! use other object for range than cursor?
673
674 ScCellTextCursor* pNew = new ScCellTextCursor( *this );
675 uno::Reference<text::XTextRange> xRange( static_cast<SvxUnoTextRangeBase*>(pNew) );
676
677 ESelection aNewSel(GetSelection());
678 aNewSel.nStartPara = aNewSel.nEndPara;
679 aNewSel.nStartPos = aNewSel.nEndPos;
680 pNew->SetSelection( aNewSel );
681
682 return xRange;
683 }
684
685 // XUnoTunnel
686
getSomething(const uno::Sequence<sal_Int8> & rId)687 sal_Int64 SAL_CALL ScCellTextCursor::getSomething(
688 const uno::Sequence<sal_Int8 >& rId ) throw(uno::RuntimeException)
689 {
690 if ( rId.getLength() == 16 &&
691 0 == rtl_compareMemory( getUnoTunnelId().getConstArray(),
692 rId.getConstArray(), 16 ) )
693 {
694 return sal::static_int_cast<sal_Int64>(reinterpret_cast<sal_IntPtr>(this));
695 }
696 return SvxUnoTextCursor::getSomething( rId );
697 }
698
699 // static
getUnoTunnelId()700 const uno::Sequence<sal_Int8>& ScCellTextCursor::getUnoTunnelId()
701 {
702 static uno::Sequence<sal_Int8> * pSeq = 0;
703 if( !pSeq )
704 {
705 osl::Guard< osl::Mutex > aGuard( osl::Mutex::getGlobalMutex() );
706 if( !pSeq )
707 {
708 static uno::Sequence< sal_Int8 > aSeq( 16 );
709 rtl_createUuid( (sal_uInt8*)aSeq.getArray(), 0, sal_True );
710 pSeq = &aSeq;
711 }
712 }
713 return *pSeq;
714 }
715
716 // static
getImplementation(const uno::Reference<uno::XInterface> xObj)717 ScCellTextCursor* ScCellTextCursor::getImplementation( const uno::Reference<uno::XInterface> xObj )
718 {
719 ScCellTextCursor* pRet = NULL;
720 uno::Reference<lang::XUnoTunnel> xUT( xObj, uno::UNO_QUERY );
721 if (xUT.is())
722 pRet = reinterpret_cast<ScCellTextCursor*>(sal::static_int_cast<sal_IntPtr>(xUT->getSomething(getUnoTunnelId())));
723 return pRet;
724 }
725
726 //------------------------------------------------------------------------
727
ScHeaderFooterTextCursor(const ScHeaderFooterTextCursor & rOther)728 ScHeaderFooterTextCursor::ScHeaderFooterTextCursor(const ScHeaderFooterTextCursor& rOther) :
729 SvxUnoTextCursor( rOther ),
730 rTextObj( rOther.rTextObj )
731 {
732 rTextObj.acquire();
733 }
734
ScHeaderFooterTextCursor(ScHeaderFooterTextObj & rText)735 ScHeaderFooterTextCursor::ScHeaderFooterTextCursor(ScHeaderFooterTextObj& rText) :
736 SvxUnoTextCursor( rText.GetUnoText() ),
737 rTextObj( rText )
738 {
739 rTextObj.acquire();
740 }
741
~ScHeaderFooterTextCursor()742 ScHeaderFooterTextCursor::~ScHeaderFooterTextCursor() throw()
743 {
744 rTextObj.release();
745 }
746
747 // SvxUnoTextCursor methods reimplemented here to return the right objects:
748
getText()749 uno::Reference<text::XText> SAL_CALL ScHeaderFooterTextCursor::getText() throw(uno::RuntimeException)
750 {
751 ScUnoGuard aGuard;
752 return &rTextObj;
753 }
754
getStart()755 uno::Reference<text::XTextRange> SAL_CALL ScHeaderFooterTextCursor::getStart() throw(uno::RuntimeException)
756 {
757 ScUnoGuard aGuard;
758
759 //! use other object for range than cursor?
760
761 ScHeaderFooterTextCursor* pNew = new ScHeaderFooterTextCursor( *this );
762 uno::Reference<text::XTextRange> xRange( static_cast<SvxUnoTextRangeBase*>(pNew) );
763
764 ESelection aNewSel(GetSelection());
765 aNewSel.nEndPara = aNewSel.nStartPara;
766 aNewSel.nEndPos = aNewSel.nStartPos;
767 pNew->SetSelection( aNewSel );
768
769 return xRange;
770 }
771
getEnd()772 uno::Reference<text::XTextRange> SAL_CALL ScHeaderFooterTextCursor::getEnd() throw(uno::RuntimeException)
773 {
774 ScUnoGuard aGuard;
775
776 //! use other object for range than cursor?
777
778 ScHeaderFooterTextCursor* pNew = new ScHeaderFooterTextCursor( *this );
779 uno::Reference<text::XTextRange> xRange( static_cast<SvxUnoTextRangeBase*>(pNew) );
780
781 ESelection aNewSel(GetSelection());
782 aNewSel.nStartPara = aNewSel.nEndPara;
783 aNewSel.nStartPos = aNewSel.nEndPos;
784 pNew->SetSelection( aNewSel );
785
786 return xRange;
787 }
788
789 // XUnoTunnel
790
getSomething(const uno::Sequence<sal_Int8> & rId)791 sal_Int64 SAL_CALL ScHeaderFooterTextCursor::getSomething(
792 const uno::Sequence<sal_Int8 >& rId ) throw(uno::RuntimeException)
793 {
794 if ( rId.getLength() == 16 &&
795 0 == rtl_compareMemory( getUnoTunnelId().getConstArray(),
796 rId.getConstArray(), 16 ) )
797 {
798 return sal::static_int_cast<sal_Int64>(reinterpret_cast<sal_IntPtr>(this));
799 }
800 return SvxUnoTextCursor::getSomething( rId );
801 }
802
803 // static
getUnoTunnelId()804 const uno::Sequence<sal_Int8>& ScHeaderFooterTextCursor::getUnoTunnelId()
805 {
806 static uno::Sequence<sal_Int8> * pSeq = 0;
807 if( !pSeq )
808 {
809 osl::Guard< osl::Mutex > aGuard( osl::Mutex::getGlobalMutex() );
810 if( !pSeq )
811 {
812 static uno::Sequence< sal_Int8 > aSeq( 16 );
813 rtl_createUuid( (sal_uInt8*)aSeq.getArray(), 0, sal_True );
814 pSeq = &aSeq;
815 }
816 }
817 return *pSeq;
818 }
819
820 // static
getImplementation(const uno::Reference<uno::XInterface> xObj)821 ScHeaderFooterTextCursor* ScHeaderFooterTextCursor::getImplementation(
822 const uno::Reference<uno::XInterface> xObj )
823 {
824 ScHeaderFooterTextCursor* pRet = NULL;
825 uno::Reference<lang::XUnoTunnel> xUT( xObj, uno::UNO_QUERY );
826 if (xUT.is())
827 pRet = reinterpret_cast<ScHeaderFooterTextCursor*>(sal::static_int_cast<sal_IntPtr>(xUT->getSomething(getUnoTunnelId())));
828 return pRet;
829 }
830
831 //------------------------------------------------------------------------
832
ScDrawTextCursor(const ScDrawTextCursor & rOther)833 ScDrawTextCursor::ScDrawTextCursor(const ScDrawTextCursor& rOther) :
834 SvxUnoTextCursor( rOther ),
835 xParentText( rOther.xParentText )
836 {
837 }
838
ScDrawTextCursor(const uno::Reference<text::XText> & xParent,const SvxUnoTextBase & rText)839 ScDrawTextCursor::ScDrawTextCursor( const uno::Reference<text::XText>& xParent,
840 const SvxUnoTextBase& rText ) :
841 SvxUnoTextCursor( rText ),
842 xParentText( xParent )
843
844 {
845 }
846
~ScDrawTextCursor()847 ScDrawTextCursor::~ScDrawTextCursor() throw()
848 {
849 }
850
851 // SvxUnoTextCursor methods reimplemented here to return the right objects:
852
getText()853 uno::Reference<text::XText> SAL_CALL ScDrawTextCursor::getText() throw(uno::RuntimeException)
854 {
855 ScUnoGuard aGuard;
856 return xParentText;
857 }
858
getStart()859 uno::Reference<text::XTextRange> SAL_CALL ScDrawTextCursor::getStart() throw(uno::RuntimeException)
860 {
861 ScUnoGuard aGuard;
862
863 //! use other object for range than cursor?
864
865 ScDrawTextCursor* pNew = new ScDrawTextCursor( *this );
866 uno::Reference<text::XTextRange> xRange( static_cast<SvxUnoTextRangeBase*>(pNew) );
867
868 ESelection aNewSel(GetSelection());
869 aNewSel.nEndPara = aNewSel.nStartPara;
870 aNewSel.nEndPos = aNewSel.nStartPos;
871 pNew->SetSelection( aNewSel );
872
873 return xRange;
874 }
875
getEnd()876 uno::Reference<text::XTextRange> SAL_CALL ScDrawTextCursor::getEnd() throw(uno::RuntimeException)
877 {
878 ScUnoGuard aGuard;
879
880 //! use other object for range than cursor?
881
882 ScDrawTextCursor* pNew = new ScDrawTextCursor( *this );
883 uno::Reference<text::XTextRange> xRange( static_cast<SvxUnoTextRangeBase*>(pNew) );
884
885 ESelection aNewSel(GetSelection());
886 aNewSel.nStartPara = aNewSel.nEndPara;
887 aNewSel.nStartPos = aNewSel.nEndPos;
888 pNew->SetSelection( aNewSel );
889
890 return xRange;
891 }
892
893 // XUnoTunnel
894
getSomething(const uno::Sequence<sal_Int8> & rId)895 sal_Int64 SAL_CALL ScDrawTextCursor::getSomething(
896 const uno::Sequence<sal_Int8 >& rId ) throw(uno::RuntimeException)
897 {
898 if ( rId.getLength() == 16 &&
899 0 == rtl_compareMemory( getUnoTunnelId().getConstArray(),
900 rId.getConstArray(), 16 ) )
901 {
902 return sal::static_int_cast<sal_Int64>(reinterpret_cast<sal_IntPtr>(this));
903 }
904 return SvxUnoTextCursor::getSomething( rId );
905 }
906
907 // static
getUnoTunnelId()908 const uno::Sequence<sal_Int8>& ScDrawTextCursor::getUnoTunnelId()
909 {
910 static uno::Sequence<sal_Int8> * pSeq = 0;
911 if( !pSeq )
912 {
913 osl::Guard< osl::Mutex > aGuard( osl::Mutex::getGlobalMutex() );
914 if( !pSeq )
915 {
916 static uno::Sequence< sal_Int8 > aSeq( 16 );
917 rtl_createUuid( (sal_uInt8*)aSeq.getArray(), 0, sal_True );
918 pSeq = &aSeq;
919 }
920 }
921 return *pSeq;
922 }
923
924 // static
getImplementation(const uno::Reference<uno::XInterface> xObj)925 ScDrawTextCursor* ScDrawTextCursor::getImplementation( const uno::Reference<uno::XInterface> xObj )
926 {
927 ScDrawTextCursor* pRet = NULL;
928 uno::Reference<lang::XUnoTunnel> xUT( xObj, uno::UNO_QUERY );
929 if (xUT.is())
930 pRet = reinterpret_cast<ScDrawTextCursor*>(sal::static_int_cast<sal_IntPtr>(xUT->getSomething(getUnoTunnelId())));
931 return pRet;
932 }
933
934 //------------------------------------------------------------------------
935
ScSimpleEditSourceHelper()936 ScSimpleEditSourceHelper::ScSimpleEditSourceHelper()
937 {
938 SfxItemPool* pEnginePool = EditEngine::CreatePool();
939 pEnginePool->SetDefaultMetric( SFX_MAPUNIT_100TH_MM );
940 pEnginePool->FreezeIdRanges();
941
942 pEditEngine = new ScFieldEditEngine( pEnginePool, NULL, sal_True ); // TRUE: become owner of pool
943 pForwarder = new SvxEditEngineForwarder( *pEditEngine );
944 pOriginalSource = new ScSimpleEditSource( pForwarder );
945 }
946
~ScSimpleEditSourceHelper()947 ScSimpleEditSourceHelper::~ScSimpleEditSourceHelper()
948 {
949 ScUnoGuard aGuard; // needed for EditEngine dtor
950
951 delete pOriginalSource;
952 delete pForwarder;
953 delete pEditEngine;
954 }
955
ScEditEngineTextObj()956 ScEditEngineTextObj::ScEditEngineTextObj() :
957 SvxUnoText( GetOriginalSource(), ScCellObj::GetEditPropertySet(), uno::Reference<text::XText>() )
958 {
959 }
960
~ScEditEngineTextObj()961 ScEditEngineTextObj::~ScEditEngineTextObj() throw()
962 {
963 }
964
SetText(const EditTextObject & rTextObject)965 void ScEditEngineTextObj::SetText( const EditTextObject& rTextObject )
966 {
967 GetEditEngine()->SetText( rTextObject );
968
969 ESelection aSel;
970 ::GetSelection( aSel, GetEditSource()->GetTextForwarder() );
971 SetSelection( aSel );
972 }
973
CreateTextObject()974 EditTextObject* ScEditEngineTextObj::CreateTextObject()
975 {
976 return GetEditEngine()->CreateTextObject();
977 }
978
979 //------------------------------------------------------------------------
980
ScCellTextData(ScDocShell * pDocSh,const ScAddress & rP)981 ScCellTextData::ScCellTextData(ScDocShell* pDocSh, const ScAddress& rP) :
982 pDocShell( pDocSh ),
983 aCellPos( rP ),
984 pEditEngine( NULL ),
985 pForwarder( NULL ),
986 pOriginalSource( NULL ),
987 bDataValid( sal_False ),
988 bInUpdate( sal_False ),
989 bDirty( sal_False ),
990 bDoUpdate( sal_True )
991 {
992 if (pDocShell)
993 pDocShell->GetDocument()->AddUnoObject(*this);
994 }
995
~ScCellTextData()996 ScCellTextData::~ScCellTextData()
997 {
998 ScUnoGuard aGuard; // needed for EditEngine dtor
999
1000 if (pDocShell)
1001 {
1002 pDocShell->GetDocument()->RemoveUnoObject(*this);
1003 pDocShell->GetDocument()->DisposeFieldEditEngine(pEditEngine);
1004 }
1005 else
1006 delete pEditEngine;
1007
1008 delete pForwarder;
1009
1010 delete pOriginalSource;
1011 }
1012
GetOriginalSource()1013 ScSharedCellEditSource* ScCellTextData::GetOriginalSource()
1014 {
1015 if (!pOriginalSource)
1016 pOriginalSource = new ScSharedCellEditSource( this );
1017 return pOriginalSource;
1018 }
1019
GetCellText(const ScAddress & rCellPos,String & rText)1020 void ScCellTextData::GetCellText(const ScAddress& rCellPos, String& rText)
1021 {
1022 if (pDocShell)
1023 {
1024 ScDocument* pDoc = pDocShell->GetDocument();
1025 pDoc->GetInputString( rCellPos.Col(), rCellPos.Row(), rCellPos.Tab(), rText );
1026 }
1027 }
1028
GetTextForwarder()1029 SvxTextForwarder* ScCellTextData::GetTextForwarder()
1030 {
1031 if (!pEditEngine)
1032 {
1033 if ( pDocShell )
1034 {
1035 ScDocument* pDoc = pDocShell->GetDocument();
1036 pEditEngine = pDoc->CreateFieldEditEngine();
1037 }
1038 else
1039 {
1040 SfxItemPool* pEnginePool = EditEngine::CreatePool();
1041 pEnginePool->FreezeIdRanges();
1042 pEditEngine = new ScFieldEditEngine( pEnginePool, NULL, sal_True );
1043 }
1044 // currently, GetPortions doesn't work if UpdateMode is sal_False,
1045 // this will be fixed (in EditEngine) by src600
1046 // pEditEngine->SetUpdateMode( sal_False );
1047 pEditEngine->EnableUndo( sal_False );
1048 if (pDocShell)
1049 pEditEngine->SetRefDevice(pDocShell->GetRefDevice());
1050 else
1051 pEditEngine->SetRefMapMode( MAP_100TH_MM );
1052 pForwarder = new SvxEditEngineForwarder(*pEditEngine);
1053 }
1054
1055 if (bDataValid)
1056 return pForwarder;
1057
1058 String aText;
1059
1060 if (pDocShell)
1061 {
1062 ScDocument* pDoc = pDocShell->GetDocument();
1063
1064 SfxItemSet aDefaults( pEditEngine->GetEmptyItemSet() );
1065 if( const ScPatternAttr* pPattern =
1066 pDoc->GetPattern( aCellPos.Col(), aCellPos.Row(), aCellPos.Tab() ) )
1067 {
1068 pPattern->FillEditItemSet( &aDefaults );
1069 pPattern->FillEditParaItems( &aDefaults ); // including alignment etc. (for reading)
1070 }
1071
1072 const ScBaseCell* pCell = pDoc->GetCell( aCellPos );
1073 if ( pCell && pCell->GetCellType() == CELLTYPE_EDIT )
1074 pEditEngine->SetTextNewDefaults( *((const ScEditCell*)pCell)->GetData(), aDefaults );
1075 else
1076 {
1077 GetCellText( aCellPos, aText );
1078 if (aText.Len())
1079 pEditEngine->SetTextNewDefaults( aText, aDefaults );
1080 else
1081 pEditEngine->SetDefaults(aDefaults);
1082 }
1083 }
1084
1085 bDataValid = sal_True;
1086 return pForwarder;
1087 }
1088
UpdateData()1089 void ScCellTextData::UpdateData()
1090 {
1091 if ( bDoUpdate )
1092 {
1093 DBG_ASSERT(pEditEngine != NULL, "no EditEngine for UpdateData()");
1094 if ( pDocShell && pEditEngine )
1095 {
1096 // during the own UpdateData call, bDataValid must not be reset,
1097 // or things like attributes after the text would be lost
1098 // (are not stored in the cell)
1099
1100 bInUpdate = sal_True; // prevents bDataValid from being reset
1101
1102 ScDocFunc aFunc(*pDocShell);
1103 aFunc.PutData( aCellPos, *pEditEngine, sal_False, sal_True ); // always as text
1104
1105 bInUpdate = sal_False;
1106 bDirty = sal_False;
1107 }
1108 }
1109 else
1110 bDirty = sal_True;
1111 }
1112
Notify(SfxBroadcaster &,const SfxHint & rHint)1113 void ScCellTextData::Notify( SfxBroadcaster&, const SfxHint& rHint )
1114 {
1115 if ( rHint.ISA( ScUpdateRefHint ) )
1116 {
1117 // const ScUpdateRefHint& rRef = (const ScUpdateRefHint&)rHint;
1118
1119 //! Ref-Update
1120 }
1121 else if ( rHint.ISA( SfxSimpleHint ) )
1122 {
1123 sal_uLong nId = ((const SfxSimpleHint&)rHint).GetId();
1124 if ( nId == SFX_HINT_DYING )
1125 {
1126 pDocShell = NULL; // invalid now
1127
1128 DELETEZ( pForwarder );
1129 DELETEZ( pEditEngine ); // EditEngine uses document's pool
1130 }
1131 else if ( nId == SFX_HINT_DATACHANGED )
1132 {
1133 if (!bInUpdate) // not for own UpdateData calls
1134 bDataValid = sal_False; // text has to be read from the cell again
1135 }
1136 }
1137 }
1138
ScCellTextObj(ScDocShell * pDocSh,const ScAddress & rP)1139 ScCellTextObj::ScCellTextObj(ScDocShell* pDocSh, const ScAddress& rP) :
1140 ScCellTextData( pDocSh, rP ),
1141 SvxUnoText( GetOriginalSource(), ScCellObj::GetEditPropertySet(), uno::Reference<text::XText>() )
1142 {
1143 }
1144
~ScCellTextObj()1145 ScCellTextObj::~ScCellTextObj() throw()
1146 {
1147 }
1148
1149