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