summaryrefslogtreecommitdiff
path: root/sw/source/uibase/uno/unoatxt.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'sw/source/uibase/uno/unoatxt.cxx')
-rw-r--r--sw/source/uibase/uno/unoatxt.cxx1122
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: */