xref: /AOO41X/main/sc/source/ui/unoobj/textuno.cxx (revision b3f79822e811ac3493b185030a72c3c5a51f32d8)
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