/* -*- 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 * * for a copy of the LGPLv3 License. * ************************************************************************/ #include "fielduno.hxx" #include "textuno.hxx" #include "miscuno.hxx" #include "docsh.hxx" #include "hints.hxx" #include "editsrc.hxx" #include "cellsuno.hxx" #include "servuno.hxx" // fuer IDs #include "unonames.hxx" #include "editutil.hxx" #include #include #include #include #include #include #include #include #include #include #include #include using namespace com::sun::star; namespace { // alles ohne Which-ID, Map nur fuer PropertySetInfo const SfxItemPropertySet* getDateTimePropertySet() { static SfxItemPropertyMapEntry aMapContent[] = { { MAP_CHAR_LEN(SC_UNONAME_DATETIME), 0, &getCppuType((const util::DateTime*)0), 0, 0 }, { MAP_CHAR_LEN(SC_UNONAME_ISFIXED), 0, &getBooleanCppuType(), 0, 0 }, { MAP_CHAR_LEN(SC_UNONAME_ISDATE), 0, &getBooleanCppuType(), 0, 0 }, { MAP_CHAR_LEN(SC_UNONAME_NUMFMT), 0, &getCppuType((const sal_Int32*)0), 0, 0 }, {0,0,0,0,0,0} }; static SfxItemPropertySet aMap(aMapContent); return &aMap; } const SfxItemPropertySet* getEmptyPropertySet() { static SfxItemPropertyMapEntry aMapContent[] = { {0,0,0,0,0,0} }; static SfxItemPropertySet aMap(aMapContent); return &aMap; } const SfxItemPropertySet* lcl_GetURLPropertySet() { static SfxItemPropertyMapEntry aURLPropertyMap_Impl[] = { {MAP_CHAR_LEN(SC_UNONAME_ANCTYPE), 0, &getCppuType((text::TextContentAnchorType*)0), beans::PropertyAttribute::READONLY, 0 }, {MAP_CHAR_LEN(SC_UNONAME_ANCTYPES), 0, &getCppuType((uno::Sequence*)0), beans::PropertyAttribute::READONLY, 0 }, {MAP_CHAR_LEN(SC_UNONAME_REPR), 0, &getCppuType((rtl::OUString*)0), 0, 0}, {MAP_CHAR_LEN(SC_UNONAME_TARGET), 0, &getCppuType((rtl::OUString*)0), 0, 0}, {MAP_CHAR_LEN(SC_UNONAME_TEXTWRAP), 0, &getCppuType((text::WrapTextMode*)0), beans::PropertyAttribute::READONLY, 0 }, {MAP_CHAR_LEN(SC_UNONAME_URL), 0, &getCppuType((rtl::OUString*)0), 0, 0}, {0,0,0,0,0,0} }; static SfxItemPropertySet aURLPropertySet_Impl( aURLPropertyMap_Impl ); return &aURLPropertySet_Impl; } const SfxItemPropertySet* lcl_GetHeaderFieldPropertySet() { static SfxItemPropertyMapEntry aHeaderFieldPropertyMap_Impl[] = { {MAP_CHAR_LEN(SC_UNONAME_ANCTYPE), 0, &getCppuType((text::TextContentAnchorType*)0), beans::PropertyAttribute::READONLY, 0 }, {MAP_CHAR_LEN(SC_UNONAME_ANCTYPES), 0, &getCppuType((uno::Sequence*)0), beans::PropertyAttribute::READONLY, 0 }, {MAP_CHAR_LEN(SC_UNONAME_TEXTWRAP), 0, &getCppuType((text::WrapTextMode*)0), beans::PropertyAttribute::READONLY, 0 }, {0,0,0,0,0,0} }; static SfxItemPropertySet aHeaderFieldPropertySet_Impl( aHeaderFieldPropertyMap_Impl ); return &aHeaderFieldPropertySet_Impl; } const SfxItemPropertySet* lcl_GetFileFieldPropertySet() { static SfxItemPropertyMapEntry aFileFieldPropertyMap_Impl[] = { {MAP_CHAR_LEN(SC_UNONAME_ANCTYPE), 0, &getCppuType((text::TextContentAnchorType*)0), beans::PropertyAttribute::READONLY, 0 }, {MAP_CHAR_LEN(SC_UNONAME_ANCTYPES), 0, &getCppuType((uno::Sequence*)0), beans::PropertyAttribute::READONLY, 0 }, {MAP_CHAR_LEN(SC_UNONAME_FILEFORM), 0, &getCppuType((sal_Int16*)0), 0, 0 }, {MAP_CHAR_LEN(SC_UNONAME_TEXTWRAP), 0, &getCppuType((text::WrapTextMode*)0), beans::PropertyAttribute::READONLY, 0 }, {0,0,0,0,0,0} }; static SfxItemPropertySet aFileFieldPropertySet_Impl( aFileFieldPropertyMap_Impl ); return &aFileFieldPropertySet_Impl; } SvxFileFormat lcl_UnoToSvxFileFormat( sal_Int16 nUnoValue ) { switch( nUnoValue ) { case text::FilenameDisplayFormat::FULL: return SVXFILEFORMAT_FULLPATH; case text::FilenameDisplayFormat::PATH: return SVXFILEFORMAT_PATH; case text::FilenameDisplayFormat::NAME: return SVXFILEFORMAT_NAME; default: return SVXFILEFORMAT_NAME_EXT; } } sal_Int16 lcl_SvxToUnoFileFormat( SvxFileFormat nSvxValue ) { switch( nSvxValue ) { case SVXFILEFORMAT_NAME_EXT: return text::FilenameDisplayFormat::NAME_AND_EXT; case SVXFILEFORMAT_FULLPATH: return text::FilenameDisplayFormat::FULL; case SVXFILEFORMAT_PATH: return text::FilenameDisplayFormat::PATH; default: return text::FilenameDisplayFormat::NAME; } } } #define SCTEXTFIELD_SERVICE "com.sun.star.text.TextField" #define SCTEXTCONTENT_SERVICE "com.sun.star.text.TextContent" SC_SIMPLE_SERVICE_INFO( ScCellFieldsObj, "ScCellFieldsObj", "com.sun.star.text.TextFields" ) SC_SIMPLE_SERVICE_INFO( ScHeaderFieldsObj, "ScHeaderFieldsObj", "com.sun.star.text.TextFields" ) //------------------------------------------------------------------------ // ScUnoEditEngine nur um aus einer EditEngine die Felder herauszubekommen... enum ScUnoCollectMode { SC_UNO_COLLECT_NONE, SC_UNO_COLLECT_COUNT, SC_UNO_COLLECT_FINDINDEX, SC_UNO_COLLECT_FINDPOS }; /** * This class exists solely to allow searching through field items. TODO: * Look into providing the same functionality directly in EditEngine, to * avoid having this class altogether. */ class ScUnoEditEngine : public ScEditEngineDefaulter { ScUnoCollectMode eMode; sal_uInt16 nFieldCount; sal_Int32 mnFieldType; SvxFieldData* pFound; // lokale Kopie sal_uInt16 nFieldPar; xub_StrLen nFieldPos; sal_uInt16 nFieldIndex; public: ScUnoEditEngine(ScEditEngineDefaulter* pSource); ~ScUnoEditEngine(); //! nPos should be xub_StrLen virtual String CalcFieldValue( const SvxFieldItem& rField, sal_uInt16 nPara, sal_uInt16 nPos, Color*& rTxtColor, Color*& rFldColor ); sal_uInt16 CountFields(); SvxFieldData* FindByIndex(sal_uInt16 nIndex); SvxFieldData* FindByPos(sal_uInt16 nPar, xub_StrLen nPos, sal_Int32 nType); sal_uInt16 GetFieldPar() const { return nFieldPar; } xub_StrLen GetFieldPos() const { return nFieldPos; } }; ScUnoEditEngine::ScUnoEditEngine(ScEditEngineDefaulter* pSource) : ScEditEngineDefaulter( *pSource ), eMode( SC_UNO_COLLECT_NONE ), nFieldCount( 0 ), mnFieldType(text::textfield::Type::UNSPECIFIED), pFound( NULL ) { if (pSource) { EditTextObject* pData = pSource->CreateTextObject(); SetText( *pData ); delete pData; } } ScUnoEditEngine::~ScUnoEditEngine() { delete pFound; } String ScUnoEditEngine::CalcFieldValue( const SvxFieldItem& rField, sal_uInt16 nPara, sal_uInt16 nPos, Color*& rTxtColor, Color*& rFldColor ) { String aRet(EditEngine::CalcFieldValue( rField, nPara, nPos, rTxtColor, rFldColor )); if (eMode != SC_UNO_COLLECT_NONE) { const SvxFieldData* pFieldData = rField.GetField(); if ( pFieldData ) { if (mnFieldType == text::textfield::Type::UNSPECIFIED || pFieldData->GetClassId() == mnFieldType) { if ( eMode == SC_UNO_COLLECT_FINDINDEX && !pFound && nFieldCount == nFieldIndex ) { pFound = pFieldData->Clone(); nFieldPar = nPara; nFieldPos = nPos; } if ( eMode == SC_UNO_COLLECT_FINDPOS && !pFound && nPara == nFieldPar && nPos == nFieldPos ) { pFound = pFieldData->Clone(); nFieldIndex = nFieldCount; } ++nFieldCount; } } } return aRet; } sal_uInt16 ScUnoEditEngine::CountFields() { eMode = SC_UNO_COLLECT_COUNT; mnFieldType = text::textfield::Type::UNSPECIFIED; nFieldCount = 0; UpdateFields(); eMode = SC_UNO_COLLECT_NONE; return nFieldCount; } SvxFieldData* ScUnoEditEngine::FindByIndex(sal_uInt16 nIndex) { eMode = SC_UNO_COLLECT_FINDINDEX; nFieldIndex = nIndex; mnFieldType = text::textfield::Type::UNSPECIFIED; nFieldCount = 0; UpdateFields(); eMode = SC_UNO_COLLECT_NONE; return pFound; } SvxFieldData* ScUnoEditEngine::FindByPos(sal_uInt16 nPar, xub_StrLen nPos, sal_Int32 nType) { eMode = SC_UNO_COLLECT_FINDPOS; nFieldPar = nPar; nFieldPos = nPos; mnFieldType = nType; nFieldCount = 0; UpdateFields(); mnFieldType = text::textfield::Type::UNSPECIFIED; eMode = SC_UNO_COLLECT_NONE; return pFound; } //------------------------------------------------------------------------ ScCellFieldsObj::ScCellFieldsObj( const uno::Reference& xContent, ScDocShell* pDocSh, const ScAddress& rPos) : mxContent(xContent), pDocShell( pDocSh ), aCellPos( rPos ), mpRefreshListeners( NULL ) { pDocShell->GetDocument()->AddUnoObject(*this); mpEditSource = new ScCellEditSource( pDocShell, aCellPos ); } ScCellFieldsObj::~ScCellFieldsObj() { if (pDocShell) pDocShell->GetDocument()->RemoveUnoObject(*this); delete mpEditSource; // increment refcount to prevent double call off dtor osl_incrementInterlockedCount( &m_refCount ); if (mpRefreshListeners) { lang::EventObject aEvent; aEvent.Source.set(static_cast(this)); if (mpRefreshListeners) { mpRefreshListeners->disposeAndClear(aEvent); DELETEZ( mpRefreshListeners ); } } } void ScCellFieldsObj::Notify( SfxBroadcaster&, const SfxHint& rHint ) { if ( rHint.ISA( ScUpdateRefHint ) ) { //! Ref-Update } else if ( rHint.ISA( SfxSimpleHint ) && ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING ) { pDocShell = NULL; // ungueltig geworden } // EditSource hat sich selber als Listener angemeldet } // XIndexAccess (via XTextFields) uno::Reference ScCellFieldsObj::GetObjectByIndex_Impl(sal_Int32 Index) const { //! Feld-Funktionen muessen an den Forwarder !!! ScEditEngineDefaulter* pEditEngine = mpEditSource->GetEditEngine(); ScUnoEditEngine aTempEngine(pEditEngine); SvxFieldData* pData = aTempEngine.FindByIndex(static_cast(Index)); if (!pData) return uno::Reference(); sal_uInt16 nPar = aTempEngine.GetFieldPar(); xub_StrLen nPos = aTempEngine.GetFieldPos(); ESelection aSelection( nPar, nPos, nPar, nPos+1 ); // Feld ist 1 Zeichen sal_Int32 eType = pData->GetClassId(); uno::Reference xRet( new ScEditFieldObj(mxContent, new ScCellEditSource(pDocShell, aCellPos), eType, aSelection)); return xRet; } sal_Int32 SAL_CALL ScCellFieldsObj::getCount() throw(uno::RuntimeException) { SolarMutexGuard aGuard; //! Feld-Funktionen muessen an den Forwarder !!! ScEditEngineDefaulter* pEditEngine = mpEditSource->GetEditEngine(); ScUnoEditEngine aTempEngine(pEditEngine); return aTempEngine.CountFields(); // Felder zaehlen, in Zelle ist der Typ egal } uno::Any SAL_CALL ScCellFieldsObj::getByIndex( sal_Int32 nIndex ) throw(lang::IndexOutOfBoundsException, lang::WrappedTargetException, uno::RuntimeException) { SolarMutexGuard aGuard; uno::Reference xField(GetObjectByIndex_Impl(nIndex)); if (xField.is()) return uno::makeAny(xField); else throw lang::IndexOutOfBoundsException(); } uno::Type SAL_CALL ScCellFieldsObj::getElementType() throw(uno::RuntimeException) { SolarMutexGuard aGuard; return getCppuType((uno::Reference*)0); } sal_Bool SAL_CALL ScCellFieldsObj::hasElements() throw(uno::RuntimeException) { SolarMutexGuard aGuard; return ( getCount() != 0 ); } uno::Reference SAL_CALL ScCellFieldsObj::createEnumeration() throw(uno::RuntimeException) { SolarMutexGuard aGuard; return new ScIndexEnumeration(this, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.text.TextFieldEnumeration"))); } void SAL_CALL ScCellFieldsObj::addContainerListener( const uno::Reference& /* xListener */ ) throw(uno::RuntimeException) { OSL_FAIL("not implemented"); } void SAL_CALL ScCellFieldsObj::removeContainerListener( const uno::Reference& /* xListener */ ) throw(uno::RuntimeException) { OSL_FAIL("not implemented"); } // XRefreshable void SAL_CALL ScCellFieldsObj::refresh( ) throw (uno::RuntimeException) { if (mpRefreshListeners) { // Call all listeners. uno::Sequence< uno::Reference< uno::XInterface > > aListeners(mpRefreshListeners->getElements()); sal_uInt32 nLength(aListeners.getLength()); if (nLength) { const uno::Reference< uno::XInterface >* pInterfaces = aListeners.getConstArray(); if (pInterfaces) { lang::EventObject aEvent; aEvent.Source.set(uno::Reference< util::XRefreshable >(const_cast(this))); sal_uInt32 i(0); while (i < nLength) { try { while(i < nLength) { static_cast< util::XRefreshListener* >(pInterfaces->get())->refreshed(aEvent); ++pInterfaces; ++i; } } catch(uno::RuntimeException&) { ++pInterfaces; ++i; } } } } } } void SAL_CALL ScCellFieldsObj::addRefreshListener( const uno::Reference< util::XRefreshListener >& xListener ) throw (uno::RuntimeException) { if (xListener.is()) { SolarMutexGuard aGuard; if (!mpRefreshListeners) mpRefreshListeners = new cppu::OInterfaceContainerHelper(aMutex); mpRefreshListeners->addInterface(xListener); } } void SAL_CALL ScCellFieldsObj::removeRefreshListener( const uno::Reference& xListener ) throw (uno::RuntimeException) { if (xListener.is()) { SolarMutexGuard aGuard; if (mpRefreshListeners) mpRefreshListeners->removeInterface(xListener); } } ScHeaderFieldsObj::ScHeaderFieldsObj(ScHeaderFooterTextData& rData) : mrData(rData), mpRefreshListeners( NULL ) { mpEditSource = new ScHeaderFooterEditSource(rData); } ScHeaderFieldsObj::~ScHeaderFieldsObj() { delete mpEditSource; // increment refcount to prevent double call off dtor osl_incrementInterlockedCount( &m_refCount ); if (mpRefreshListeners) { lang::EventObject aEvent; aEvent.Source = static_cast(this); if (mpRefreshListeners) { mpRefreshListeners->disposeAndClear(aEvent); DELETEZ( mpRefreshListeners ); } } } // XIndexAccess (via XTextFields) uno::Reference ScHeaderFieldsObj::GetObjectByIndex_Impl(sal_Int32 Index) const { //! Feld-Funktionen muessen an den Forwarder !!! ScEditEngineDefaulter* pEditEngine = mpEditSource->GetEditEngine(); ScUnoEditEngine aTempEngine(pEditEngine); SvxFieldData* pData = aTempEngine.FindByIndex(static_cast(Index)); if (!pData) return NULL; // Get the parent text range instance. uno::Reference xTextRange; ScHeaderFooterContentObj& rContentObj = mrData.GetContentObj(); uno::Reference xText; sal_uInt16 nPart = mrData.GetPart(); if (nPart == SC_HDFT_LEFT) xText = rContentObj.getLeftText(); else if (nPart == SC_HDFT_CENTER) xText = rContentObj.getCenterText(); else xText = rContentObj.getRightText(); uno::Reference xTemp(xText, uno::UNO_QUERY); xTextRange = xTemp; sal_uInt16 nPar = aTempEngine.GetFieldPar(); xub_StrLen nPos = aTempEngine.GetFieldPos(); ESelection aSelection( nPar, nPos, nPar, nPos+1 ); // Field is 1 character sal_Int32 eRealType = pData->GetClassId(); uno::Reference xRet( new ScEditFieldObj(xTextRange, new ScHeaderFooterEditSource(mrData), eRealType, aSelection)); return xRet; } sal_Int32 SAL_CALL ScHeaderFieldsObj::getCount() throw(uno::RuntimeException) { SolarMutexGuard aGuard; //! Feld-Funktionen muessen an den Forwarder !!! ScEditEngineDefaulter* pEditEngine = mpEditSource->GetEditEngine(); ScUnoEditEngine aTempEngine(pEditEngine); return aTempEngine.CountFields(); } uno::Any SAL_CALL ScHeaderFieldsObj::getByIndex( sal_Int32 nIndex ) throw(lang::IndexOutOfBoundsException, lang::WrappedTargetException, uno::RuntimeException) { SolarMutexGuard aGuard; uno::Reference xField(GetObjectByIndex_Impl(nIndex)); if (xField.is()) return uno::makeAny(xField); else throw lang::IndexOutOfBoundsException(); } uno::Type SAL_CALL ScHeaderFieldsObj::getElementType() throw(uno::RuntimeException) { SolarMutexGuard aGuard; return getCppuType((uno::Reference*)0); } sal_Bool SAL_CALL ScHeaderFieldsObj::hasElements() throw(uno::RuntimeException) { SolarMutexGuard aGuard; return ( getCount() != 0 ); } uno::Reference SAL_CALL ScHeaderFieldsObj::createEnumeration() throw(uno::RuntimeException) { SolarMutexGuard aGuard; return new ScIndexEnumeration(this, rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.text.TextFieldEnumeration"))); } void SAL_CALL ScHeaderFieldsObj::addContainerListener( const uno::Reference& /* xListener */ ) throw(uno::RuntimeException) { OSL_FAIL("not implemented"); } void SAL_CALL ScHeaderFieldsObj::removeContainerListener( const uno::Reference& /* xListener */ ) throw(uno::RuntimeException) { OSL_FAIL("not implemented"); } // XRefreshable void SAL_CALL ScHeaderFieldsObj::refresh( ) throw (uno::RuntimeException) { if (mpRefreshListeners) { // Call all listeners. uno::Sequence< uno::Reference< uno::XInterface > > aListeners(mpRefreshListeners->getElements()); sal_uInt32 nLength(aListeners.getLength()); if (nLength) { const uno::Reference< uno::XInterface >* pInterfaces = aListeners.getConstArray(); if (pInterfaces) { lang::EventObject aEvent; aEvent.Source.set(uno::Reference< util::XRefreshable >(const_cast(this))); sal_uInt32 i(0); while (i < nLength) { try { while(i < nLength) { static_cast< util::XRefreshListener* >(pInterfaces->get())->refreshed(aEvent); ++pInterfaces; ++i; } } catch(uno::RuntimeException&) { ++pInterfaces; ++i; } } } } } } void SAL_CALL ScHeaderFieldsObj::addRefreshListener( const uno::Reference< util::XRefreshListener >& xListener ) throw (uno::RuntimeException) { if (xListener.is()) { SolarMutexGuard aGuard; if (!mpRefreshListeners) mpRefreshListeners = new cppu::OInterfaceContainerHelper(aMutex); mpRefreshListeners->addInterface(xListener); } } void SAL_CALL ScHeaderFieldsObj::removeRefreshListener( const uno::Reference& xListener ) throw (uno::RuntimeException) { if (xListener.is()) { SolarMutexGuard aGuard; if (mpRefreshListeners) mpRefreshListeners->removeInterface(xListener); } } SvxFieldData* ScEditFieldObj::getData() { if (!mpData) { switch (meType) { case text::textfield::Type::DATE: mpData.reset(new SvxDateField); break; case text::textfield::Type::EXTENDED_FILE: mpData.reset( new SvxExtFileField(rtl::OUString(), SVXFILETYPE_VAR, SVXFILEFORMAT_NAME_EXT)); break; case text::textfield::Type::PAGE: mpData.reset(new SvxPageField); break; case text::textfield::Type::PAGES: mpData.reset(new SvxPagesField); break; case text::textfield::Type::TABLE: mpData.reset(new SvxTableField); break; case text::textfield::Type::TIME: mpData.reset(new SvxTimeField); break; case text::textfield::Type::EXTENDED_TIME: { if (mbIsDate) mpData.reset(new SvxDateField); else mpData.reset(new SvxExtTimeField); } break; case text::textfield::Type::DOCINFO_TITLE: mpData.reset(new SvxFileField); break; case text::textfield::Type::URL: mpData.reset( new SvxURLField(rtl::OUString(), rtl::OUString(), SVXURLFORMAT_APPDEFAULT)); break; default: mpData.reset(new SvxFieldData); } } return mpData.get(); } void ScEditFieldObj::setPropertyValueURL(const rtl::OUString& rName, const com::sun::star::uno::Any& rVal) { rtl::OUString aStrVal; if (mpEditSource) { // Edit engine instance already exists for this field item. Use it. ScEditEngineDefaulter* pEditEngine = mpEditSource->GetEditEngine(); ScUnoEditEngine aTempEngine(pEditEngine); // Typ egal (in Zellen gibts nur URLs) SvxFieldData* pField = aTempEngine.FindByPos( aSelection.nStartPara, aSelection.nStartPos, text::textfield::Type::UNSPECIFIED); OSL_ENSURE(pField,"setPropertyValue: Feld nicht gefunden"); if (!pField) return; if (pField->GetClassId() != text::textfield::Type::URL) // Make sure this is indeed a URL field. return; SvxURLField* pURL = static_cast(pField); if (rName == SC_UNONAME_URL) { if (rVal >>= aStrVal) pURL->SetURL(aStrVal); } else if (rName == SC_UNONAME_REPR) { if (rVal >>= aStrVal) pURL->SetRepresentation(aStrVal); } else if (rName == SC_UNONAME_TARGET) { if (rVal >>= aStrVal) pURL->SetTargetFrame(aStrVal); } else throw beans::UnknownPropertyException(); pEditEngine->QuickInsertField( SvxFieldItem(*pField, EE_FEATURE_FIELD), aSelection ); mpEditSource->UpdateData(); return; } // Edit engine instance not yet present. Store the item data for later use. SvxFieldData* pData = getData(); if (!pData) throw uno::RuntimeException(); SvxURLField* p = static_cast(pData); if (rName == SC_UNONAME_URL) { if (rVal >>= aStrVal) p->SetURL(aStrVal); } else if (rName == SC_UNONAME_REPR) { if (rVal >>= aStrVal) p->SetRepresentation(aStrVal); } else if (rName == SC_UNONAME_TARGET) { if (rVal >>= aStrVal) p->SetTargetFrame(aStrVal); } else throw beans::UnknownPropertyException(); } uno::Any ScEditFieldObj::getPropertyValueURL(const rtl::OUString& rName) { uno::Any aRet; // anchor type is always "as character", text wrap always "none" if (mpEditSource) { //! Feld-Funktionen muessen an den Forwarder !!! ScEditEngineDefaulter* pEditEngine = mpEditSource->GetEditEngine(); ScUnoEditEngine aTempEngine(pEditEngine); // Typ egal (in Zellen gibts nur URLs) const SvxFieldData* pField = aTempEngine.FindByPos( aSelection.nStartPara, aSelection.nStartPos, text::textfield::Type::UNSPECIFIED); OSL_ENSURE(pField,"getPropertyValue: Feld nicht gefunden"); if (!pField) throw uno::RuntimeException(); if (pField->GetClassId() != text::textfield::Type::URL) throw uno::RuntimeException(); const SvxURLField* pURL = static_cast(pField); if (rName == SC_UNONAME_URL) aRet <<= pURL->GetURL(); else if (rName == SC_UNONAME_REPR) aRet <<= pURL->GetRepresentation(); else if (rName == SC_UNONAME_TARGET) aRet <<= pURL->GetTargetFrame(); else throw beans::UnknownPropertyException(); } else // noch nicht eingefuegt { const SvxFieldData* pField = getData(); if (!pField) return aRet; const SvxURLField* pURL = static_cast(pField); if (rName == SC_UNONAME_URL) aRet <<= pURL->GetURL(); else if (rName == SC_UNONAME_REPR) aRet <<= pURL->GetRepresentation(); else if (rName == SC_UNONAME_TARGET) aRet <<= pURL->GetTargetFrame(); else throw beans::UnknownPropertyException(); } return aRet; } void ScEditFieldObj::setPropertyValueFile(const rtl::OUString& rName, const uno::Any& rVal) { if (rName == SC_UNONAME_FILEFORM) { sal_Int16 nIntVal = 0; if (rVal >>= nIntVal) { SvxFileFormat eFormat = lcl_UnoToSvxFileFormat(nIntVal); if (mpEditSource) { ScEditEngineDefaulter* pEditEngine = mpEditSource->GetEditEngine(); ScUnoEditEngine aTempEngine(pEditEngine); SvxFieldData* pField = aTempEngine.FindByPos( aSelection.nStartPara, aSelection.nStartPos, text::textfield::Type::EXTENDED_FILE); OSL_ENSURE(pField, "setPropertyValueFile: Field not found"); if (pField) { SvxExtFileField* pExtFile = static_cast(pField); // local to the ScUnoEditEngine pExtFile->SetFormat(eFormat); pEditEngine->QuickInsertField(SvxFieldItem(*pField, EE_FEATURE_FIELD), aSelection); mpEditSource->UpdateData(); } } else { SvxFieldData* pField = getData(); SvxExtFileField* pExtFile = static_cast(pField); pExtFile->SetFormat(eFormat); } } } else throw beans::UnknownPropertyException(); } uno::Any ScEditFieldObj::getPropertyValueFile(const rtl::OUString& rName) { uno::Any aRet; if (rName == SC_UNONAME_FILEFORM) { SvxFileFormat eFormat = SVXFILEFORMAT_NAME_EXT; const SvxFieldData* pField = NULL; if (mpEditSource) { ScEditEngineDefaulter* pEditEngine = mpEditSource->GetEditEngine(); ScUnoEditEngine aTempEngine(pEditEngine); pField = aTempEngine.FindByPos( aSelection.nStartPara, aSelection.nStartPos, text::textfield::Type::EXTENDED_FILE); } else pField = getData(); OSL_ENSURE(pField, "setPropertyValueFile: Field not found"); if (!pField) throw uno::RuntimeException(); const SvxExtFileField* pExtFile = static_cast(pField); eFormat = pExtFile->GetFormat(); sal_Int16 nIntVal = lcl_SvxToUnoFileFormat(eFormat); aRet <<= nIntVal; } else throw beans::UnknownPropertyException(); return aRet; } void ScEditFieldObj::setPropertyValueDateTime(const rtl::OUString& rName, const uno::Any& rVal) { if (mpEditSource) { // Field already inserted. ScEditEngineDefaulter* pEditEngine = mpEditSource->GetEditEngine(); ScUnoEditEngine aTempEngine(pEditEngine); SvxFieldData* pField = aTempEngine.FindByPos(aSelection.nStartPara, aSelection.nStartPos, meType); if (!pField) return; switch (meType) { case text::textfield::Type::DATE: { SvxDateField* p = static_cast(pField); if (rName == SC_UNONAME_ISDATE) { // Do nothing for now. } else if (rName == SC_UNONAME_ISFIXED) { SvxDateType eType = rVal.get() ? SVXDATETYPE_FIX : SVXDATETYPE_VAR; p->SetType(eType); } else if (rName == SC_UNONAME_DATETIME) { maDateTime = rVal.get(); Date aDate(maDateTime.Day, maDateTime.Month, maDateTime.Year); p->SetFixDate(aDate); } else if (rName == SC_UNONAME_NUMFMT) { mnNumFormat = rVal.get(); p->SetFormat(static_cast(mnNumFormat)); } else throw beans::UnknownPropertyException(); } break; case text::textfield::Type::TIME: { // SvxTimeField doesn't have any attributes. if (rName != SC_UNONAME_ISDATE && rName != SC_UNONAME_ISFIXED && rName != SC_UNONAME_DATETIME && rName != SC_UNONAME_NUMFMT) throw beans::UnknownPropertyException(); } break; case text::textfield::Type::EXTENDED_TIME: { SvxExtTimeField* p = static_cast(pField); if (rName == SC_UNONAME_ISDATE) { // Do nothing for now. } else if (rName == SC_UNONAME_ISFIXED) { SvxTimeType eType = rVal.get() ? SVXTIMETYPE_FIX : SVXTIMETYPE_VAR; p->SetType(eType); } else if (rName == SC_UNONAME_DATETIME) { maDateTime = rVal.get(); Time aTime(maDateTime.Hours, maDateTime.Minutes, maDateTime.Seconds, maDateTime.HundredthSeconds); p->SetFixTime(aTime); } else if (rName == SC_UNONAME_NUMFMT) { mnNumFormat = rVal.get(); p->SetFormat(static_cast(mnNumFormat)); } else throw beans::UnknownPropertyException(); } break; default: throw beans::UnknownPropertyException(); } } else { if (rName == SC_UNONAME_ISDATE) mbIsDate = rVal.get(); else if (rName == SC_UNONAME_ISFIXED) mbIsFixed = rVal.get(); else if (rName == SC_UNONAME_DATETIME) maDateTime = rVal.get(); else if (rName == SC_UNONAME_NUMFMT) mnNumFormat = rVal.get(); else throw beans::UnknownPropertyException(); } } uno::Any ScEditFieldObj::getPropertyValueDateTime(const rtl::OUString& rName) { if (mpEditSource) { // Field already inserted. ScEditEngineDefaulter* pEditEngine = mpEditSource->GetEditEngine(); ScUnoEditEngine aTempEngine(pEditEngine); SvxFieldData* pField = aTempEngine.FindByPos(aSelection.nStartPara, aSelection.nStartPos, meType); if (!pField) throw uno::RuntimeException(); switch (meType) { case text::textfield::Type::DATE: { SvxDateField* p = static_cast(pField); if (rName == SC_UNONAME_ISDATE) return uno::makeAny(sal_True); if (rName == SC_UNONAME_ISFIXED) return uno::makeAny(p->GetType() == SVXDATETYPE_FIX); if (rName == SC_UNONAME_DATETIME) { Date aD(p->GetFixDate()); maDateTime.Year = aD.GetYear(); maDateTime.Month = aD.GetMonth(); maDateTime.Day = aD.GetDay(); maDateTime.Hours = 0; maDateTime.Minutes = 0; maDateTime.Seconds = 0; maDateTime.HundredthSeconds = 0; return uno::makeAny(maDateTime); } if (rName == SC_UNONAME_NUMFMT) return uno::makeAny(p->GetFormat()); } break; case text::textfield::Type::TIME: { // SvxTimeField doesn't have any attributes. if (rName == SC_UNONAME_ISDATE) return uno::makeAny(sal_False); if (rName == SC_UNONAME_ISFIXED) return uno::makeAny(sal_False); if (rName == SC_UNONAME_DATETIME) // This is the best we can do. return uno::makeAny(maDateTime); if (rName == SC_UNONAME_NUMFMT) // Same as above. return uno::makeAny(0); } break; case text::textfield::Type::EXTENDED_TIME: { SvxExtTimeField* p = static_cast(pField); if (rName == SC_UNONAME_ISDATE) return uno::makeAny(sal_False); if (rName == SC_UNONAME_ISFIXED) return uno::makeAny(p->GetType() == SVXTIMETYPE_FIX); if (rName == SC_UNONAME_DATETIME) { Time aT(p->GetFixTime()); maDateTime.Year = 0; maDateTime.Month = 0; maDateTime.Day = 0; maDateTime.Hours = aT.GetHour(); maDateTime.Minutes = aT.GetMin(); maDateTime.Seconds = aT.GetSec(); maDateTime.HundredthSeconds = aT.Get100Sec(); return uno::makeAny(maDateTime); } if (rName == SC_UNONAME_NUMFMT) return uno::makeAny(p->GetFormat()); } break; default: ; } } else { if (rName == SC_UNONAME_ISDATE) return uno::makeAny(mbIsDate); if (rName == SC_UNONAME_ISFIXED) return uno::makeAny(mbIsFixed); if (rName == SC_UNONAME_DATETIME) return uno::makeAny(maDateTime); if (rName == SC_UNONAME_NUMFMT) return uno::makeAny(mnNumFormat); } throw beans::UnknownPropertyException(); } void ScEditFieldObj::setPropertyValueSheet(const rtl::OUString& rName, const uno::Any& rVal) { if (mpEditSource) { // Edit engine instance already exists for this field item. Use it. ScEditEngineDefaulter* pEditEngine = mpEditSource->GetEditEngine(); ScUnoEditEngine aTempEngine(pEditEngine); // Typ egal (in Zellen gibts nur URLs) SvxFieldData* pField = aTempEngine.FindByPos( aSelection.nStartPara, aSelection.nStartPos, text::textfield::Type::UNSPECIFIED); OSL_ENSURE(pField,"setPropertyValue: Feld nicht gefunden"); if (!pField) return; if (pField->GetClassId() != text::textfield::Type::TABLE) // Make sure this is indeed a URL field. return; SvxTableField* p = static_cast(pField); if (rName == SC_UNONAME_TABLEPOS) { sal_Int32 nTab = rVal.get(); p->SetTab(nTab); } else throw beans::UnknownPropertyException(); pEditEngine->QuickInsertField(SvxFieldItem(*pField, EE_FEATURE_FIELD), aSelection); mpEditSource->UpdateData(); return; } // Edit engine instance not yet present. Store the item data for later use. SvxFieldData* pData = getData(); if (!pData) throw uno::RuntimeException(); SvxTableField* p = static_cast(pData); if (rName == SC_UNONAME_TABLEPOS) { sal_Int32 nTab = rVal.get(); p->SetTab(nTab); } else throw beans::UnknownPropertyException(); } ScEditFieldObj::ScEditFieldObj( const uno::Reference& rContent, ScEditSource* pEditSrc, sal_Int32 eType, const ESelection& rSel) : OComponentHelper(getMutex()), pPropSet(NULL), mpEditSource(pEditSrc), aSelection(rSel), meType(eType), mpData(NULL), mpContent(rContent), mnNumFormat(0), mbIsDate(false), mbIsFixed(false) { switch (meType) { case text::textfield::Type::DOCINFO_TITLE: pPropSet = getEmptyPropertySet(); break; case text::textfield::Type::EXTENDED_FILE: pPropSet = lcl_GetFileFieldPropertySet(); break; case text::textfield::Type::URL: pPropSet = lcl_GetURLPropertySet(); break; case text::textfield::Type::DATE: case text::textfield::Type::TIME: case text::textfield::Type::EXTENDED_TIME: pPropSet = getDateTimePropertySet(); break; default: pPropSet = lcl_GetHeaderFieldPropertySet(); } if (meType == text::textfield::Type::DATE) mbIsDate = true; } void ScEditFieldObj::InitDoc( const uno::Reference& rContent, ScEditSource* pEditSrc, const ESelection& rSel) { if (!mpEditSource) { mpContent = rContent; mpData.reset(); aSelection = rSel; mpEditSource = pEditSrc; } } ScEditFieldObj::~ScEditFieldObj() { delete mpEditSource; } SvxFieldItem ScEditFieldObj::CreateFieldItem() { OSL_ENSURE( !mpEditSource, "CreateFieldItem mit eingefuegtem Feld" ); return SvxFieldItem(*getData(), EE_FEATURE_FIELD); } sal_Int32 ScEditFieldObj::GetFieldType() const { return meType; } void ScEditFieldObj::DeleteField() { if (mpEditSource) { SvxTextForwarder* pForwarder = mpEditSource->GetTextForwarder(); pForwarder->QuickInsertText( String(), aSelection ); mpEditSource->UpdateData(); aSelection.nEndPara = aSelection.nStartPara; aSelection.nEndPos = aSelection.nStartPos; //! Broadcast, um Selektion in anderen Objekten anzupassen //! (auch bei anderen Aktionen) } } bool ScEditFieldObj::IsInserted() const { return mpEditSource != NULL; } // XTextField rtl::OUString SAL_CALL ScEditFieldObj::getPresentation( sal_Bool bShowCommand ) throw(uno::RuntimeException) { SolarMutexGuard aGuard; if (!mpEditSource) return rtl::OUString(); //! Feld-Funktionen muessen an den Forwarder !!! ScEditEngineDefaulter* pEditEngine = mpEditSource->GetEditEngine(); ScUnoEditEngine aTempEngine(pEditEngine); // Typ egal (in Zellen gibts nur URLs) const SvxFieldData* pField = aTempEngine.FindByPos( aSelection.nStartPara, aSelection.nStartPos, text::textfield::Type::UNSPECIFIED); OSL_ENSURE(pField,"getPresentation: Feld nicht gefunden"); if (!pField) return rtl::OUString(); switch (meType) { case text::textfield::Type::URL: { if (pField->GetClassId() != text::textfield::Type::URL) // Not an URL field, but URL is expected. throw uno::RuntimeException(); const SvxURLField* pURL = static_cast(pField); return bShowCommand ? pURL->GetURL() : pURL->GetRepresentation(); } break; default: ; } return rtl::OUString(); } // XTextContent void SAL_CALL ScEditFieldObj::attach( const uno::Reference& xTextRange ) throw(lang::IllegalArgumentException, uno::RuntimeException) { SolarMutexGuard aGuard; if (xTextRange.is()) { uno::Reference xText(xTextRange->getText()); if (xText.is()) { xText->insertTextContent( xTextRange, this, sal_True ); } } } uno::Reference SAL_CALL ScEditFieldObj::getAnchor() throw(uno::RuntimeException) { SolarMutexGuard aGuard; return mpContent; } // XComponent void SAL_CALL ScEditFieldObj::dispose() throw(uno::RuntimeException) { OComponentHelper::dispose(); } void SAL_CALL ScEditFieldObj::addEventListener( const uno::Reference& xListener ) throw(uno::RuntimeException) { OComponentHelper::addEventListener( xListener ); } void SAL_CALL ScEditFieldObj::removeEventListener( const uno::Reference& xListener ) throw(uno::RuntimeException) { OComponentHelper::removeEventListener( xListener ); } // XPropertySet uno::Reference SAL_CALL ScEditFieldObj::getPropertySetInfo() throw(uno::RuntimeException) { SolarMutexGuard aGuard; uno::Reference aRef = pPropSet->getPropertySetInfo(); return aRef; } void SAL_CALL ScEditFieldObj::setPropertyValue( const rtl::OUString& aPropertyName, const uno::Any& aValue ) throw(beans::UnknownPropertyException, beans::PropertyVetoException, lang::IllegalArgumentException, lang::WrappedTargetException, uno::RuntimeException) { SolarMutexGuard aGuard; if (aPropertyName == SC_UNONAME_ANCHOR) { aValue >>= mpContent; return; } switch (meType) { case text::textfield::Type::URL: setPropertyValueURL(aPropertyName, aValue); break; case text::textfield::Type::EXTENDED_FILE: setPropertyValueFile(aPropertyName, aValue); break; case text::textfield::Type::DATE: case text::textfield::Type::TIME: case text::textfield::Type::EXTENDED_TIME: setPropertyValueDateTime(aPropertyName, aValue); break; case text::textfield::Type::TABLE: setPropertyValueSheet(aPropertyName, aValue); break; case text::textfield::Type::DOCINFO_TITLE: default: throw beans::UnknownPropertyException(); } } uno::Any SAL_CALL ScEditFieldObj::getPropertyValue( const rtl::OUString& aPropertyName ) throw(beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException) { SolarMutexGuard aGuard; if (aPropertyName.equals(SC_UNONAME_TEXTFIELD_TYPE)) return uno::makeAny(meType); if (aPropertyName == SC_UNONAME_ANCHOR) return uno::makeAny(mpContent); if (aPropertyName == SC_UNONAME_ANCTYPE) { uno::Any aRet; aRet <<= text::TextContentAnchorType_AS_CHARACTER; return aRet; } if (aPropertyName == SC_UNONAME_ANCTYPES) { uno::Any aRet; uno::Sequence aSeq(1); aSeq[0] = text::TextContentAnchorType_AS_CHARACTER; aRet <<= aSeq; return aRet; } if (aPropertyName == SC_UNONAME_TEXTWRAP) { uno::Any aRet; aRet <<= text::WrapTextMode_NONE; return aRet; } switch (meType) { case text::textfield::Type::URL: return getPropertyValueURL(aPropertyName); case text::textfield::Type::EXTENDED_FILE: return getPropertyValueFile(aPropertyName); case text::textfield::Type::DATE: case text::textfield::Type::TIME: case text::textfield::Type::EXTENDED_TIME: return getPropertyValueDateTime(aPropertyName); case text::textfield::Type::DOCINFO_TITLE: default: throw beans::UnknownPropertyException(); } } SC_IMPL_DUMMY_PROPERTY_LISTENER( ScEditFieldObj ) // XUnoTunnel sal_Int64 SAL_CALL ScEditFieldObj::getSomething( const uno::Sequence& rId ) throw(uno::RuntimeException) { if ( rId.getLength() == 16 && 0 == rtl_compareMemory( getUnoTunnelId().getConstArray(), rId.getConstArray(), 16 ) ) { return sal::static_int_cast(reinterpret_cast(this)); } return 0; } namespace { class theScEditFieldObjUnoTunnelId : public rtl::Static< UnoTunnelIdInit, theScEditFieldObjUnoTunnelId> {}; } const uno::Sequence& ScEditFieldObj::getUnoTunnelId() { return theScEditFieldObjUnoTunnelId::get().getSeq(); } ScEditFieldObj* ScEditFieldObj::getImplementation(const uno::Reference& xObj) { ScEditFieldObj* pRet = NULL; uno::Reference xUT( xObj, uno::UNO_QUERY ); if (xUT.is()) pRet = reinterpret_cast(sal::static_int_cast(xUT->getSomething(getUnoTunnelId()))); return pRet; } // XServiceInfo rtl::OUString SAL_CALL ScEditFieldObj::getImplementationName() throw(uno::RuntimeException) { return rtl::OUString("ScEditFieldObj"); } sal_Bool SAL_CALL ScEditFieldObj::supportsService( const rtl::OUString& rServiceName ) throw(uno::RuntimeException) { return rServiceName == SCTEXTFIELD_SERVICE || rServiceName == SCTEXTCONTENT_SERVICE; } uno::Sequence SAL_CALL ScEditFieldObj::getSupportedServiceNames() throw(uno::RuntimeException) { uno::Sequence aRet(2); rtl::OUString* pArray = aRet.getArray(); pArray[0] = SCTEXTFIELD_SERVICE; pArray[1] = SCTEXTCONTENT_SERVICE; return aRet; } uno::Sequence SAL_CALL ScEditFieldObj::getTypes() throw(uno::RuntimeException) { static uno::Sequence aTypes; if ( aTypes.getLength() == 0 ) { uno::Sequence aParentTypes(OComponentHelper::getTypes()); long nParentLen = aParentTypes.getLength(); const uno::Type* pParentPtr = aParentTypes.getConstArray(); aTypes.realloc( nParentLen + 4 ); uno::Type* pPtr = aTypes.getArray(); pPtr[nParentLen + 0] = getCppuType((const uno::Reference*)0); pPtr[nParentLen + 1] = getCppuType((const uno::Reference*)0); pPtr[nParentLen + 2] = getCppuType((const uno::Reference*)0); pPtr[nParentLen + 3] = getCppuType((const uno::Reference*)0); for (long i=0; i {}; } uno::Sequence SAL_CALL ScEditFieldObj::getImplementationId() throw(uno::RuntimeException) { return theScEditFieldObjImplementationId::get().getSeq(); } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */