merge the formfield patch from ooo-build
[ooovba.git] / sc / source / ui / unoobj / textuno.cxx
blob1595d8af3d3a7e008fd95d3a5c408fd89dbe2a9b
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: textuno.cxx,v $
10 * $Revision: 1.25.32.2 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sc.hxx"
36 #include "scitems.hxx"
37 #include <svx/eeitem.hxx>
40 #include <svx/editeng.hxx>
41 #include <svx/editobj.hxx>
42 #include <svx/flditem.hxx>
43 #include <svx/unomid.hxx>
44 #include <svx/unoprnms.hxx>
45 #include <svx/unofored.hxx>
46 #include <rtl/uuid.h>
47 #include <vcl/virdev.hxx>
48 #include <com/sun/star/awt/FontSlant.hpp>
50 #include <com/sun/star/beans/PropertyAttribute.hpp>
52 #include "textuno.hxx"
53 #include "fielduno.hxx"
54 #include "servuno.hxx"
55 #include "editsrc.hxx"
56 #include "docsh.hxx"
57 #include "editutil.hxx"
58 #include "unoguard.hxx"
59 #include "miscuno.hxx"
60 #include "cellsuno.hxx"
61 #include "hints.hxx"
62 #include "patattr.hxx"
63 #include "cell.hxx"
64 #include "docfunc.hxx"
65 #include "scmod.hxx"
67 using namespace com::sun::star;
69 //------------------------------------------------------------------------
71 const SvxItemPropertySet * lcl_GetHdFtPropertySet()
73 static SfxItemPropertyMapEntry aHdFtPropertyMap_Impl[] =
75 SVX_UNOEDIT_CHAR_PROPERTIES,
76 SVX_UNOEDIT_FONT_PROPERTIES,
77 SVX_UNOEDIT_PARA_PROPERTIES,
78 SVX_UNOEDIT_NUMBERING_PROPERTIE, // for completeness of service ParagraphProperties
79 {0,0,0,0,0,0}
81 static BOOL bTwipsSet = FALSE;
83 if (!bTwipsSet)
85 // modify PropertyMap to include CONVERT_TWIPS flag for font height
86 // (headers/footers are in twips)
88 SfxItemPropertyMapEntry* pEntry = aHdFtPropertyMap_Impl;
89 while (pEntry->pName)
91 if ( ( pEntry->nWID == EE_CHAR_FONTHEIGHT ||
92 pEntry->nWID == EE_CHAR_FONTHEIGHT_CJK ||
93 pEntry->nWID == EE_CHAR_FONTHEIGHT_CTL ) &&
94 pEntry->nMemberId == MID_FONTHEIGHT )
96 pEntry->nMemberId |= CONVERT_TWIPS;
99 ++pEntry;
101 bTwipsSet = TRUE;
103 static SvxItemPropertySet aHdFtPropertySet_Impl( aHdFtPropertyMap_Impl );
104 return &aHdFtPropertySet_Impl;
107 //------------------------------------------------------------------------
109 SC_SIMPLE_SERVICE_INFO( ScHeaderFooterContentObj, "ScHeaderFooterContentObj", "com.sun.star.sheet.HeaderFooterContent" )
110 SC_SIMPLE_SERVICE_INFO( ScHeaderFooterTextObj, "ScHeaderFooterTextObj", "stardiv.one.Text.Text" )
112 //------------------------------------------------------------------------
114 ScHeaderFooterContentObj::ScHeaderFooterContentObj( const EditTextObject* pLeft,
115 const EditTextObject* pCenter,
116 const EditTextObject* pRight ) :
117 pLeftText ( NULL ),
118 pCenterText ( NULL ),
119 pRightText ( NULL )
121 if ( pLeft )
122 pLeftText = pLeft->Clone();
123 if ( pCenter )
124 pCenterText = pCenter->Clone();
125 if ( pRight )
126 pRightText = pRight->Clone();
129 ScHeaderFooterContentObj::~ScHeaderFooterContentObj()
131 delete pLeftText;
132 delete pCenterText;
133 delete pRightText;
136 void ScHeaderFooterContentObj::AddListener( SfxListener& rListener )
138 rListener.StartListening( aBC );
141 void ScHeaderFooterContentObj::RemoveListener( SfxListener& rListener )
143 rListener.EndListening( aBC );
146 void ScHeaderFooterContentObj::UpdateText( USHORT nPart, EditEngine& rSource )
148 EditTextObject* pNew = rSource.CreateTextObject();
149 switch (nPart)
151 case SC_HDFT_LEFT:
152 delete pLeftText;
153 pLeftText = pNew;
154 break;
155 case SC_HDFT_CENTER:
156 delete pCenterText;
157 pCenterText = pNew;
158 break;
159 default: // SC_HDFT_RIGHT
160 delete pRightText;
161 pRightText = pNew;
162 break;
165 aBC.Broadcast( ScHeaderFooterChangedHint( nPart ) );
168 // XHeaderFooterContent
170 uno::Reference<text::XText> SAL_CALL ScHeaderFooterContentObj::getLeftText()
171 throw(uno::RuntimeException)
173 ScUnoGuard aGuard;
174 return new ScHeaderFooterTextObj( *this, SC_HDFT_LEFT );
177 uno::Reference<text::XText> SAL_CALL ScHeaderFooterContentObj::getCenterText()
178 throw(uno::RuntimeException)
180 ScUnoGuard aGuard;
181 return new ScHeaderFooterTextObj( *this, SC_HDFT_CENTER );
184 uno::Reference<text::XText> SAL_CALL ScHeaderFooterContentObj::getRightText()
185 throw(uno::RuntimeException)
187 ScUnoGuard aGuard;
188 return new ScHeaderFooterTextObj( *this, SC_HDFT_RIGHT );
191 // XUnoTunnel
193 sal_Int64 SAL_CALL ScHeaderFooterContentObj::getSomething(
194 const uno::Sequence<sal_Int8 >& rId ) throw(uno::RuntimeException)
196 if ( rId.getLength() == 16 &&
197 0 == rtl_compareMemory( getUnoTunnelId().getConstArray(),
198 rId.getConstArray(), 16 ) )
200 return sal::static_int_cast<sal_Int64>(reinterpret_cast<sal_IntPtr>(this));
202 return 0;
205 // static
206 const uno::Sequence<sal_Int8>& ScHeaderFooterContentObj::getUnoTunnelId()
208 static uno::Sequence<sal_Int8> * pSeq = 0;
209 if( !pSeq )
211 osl::Guard< osl::Mutex > aGuard( osl::Mutex::getGlobalMutex() );
212 if( !pSeq )
214 static uno::Sequence< sal_Int8 > aSeq( 16 );
215 rtl_createUuid( (sal_uInt8*)aSeq.getArray(), 0, sal_True );
216 pSeq = &aSeq;
219 return *pSeq;
222 // static
223 ScHeaderFooterContentObj* ScHeaderFooterContentObj::getImplementation(
224 const uno::Reference<sheet::XHeaderFooterContent> xObj )
226 ScHeaderFooterContentObj* pRet = NULL;
227 uno::Reference<lang::XUnoTunnel> xUT( xObj, uno::UNO_QUERY );
228 if (xUT.is())
229 pRet = reinterpret_cast<ScHeaderFooterContentObj*>(sal::static_int_cast<sal_IntPtr>(xUT->getSomething(getUnoTunnelId())));
230 return pRet;
234 //------------------------------------------------------------------------
236 ScHeaderFooterTextData::ScHeaderFooterTextData( ScHeaderFooterContentObj& rContent,
237 USHORT nP ) :
238 rContentObj( rContent ),
239 nPart( nP ),
240 pEditEngine( NULL ),
241 pForwarder( NULL ),
242 bDataValid( FALSE ),
243 bInUpdate( FALSE )
245 rContentObj.acquire(); // must not go away
246 rContentObj.AddListener( *this );
249 ScHeaderFooterTextData::~ScHeaderFooterTextData()
251 ScUnoGuard aGuard; // needed for EditEngine dtor
253 rContentObj.RemoveListener( *this );
255 delete pForwarder;
256 delete pEditEngine;
258 rContentObj.release();
261 void ScHeaderFooterTextData::Notify( SfxBroadcaster&, const SfxHint& rHint )
263 if ( rHint.ISA( ScHeaderFooterChangedHint ) )
265 if ( ((const ScHeaderFooterChangedHint&)rHint).GetPart() == nPart )
267 if (!bInUpdate) // not for own updates
268 bDataValid = FALSE; // text has to be fetched again
273 SvxTextForwarder* ScHeaderFooterTextData::GetTextForwarder()
275 if (!pEditEngine)
277 SfxItemPool* pEnginePool = EditEngine::CreatePool();
278 pEnginePool->FreezeIdRanges();
279 ScHeaderEditEngine* pHdrEngine = new ScHeaderEditEngine( pEnginePool, TRUE );
281 pHdrEngine->EnableUndo( FALSE );
282 pHdrEngine->SetRefMapMode( MAP_TWIP );
284 // default font must be set, independently of document
285 // -> use global pool from module
287 SfxItemSet aDefaults( pHdrEngine->GetEmptyItemSet() );
288 const ScPatternAttr& rPattern = (const ScPatternAttr&)SC_MOD()->GetPool().GetDefaultItem(ATTR_PATTERN);
289 rPattern.FillEditItemSet( &aDefaults );
290 // FillEditItemSet adjusts font height to 1/100th mm,
291 // but for header/footer twips is needed, as in the PatternAttr:
292 aDefaults.Put( rPattern.GetItem(ATTR_FONT_HEIGHT), EE_CHAR_FONTHEIGHT );
293 aDefaults.Put( rPattern.GetItem(ATTR_CJK_FONT_HEIGHT), EE_CHAR_FONTHEIGHT_CJK );
294 aDefaults.Put( rPattern.GetItem(ATTR_CTL_FONT_HEIGHT), EE_CHAR_FONTHEIGHT_CTL );
295 pHdrEngine->SetDefaults( aDefaults );
297 ScHeaderFieldData aData;
298 ScHeaderFooterTextObj::FillDummyFieldData( aData );
299 pHdrEngine->SetData( aData );
301 pEditEngine = pHdrEngine;
302 pForwarder = new SvxEditEngineForwarder(*pEditEngine);
305 if (bDataValid)
306 return pForwarder;
308 const EditTextObject* pData;
309 if (nPart == SC_HDFT_LEFT)
310 pData = rContentObj.GetLeftEditObject();
311 else if (nPart == SC_HDFT_CENTER)
312 pData = rContentObj.GetCenterEditObject();
313 else
314 pData = rContentObj.GetRightEditObject();
316 if (pData)
317 pEditEngine->SetText(*pData);
319 bDataValid = TRUE;
320 return pForwarder;
323 void ScHeaderFooterTextData::UpdateData()
325 if ( pEditEngine )
327 bInUpdate = TRUE; // don't reset bDataValid during UpdateText
329 rContentObj.UpdateText( nPart, *pEditEngine );
331 bInUpdate = FALSE;
335 //------------------------------------------------------------------------
337 ScHeaderFooterTextObj::ScHeaderFooterTextObj( ScHeaderFooterContentObj& rContent,
338 USHORT nP ) :
339 aTextData( rContent, nP ),
340 pUnoText( NULL )
342 // ScHeaderFooterTextData acquires rContent
343 // pUnoText is created on demand (getString/setString work without it)
346 void ScHeaderFooterTextObj::CreateUnoText_Impl()
348 if ( !pUnoText )
350 // can't be aggregated because getString/setString is handled here
351 ScSharedHeaderFooterEditSource aEditSource( &aTextData );
352 pUnoText = new SvxUnoText( &aEditSource, lcl_GetHdFtPropertySet(), uno::Reference<text::XText>() );
353 pUnoText->acquire();
357 ScHeaderFooterTextObj::~ScHeaderFooterTextObj()
359 if (pUnoText)
360 pUnoText->release();
363 const SvxUnoText& ScHeaderFooterTextObj::GetUnoText()
365 if (!pUnoText)
366 CreateUnoText_Impl();
367 return *pUnoText;
370 // XText
372 uno::Reference<text::XTextCursor> SAL_CALL ScHeaderFooterTextObj::createTextCursor()
373 throw(uno::RuntimeException)
375 ScUnoGuard aGuard;
376 return new ScHeaderFooterTextCursor( *this );
379 uno::Reference<text::XTextCursor> SAL_CALL ScHeaderFooterTextObj::createTextCursorByRange(
380 const uno::Reference<text::XTextRange>& aTextPosition )
381 throw(uno::RuntimeException)
383 ScUnoGuard aGuard;
384 if (!pUnoText)
385 CreateUnoText_Impl();
386 return pUnoText->createTextCursorByRange(aTextPosition);
387 //! wie ScCellObj::createTextCursorByRange, wenn SvxUnoTextRange_getReflection verfuegbar
390 void ScHeaderFooterTextObj::FillDummyFieldData( ScHeaderFieldData& rData ) // static
392 String aDummy(String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM( "???" )));
393 rData.aTitle = aDummy;
394 rData.aLongDocName = aDummy;
395 rData.aShortDocName = aDummy;
396 rData.aTabName = aDummy;
397 rData.nPageNo = 1;
398 rData.nTotalPages = 99;
401 rtl::OUString SAL_CALL ScHeaderFooterTextObj::getString() throw(uno::RuntimeException)
403 ScUnoGuard aGuard;
404 rtl::OUString aRet;
405 const EditTextObject* pData;
407 USHORT nPart = aTextData.GetPart();
408 ScHeaderFooterContentObj& rContentObj = aTextData.GetContentObj();
410 if (nPart == SC_HDFT_LEFT)
411 pData = rContentObj.GetLeftEditObject();
412 else if (nPart == SC_HDFT_CENTER)
413 pData = rContentObj.GetCenterEditObject();
414 else
415 pData = rContentObj.GetRightEditObject();
416 if (pData)
418 // for pure text, no font info is needed in pool defaults
419 ScHeaderEditEngine aEditEngine( EditEngine::CreatePool(), TRUE );
421 ScHeaderFieldData aData;
422 FillDummyFieldData( aData );
423 aEditEngine.SetData( aData );
425 aEditEngine.SetText(*pData);
426 aRet = ScEditUtil::GetSpaceDelimitedString( aEditEngine );
428 return aRet;
431 void SAL_CALL ScHeaderFooterTextObj::setString( const rtl::OUString& aText ) throw(uno::RuntimeException)
433 ScUnoGuard aGuard;
434 String aString(aText);
436 // for pure text, no font info is needed in pool defaults
437 ScHeaderEditEngine aEditEngine( EditEngine::CreatePool(), TRUE );
438 aEditEngine.SetText( aString );
440 aTextData.GetContentObj().UpdateText( aTextData.GetPart(), aEditEngine );
443 void SAL_CALL ScHeaderFooterTextObj::insertString( const uno::Reference<text::XTextRange>& xRange,
444 const rtl::OUString& aString, sal_Bool bAbsorb )
445 throw(uno::RuntimeException)
447 ScUnoGuard aGuard;
448 if (!pUnoText)
449 CreateUnoText_Impl();
450 pUnoText->insertString( xRange, aString, bAbsorb );
453 void SAL_CALL ScHeaderFooterTextObj::insertControlCharacter(
454 const uno::Reference<text::XTextRange>& xRange,
455 sal_Int16 nControlCharacter, sal_Bool bAbsorb )
456 throw(lang::IllegalArgumentException, uno::RuntimeException)
458 ScUnoGuard aGuard;
459 if (!pUnoText)
460 CreateUnoText_Impl();
461 pUnoText->insertControlCharacter( xRange, nControlCharacter, bAbsorb );
464 void SAL_CALL ScHeaderFooterTextObj::insertTextContent(
465 const uno::Reference<text::XTextRange >& xRange,
466 const uno::Reference<text::XTextContent >& xContent,
467 sal_Bool bAbsorb )
468 throw(lang::IllegalArgumentException, uno::RuntimeException)
470 ScUnoGuard aGuard;
471 if ( xContent.is() && xRange.is() )
473 ScHeaderFieldObj* pHeaderField = ScHeaderFieldObj::getImplementation( xContent );
475 SvxUnoTextRangeBase* pTextRange =
476 ScHeaderFooterTextCursor::getImplementation( xRange );
478 #if 0
479 if (!pTextRange)
480 pTextRange = (SvxUnoTextRange*)xRange->getImplementation(
481 SvxUnoTextRange_getReflection() );
482 //! bei SvxUnoTextRange testen, ob in passendem Objekt !!!
483 #endif
485 if ( pHeaderField && !pHeaderField->IsInserted() && pTextRange )
487 SvxEditSource* pEditSource = pTextRange->GetEditSource();
488 ESelection aSelection(pTextRange->GetSelection());
490 if (!bAbsorb)
492 // don't replace -> append at end
493 aSelection.Adjust();
494 aSelection.nStartPara = aSelection.nEndPara;
495 aSelection.nStartPos = aSelection.nEndPos;
498 SvxFieldItem aItem(pHeaderField->CreateFieldItem());
500 SvxTextForwarder* pForwarder = pEditSource->GetTextForwarder();
501 pForwarder->QuickInsertField( aItem, aSelection );
502 pEditSource->UpdateData();
504 // neue Selektion: ein Zeichen
505 aSelection.Adjust();
506 aSelection.nEndPara = aSelection.nStartPara;
507 aSelection.nEndPos = aSelection.nStartPos + 1;
508 pHeaderField->InitDoc( &aTextData.GetContentObj(), aTextData.GetPart(), aSelection );
510 // #91431# for bAbsorb=FALSE, the new selection must be behind the inserted content
511 // (the xml filter relies on this)
512 if (!bAbsorb)
513 aSelection.nStartPos = aSelection.nEndPos;
515 pTextRange->SetSelection( aSelection );
517 return;
521 if (!pUnoText)
522 CreateUnoText_Impl();
523 pUnoText->insertTextContent( xRange, xContent, bAbsorb );
526 void SAL_CALL ScHeaderFooterTextObj::removeTextContent(
527 const uno::Reference<text::XTextContent>& xContent )
528 throw(container::NoSuchElementException, uno::RuntimeException)
530 ScUnoGuard aGuard;
531 if ( xContent.is() )
533 ScHeaderFieldObj* pHeaderField = ScHeaderFieldObj::getImplementation( xContent );
534 if ( pHeaderField && pHeaderField->IsInserted() )
536 //! Testen, ob das Feld in dieser Zelle ist
537 pHeaderField->DeleteField();
538 return;
541 if (!pUnoText)
542 CreateUnoText_Impl();
543 pUnoText->removeTextContent( xContent );
546 uno::Reference<text::XText> SAL_CALL ScHeaderFooterTextObj::getText() throw(uno::RuntimeException)
548 ScUnoGuard aGuard;
549 if (!pUnoText)
550 CreateUnoText_Impl();
551 return pUnoText->getText();
554 uno::Reference<text::XTextRange> SAL_CALL ScHeaderFooterTextObj::getStart() throw(uno::RuntimeException)
556 ScUnoGuard aGuard;
557 if (!pUnoText)
558 CreateUnoText_Impl();
559 return pUnoText->getStart();
562 uno::Reference<text::XTextRange> SAL_CALL ScHeaderFooterTextObj::getEnd() throw(uno::RuntimeException)
564 ScUnoGuard aGuard;
565 if (!pUnoText)
566 CreateUnoText_Impl();
567 return pUnoText->getEnd();
570 // XTextFieldsSupplier
572 uno::Reference<container::XEnumerationAccess> SAL_CALL ScHeaderFooterTextObj::getTextFields()
573 throw(uno::RuntimeException)
575 ScUnoGuard aGuard;
576 // all fields
577 return new ScHeaderFieldsObj( &aTextData.GetContentObj(), aTextData.GetPart(), SC_SERVICE_INVALID );
580 uno::Reference<container::XNameAccess> SAL_CALL ScHeaderFooterTextObj::getTextFieldMasters()
581 throw(uno::RuntimeException)
583 // sowas gibts nicht im Calc (?)
584 return NULL;
587 // XTextRangeMover
589 void SAL_CALL ScHeaderFooterTextObj::moveTextRange(
590 const uno::Reference<text::XTextRange>& xRange,
591 sal_Int16 nParagraphs )
592 throw(uno::RuntimeException)
594 ScUnoGuard aGuard;
595 if (!pUnoText)
596 CreateUnoText_Impl();
597 pUnoText->moveTextRange( xRange, nParagraphs );
600 // XEnumerationAccess
602 uno::Reference<container::XEnumeration> SAL_CALL ScHeaderFooterTextObj::createEnumeration()
603 throw(uno::RuntimeException)
605 ScUnoGuard aGuard;
606 if (!pUnoText)
607 CreateUnoText_Impl();
608 return pUnoText->createEnumeration();
611 // XElementAccess
613 uno::Type SAL_CALL ScHeaderFooterTextObj::getElementType() throw(uno::RuntimeException)
615 ScUnoGuard aGuard;
616 if (!pUnoText)
617 CreateUnoText_Impl();
618 return pUnoText->getElementType();
621 sal_Bool SAL_CALL ScHeaderFooterTextObj::hasElements() throw(uno::RuntimeException)
623 ScUnoGuard aGuard;
624 if (!pUnoText)
625 CreateUnoText_Impl();
626 return pUnoText->hasElements();
629 //------------------------------------------------------------------------
631 ScCellTextCursor::ScCellTextCursor(const ScCellTextCursor& rOther) :
632 SvxUnoTextCursor( rOther ),
633 rTextObj( rOther.rTextObj )
635 rTextObj.acquire();
638 ScCellTextCursor::ScCellTextCursor(ScCellObj& rText) :
639 SvxUnoTextCursor( rText.GetUnoText() ),
640 rTextObj( rText )
642 rTextObj.acquire();
645 ScCellTextCursor::~ScCellTextCursor() throw()
647 rTextObj.release();
650 // SvxUnoTextCursor methods reimplemented here to return the right objects:
652 uno::Reference<text::XText> SAL_CALL ScCellTextCursor::getText() throw(uno::RuntimeException)
654 ScUnoGuard aGuard;
655 return &rTextObj;
658 uno::Reference<text::XTextRange> SAL_CALL ScCellTextCursor::getStart() throw(uno::RuntimeException)
660 ScUnoGuard aGuard;
662 //! use other object for range than cursor?
664 ScCellTextCursor* pNew = new ScCellTextCursor( *this );
665 uno::Reference<text::XTextRange> xRange( static_cast<SvxUnoTextRangeBase*>(pNew) );
667 ESelection aNewSel(GetSelection());
668 aNewSel.nEndPara = aNewSel.nStartPara;
669 aNewSel.nEndPos = aNewSel.nStartPos;
670 pNew->SetSelection( aNewSel );
672 return xRange;
675 uno::Reference<text::XTextRange> SAL_CALL ScCellTextCursor::getEnd() throw(uno::RuntimeException)
677 ScUnoGuard aGuard;
679 //! use other object for range than cursor?
681 ScCellTextCursor* pNew = new ScCellTextCursor( *this );
682 uno::Reference<text::XTextRange> xRange( static_cast<SvxUnoTextRangeBase*>(pNew) );
684 ESelection aNewSel(GetSelection());
685 aNewSel.nStartPara = aNewSel.nEndPara;
686 aNewSel.nStartPos = aNewSel.nEndPos;
687 pNew->SetSelection( aNewSel );
689 return xRange;
692 // XUnoTunnel
694 sal_Int64 SAL_CALL ScCellTextCursor::getSomething(
695 const uno::Sequence<sal_Int8 >& rId ) throw(uno::RuntimeException)
697 if ( rId.getLength() == 16 &&
698 0 == rtl_compareMemory( getUnoTunnelId().getConstArray(),
699 rId.getConstArray(), 16 ) )
701 return sal::static_int_cast<sal_Int64>(reinterpret_cast<sal_IntPtr>(this));
703 return SvxUnoTextCursor::getSomething( rId );
706 // static
707 const uno::Sequence<sal_Int8>& ScCellTextCursor::getUnoTunnelId()
709 static uno::Sequence<sal_Int8> * pSeq = 0;
710 if( !pSeq )
712 osl::Guard< osl::Mutex > aGuard( osl::Mutex::getGlobalMutex() );
713 if( !pSeq )
715 static uno::Sequence< sal_Int8 > aSeq( 16 );
716 rtl_createUuid( (sal_uInt8*)aSeq.getArray(), 0, sal_True );
717 pSeq = &aSeq;
720 return *pSeq;
723 // static
724 ScCellTextCursor* ScCellTextCursor::getImplementation( const uno::Reference<uno::XInterface> xObj )
726 ScCellTextCursor* pRet = NULL;
727 uno::Reference<lang::XUnoTunnel> xUT( xObj, uno::UNO_QUERY );
728 if (xUT.is())
729 pRet = reinterpret_cast<ScCellTextCursor*>(sal::static_int_cast<sal_IntPtr>(xUT->getSomething(getUnoTunnelId())));
730 return pRet;
733 //------------------------------------------------------------------------
735 ScHeaderFooterTextCursor::ScHeaderFooterTextCursor(const ScHeaderFooterTextCursor& rOther) :
736 SvxUnoTextCursor( rOther ),
737 rTextObj( rOther.rTextObj )
739 rTextObj.acquire();
742 ScHeaderFooterTextCursor::ScHeaderFooterTextCursor(ScHeaderFooterTextObj& rText) :
743 SvxUnoTextCursor( rText.GetUnoText() ),
744 rTextObj( rText )
746 rTextObj.acquire();
749 ScHeaderFooterTextCursor::~ScHeaderFooterTextCursor() throw()
751 rTextObj.release();
754 // SvxUnoTextCursor methods reimplemented here to return the right objects:
756 uno::Reference<text::XText> SAL_CALL ScHeaderFooterTextCursor::getText() throw(uno::RuntimeException)
758 ScUnoGuard aGuard;
759 return &rTextObj;
762 uno::Reference<text::XTextRange> SAL_CALL ScHeaderFooterTextCursor::getStart() throw(uno::RuntimeException)
764 ScUnoGuard aGuard;
766 //! use other object for range than cursor?
768 ScHeaderFooterTextCursor* pNew = new ScHeaderFooterTextCursor( *this );
769 uno::Reference<text::XTextRange> xRange( static_cast<SvxUnoTextRangeBase*>(pNew) );
771 ESelection aNewSel(GetSelection());
772 aNewSel.nEndPara = aNewSel.nStartPara;
773 aNewSel.nEndPos = aNewSel.nStartPos;
774 pNew->SetSelection( aNewSel );
776 return xRange;
779 uno::Reference<text::XTextRange> SAL_CALL ScHeaderFooterTextCursor::getEnd() throw(uno::RuntimeException)
781 ScUnoGuard aGuard;
783 //! use other object for range than cursor?
785 ScHeaderFooterTextCursor* pNew = new ScHeaderFooterTextCursor( *this );
786 uno::Reference<text::XTextRange> xRange( static_cast<SvxUnoTextRangeBase*>(pNew) );
788 ESelection aNewSel(GetSelection());
789 aNewSel.nStartPara = aNewSel.nEndPara;
790 aNewSel.nStartPos = aNewSel.nEndPos;
791 pNew->SetSelection( aNewSel );
793 return xRange;
796 // XUnoTunnel
798 sal_Int64 SAL_CALL ScHeaderFooterTextCursor::getSomething(
799 const uno::Sequence<sal_Int8 >& rId ) throw(uno::RuntimeException)
801 if ( rId.getLength() == 16 &&
802 0 == rtl_compareMemory( getUnoTunnelId().getConstArray(),
803 rId.getConstArray(), 16 ) )
805 return sal::static_int_cast<sal_Int64>(reinterpret_cast<sal_IntPtr>(this));
807 return SvxUnoTextCursor::getSomething( rId );
810 // static
811 const uno::Sequence<sal_Int8>& ScHeaderFooterTextCursor::getUnoTunnelId()
813 static uno::Sequence<sal_Int8> * pSeq = 0;
814 if( !pSeq )
816 osl::Guard< osl::Mutex > aGuard( osl::Mutex::getGlobalMutex() );
817 if( !pSeq )
819 static uno::Sequence< sal_Int8 > aSeq( 16 );
820 rtl_createUuid( (sal_uInt8*)aSeq.getArray(), 0, sal_True );
821 pSeq = &aSeq;
824 return *pSeq;
827 // static
828 ScHeaderFooterTextCursor* ScHeaderFooterTextCursor::getImplementation(
829 const uno::Reference<uno::XInterface> xObj )
831 ScHeaderFooterTextCursor* pRet = NULL;
832 uno::Reference<lang::XUnoTunnel> xUT( xObj, uno::UNO_QUERY );
833 if (xUT.is())
834 pRet = reinterpret_cast<ScHeaderFooterTextCursor*>(sal::static_int_cast<sal_IntPtr>(xUT->getSomething(getUnoTunnelId())));
835 return pRet;
838 //------------------------------------------------------------------------
840 ScDrawTextCursor::ScDrawTextCursor(const ScDrawTextCursor& rOther) :
841 SvxUnoTextCursor( rOther ),
842 xParentText( rOther.xParentText )
846 ScDrawTextCursor::ScDrawTextCursor( const uno::Reference<text::XText>& xParent,
847 const SvxUnoTextBase& rText ) :
848 SvxUnoTextCursor( rText ),
849 xParentText( xParent )
854 ScDrawTextCursor::~ScDrawTextCursor() throw()
858 // SvxUnoTextCursor methods reimplemented here to return the right objects:
860 uno::Reference<text::XText> SAL_CALL ScDrawTextCursor::getText() throw(uno::RuntimeException)
862 ScUnoGuard aGuard;
863 return xParentText;
866 uno::Reference<text::XTextRange> SAL_CALL ScDrawTextCursor::getStart() throw(uno::RuntimeException)
868 ScUnoGuard aGuard;
870 //! use other object for range than cursor?
872 ScDrawTextCursor* pNew = new ScDrawTextCursor( *this );
873 uno::Reference<text::XTextRange> xRange( static_cast<SvxUnoTextRangeBase*>(pNew) );
875 ESelection aNewSel(GetSelection());
876 aNewSel.nEndPara = aNewSel.nStartPara;
877 aNewSel.nEndPos = aNewSel.nStartPos;
878 pNew->SetSelection( aNewSel );
880 return xRange;
883 uno::Reference<text::XTextRange> SAL_CALL ScDrawTextCursor::getEnd() throw(uno::RuntimeException)
885 ScUnoGuard aGuard;
887 //! use other object for range than cursor?
889 ScDrawTextCursor* pNew = new ScDrawTextCursor( *this );
890 uno::Reference<text::XTextRange> xRange( static_cast<SvxUnoTextRangeBase*>(pNew) );
892 ESelection aNewSel(GetSelection());
893 aNewSel.nStartPara = aNewSel.nEndPara;
894 aNewSel.nStartPos = aNewSel.nEndPos;
895 pNew->SetSelection( aNewSel );
897 return xRange;
900 // XUnoTunnel
902 sal_Int64 SAL_CALL ScDrawTextCursor::getSomething(
903 const uno::Sequence<sal_Int8 >& rId ) throw(uno::RuntimeException)
905 if ( rId.getLength() == 16 &&
906 0 == rtl_compareMemory( getUnoTunnelId().getConstArray(),
907 rId.getConstArray(), 16 ) )
909 return sal::static_int_cast<sal_Int64>(reinterpret_cast<sal_IntPtr>(this));
911 return SvxUnoTextCursor::getSomething( rId );
914 // static
915 const uno::Sequence<sal_Int8>& ScDrawTextCursor::getUnoTunnelId()
917 static uno::Sequence<sal_Int8> * pSeq = 0;
918 if( !pSeq )
920 osl::Guard< osl::Mutex > aGuard( osl::Mutex::getGlobalMutex() );
921 if( !pSeq )
923 static uno::Sequence< sal_Int8 > aSeq( 16 );
924 rtl_createUuid( (sal_uInt8*)aSeq.getArray(), 0, sal_True );
925 pSeq = &aSeq;
928 return *pSeq;
931 // static
932 ScDrawTextCursor* ScDrawTextCursor::getImplementation( const uno::Reference<uno::XInterface> xObj )
934 ScDrawTextCursor* pRet = NULL;
935 uno::Reference<lang::XUnoTunnel> xUT( xObj, uno::UNO_QUERY );
936 if (xUT.is())
937 pRet = reinterpret_cast<ScDrawTextCursor*>(sal::static_int_cast<sal_IntPtr>(xUT->getSomething(getUnoTunnelId())));
938 return pRet;
941 //------------------------------------------------------------------------
943 ScSimpleEditSourceHelper::ScSimpleEditSourceHelper()
945 SfxItemPool* pEnginePool = EditEngine::CreatePool();
946 pEnginePool->SetDefaultMetric( SFX_MAPUNIT_100TH_MM );
947 pEnginePool->FreezeIdRanges();
949 pEditEngine = new ScFieldEditEngine( pEnginePool, NULL, TRUE ); // TRUE: become owner of pool
950 pForwarder = new SvxEditEngineForwarder( *pEditEngine );
951 pOriginalSource = new ScSimpleEditSource( pForwarder );
954 ScSimpleEditSourceHelper::~ScSimpleEditSourceHelper()
956 ScUnoGuard aGuard; // needed for EditEngine dtor
958 delete pOriginalSource;
959 delete pForwarder;
960 delete pEditEngine;
963 ScEditEngineTextObj::ScEditEngineTextObj() :
964 SvxUnoText( GetOriginalSource(), ScCellObj::GetEditPropertySet(), uno::Reference<text::XText>() )
968 ScEditEngineTextObj::~ScEditEngineTextObj() throw()
972 void ScEditEngineTextObj::SetText( const EditTextObject& rTextObject )
974 GetEditEngine()->SetText( rTextObject );
976 ESelection aSel;
977 ::GetSelection( aSel, GetEditSource()->GetTextForwarder() );
978 SetSelection( aSel );
981 EditTextObject* ScEditEngineTextObj::CreateTextObject()
983 return GetEditEngine()->CreateTextObject();
986 //------------------------------------------------------------------------
988 ScCellTextData::ScCellTextData(ScDocShell* pDocSh, const ScAddress& rP) :
989 pDocShell( pDocSh ),
990 aCellPos( rP ),
991 pEditEngine( NULL ),
992 pForwarder( NULL ),
993 pOriginalSource( NULL ),
994 bDataValid( FALSE ),
995 bInUpdate( FALSE ),
996 bDirty( FALSE ),
997 bDoUpdate( TRUE )
999 if (pDocShell)
1000 pDocShell->GetDocument()->AddUnoObject(*this);
1003 ScCellTextData::~ScCellTextData()
1005 ScUnoGuard aGuard; // needed for EditEngine dtor
1007 if (pDocShell)
1009 pDocShell->GetDocument()->RemoveUnoObject(*this);
1010 pDocShell->GetDocument()->DisposeFieldEditEngine(pEditEngine);
1012 else
1013 delete pEditEngine;
1015 delete pForwarder;
1017 delete pOriginalSource;
1020 ScSharedCellEditSource* ScCellTextData::GetOriginalSource()
1022 if (!pOriginalSource)
1023 pOriginalSource = new ScSharedCellEditSource( this );
1024 return pOriginalSource;
1027 void ScCellTextData::GetCellText(const ScAddress& rCellPos, String& rText)
1029 if (pDocShell)
1031 ScDocument* pDoc = pDocShell->GetDocument();
1032 pDoc->GetInputString( rCellPos.Col(), rCellPos.Row(), rCellPos.Tab(), rText );
1036 SvxTextForwarder* ScCellTextData::GetTextForwarder()
1038 if (!pEditEngine)
1040 if ( pDocShell )
1042 ScDocument* pDoc = pDocShell->GetDocument();
1043 pEditEngine = pDoc->CreateFieldEditEngine();
1045 else
1047 SfxItemPool* pEnginePool = EditEngine::CreatePool();
1048 pEnginePool->FreezeIdRanges();
1049 pEditEngine = new ScFieldEditEngine( pEnginePool, NULL, TRUE );
1051 // currently, GetPortions doesn't work if UpdateMode is FALSE,
1052 // this will be fixed (in EditEngine) by src600
1053 // pEditEngine->SetUpdateMode( FALSE );
1054 pEditEngine->EnableUndo( FALSE );
1055 if (pDocShell)
1056 pEditEngine->SetRefDevice(pDocShell->GetRefDevice());
1057 else
1058 pEditEngine->SetRefMapMode( MAP_100TH_MM );
1059 pForwarder = new SvxEditEngineForwarder(*pEditEngine);
1062 if (bDataValid)
1063 return pForwarder;
1065 String aText;
1067 if (pDocShell)
1069 ScDocument* pDoc = pDocShell->GetDocument();
1071 SfxItemSet aDefaults( pEditEngine->GetEmptyItemSet() );
1072 if( const ScPatternAttr* pPattern =
1073 pDoc->GetPattern( aCellPos.Col(), aCellPos.Row(), aCellPos.Tab() ) )
1075 pPattern->FillEditItemSet( &aDefaults );
1076 pPattern->FillEditParaItems( &aDefaults ); // including alignment etc. (for reading)
1079 const ScBaseCell* pCell = pDoc->GetCell( aCellPos );
1080 if ( pCell && pCell->GetCellType() == CELLTYPE_EDIT )
1081 pEditEngine->SetTextNewDefaults( *((const ScEditCell*)pCell)->GetData(), aDefaults );
1082 else
1084 GetCellText( aCellPos, aText );
1085 if (aText.Len())
1086 pEditEngine->SetTextNewDefaults( aText, aDefaults );
1087 else
1088 pEditEngine->SetDefaults(aDefaults);
1092 bDataValid = TRUE;
1093 return pForwarder;
1096 void ScCellTextData::UpdateData()
1098 if ( bDoUpdate )
1100 DBG_ASSERT(pEditEngine != NULL, "no EditEngine for UpdateData()");
1101 if ( pDocShell && pEditEngine )
1103 // during the own UpdateData call, bDataValid must not be reset,
1104 // or things like attributes after the text would be lost
1105 // (are not stored in the cell)
1107 bInUpdate = TRUE; // prevents bDataValid from being reset
1109 ScDocFunc aFunc(*pDocShell);
1110 aFunc.PutData( aCellPos, *pEditEngine, FALSE, TRUE ); // always as text
1112 bInUpdate = FALSE;
1113 bDirty = FALSE;
1116 else
1117 bDirty = TRUE;
1120 void ScCellTextData::Notify( SfxBroadcaster&, const SfxHint& rHint )
1122 if ( rHint.ISA( ScUpdateRefHint ) )
1124 // const ScUpdateRefHint& rRef = (const ScUpdateRefHint&)rHint;
1126 //! Ref-Update
1128 else if ( rHint.ISA( SfxSimpleHint ) )
1130 ULONG nId = ((const SfxSimpleHint&)rHint).GetId();
1131 if ( nId == SFX_HINT_DYING )
1133 pDocShell = NULL; // invalid now
1135 DELETEZ( pForwarder );
1136 DELETEZ( pEditEngine ); // EditEngine uses document's pool
1138 else if ( nId == SFX_HINT_DATACHANGED )
1140 if (!bInUpdate) // not for own UpdateData calls
1141 bDataValid = FALSE; // text has to be read from the cell again
1146 ScCellTextObj::ScCellTextObj(ScDocShell* pDocSh, const ScAddress& rP) :
1147 ScCellTextData( pDocSh, rP ),
1148 SvxUnoText( GetOriginalSource(), ScCellObj::GetEditPropertySet(), uno::Reference<text::XText>() )
1152 ScCellTextObj::~ScCellTextObj() throw()