summaryrefslogtreecommitdiff
path: root/sc/source/ui/unoobj/textuno.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'sc/source/ui/unoobj/textuno.cxx')
-rw-r--r--sc/source/ui/unoobj/textuno.cxx1139
1 files changed, 1139 insertions, 0 deletions
diff --git a/sc/source/ui/unoobj/textuno.cxx b/sc/source/ui/unoobj/textuno.cxx
new file mode 100644
index 000000000000..4e21b587294d
--- /dev/null
+++ b/sc/source/ui/unoobj/textuno.cxx
@@ -0,0 +1,1139 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sc.hxx"
+
+
+
+#include "scitems.hxx"
+#include <editeng/eeitem.hxx>
+#include <svx/svdpool.hxx>
+#include <svx/svdobj.hxx>
+#include <editeng/editeng.hxx>
+#include <editeng/editobj.hxx>
+#include <editeng/flditem.hxx>
+#include <svx/unomid.hxx>
+#include <editeng/unoprnms.hxx>
+#include <editeng/unofored.hxx>
+#include <rtl/uuid.h>
+#include <vcl/virdev.hxx>
+#include <vcl/svapp.hxx>
+#include <com/sun/star/awt/FontSlant.hpp>
+
+#include <com/sun/star/beans/PropertyAttribute.hpp>
+#include <editeng/unoipset.hxx>
+#include "textuno.hxx"
+#include "fielduno.hxx"
+#include "servuno.hxx"
+#include "editsrc.hxx"
+#include "docsh.hxx"
+#include "editutil.hxx"
+#include "miscuno.hxx"
+#include "cellsuno.hxx"
+#include "hints.hxx"
+#include "patattr.hxx"
+#include "cell.hxx"
+#include "docfunc.hxx"
+#include "scmod.hxx"
+
+using namespace com::sun::star;
+
+//------------------------------------------------------------------------
+
+const SvxItemPropertySet * lcl_GetHdFtPropertySet()
+{
+ static SfxItemPropertyMapEntry aHdFtPropertyMap_Impl[] =
+ {
+ SVX_UNOEDIT_CHAR_PROPERTIES,
+ SVX_UNOEDIT_FONT_PROPERTIES,
+ SVX_UNOEDIT_PARA_PROPERTIES,
+ SVX_UNOEDIT_NUMBERING_PROPERTIE, // for completeness of service ParagraphProperties
+ {0,0,0,0,0,0}
+ };
+ static sal_Bool bTwipsSet = false;
+
+ if (!bTwipsSet)
+ {
+ // modify PropertyMap to include CONVERT_TWIPS flag for font height
+ // (headers/footers are in twips)
+
+ SfxItemPropertyMapEntry* pEntry = aHdFtPropertyMap_Impl;
+ while (pEntry->pName)
+ {
+ if ( ( pEntry->nWID == EE_CHAR_FONTHEIGHT ||
+ pEntry->nWID == EE_CHAR_FONTHEIGHT_CJK ||
+ pEntry->nWID == EE_CHAR_FONTHEIGHT_CTL ) &&
+ pEntry->nMemberId == MID_FONTHEIGHT )
+ {
+ pEntry->nMemberId |= CONVERT_TWIPS;
+ }
+
+ ++pEntry;
+ }
+ bTwipsSet = sal_True;
+ }
+ static SvxItemPropertySet aHdFtPropertySet_Impl( aHdFtPropertyMap_Impl, SdrObject::GetGlobalDrawObjectItemPool() );
+ return &aHdFtPropertySet_Impl;
+}
+
+//------------------------------------------------------------------------
+
+SC_SIMPLE_SERVICE_INFO( ScHeaderFooterContentObj, "ScHeaderFooterContentObj", "com.sun.star.sheet.HeaderFooterContent" )
+SC_SIMPLE_SERVICE_INFO( ScHeaderFooterTextObj, "ScHeaderFooterTextObj", "stardiv.one.Text.Text" )
+
+//------------------------------------------------------------------------
+
+ScHeaderFooterContentObj::ScHeaderFooterContentObj( const EditTextObject* pLeft,
+ const EditTextObject* pCenter,
+ const EditTextObject* pRight ) :
+ pLeftText ( NULL ),
+ pCenterText ( NULL ),
+ pRightText ( NULL )
+{
+ if ( pLeft )
+ pLeftText = pLeft->Clone();
+ if ( pCenter )
+ pCenterText = pCenter->Clone();
+ if ( pRight )
+ pRightText = pRight->Clone();
+}
+
+ScHeaderFooterContentObj::~ScHeaderFooterContentObj()
+{
+ delete pLeftText;
+ delete pCenterText;
+ delete pRightText;
+}
+
+void ScHeaderFooterContentObj::AddListener( SfxListener& rListener )
+{
+ rListener.StartListening( aBC );
+}
+
+void ScHeaderFooterContentObj::RemoveListener( SfxListener& rListener )
+{
+ rListener.EndListening( aBC );
+}
+
+void ScHeaderFooterContentObj::UpdateText( sal_uInt16 nPart, EditEngine& rSource )
+{
+ EditTextObject* pNew = rSource.CreateTextObject();
+ switch (nPart)
+ {
+ case SC_HDFT_LEFT:
+ delete pLeftText;
+ pLeftText = pNew;
+ break;
+ case SC_HDFT_CENTER:
+ delete pCenterText;
+ pCenterText = pNew;
+ break;
+ default: // SC_HDFT_RIGHT
+ delete pRightText;
+ pRightText = pNew;
+ break;
+ }
+
+ aBC.Broadcast( ScHeaderFooterChangedHint( nPart ) );
+}
+
+// XHeaderFooterContent
+
+uno::Reference<text::XText> SAL_CALL ScHeaderFooterContentObj::getLeftText()
+ throw(uno::RuntimeException)
+{
+ SolarMutexGuard aGuard;
+ return new ScHeaderFooterTextObj( *this, SC_HDFT_LEFT );
+}
+
+uno::Reference<text::XText> SAL_CALL ScHeaderFooterContentObj::getCenterText()
+ throw(uno::RuntimeException)
+{
+ SolarMutexGuard aGuard;
+ return new ScHeaderFooterTextObj( *this, SC_HDFT_CENTER );
+}
+
+uno::Reference<text::XText> SAL_CALL ScHeaderFooterContentObj::getRightText()
+ throw(uno::RuntimeException)
+{
+ SolarMutexGuard aGuard;
+ return new ScHeaderFooterTextObj( *this, SC_HDFT_RIGHT );
+}
+
+// XUnoTunnel
+
+sal_Int64 SAL_CALL ScHeaderFooterContentObj::getSomething(
+ const uno::Sequence<sal_Int8 >& rId ) throw(uno::RuntimeException)
+{
+ if ( rId.getLength() == 16 &&
+ 0 == rtl_compareMemory( getUnoTunnelId().getConstArray(),
+ rId.getConstArray(), 16 ) )
+ {
+ return sal::static_int_cast<sal_Int64>(reinterpret_cast<sal_IntPtr>(this));
+ }
+ return 0;
+}
+
+const uno::Sequence<sal_Int8>& ScHeaderFooterContentObj::getUnoTunnelId()
+{
+ static uno::Sequence<sal_Int8> * pSeq = 0;
+ if( !pSeq )
+ {
+ osl::Guard< osl::Mutex > aGuard( osl::Mutex::getGlobalMutex() );
+ if( !pSeq )
+ {
+ static uno::Sequence< sal_Int8 > aSeq( 16 );
+ rtl_createUuid( (sal_uInt8*)aSeq.getArray(), 0, sal_True );
+ pSeq = &aSeq;
+ }
+ }
+ return *pSeq;
+}
+
+ScHeaderFooterContentObj* ScHeaderFooterContentObj::getImplementation(
+ const uno::Reference<sheet::XHeaderFooterContent> xObj )
+{
+ ScHeaderFooterContentObj* pRet = NULL;
+ uno::Reference<lang::XUnoTunnel> xUT( xObj, uno::UNO_QUERY );
+ if (xUT.is())
+ pRet = reinterpret_cast<ScHeaderFooterContentObj*>(sal::static_int_cast<sal_IntPtr>(xUT->getSomething(getUnoTunnelId())));
+ return pRet;
+}
+
+
+//------------------------------------------------------------------------
+
+ScHeaderFooterTextData::ScHeaderFooterTextData( ScHeaderFooterContentObj& rContent,
+ sal_uInt16 nP ) :
+ rContentObj( rContent ),
+ nPart( nP ),
+ pEditEngine( NULL ),
+ pForwarder( NULL ),
+ bDataValid( false ),
+ bInUpdate( false )
+{
+ rContentObj.acquire(); // must not go away
+ rContentObj.AddListener( *this );
+}
+
+ScHeaderFooterTextData::~ScHeaderFooterTextData()
+{
+ SolarMutexGuard aGuard; // needed for EditEngine dtor
+
+ rContentObj.RemoveListener( *this );
+
+ delete pForwarder;
+ delete pEditEngine;
+
+ rContentObj.release();
+}
+
+void ScHeaderFooterTextData::Notify( SfxBroadcaster&, const SfxHint& rHint )
+{
+ if ( rHint.ISA( ScHeaderFooterChangedHint ) )
+ {
+ if ( ((const ScHeaderFooterChangedHint&)rHint).GetPart() == nPart )
+ {
+ if (!bInUpdate) // not for own updates
+ bDataValid = false; // text has to be fetched again
+ }
+ }
+}
+
+SvxTextForwarder* ScHeaderFooterTextData::GetTextForwarder()
+{
+ if (!pEditEngine)
+ {
+ SfxItemPool* pEnginePool = EditEngine::CreatePool();
+ pEnginePool->FreezeIdRanges();
+ ScHeaderEditEngine* pHdrEngine = new ScHeaderEditEngine( pEnginePool, sal_True );
+
+ pHdrEngine->EnableUndo( false );
+ pHdrEngine->SetRefMapMode( MAP_TWIP );
+
+ // default font must be set, independently of document
+ // -> use global pool from module
+
+ SfxItemSet aDefaults( pHdrEngine->GetEmptyItemSet() );
+ const ScPatternAttr& rPattern = (const ScPatternAttr&)SC_MOD()->GetPool().GetDefaultItem(ATTR_PATTERN);
+ rPattern.FillEditItemSet( &aDefaults );
+ // FillEditItemSet adjusts font height to 1/100th mm,
+ // but for header/footer twips is needed, as in the PatternAttr:
+ aDefaults.Put( rPattern.GetItem(ATTR_FONT_HEIGHT), EE_CHAR_FONTHEIGHT );
+ aDefaults.Put( rPattern.GetItem(ATTR_CJK_FONT_HEIGHT), EE_CHAR_FONTHEIGHT_CJK );
+ aDefaults.Put( rPattern.GetItem(ATTR_CTL_FONT_HEIGHT), EE_CHAR_FONTHEIGHT_CTL );
+ pHdrEngine->SetDefaults( aDefaults );
+
+ ScHeaderFieldData aData;
+ ScHeaderFooterTextObj::FillDummyFieldData( aData );
+ pHdrEngine->SetData( aData );
+
+ pEditEngine = pHdrEngine;
+ pForwarder = new SvxEditEngineForwarder(*pEditEngine);
+ }
+
+ if (bDataValid)
+ return pForwarder;
+
+ const EditTextObject* pData;
+ if (nPart == SC_HDFT_LEFT)
+ pData = rContentObj.GetLeftEditObject();
+ else if (nPart == SC_HDFT_CENTER)
+ pData = rContentObj.GetCenterEditObject();
+ else
+ pData = rContentObj.GetRightEditObject();
+
+ if (pData)
+ pEditEngine->SetText(*pData);
+
+ bDataValid = sal_True;
+ return pForwarder;
+}
+
+void ScHeaderFooterTextData::UpdateData()
+{
+ if ( pEditEngine )
+ {
+ bInUpdate = sal_True; // don't reset bDataValid during UpdateText
+
+ rContentObj.UpdateText( nPart, *pEditEngine );
+
+ bInUpdate = false;
+ }
+}
+
+//------------------------------------------------------------------------
+
+ScHeaderFooterTextObj::ScHeaderFooterTextObj( ScHeaderFooterContentObj& rContent,
+ sal_uInt16 nP ) :
+ aTextData( rContent, nP ),
+ pUnoText( NULL )
+{
+ // ScHeaderFooterTextData acquires rContent
+ // pUnoText is created on demand (getString/setString work without it)
+}
+
+void ScHeaderFooterTextObj::CreateUnoText_Impl()
+{
+ if ( !pUnoText )
+ {
+ // can't be aggregated because getString/setString is handled here
+ ScSharedHeaderFooterEditSource aEditSource( &aTextData );
+ pUnoText = new SvxUnoText( &aEditSource, lcl_GetHdFtPropertySet(), uno::Reference<text::XText>() );
+ pUnoText->acquire();
+ }
+}
+
+ScHeaderFooterTextObj::~ScHeaderFooterTextObj()
+{
+ if (pUnoText)
+ pUnoText->release();
+}
+
+const SvxUnoText& ScHeaderFooterTextObj::GetUnoText()
+{
+ if (!pUnoText)
+ CreateUnoText_Impl();
+ return *pUnoText;
+}
+
+// XText
+
+uno::Reference<text::XTextCursor> SAL_CALL ScHeaderFooterTextObj::createTextCursor()
+ throw(uno::RuntimeException)
+{
+ SolarMutexGuard aGuard;
+ return new ScHeaderFooterTextCursor( *this );
+}
+
+uno::Reference<text::XTextCursor> SAL_CALL ScHeaderFooterTextObj::createTextCursorByRange(
+ const uno::Reference<text::XTextRange>& aTextPosition )
+ throw(uno::RuntimeException)
+{
+ SolarMutexGuard aGuard;
+ if (!pUnoText)
+ CreateUnoText_Impl();
+ return pUnoText->createTextCursorByRange(aTextPosition);
+ //! wie ScCellObj::createTextCursorByRange, wenn SvxUnoTextRange_getReflection verfuegbar
+}
+
+void ScHeaderFooterTextObj::FillDummyFieldData( ScHeaderFieldData& rData )
+{
+ String aDummy(String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM( "???" )));
+ rData.aTitle = aDummy;
+ rData.aLongDocName = aDummy;
+ rData.aShortDocName = aDummy;
+ rData.aTabName = aDummy;
+ rData.nPageNo = 1;
+ rData.nTotalPages = 99;
+}
+
+rtl::OUString SAL_CALL ScHeaderFooterTextObj::getString() throw(uno::RuntimeException)
+{
+ SolarMutexGuard aGuard;
+ rtl::OUString aRet;
+ const EditTextObject* pData;
+
+ sal_uInt16 nPart = aTextData.GetPart();
+ ScHeaderFooterContentObj& rContentObj = aTextData.GetContentObj();
+
+ if (nPart == SC_HDFT_LEFT)
+ pData = rContentObj.GetLeftEditObject();
+ else if (nPart == SC_HDFT_CENTER)
+ pData = rContentObj.GetCenterEditObject();
+ else
+ pData = rContentObj.GetRightEditObject();
+ if (pData)
+ {
+ // for pure text, no font info is needed in pool defaults
+ ScHeaderEditEngine aEditEngine( EditEngine::CreatePool(), sal_True );
+
+ ScHeaderFieldData aData;
+ FillDummyFieldData( aData );
+ aEditEngine.SetData( aData );
+
+ aEditEngine.SetText(*pData);
+ aRet = ScEditUtil::GetSpaceDelimitedString( aEditEngine );
+ }
+ return aRet;
+}
+
+void SAL_CALL ScHeaderFooterTextObj::setString( const rtl::OUString& aText ) throw(uno::RuntimeException)
+{
+ SolarMutexGuard aGuard;
+ String aString(aText);
+
+ // for pure text, no font info is needed in pool defaults
+ ScHeaderEditEngine aEditEngine( EditEngine::CreatePool(), sal_True );
+ aEditEngine.SetText( aString );
+
+ aTextData.GetContentObj().UpdateText( aTextData.GetPart(), aEditEngine );
+}
+
+void SAL_CALL ScHeaderFooterTextObj::insertString( const uno::Reference<text::XTextRange>& xRange,
+ const rtl::OUString& aString, sal_Bool bAbsorb )
+ throw(uno::RuntimeException)
+{
+ SolarMutexGuard aGuard;
+ if (!pUnoText)
+ CreateUnoText_Impl();
+ pUnoText->insertString( xRange, aString, bAbsorb );
+}
+
+void SAL_CALL ScHeaderFooterTextObj::insertControlCharacter(
+ const uno::Reference<text::XTextRange>& xRange,
+ sal_Int16 nControlCharacter, sal_Bool bAbsorb )
+ throw(lang::IllegalArgumentException, uno::RuntimeException)
+{
+ SolarMutexGuard aGuard;
+ if (!pUnoText)
+ CreateUnoText_Impl();
+ pUnoText->insertControlCharacter( xRange, nControlCharacter, bAbsorb );
+}
+
+void SAL_CALL ScHeaderFooterTextObj::insertTextContent(
+ const uno::Reference<text::XTextRange >& xRange,
+ const uno::Reference<text::XTextContent >& xContent,
+ sal_Bool bAbsorb )
+ throw(lang::IllegalArgumentException, uno::RuntimeException)
+{
+ SolarMutexGuard aGuard;
+ if ( xContent.is() && xRange.is() )
+ {
+ ScHeaderFieldObj* pHeaderField = ScHeaderFieldObj::getImplementation( xContent );
+
+ SvxUnoTextRangeBase* pTextRange =
+ ScHeaderFooterTextCursor::getImplementation( xRange );
+
+ if ( pHeaderField && !pHeaderField->IsInserted() && pTextRange )
+ {
+ SvxEditSource* pEditSource = pTextRange->GetEditSource();
+ ESelection aSelection(pTextRange->GetSelection());
+
+ if (!bAbsorb)
+ {
+ // don't replace -> append at end
+ aSelection.Adjust();
+ aSelection.nStartPara = aSelection.nEndPara;
+ aSelection.nStartPos = aSelection.nEndPos;
+ }
+
+ SvxFieldItem aItem(pHeaderField->CreateFieldItem());
+
+ SvxTextForwarder* pForwarder = pEditSource->GetTextForwarder();
+ pForwarder->QuickInsertField( aItem, aSelection );
+ pEditSource->UpdateData();
+
+ // neue Selektion: ein Zeichen
+ aSelection.Adjust();
+ aSelection.nEndPara = aSelection.nStartPara;
+ aSelection.nEndPos = aSelection.nStartPos + 1;
+ pHeaderField->InitDoc( &aTextData.GetContentObj(), aTextData.GetPart(), aSelection );
+
+ // for bAbsorb=FALSE, the new selection must be behind the inserted content
+ // (the xml filter relies on this)
+ if (!bAbsorb)
+ aSelection.nStartPos = aSelection.nEndPos;
+
+ pTextRange->SetSelection( aSelection );
+
+ return;
+ }
+ }
+
+ if (!pUnoText)
+ CreateUnoText_Impl();
+ pUnoText->insertTextContent( xRange, xContent, bAbsorb );
+}
+
+void SAL_CALL ScHeaderFooterTextObj::removeTextContent(
+ const uno::Reference<text::XTextContent>& xContent )
+ throw(container::NoSuchElementException, uno::RuntimeException)
+{
+ SolarMutexGuard aGuard;
+ if ( xContent.is() )
+ {
+ ScHeaderFieldObj* pHeaderField = ScHeaderFieldObj::getImplementation( xContent );
+ if ( pHeaderField && pHeaderField->IsInserted() )
+ {
+ //! Testen, ob das Feld in dieser Zelle ist
+ pHeaderField->DeleteField();
+ return;
+ }
+ }
+ if (!pUnoText)
+ CreateUnoText_Impl();
+ pUnoText->removeTextContent( xContent );
+}
+
+uno::Reference<text::XText> SAL_CALL ScHeaderFooterTextObj::getText() throw(uno::RuntimeException)
+{
+ SolarMutexGuard aGuard;
+ if (!pUnoText)
+ CreateUnoText_Impl();
+ return pUnoText->getText();
+}
+
+uno::Reference<text::XTextRange> SAL_CALL ScHeaderFooterTextObj::getStart() throw(uno::RuntimeException)
+{
+ SolarMutexGuard aGuard;
+ if (!pUnoText)
+ CreateUnoText_Impl();
+ return pUnoText->getStart();
+}
+
+uno::Reference<text::XTextRange> SAL_CALL ScHeaderFooterTextObj::getEnd() throw(uno::RuntimeException)
+{
+ SolarMutexGuard aGuard;
+ if (!pUnoText)
+ CreateUnoText_Impl();
+ return pUnoText->getEnd();
+}
+
+// XTextFieldsSupplier
+
+uno::Reference<container::XEnumerationAccess> SAL_CALL ScHeaderFooterTextObj::getTextFields()
+ throw(uno::RuntimeException)
+{
+ SolarMutexGuard aGuard;
+ // all fields
+ return new ScHeaderFieldsObj( &aTextData.GetContentObj(), aTextData.GetPart(), SC_SERVICE_INVALID );
+}
+
+uno::Reference<container::XNameAccess> SAL_CALL ScHeaderFooterTextObj::getTextFieldMasters()
+ throw(uno::RuntimeException)
+{
+ // sowas gibts nicht im Calc (?)
+ return NULL;
+}
+
+// XTextRangeMover
+
+void SAL_CALL ScHeaderFooterTextObj::moveTextRange(
+ const uno::Reference<text::XTextRange>& xRange,
+ sal_Int16 nParagraphs )
+ throw(uno::RuntimeException)
+{
+ SolarMutexGuard aGuard;
+ if (!pUnoText)
+ CreateUnoText_Impl();
+ pUnoText->moveTextRange( xRange, nParagraphs );
+}
+
+// XEnumerationAccess
+
+uno::Reference<container::XEnumeration> SAL_CALL ScHeaderFooterTextObj::createEnumeration()
+ throw(uno::RuntimeException)
+{
+ SolarMutexGuard aGuard;
+ if (!pUnoText)
+ CreateUnoText_Impl();
+ return pUnoText->createEnumeration();
+}
+
+// XElementAccess
+
+uno::Type SAL_CALL ScHeaderFooterTextObj::getElementType() throw(uno::RuntimeException)
+{
+ SolarMutexGuard aGuard;
+ if (!pUnoText)
+ CreateUnoText_Impl();
+ return pUnoText->getElementType();
+}
+
+sal_Bool SAL_CALL ScHeaderFooterTextObj::hasElements() throw(uno::RuntimeException)
+{
+ SolarMutexGuard aGuard;
+ if (!pUnoText)
+ CreateUnoText_Impl();
+ return pUnoText->hasElements();
+}
+
+//------------------------------------------------------------------------
+
+ScCellTextCursor::ScCellTextCursor(const ScCellTextCursor& rOther) :
+ SvxUnoTextCursor( rOther ),
+ rTextObj( rOther.rTextObj )
+{
+ rTextObj.acquire();
+}
+
+ScCellTextCursor::ScCellTextCursor(ScCellObj& rText) :
+ SvxUnoTextCursor( rText.GetUnoText() ),
+ rTextObj( rText )
+{
+ rTextObj.acquire();
+}
+
+ScCellTextCursor::~ScCellTextCursor() throw()
+{
+ rTextObj.release();
+}
+
+// SvxUnoTextCursor methods reimplemented here to return the right objects:
+
+uno::Reference<text::XText> SAL_CALL ScCellTextCursor::getText() throw(uno::RuntimeException)
+{
+ SolarMutexGuard aGuard;
+ return &rTextObj;
+}
+
+uno::Reference<text::XTextRange> SAL_CALL ScCellTextCursor::getStart() throw(uno::RuntimeException)
+{
+ SolarMutexGuard aGuard;
+
+ //! use other object for range than cursor?
+
+ ScCellTextCursor* pNew = new ScCellTextCursor( *this );
+ uno::Reference<text::XTextRange> xRange( static_cast<SvxUnoTextRangeBase*>(pNew) );
+
+ ESelection aNewSel(GetSelection());
+ aNewSel.nEndPara = aNewSel.nStartPara;
+ aNewSel.nEndPos = aNewSel.nStartPos;
+ pNew->SetSelection( aNewSel );
+
+ return xRange;
+}
+
+uno::Reference<text::XTextRange> SAL_CALL ScCellTextCursor::getEnd() throw(uno::RuntimeException)
+{
+ SolarMutexGuard aGuard;
+
+ //! use other object for range than cursor?
+
+ ScCellTextCursor* pNew = new ScCellTextCursor( *this );
+ uno::Reference<text::XTextRange> xRange( static_cast<SvxUnoTextRangeBase*>(pNew) );
+
+ ESelection aNewSel(GetSelection());
+ aNewSel.nStartPara = aNewSel.nEndPara;
+ aNewSel.nStartPos = aNewSel.nEndPos;
+ pNew->SetSelection( aNewSel );
+
+ return xRange;
+}
+
+// XUnoTunnel
+
+sal_Int64 SAL_CALL ScCellTextCursor::getSomething(
+ const uno::Sequence<sal_Int8 >& rId ) throw(uno::RuntimeException)
+{
+ if ( rId.getLength() == 16 &&
+ 0 == rtl_compareMemory( getUnoTunnelId().getConstArray(),
+ rId.getConstArray(), 16 ) )
+ {
+ return sal::static_int_cast<sal_Int64>(reinterpret_cast<sal_IntPtr>(this));
+ }
+ return SvxUnoTextCursor::getSomething( rId );
+}
+
+const uno::Sequence<sal_Int8>& ScCellTextCursor::getUnoTunnelId()
+{
+ static uno::Sequence<sal_Int8> * pSeq = 0;
+ if( !pSeq )
+ {
+ osl::Guard< osl::Mutex > aGuard( osl::Mutex::getGlobalMutex() );
+ if( !pSeq )
+ {
+ static uno::Sequence< sal_Int8 > aSeq( 16 );
+ rtl_createUuid( (sal_uInt8*)aSeq.getArray(), 0, sal_True );
+ pSeq = &aSeq;
+ }
+ }
+ return *pSeq;
+}
+
+ScCellTextCursor* ScCellTextCursor::getImplementation( const uno::Reference<uno::XInterface> xObj )
+{
+ ScCellTextCursor* pRet = NULL;
+ uno::Reference<lang::XUnoTunnel> xUT( xObj, uno::UNO_QUERY );
+ if (xUT.is())
+ pRet = reinterpret_cast<ScCellTextCursor*>(sal::static_int_cast<sal_IntPtr>(xUT->getSomething(getUnoTunnelId())));
+ return pRet;
+}
+
+//------------------------------------------------------------------------
+
+ScHeaderFooterTextCursor::ScHeaderFooterTextCursor(const ScHeaderFooterTextCursor& rOther) :
+ SvxUnoTextCursor( rOther ),
+ rTextObj( rOther.rTextObj )
+{
+ rTextObj.acquire();
+}
+
+ScHeaderFooterTextCursor::ScHeaderFooterTextCursor(ScHeaderFooterTextObj& rText) :
+ SvxUnoTextCursor( rText.GetUnoText() ),
+ rTextObj( rText )
+{
+ rTextObj.acquire();
+}
+
+ScHeaderFooterTextCursor::~ScHeaderFooterTextCursor() throw()
+{
+ rTextObj.release();
+}
+
+// SvxUnoTextCursor methods reimplemented here to return the right objects:
+
+uno::Reference<text::XText> SAL_CALL ScHeaderFooterTextCursor::getText() throw(uno::RuntimeException)
+{
+ SolarMutexGuard aGuard;
+ return &rTextObj;
+}
+
+uno::Reference<text::XTextRange> SAL_CALL ScHeaderFooterTextCursor::getStart() throw(uno::RuntimeException)
+{
+ SolarMutexGuard aGuard;
+
+ //! use other object for range than cursor?
+
+ ScHeaderFooterTextCursor* pNew = new ScHeaderFooterTextCursor( *this );
+ uno::Reference<text::XTextRange> xRange( static_cast<SvxUnoTextRangeBase*>(pNew) );
+
+ ESelection aNewSel(GetSelection());
+ aNewSel.nEndPara = aNewSel.nStartPara;
+ aNewSel.nEndPos = aNewSel.nStartPos;
+ pNew->SetSelection( aNewSel );
+
+ return xRange;
+}
+
+uno::Reference<text::XTextRange> SAL_CALL ScHeaderFooterTextCursor::getEnd() throw(uno::RuntimeException)
+{
+ SolarMutexGuard aGuard;
+
+ //! use other object for range than cursor?
+
+ ScHeaderFooterTextCursor* pNew = new ScHeaderFooterTextCursor( *this );
+ uno::Reference<text::XTextRange> xRange( static_cast<SvxUnoTextRangeBase*>(pNew) );
+
+ ESelection aNewSel(GetSelection());
+ aNewSel.nStartPara = aNewSel.nEndPara;
+ aNewSel.nStartPos = aNewSel.nEndPos;
+ pNew->SetSelection( aNewSel );
+
+ return xRange;
+}
+
+// XUnoTunnel
+
+sal_Int64 SAL_CALL ScHeaderFooterTextCursor::getSomething(
+ const uno::Sequence<sal_Int8 >& rId ) throw(uno::RuntimeException)
+{
+ if ( rId.getLength() == 16 &&
+ 0 == rtl_compareMemory( getUnoTunnelId().getConstArray(),
+ rId.getConstArray(), 16 ) )
+ {
+ return sal::static_int_cast<sal_Int64>(reinterpret_cast<sal_IntPtr>(this));
+ }
+ return SvxUnoTextCursor::getSomething( rId );
+}
+
+const uno::Sequence<sal_Int8>& ScHeaderFooterTextCursor::getUnoTunnelId()
+{
+ static uno::Sequence<sal_Int8> * pSeq = 0;
+ if( !pSeq )
+ {
+ osl::Guard< osl::Mutex > aGuard( osl::Mutex::getGlobalMutex() );
+ if( !pSeq )
+ {
+ static uno::Sequence< sal_Int8 > aSeq( 16 );
+ rtl_createUuid( (sal_uInt8*)aSeq.getArray(), 0, sal_True );
+ pSeq = &aSeq;
+ }
+ }
+ return *pSeq;
+}
+
+ScHeaderFooterTextCursor* ScHeaderFooterTextCursor::getImplementation(
+ const uno::Reference<uno::XInterface> xObj )
+{
+ ScHeaderFooterTextCursor* pRet = NULL;
+ uno::Reference<lang::XUnoTunnel> xUT( xObj, uno::UNO_QUERY );
+ if (xUT.is())
+ pRet = reinterpret_cast<ScHeaderFooterTextCursor*>(sal::static_int_cast<sal_IntPtr>(xUT->getSomething(getUnoTunnelId())));
+ return pRet;
+}
+
+//------------------------------------------------------------------------
+
+ScDrawTextCursor::ScDrawTextCursor(const ScDrawTextCursor& rOther) :
+ SvxUnoTextCursor( rOther ),
+ xParentText( rOther.xParentText )
+{
+}
+
+ScDrawTextCursor::ScDrawTextCursor( const uno::Reference<text::XText>& xParent,
+ const SvxUnoTextBase& rText ) :
+ SvxUnoTextCursor( rText ),
+ xParentText( xParent )
+
+{
+}
+
+ScDrawTextCursor::~ScDrawTextCursor() throw()
+{
+}
+
+// SvxUnoTextCursor methods reimplemented here to return the right objects:
+
+uno::Reference<text::XText> SAL_CALL ScDrawTextCursor::getText() throw(uno::RuntimeException)
+{
+ SolarMutexGuard aGuard;
+ return xParentText;
+}
+
+uno::Reference<text::XTextRange> SAL_CALL ScDrawTextCursor::getStart() throw(uno::RuntimeException)
+{
+ SolarMutexGuard aGuard;
+
+ //! use other object for range than cursor?
+
+ ScDrawTextCursor* pNew = new ScDrawTextCursor( *this );
+ uno::Reference<text::XTextRange> xRange( static_cast<SvxUnoTextRangeBase*>(pNew) );
+
+ ESelection aNewSel(GetSelection());
+ aNewSel.nEndPara = aNewSel.nStartPara;
+ aNewSel.nEndPos = aNewSel.nStartPos;
+ pNew->SetSelection( aNewSel );
+
+ return xRange;
+}
+
+uno::Reference<text::XTextRange> SAL_CALL ScDrawTextCursor::getEnd() throw(uno::RuntimeException)
+{
+ SolarMutexGuard aGuard;
+
+ //! use other object for range than cursor?
+
+ ScDrawTextCursor* pNew = new ScDrawTextCursor( *this );
+ uno::Reference<text::XTextRange> xRange( static_cast<SvxUnoTextRangeBase*>(pNew) );
+
+ ESelection aNewSel(GetSelection());
+ aNewSel.nStartPara = aNewSel.nEndPara;
+ aNewSel.nStartPos = aNewSel.nEndPos;
+ pNew->SetSelection( aNewSel );
+
+ return xRange;
+}
+
+// XUnoTunnel
+
+sal_Int64 SAL_CALL ScDrawTextCursor::getSomething(
+ const uno::Sequence<sal_Int8 >& rId ) throw(uno::RuntimeException)
+{
+ if ( rId.getLength() == 16 &&
+ 0 == rtl_compareMemory( getUnoTunnelId().getConstArray(),
+ rId.getConstArray(), 16 ) )
+ {
+ return sal::static_int_cast<sal_Int64>(reinterpret_cast<sal_IntPtr>(this));
+ }
+ return SvxUnoTextCursor::getSomething( rId );
+}
+
+const uno::Sequence<sal_Int8>& ScDrawTextCursor::getUnoTunnelId()
+{
+ static uno::Sequence<sal_Int8> * pSeq = 0;
+ if( !pSeq )
+ {
+ osl::Guard< osl::Mutex > aGuard( osl::Mutex::getGlobalMutex() );
+ if( !pSeq )
+ {
+ static uno::Sequence< sal_Int8 > aSeq( 16 );
+ rtl_createUuid( (sal_uInt8*)aSeq.getArray(), 0, sal_True );
+ pSeq = &aSeq;
+ }
+ }
+ return *pSeq;
+}
+
+ScDrawTextCursor* ScDrawTextCursor::getImplementation( const uno::Reference<uno::XInterface> xObj )
+{
+ ScDrawTextCursor* pRet = NULL;
+ uno::Reference<lang::XUnoTunnel> xUT( xObj, uno::UNO_QUERY );
+ if (xUT.is())
+ pRet = reinterpret_cast<ScDrawTextCursor*>(sal::static_int_cast<sal_IntPtr>(xUT->getSomething(getUnoTunnelId())));
+ return pRet;
+}
+
+//------------------------------------------------------------------------
+
+ScSimpleEditSourceHelper::ScSimpleEditSourceHelper()
+{
+ SfxItemPool* pEnginePool = EditEngine::CreatePool();
+ pEnginePool->SetDefaultMetric( SFX_MAPUNIT_100TH_MM );
+ pEnginePool->FreezeIdRanges();
+
+ pEditEngine = new ScFieldEditEngine( pEnginePool, NULL, sal_True ); // TRUE: become owner of pool
+ pForwarder = new SvxEditEngineForwarder( *pEditEngine );
+ pOriginalSource = new ScSimpleEditSource( pForwarder );
+}
+
+ScSimpleEditSourceHelper::~ScSimpleEditSourceHelper()
+{
+ SolarMutexGuard aGuard; // needed for EditEngine dtor
+
+ delete pOriginalSource;
+ delete pForwarder;
+ delete pEditEngine;
+}
+
+ScEditEngineTextObj::ScEditEngineTextObj() :
+ SvxUnoText( GetOriginalSource(), ScCellObj::GetEditPropertySet(), uno::Reference<text::XText>() )
+{
+}
+
+ScEditEngineTextObj::~ScEditEngineTextObj() throw()
+{
+}
+
+void ScEditEngineTextObj::SetText( const EditTextObject& rTextObject )
+{
+ GetEditEngine()->SetText( rTextObject );
+
+ ESelection aSel;
+ ::GetSelection( aSel, GetEditSource()->GetTextForwarder() );
+ SetSelection( aSel );
+}
+
+EditTextObject* ScEditEngineTextObj::CreateTextObject()
+{
+ return GetEditEngine()->CreateTextObject();
+}
+
+//------------------------------------------------------------------------
+
+ScCellTextData::ScCellTextData(ScDocShell* pDocSh, const ScAddress& rP) :
+ pDocShell( pDocSh ),
+ aCellPos( rP ),
+ pEditEngine( NULL ),
+ pForwarder( NULL ),
+ pOriginalSource( NULL ),
+ bDataValid( false ),
+ bInUpdate( false ),
+ bDirty( false ),
+ bDoUpdate( sal_True )
+{
+ if (pDocShell)
+ pDocShell->GetDocument()->AddUnoObject(*this);
+}
+
+ScCellTextData::~ScCellTextData()
+{
+ SolarMutexGuard aGuard; // needed for EditEngine dtor
+
+ if (pDocShell)
+ {
+ pDocShell->GetDocument()->RemoveUnoObject(*this);
+ pDocShell->GetDocument()->DisposeFieldEditEngine(pEditEngine);
+ }
+ else
+ delete pEditEngine;
+
+ delete pForwarder;
+
+ delete pOriginalSource;
+}
+
+ScSharedCellEditSource* ScCellTextData::GetOriginalSource()
+{
+ if (!pOriginalSource)
+ pOriginalSource = new ScSharedCellEditSource( this );
+ return pOriginalSource;
+}
+
+void ScCellTextData::GetCellText(const ScAddress& rCellPos, String& rText)
+{
+ if (pDocShell)
+ {
+ ScDocument* pDoc = pDocShell->GetDocument();
+ pDoc->GetInputString( rCellPos.Col(), rCellPos.Row(), rCellPos.Tab(), rText );
+ }
+}
+
+SvxTextForwarder* ScCellTextData::GetTextForwarder()
+{
+ if (!pEditEngine)
+ {
+ if ( pDocShell )
+ {
+ ScDocument* pDoc = pDocShell->GetDocument();
+ pEditEngine = pDoc->CreateFieldEditEngine();
+ }
+ else
+ {
+ SfxItemPool* pEnginePool = EditEngine::CreatePool();
+ pEnginePool->FreezeIdRanges();
+ pEditEngine = new ScFieldEditEngine( pEnginePool, NULL, sal_True );
+ }
+ // currently, GetPortions doesn't work if UpdateMode is sal_False,
+ // this will be fixed (in EditEngine) by src600
+// pEditEngine->SetUpdateMode( sal_False );
+ pEditEngine->EnableUndo( false );
+ if (pDocShell)
+ pEditEngine->SetRefDevice(pDocShell->GetRefDevice());
+ else
+ pEditEngine->SetRefMapMode( MAP_100TH_MM );
+ pForwarder = new SvxEditEngineForwarder(*pEditEngine);
+ }
+
+ if (bDataValid)
+ return pForwarder;
+
+ String aText;
+
+ if (pDocShell)
+ {
+ ScDocument* pDoc = pDocShell->GetDocument();
+
+ SfxItemSet aDefaults( pEditEngine->GetEmptyItemSet() );
+ if( const ScPatternAttr* pPattern =
+ pDoc->GetPattern( aCellPos.Col(), aCellPos.Row(), aCellPos.Tab() ) )
+ {
+ pPattern->FillEditItemSet( &aDefaults );
+ pPattern->FillEditParaItems( &aDefaults ); // including alignment etc. (for reading)
+ }
+
+ const ScBaseCell* pCell = pDoc->GetCell( aCellPos );
+ if ( pCell && pCell->GetCellType() == CELLTYPE_EDIT )
+ pEditEngine->SetTextNewDefaults( *((const ScEditCell*)pCell)->GetData(), aDefaults );
+ else
+ {
+ GetCellText( aCellPos, aText );
+ if (aText.Len())
+ pEditEngine->SetTextNewDefaults( aText, aDefaults );
+ else
+ pEditEngine->SetDefaults(aDefaults);
+ }
+ }
+
+ bDataValid = sal_True;
+ return pForwarder;
+}
+
+void ScCellTextData::UpdateData()
+{
+ if ( bDoUpdate )
+ {
+ DBG_ASSERT(pEditEngine != NULL, "no EditEngine for UpdateData()");
+ if ( pDocShell && pEditEngine )
+ {
+ // during the own UpdateData call, bDataValid must not be reset,
+ // or things like attributes after the text would be lost
+ // (are not stored in the cell)
+
+ bInUpdate = sal_True; // prevents bDataValid from being reset
+
+ ScDocFunc aFunc(*pDocShell);
+ aFunc.PutData( aCellPos, *pEditEngine, false, sal_True ); // always as text
+
+ bInUpdate = false;
+ bDirty = false;
+ }
+ }
+ else
+ bDirty = sal_True;
+}
+
+void ScCellTextData::Notify( SfxBroadcaster&, const SfxHint& rHint )
+{
+ if ( rHint.ISA( ScUpdateRefHint ) )
+ {
+// const ScUpdateRefHint& rRef = (const ScUpdateRefHint&)rHint;
+
+ //! Ref-Update
+ }
+ else if ( rHint.ISA( SfxSimpleHint ) )
+ {
+ sal_uLong nId = ((const SfxSimpleHint&)rHint).GetId();
+ if ( nId == SFX_HINT_DYING )
+ {
+ pDocShell = NULL; // invalid now
+
+ DELETEZ( pForwarder );
+ DELETEZ( pEditEngine ); // EditEngine uses document's pool
+ }
+ else if ( nId == SFX_HINT_DATACHANGED )
+ {
+ if (!bInUpdate) // not for own UpdateData calls
+ bDataValid = false; // text has to be read from the cell again
+ }
+ }
+}
+
+ScCellTextObj::ScCellTextObj(ScDocShell* pDocSh, const ScAddress& rP) :
+ ScCellTextData( pDocSh, rP ),
+ SvxUnoText( GetOriginalSource(), ScCellObj::GetEditPropertySet(), uno::Reference<text::XText>() )
+{
+}
+
+ScCellTextObj::~ScCellTextObj() throw()
+{
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */