diff options
Diffstat (limited to 'sw/source/uibase/uno/unoatxt.cxx')
-rw-r--r-- | sw/source/uibase/uno/unoatxt.cxx | 1122 |
1 files changed, 1122 insertions, 0 deletions
diff --git a/sw/source/uibase/uno/unoatxt.cxx b/sw/source/uibase/uno/unoatxt.cxx new file mode 100644 index 000000000000..fad89f4aa69c --- /dev/null +++ b/sw/source/uibase/uno/unoatxt.cxx @@ -0,0 +1,1122 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include <com/sun/star/beans/PropertyAttribute.hpp> +#include <osl/mutex.hxx> +#include <osl/diagnose.h> +#include <vcl/svapp.hxx> +#include <svtools/unoevent.hxx> +#include <svl/urihelper.hxx> +#include <sfx2/event.hxx> +#include <swtypes.hxx> +#include <glosdoc.hxx> +#include <shellio.hxx> +#include <initui.hxx> +#include <gloslst.hxx> +#include <unoatxt.hxx> +#include <unomap.hxx> +#include <unomid.h> +#include <unotextbodyhf.hxx> +#include <unotextrange.hxx> +#include <TextCursorHelper.hxx> +#include <swevent.hxx> +#include <doc.hxx> +#include <unocrsr.hxx> +#include <IMark.hxx> +#include <unoprnms.hxx> +#include <docsh.hxx> +#include <swmodule.hxx> +#include <svl/smplhint.hxx> +#include <svl/macitem.hxx> +#include <editeng/acorrcfg.hxx> +#include <comphelper/servicehelper.hxx> +#include <comphelper/string.hxx> +#include <cppuhelper/supportsservice.hxx> + +#include <boost/scoped_ptr.hpp> + +using namespace ::com::sun::star; + +uno::Reference< uno::XInterface > SAL_CALL SwXAutoTextContainer_createInstance( + const uno::Reference< lang::XMultiServiceFactory > & ) throw( uno::Exception ) +{ + //the module may not be loaded + SolarMutexGuard aGuard; + SwGlobals::ensure(); + static uno::Reference< uno::XInterface > xAText = (cppu::OWeakObject*)new SwXAutoTextContainer(); + return xAText; +} + +uno::Sequence< OUString > SAL_CALL SwXAutoTextContainer_getSupportedServiceNames() throw() +{ + OUString sService("com.sun.star.text.AutoTextContainer"); + const uno::Sequence< OUString > aSeq( &sService, 1 ); + return aSeq; +} + +OUString SAL_CALL SwXAutoTextContainer_getImplementationName() throw() +{ + return OUString("SwXAutoTextContainer" ); +} + +SwXAutoTextContainer::SwXAutoTextContainer() +{ + pGlossaries = ::GetGlossaries(); + +} + +SwXAutoTextContainer::~SwXAutoTextContainer() +{ + +} + +sal_Int32 SwXAutoTextContainer::getCount(void) throw( uno::RuntimeException, std::exception ) +{ + return pGlossaries->GetGroupCnt(); +} + +uno::Any SwXAutoTextContainer::getByIndex(sal_Int32 nIndex) + throw( lang::IndexOutOfBoundsException, lang::WrappedTargetException, uno::RuntimeException, std::exception ) +{ + SolarMutexGuard aGuard; + uno::Any aRet; + sal_uInt16 nCount = pGlossaries->GetGroupCnt(); + if ( 0 <= nIndex && nIndex < nCount ) + aRet = getByName(pGlossaries->GetGroupName( static_cast< sal_uInt16 >(nIndex) )); + else + throw lang::IndexOutOfBoundsException(); + return aRet; +} + +uno::Type SwXAutoTextContainer::getElementType(void) throw( uno::RuntimeException, std::exception ) +{ + return cppu::UnoType<text::XAutoTextGroup>::get(); + +} + +sal_Bool SwXAutoTextContainer::hasElements(void) throw( uno::RuntimeException, std::exception ) +{ + // At least standard should always exists! + return sal_True; +} + +uno::Any SwXAutoTextContainer::getByName(const OUString& GroupName) + throw( container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException, std::exception ) +{ + SolarMutexGuard aGuard; + + uno::Reference< text::XAutoTextGroup > xGroup; + if ( pGlossaries && hasByName( GroupName ) ) // group name already known? + // sal_True = create group if not already available + xGroup = pGlossaries->GetAutoTextGroup( GroupName, true ); + + if ( !xGroup.is() ) + throw container::NoSuchElementException(); + + return makeAny( xGroup ); +} + +uno::Sequence< OUString > SwXAutoTextContainer::getElementNames(void) throw( uno::RuntimeException, std::exception ) +{ + SolarMutexGuard aGuard; + sal_uInt16 nCount = pGlossaries->GetGroupCnt(); + + uno::Sequence< OUString > aGroupNames(nCount); + OUString *pArr = aGroupNames.getArray(); + + for ( sal_uInt16 i = 0; i < nCount; i++ ) + { + // The names will be passed without a path extension. + OUString sGroupName(pGlossaries->GetGroupName(i)); + pArr[i] = sGroupName.getToken(0, GLOS_DELIM); + } + return aGroupNames; +} +// Finds group names with or without path index. +sal_Bool SwXAutoTextContainer::hasByName(const OUString& Name) + throw( uno::RuntimeException, std::exception ) +{ + SolarMutexGuard aGuard; + OUString sGroupName( pGlossaries->GetCompleteGroupName( Name ) ); + if(!sGroupName.isEmpty()) + return sal_True; + return sal_False; +} + +uno::Reference< text::XAutoTextGroup > SwXAutoTextContainer::insertNewByName( + const OUString& aGroupName) + throw( lang::IllegalArgumentException, container::ElementExistException, uno::RuntimeException, std::exception ) +{ + SolarMutexGuard aGuard; + if(hasByName(aGroupName)) + throw container::ElementExistException(); + //check for non-ASCII characters + if(aGroupName.isEmpty()) + { + lang::IllegalArgumentException aIllegal; + aIllegal.Message = "group name must not be empty"; + throw aIllegal; + } + for(sal_Int32 nPos = 0; nPos < aGroupName.getLength(); nPos++) + { + sal_Unicode cChar = aGroupName[nPos]; + if (comphelper::string::isalnumAscii(cChar) || + (cChar == '_') || + (cChar == 0x20) || + (cChar == GLOS_DELIM) ) + { + continue; + } + lang::IllegalArgumentException aIllegal; + aIllegal.Message = "group name must contain a-z, A-z, '_', ' ' only"; + throw aIllegal; + } + OUString sGroup(aGroupName); + if (sGroup.indexOf(GLOS_DELIM)<0) + { + sGroup += OUString(GLOS_DELIM) + "0"; + } + pGlossaries->NewGroupDoc(sGroup, sGroup.getToken(0, GLOS_DELIM)); + + uno::Reference< text::XAutoTextGroup > xGroup = pGlossaries->GetAutoTextGroup( sGroup, true ); + OSL_ENSURE( xGroup.is(), "SwXAutoTextContainer::insertNewByName: no UNO object created? How this?" ); + // We just inserted the group into the glossaries, so why doesn't it exist? + + return xGroup; +} + +void SwXAutoTextContainer::removeByName(const OUString& aGroupName) + throw( container::NoSuchElementException, uno::RuntimeException, std::exception ) +{ + SolarMutexGuard aGuard; + // At first find the name with path extension + OUString sGroupName = pGlossaries->GetCompleteGroupName( aGroupName ); + if(sGroupName.isEmpty()) + throw container::NoSuchElementException(); + pGlossaries->DelGroupDoc(sGroupName); +} + +OUString SwXAutoTextContainer::getImplementationName(void) throw( uno::RuntimeException, std::exception ) +{ + return SwXAutoTextContainer_getImplementationName(); +} + +sal_Bool SwXAutoTextContainer::supportsService(const OUString& rServiceName) throw( uno::RuntimeException, std::exception ) +{ + return cppu::supportsService(this, rServiceName); +} + +uno::Sequence< OUString > SwXAutoTextContainer::getSupportedServiceNames(void) throw( uno::RuntimeException, std::exception ) +{ + return SwXAutoTextContainer_getSupportedServiceNames(); +} + +namespace +{ + class theSwXAutoTextGroupUnoTunnelId : public rtl::Static< UnoTunnelIdInit, theSwXAutoTextGroupUnoTunnelId > {}; +} + +const uno::Sequence< sal_Int8 > & SwXAutoTextGroup::getUnoTunnelId() +{ + return theSwXAutoTextGroupUnoTunnelId::get().getSeq(); +} + +sal_Int64 SAL_CALL SwXAutoTextGroup::getSomething( const uno::Sequence< sal_Int8 >& rId ) + throw(uno::RuntimeException, std::exception) +{ + if( rId.getLength() == 16 + && 0 == memcmp( getUnoTunnelId().getConstArray(), + rId.getConstArray(), 16 ) ) + { + return sal::static_int_cast< sal_Int64 >( reinterpret_cast< sal_IntPtr >( this )); + } + return 0; +} + +SwXAutoTextGroup::SwXAutoTextGroup(const OUString& rName, + SwGlossaries* pGlos) : + pPropSet(aSwMapProvider.GetPropertySet(PROPERTY_MAP_AUTO_TEXT_GROUP)), + pGlossaries(pGlos), + sName(rName), + m_sGroupName(rName) +{ + OSL_ENSURE( -1 != rName.indexOf( GLOS_DELIM ), + "SwXAutoTextGroup::SwXAutoTextGroup: to be constructed with a complete name only!" ); +} + +SwXAutoTextGroup::~SwXAutoTextGroup() +{ +} + +uno::Sequence< OUString > SwXAutoTextGroup::getTitles(void) throw( uno::RuntimeException, std::exception ) +{ + SolarMutexGuard aGuard; + sal_uInt16 nCount = 0; + SwTextBlocks* pGlosGroup = pGlossaries ? pGlossaries->GetGroupDoc(m_sGroupName, false) : 0; + if(pGlosGroup && !pGlosGroup->GetError()) + nCount = pGlosGroup->GetCount(); + else + throw uno::RuntimeException(); + + uno::Sequence< OUString > aEntryTitles(nCount); + OUString *pArr = aEntryTitles.getArray(); + + for ( sal_uInt16 i = 0; i < nCount; i++ ) + pArr[i] = pGlosGroup->GetLongName(i); + delete pGlosGroup; + return aEntryTitles; +} + +void SwXAutoTextGroup::renameByName(const OUString& aElementName, + const OUString& aNewElementName, const OUString& aNewElementTitle) + throw( lang::IllegalArgumentException, container::ElementExistException, io::IOException, + uno::RuntimeException, std::exception) +{ + SolarMutexGuard aGuard; + // throw exception only if the programmatic name is to be changed into an existing name + if(aNewElementName != aElementName && hasByName(aNewElementName)) + throw container::ElementExistException(); + SwTextBlocks* pGlosGroup = pGlossaries ? pGlossaries->GetGroupDoc(m_sGroupName, false) : 0; + if(pGlosGroup && !pGlosGroup->GetError()) + { + sal_uInt16 nIdx = pGlosGroup->GetIndex( aElementName); + if(USHRT_MAX == nIdx) + throw lang::IllegalArgumentException(); + OUString aNewShort(aNewElementName); + OUString aNewName(aNewElementTitle); + sal_uInt16 nOldLongIdx = pGlosGroup->GetLongIndex( aNewShort ); + sal_uInt16 nOldIdx = pGlosGroup->GetIndex( aNewName ); + + if( nIdx != USHRT_MAX && + (nOldLongIdx == USHRT_MAX || nOldLongIdx == nIdx )&& + (nOldIdx == USHRT_MAX || nOldIdx == nIdx )) + { + pGlosGroup->Rename( nIdx, &aNewShort, &aNewName ); + if(pGlosGroup->GetError() != 0) + throw io::IOException(); + } + delete pGlosGroup; + } + else + throw uno::RuntimeException(); +} + +static bool lcl_CopySelToDoc( SwDoc* pInsDoc, OTextCursorHelper* pxCursor, SwXTextRange* pxRange) +{ + OSL_ENSURE( pInsDoc, "no InsDoc"); + + SwNodes& rNds = pInsDoc->GetNodes(); + + SwNodeIndex aIdx( rNds.GetEndOfContent(), -1 ); + SwCntntNode * pNd = aIdx.GetNode().GetCntntNode(); + SwPosition aPos(aIdx, SwIndex(pNd, (pNd) ? pNd->Len() : 0)); + + bool bRet = false; + pInsDoc->LockExpFlds(); + { + SwDoc *const pDoc((pxCursor) ? pxCursor->GetDoc() : pxRange->GetDoc()); + SwPaM aPam(pDoc->GetNodes()); + SwPaM * pPam(0); + if(pxCursor) + { + pPam = pxCursor->GetPaM(); + } + else + { + if (pxRange->GetPositions(aPam)) + { + pPam = & aPam; + } + } + if (!pPam) { return false; } + bRet = pDoc->CopyRange( *pPam, aPos, false ) || bRet; + } + + pInsDoc->UnlockExpFlds(); + if( !pInsDoc->IsExpFldsLocked() ) + pInsDoc->UpdateExpFlds(NULL, true); + + return bRet; +} + +uno::Reference< text::XAutoTextEntry > SwXAutoTextGroup::insertNewByName(const OUString& aName, + const OUString& aTitle, const uno::Reference< text::XTextRange > & xTextRange) + throw( container::ElementExistException, uno::RuntimeException, std::exception ) +{ + SolarMutexGuard aGuard; + if(hasByName(aName)) + throw container::ElementExistException(); + if(!xTextRange.is()) + throw uno::RuntimeException(); + + SwTextBlocks* pGlosGroup = pGlossaries ? pGlossaries->GetGroupDoc(m_sGroupName, false) : 0; + OUString sShortName(aName); + OUString sLongName(aTitle); + if(pGlosGroup && !pGlosGroup->GetError()) + { + uno::Reference<lang::XUnoTunnel> xRangeTunnel( xTextRange, uno::UNO_QUERY); + SwXTextRange* pxRange = 0; + OTextCursorHelper* pxCursor = 0; + if(xRangeTunnel.is()) + { + pxRange = reinterpret_cast<SwXTextRange*>(xRangeTunnel->getSomething( + SwXTextRange::getUnoTunnelId())); + pxCursor = reinterpret_cast<OTextCursorHelper*>(xRangeTunnel->getSomething( + OTextCursorHelper::getUnoTunnelId())); + } + + OUString sOnlyTxt; + OUString* pOnlyTxt = 0; + bool bNoAttr = !pxCursor && !pxRange; + if(bNoAttr) + { + sOnlyTxt = OUString(xTextRange->getString()); + pOnlyTxt = &sOnlyTxt; + } + + const SvxAutoCorrCfg& rCfg = SvxAutoCorrCfg::Get(); + + SwDoc* pGDoc = pGlosGroup->GetDoc(); + + // Until there is an option for that, delete base util::URL + if(rCfg.IsSaveRelFile()) + { + INetURLObject aTemp(pGlosGroup->GetFileName()); + pGlosGroup->SetBaseURL( aTemp.GetMainURL(INetURLObject::NO_DECODE)); + } + else + pGlosGroup->SetBaseURL( OUString() ); + + sal_uInt16 nRet; + if( pOnlyTxt ) + nRet = pGlosGroup->PutText( sShortName, sLongName, *pOnlyTxt ); + else + { + pGlosGroup->ClearDoc(); + if( pGlosGroup->BeginPutDoc( sShortName, sLongName ) ) + { + pGDoc->SetRedlineMode_intern( nsRedlineMode_t::REDLINE_DELETE_REDLINES ); + lcl_CopySelToDoc( pGDoc, pxCursor, pxRange ); + pGDoc->SetRedlineMode_intern((RedlineMode_t)( 0 )); + nRet = pGlosGroup->PutDoc(); + } + else + nRet = (sal_uInt16) -1; + } + + if(nRet == (sal_uInt16) -1 ) + { + throw uno::RuntimeException(); + } + pGlossaries->PutGroupDoc( pGlosGroup ); + } + + uno::Reference< text::XAutoTextEntry > xEntry = pGlossaries ? + pGlossaries->GetAutoTextEntry( m_sGroupName, sName, sShortName, true ) : + uno::Reference< text::XAutoTextEntry >(); + OSL_ENSURE( xEntry.is(), "SwXAutoTextGroup::insertNewByName: no UNO object created? How this?" ); + // we just inserted the entry into the group, so why doesn't it exist? + + return xEntry; +} + +void SwXAutoTextGroup::removeByName(const OUString& aEntryName) throw( container::NoSuchElementException, uno::RuntimeException, std::exception ) +{ + SolarMutexGuard aGuard; + SwTextBlocks* pGlosGroup = pGlossaries ? pGlossaries->GetGroupDoc(m_sGroupName, false) : 0; + if(pGlosGroup && !pGlosGroup->GetError()) + { + sal_uInt16 nIdx = pGlosGroup->GetIndex(aEntryName); + if ( nIdx != USHRT_MAX ) + pGlosGroup->Delete(nIdx); + delete pGlosGroup; + } + else + throw container::NoSuchElementException(); +} + +OUString SwXAutoTextGroup::getName(void) throw( uno::RuntimeException, std::exception ) +{ + SolarMutexGuard aGuard; + return sName; +} + +void SwXAutoTextGroup::setName(const OUString& rName) throw( uno::RuntimeException, std::exception ) +{ + SolarMutexGuard aGuard; + if( !pGlossaries ) + throw uno::RuntimeException(); + + sal_Int32 nNewDelimPos = rName.lastIndexOf( GLOS_DELIM ); + sal_Int32 nOldDelimPos = sName.lastIndexOf( GLOS_DELIM ); + + OUString aNewSuffix; + if (nNewDelimPos > -1) + aNewSuffix = rName.copy( nNewDelimPos + 1 ); + OUString aOldSuffix; + if (nOldDelimPos > -1) + aOldSuffix = sName.copy( nOldDelimPos + 1 ); + + sal_Int32 nNewNumeric = aNewSuffix.toInt32(); + sal_Int32 nOldNumeric = aOldSuffix.toInt32(); + + OUString aNewPrefix( (nNewDelimPos > 1) ? rName.copy( 0, nNewDelimPos ) : rName ); + OUString aOldPrefix( (nOldDelimPos > 1) ? sName.copy( 0, nOldDelimPos ) : sName ); + + if ( sName == rName || + ( nNewNumeric == nOldNumeric && aNewPrefix == aOldPrefix ) ) + return; + OUString sNewGroup(rName); + if (sNewGroup.indexOf(GLOS_DELIM)<0) + { + sNewGroup += OUString(GLOS_DELIM) + "0"; + } + + //the name must be saved, the group may be invalidated while in RenameGroupDoc() + SwGlossaries* pTempGlossaries = pGlossaries; + + OUString sPreserveTitle( pGlossaries->GetGroupTitle( sName ) ); + if ( !pGlossaries->RenameGroupDoc( sName, sNewGroup, sPreserveTitle ) ) + throw uno::RuntimeException(); + else + { + sName = rName; + m_sGroupName = sNewGroup; + pGlossaries = pTempGlossaries; + } +} + +sal_Int32 SwXAutoTextGroup::getCount(void) throw( uno::RuntimeException, std::exception ) +{ + SolarMutexGuard aGuard; + int nCount = 0; + SwTextBlocks* pGlosGroup = pGlossaries ? pGlossaries->GetGroupDoc(m_sGroupName, false) : 0; + if(pGlosGroup && !pGlosGroup->GetError()) + nCount = pGlosGroup->GetCount(); + else + throw uno::RuntimeException(); + delete pGlosGroup; + return nCount; +} + +uno::Any SwXAutoTextGroup::getByIndex(sal_Int32 nIndex) + throw( lang::IndexOutOfBoundsException, lang::WrappedTargetException, uno::RuntimeException, std::exception ) +{ + SolarMutexGuard aGuard; + uno::Any aRet; + sal_uInt16 nCount = 0; + SwTextBlocks* pGlosGroup = pGlossaries ? pGlossaries->GetGroupDoc(m_sGroupName, false) : 0; + if(pGlosGroup && !pGlosGroup->GetError()) + nCount = pGlosGroup->GetCount(); + else + throw uno::RuntimeException(); + if(0 <= nIndex && nIndex < nCount) + aRet = getByName(pGlosGroup->GetShortName((sal_uInt16) nIndex)); + else + throw lang::IndexOutOfBoundsException(); + delete pGlosGroup; + return aRet; +} + +uno::Type SwXAutoTextGroup::getElementType(void) throw( uno::RuntimeException, std::exception ) +{ + return cppu::UnoType<text::XAutoTextEntry>::get(); + +} + +sal_Bool SwXAutoTextGroup::hasElements(void) throw( uno::RuntimeException, std::exception ) +{ + SolarMutexGuard aGuard; + SwTextBlocks* pGlosGroup = pGlossaries ? pGlossaries->GetGroupDoc(m_sGroupName, false) : 0; + sal_uInt16 nCount = 0; + if(pGlosGroup && !pGlosGroup->GetError()) + nCount = pGlosGroup->GetCount(); + else + throw uno::RuntimeException(); + delete pGlosGroup; + return nCount > 0; + +} + +uno::Any SwXAutoTextGroup::getByName(const OUString& _rName) + throw( container::NoSuchElementException, lang::WrappedTargetException, uno::RuntimeException, std::exception ) +{ + SolarMutexGuard aGuard; + uno::Reference< text::XAutoTextEntry > xEntry = pGlossaries->GetAutoTextEntry( m_sGroupName, sName, _rName, true ); + OSL_ENSURE( xEntry.is(), "SwXAutoTextGroup::getByName: GetAutoTextEntry is fractious!" ); + // we told it to create the object, so why didn't it? + return makeAny( xEntry ); +} + +uno::Sequence< OUString > SwXAutoTextGroup::getElementNames(void) + throw( uno::RuntimeException, std::exception ) +{ + SolarMutexGuard aGuard; + sal_uInt16 nCount = 0; + SwTextBlocks* pGlosGroup = pGlossaries ? pGlossaries->GetGroupDoc(m_sGroupName, false) : 0; + if(pGlosGroup && !pGlosGroup->GetError()) + nCount = pGlosGroup->GetCount(); + else + throw uno::RuntimeException(); + + uno::Sequence< OUString > aEntryNames(nCount); + OUString *pArr = aEntryNames.getArray(); + + for ( sal_uInt16 i = 0; i < nCount; i++ ) + pArr[i] = pGlosGroup->GetShortName(i); + delete pGlosGroup; + return aEntryNames; +} + +sal_Bool SwXAutoTextGroup::hasByName(const OUString& rName) + throw( uno::RuntimeException, std::exception ) +{ + SolarMutexGuard aGuard; + bool bRet = false; + sal_uInt16 nCount = 0; + SwTextBlocks* pGlosGroup = pGlossaries ? pGlossaries->GetGroupDoc(m_sGroupName, false) : 0; + if(pGlosGroup && !pGlosGroup->GetError()) + nCount = pGlosGroup->GetCount(); + else + throw uno::RuntimeException(); + + for( sal_uInt16 i = 0; i < nCount; ++i ) + { + OUString sCompare(pGlosGroup->GetShortName(i)); + if(sCompare.equalsIgnoreAsciiCase(rName)) + { + bRet = true; + break; + } + } + delete pGlosGroup; + return bRet; +} + +uno::Reference< beans::XPropertySetInfo > SwXAutoTextGroup::getPropertySetInfo(void) + throw( uno::RuntimeException, std::exception ) +{ + static uno::Reference< beans::XPropertySetInfo > xRet = pPropSet->getPropertySetInfo(); + return xRet; +} + +void SwXAutoTextGroup::setPropertyValue( + const OUString& rPropertyName, const uno::Any& aValue) + throw( beans::UnknownPropertyException, beans::PropertyVetoException, + lang::IllegalArgumentException, lang::WrappedTargetException, uno::RuntimeException, std::exception) +{ + SolarMutexGuard aGuard; + const SfxItemPropertySimpleEntry* pEntry = pPropSet->getPropertyMap().getByName( rPropertyName ); + + if(!pEntry) + throw beans::UnknownPropertyException(); + + SwTextBlocks* pGlosGroup = pGlossaries ? pGlossaries->GetGroupDoc(m_sGroupName, false) : 0; + if(!pGlosGroup || pGlosGroup->GetError()) + throw uno::RuntimeException(); + switch(pEntry->nWID) + { + case WID_GROUP_TITLE: + { + OUString sNewTitle; + aValue >>= sNewTitle; + if(sNewTitle.isEmpty()) + throw lang::IllegalArgumentException(); + bool bChanged = !sNewTitle.equals(pGlosGroup->GetName()); + pGlosGroup->SetName(sNewTitle); + if(bChanged && HasGlossaryList()) + GetGlossaryList()->ClearGroups(); + } + break; + } + delete pGlosGroup; +} + +uno::Any SwXAutoTextGroup::getPropertyValue(const OUString& rPropertyName) + throw( beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException, std::exception ) +{ + SolarMutexGuard aGuard; + const SfxItemPropertySimpleEntry* pEntry = pPropSet->getPropertyMap().getByName( rPropertyName); + + if(!pEntry) + throw beans::UnknownPropertyException(); + SwTextBlocks* pGlosGroup = pGlossaries ? pGlossaries->GetGroupDoc(m_sGroupName, false) : 0; + if(!pGlosGroup || pGlosGroup->GetError()) + throw uno::RuntimeException(); + + uno::Any aAny; + switch(pEntry->nWID) + { + case WID_GROUP_PATH: + aAny <<= OUString(pGlosGroup->GetFileName()); + break; + case WID_GROUP_TITLE: + aAny <<= OUString(pGlosGroup->GetName()); + break; + } + delete pGlosGroup; + return aAny; +} + +void SwXAutoTextGroup::addPropertyChangeListener( + const OUString& /*PropertyName*/, const uno::Reference< beans::XPropertyChangeListener > & /*aListener*/) + throw( beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException, std::exception ) +{ +} + +void SwXAutoTextGroup::removePropertyChangeListener( + const OUString& /*PropertyName*/, const uno::Reference< beans::XPropertyChangeListener > & /*aListener*/) + throw( beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException, std::exception ) +{ +} + +void SwXAutoTextGroup::addVetoableChangeListener( + const OUString& /*PropertyName*/, const uno::Reference< beans::XVetoableChangeListener > & /*aListener*/) + throw( beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException, std::exception ) +{ +} + +void SwXAutoTextGroup::removeVetoableChangeListener( + const OUString& /*PropertyName*/, const uno::Reference< beans::XVetoableChangeListener > & /*aListener*/) + throw( beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException, std::exception ) +{ +} + +void SwXAutoTextGroup::Invalidate() +{ + pGlossaries = 0; + sName = OUString(); + m_sGroupName = OUString(); +} + +OUString SwXAutoTextGroup::getImplementationName(void) throw( uno::RuntimeException, std::exception ) +{ + return OUString("SwXAutoTextGroup"); +} + +sal_Bool SwXAutoTextGroup::supportsService(const OUString& rServiceName) throw( uno::RuntimeException, std::exception ) +{ + return cppu::supportsService(this, rServiceName); +} + +uno::Sequence< OUString > SwXAutoTextGroup::getSupportedServiceNames(void) throw( uno::RuntimeException, std::exception ) +{ + uno::Sequence< OUString > aRet(1); + OUString* pArray = aRet.getArray(); + pArray[0] = "com.sun.star.text.AutoTextGroup"; + return aRet; +} + +namespace +{ + class theSwXAutoTextEntryUnoTunnelId : public rtl::Static< UnoTunnelIdInit, theSwXAutoTextEntryUnoTunnelId > {}; +} + +const uno::Sequence< sal_Int8 > & SwXAutoTextEntry::getUnoTunnelId() +{ + return theSwXAutoTextEntryUnoTunnelId::get().getSeq(); +} + +sal_Int64 SAL_CALL SwXAutoTextEntry::getSomething( const uno::Sequence< sal_Int8 >& rId ) + throw(uno::RuntimeException, std::exception) +{ + if( rId.getLength() == 16 + && 0 == memcmp( getUnoTunnelId().getConstArray(), + rId.getConstArray(), 16 ) ) + { + return sal::static_int_cast< sal_Int64 >( reinterpret_cast< sal_IntPtr >( this )); + } + return 0; +} + +SwXAutoTextEntry::SwXAutoTextEntry(SwGlossaries* pGlss, const OUString& rGroupName, + const OUString& rEntryName) : + pGlossaries(pGlss), + sGroupName(rGroupName), + sEntryName(rEntryName), + pBodyText ( NULL ) +{ +} + +SwXAutoTextEntry::~SwXAutoTextEntry() +{ + { + SolarMutexGuard aGuard; + + // ensure that any pending modifications are written + implFlushDocument( true ); + + //! Bug #96559 + // DocShell must be cleared before mutex is lost. + // Needs to be done explicitly since xDocSh is a class member. + // Thus, an own block here, guarded by the SolarMutex + } +} + +void SwXAutoTextEntry::implFlushDocument( bool _bCloseDoc ) +{ + if ( xDocSh.Is() ) + { + if ( xDocSh->GetDoc()->IsModified () ) + xDocSh->Save(); + + if ( _bCloseDoc ) + { + // stop listening at the document + EndListening( *&xDocSh ); + + xDocSh->DoClose(); + xDocSh.Clear(); + } + } +} + +void SwXAutoTextEntry::Notify( SfxBroadcaster& _rBC, const SfxHint& _rHint ) +{ + if ( &_rBC == &xDocSh ) + { // it's our document + if ( _rHint.ISA( SfxSimpleHint ) ) + { + if ( SFX_HINT_DEINITIALIZING == static_cast< const SfxSimpleHint& >( _rHint ).GetId() ) + { + // our document is dying (possibly because we're shuting down, and the document was notified + // earlier than we are?) + // stop listening at the docu + EndListening( *&xDocSh ); + // and release our reference + xDocSh.Clear(); + } + } + else if(_rHint.ISA(SfxEventHint)) + { + if(SFX_EVENT_PREPARECLOSEDOC == static_cast< const SfxEventHint& >( _rHint ).GetEventId()) + { + implFlushDocument( false ); + xBodyText = 0; + xDocSh.Clear(); + } + } + } +} + +void SwXAutoTextEntry::GetBodyText () +{ + SolarMutexGuard aGuard; + + xDocSh = pGlossaries->EditGroupDoc ( sGroupName, sEntryName, false ); + OSL_ENSURE( xDocSh.Is(), "SwXAutoTextEntry::GetBodyText: unexpected: no doc returned by EditGroupDoc!" ); + + // start listening at the document + StartListening( *&xDocSh ); + + pBodyText = new SwXBodyText ( xDocSh->GetDoc() ); + xBodyText = uno::Reference < lang::XServiceInfo > ( *pBodyText, uno::UNO_QUERY); +} + +uno::Reference< text::XTextCursor > SwXAutoTextEntry::createTextCursor(void) throw( uno::RuntimeException, std::exception ) +{ + SolarMutexGuard aGuard; + EnsureBodyText(); + return pBodyText->createTextCursor(); +} + +uno::Reference< text::XTextCursor > SwXAutoTextEntry::createTextCursorByRange( + const uno::Reference< text::XTextRange > & aTextPosition) throw( uno::RuntimeException, std::exception ) +{ + SolarMutexGuard aGuard; + EnsureBodyText(); + return pBodyText->createTextCursorByRange ( aTextPosition ); +} + +void SwXAutoTextEntry::insertString(const uno::Reference< text::XTextRange > & xRange, const OUString& aString, sal_Bool bAbsorb) throw( uno::RuntimeException, std::exception ) +{ + SolarMutexGuard aGuard; + EnsureBodyText(); + pBodyText->insertString ( xRange, aString, bAbsorb ); +} + +void SwXAutoTextEntry::insertControlCharacter(const uno::Reference< text::XTextRange > & xRange, + sal_Int16 nControlCharacter, sal_Bool bAbsorb) + throw( lang::IllegalArgumentException, uno::RuntimeException, std::exception ) +{ + SolarMutexGuard aGuard; + EnsureBodyText(); + pBodyText->insertControlCharacter ( xRange, nControlCharacter, bAbsorb ); +} + +void SwXAutoTextEntry::insertTextContent( + const uno::Reference< text::XTextRange > & xRange, + const uno::Reference< text::XTextContent > & xContent, sal_Bool bAbsorb) + throw( lang::IllegalArgumentException, uno::RuntimeException, std::exception ) +{ + SolarMutexGuard aGuard; + EnsureBodyText(); + pBodyText->insertTextContent ( xRange, xContent, bAbsorb ); +} + +void SwXAutoTextEntry::removeTextContent( + const uno::Reference< text::XTextContent > & xContent) + throw( container::NoSuchElementException, uno::RuntimeException, std::exception ) +{ + SolarMutexGuard aGuard; + EnsureBodyText(); + pBodyText->removeTextContent ( xContent ); +} + +uno::Reference< text::XText > SwXAutoTextEntry::getText(void) throw( uno::RuntimeException, std::exception ) +{ + SolarMutexGuard aGuard; + uno::Reference< text::XText > xRet = (text::XText*)this; + return xRet; +} + +uno::Reference< text::XTextRange > SwXAutoTextEntry::getStart(void) throw( uno::RuntimeException, std::exception ) +{ + SolarMutexGuard aGuard; + EnsureBodyText(); + return pBodyText->getStart(); +} + +uno::Reference< text::XTextRange > SwXAutoTextEntry::getEnd(void) throw( uno::RuntimeException, std::exception ) +{ + SolarMutexGuard aGuard; + EnsureBodyText(); + return pBodyText->getEnd(); +} + +OUString SwXAutoTextEntry::getString(void) throw( uno::RuntimeException, std::exception ) +{ + SolarMutexGuard aGuard; + EnsureBodyText(); + return pBodyText->getString(); +} + +void SwXAutoTextEntry::setString(const OUString& aString) throw( uno::RuntimeException, std::exception ) +{ + SolarMutexGuard aGuard; + EnsureBodyText(); + pBodyText->setString( aString ); +} + +void SwXAutoTextEntry::applyTo(const uno::Reference< text::XTextRange > & xTextRange)throw( uno::RuntimeException, std::exception ) +{ + SolarMutexGuard aGuard; + + // ensure that any pending modifications are written + // reason is that we're holding the _copy_ of the auto text, while the real auto text + // is stored somewhere. And below, we're not working with our copy, but only tell the target + // TextRange to work with the stored version. + // #96380# - 2003-03-03 - fs@openoffice.org + implFlushDocument( false ); + // TODO: think about if we should pass "true" here + // The difference would be that when the next modification is made to this instance here, then + // we would be forced to open the document again, instead of working on our current copy. + // This means that we would reflect any changes which were done to the AutoText by foreign instances + // in the meantime + + uno::Reference<lang::XUnoTunnel> xTunnel( xTextRange, uno::UNO_QUERY); + SwXTextRange* pRange = 0; + OTextCursorHelper* pCursor = 0; + SwXText *pText = 0; + + if(xTunnel.is()) + { + pRange = reinterpret_cast < SwXTextRange* > + ( xTunnel->getSomething( SwXTextRange::getUnoTunnelId() ) ); + pCursor = reinterpret_cast < OTextCursorHelper*> + ( xTunnel->getSomething( OTextCursorHelper::getUnoTunnelId() ) ); + pText = reinterpret_cast < SwXText* > + ( xTunnel->getSomething( SwXText::getUnoTunnelId() ) ); + } + + SwDoc* pDoc = 0; + if (pRange) + pDoc = pRange->GetDoc(); + else if ( pCursor ) + pDoc = pCursor->GetDoc(); + else if ( pText && pText->GetDoc() ) + { + xTunnel = uno::Reference < lang::XUnoTunnel > (pText->getStart(), uno::UNO_QUERY); + if (xTunnel.is()) + { + pCursor = reinterpret_cast < OTextCursorHelper* > + ( xTunnel->getSomething( OTextCursorHelper::getUnoTunnelId() ) ); + if (pCursor) + pDoc = pText->GetDoc(); + } + } + + if(!pDoc) + throw uno::RuntimeException(); + + SwPaM InsertPaM(pDoc->GetNodes()); + if (pRange) + { + if (!pRange->GetPositions(InsertPaM)) + { + throw uno::RuntimeException(); + } + } + else + { + InsertPaM = *pCursor->GetPaM(); + } + + boost::scoped_ptr<SwTextBlocks> pBlock(pGlossaries->GetGroupDoc(sGroupName)); + const bool bResult = pBlock.get() && !pBlock->GetError() + && pDoc->InsertGlossary( *pBlock, sEntryName, InsertPaM); + + if(!bResult) + throw uno::RuntimeException(); +} + +OUString SwXAutoTextEntry::getImplementationName(void) throw( uno::RuntimeException, std::exception ) +{ + return OUString("SwXAutoTextEntry"); +} + +sal_Bool SwXAutoTextEntry::supportsService(const OUString& rServiceName) throw( uno::RuntimeException, std::exception ) +{ + return cppu::supportsService(this, rServiceName); +} + +uno::Sequence< OUString > SwXAutoTextEntry::getSupportedServiceNames(void) throw( uno::RuntimeException, std::exception ) +{ + uno::Sequence< OUString > aRet(1); + OUString* pArray = aRet.getArray(); + pArray[0] = "com.sun.star.text.AutoTextEntry"; + return aRet; +} + +uno::Reference< container::XNameReplace > SwXAutoTextEntry::getEvents() + throw( uno::RuntimeException, std::exception ) +{ + return new SwAutoTextEventDescriptor( *this ); +} + +const struct SvEventDescription aAutotextEvents[] = +{ + { SW_EVENT_START_INS_GLOSSARY, "OnInsertStart" }, + { SW_EVENT_END_INS_GLOSSARY, "OnInsertDone" }, + { 0, NULL } +}; + +SwAutoTextEventDescriptor::SwAutoTextEventDescriptor( + SwXAutoTextEntry& rAutoText ) : + SvBaseEventDescriptor(aAutotextEvents), + sSwAutoTextEventDescriptor( + "SwAutoTextEventDescriptor"), + rAutoTextEntry(rAutoText) +{ +} + +SwAutoTextEventDescriptor::~SwAutoTextEventDescriptor() +{ +} + +OUString SwAutoTextEventDescriptor::getImplementationName() + throw( uno::RuntimeException, std::exception ) +{ + return sSwAutoTextEventDescriptor; +} + +void SwAutoTextEventDescriptor::replaceByName( + const sal_uInt16 nEvent, + const SvxMacro& rMacro) + throw( + lang::IllegalArgumentException, + container::NoSuchElementException, + lang::WrappedTargetException, + uno::RuntimeException) +{ + OSL_ENSURE( NULL != rAutoTextEntry.GetGlossaries(), + "Strangely enough, the AutoText vanished!" ); + OSL_ENSURE( (nEvent == SW_EVENT_END_INS_GLOSSARY) || + (nEvent == SW_EVENT_START_INS_GLOSSARY) , + "Unknown event ID" ); + + SwGlossaries *const pGlossaries = + const_cast<SwGlossaries*>(rAutoTextEntry.GetGlossaries()); + SwTextBlocks* pBlocks = + pGlossaries->GetGroupDoc( rAutoTextEntry.GetGroupName() ); + OSL_ENSURE( NULL != pBlocks, + "can't get autotext group; SwAutoTextEntry has illegal name?"); + + if( pBlocks && !pBlocks->GetError()) + { + sal_uInt16 nIndex = pBlocks->GetIndex( rAutoTextEntry.GetEntryName() ); + if( nIndex != USHRT_MAX ) + { + SvxMacroTableDtor aMacroTable; + if( pBlocks->GetMacroTable( nIndex, aMacroTable ) ) + { + aMacroTable.Insert( nEvent, rMacro ); + pBlocks->SetMacroTable( nIndex, aMacroTable ); + } + } + + delete pBlocks; + } + // else: ignore +} + +void SwAutoTextEventDescriptor::getByName( + SvxMacro& rMacro, + const sal_uInt16 nEvent ) + throw( + container::NoSuchElementException, + lang::WrappedTargetException, + uno::RuntimeException) +{ + OSL_ENSURE( NULL != rAutoTextEntry.GetGlossaries(), "no AutoText" ); + OSL_ENSURE( (nEvent == SW_EVENT_END_INS_GLOSSARY) || + (nEvent == SW_EVENT_START_INS_GLOSSARY) , + "Unknown event ID" ); + + SwGlossaries *const pGlossaries = + const_cast<SwGlossaries*>(rAutoTextEntry.GetGlossaries()); + SwTextBlocks* pBlocks = + pGlossaries->GetGroupDoc( rAutoTextEntry.GetGroupName() ); + OSL_ENSURE( NULL != pBlocks, + "can't get autotext group; SwAutoTextEntry has illegal name?"); + + // return empty macro, unless macro is found + OUString sEmptyStr; + SvxMacro aEmptyMacro(sEmptyStr, sEmptyStr); + rMacro = aEmptyMacro; + + if ( pBlocks && !pBlocks->GetError()) + { + sal_uInt16 nIndex = pBlocks->GetIndex( rAutoTextEntry.GetEntryName() ); + if( nIndex != USHRT_MAX ) + { + SvxMacroTableDtor aMacroTable; + if( pBlocks->GetMacroTable( nIndex, aMacroTable ) ) + { + SvxMacro *pMacro = aMacroTable.Get( nEvent ); + if( pMacro ) + rMacro = *pMacro; + } + } + + delete pBlocks; + } +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |