summaryrefslogtreecommitdiff
path: root/sw/source/core/unocore/unotext.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'sw/source/core/unocore/unotext.cxx')
-rw-r--r--sw/source/core/unocore/unotext.cxx2961
1 files changed, 2961 insertions, 0 deletions
diff --git a/sw/source/core/unocore/unotext.cxx b/sw/source/core/unocore/unotext.cxx
new file mode 100644
index 000000000000..875d0e23235d
--- /dev/null
+++ b/sw/source/core/unocore/unotext.cxx
@@ -0,0 +1,2961 @@
+/*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sw.hxx"
+
+#include <stdlib.h>
+
+#include <memory>
+#include <iostream>
+
+#include <com/sun/star/drawing/XDrawPageSupplier.hpp>
+#include <com/sun/star/text/ControlCharacter.hpp>
+#include <com/sun/star/text/TableColumnSeparator.hpp>
+
+#include <rtl/uuid.h>
+
+#include <vos/mutex.hxx>
+#include <vcl/svapp.hxx>
+#include <comphelper/sequence.hxx>
+
+#include <cmdid.h>
+#include <unotextbodyhf.hxx>
+#include <unotext.hxx>
+#include <unotextrange.hxx>
+#include <unotextcursor.hxx>
+#include <unosection.hxx>
+#include <unobookmark.hxx>
+#include <unorefmark.hxx>
+#include <unoport.hxx>
+#include <unotbl.hxx>
+#include <unoidx.hxx>
+#include <unoframe.hxx>
+#include <unofield.hxx>
+#include <unometa.hxx>
+#include <unodraw.hxx>
+#include <unoredline.hxx>
+#include <unomap.hxx>
+#include <unoprnms.hxx>
+#include <unoparagraph.hxx>
+#include <unocrsrhelper.hxx>
+#include <docsh.hxx>
+#include <docary.hxx>
+#include <doc.hxx>
+#include <IDocumentUndoRedo.hxx>
+#include <redline.hxx>
+#include <swundo.hxx>
+#include <section.hxx>
+#include <IMark.hxx>
+#include <fmtanchr.hxx>
+#include <fmtcntnt.hxx>
+#include <crsskip.hxx>
+#include <ndtxt.hxx>
+
+
+using namespace ::com::sun::star;
+using ::rtl::OUString;
+
+
+const sal_Char cInvalidObject[] = "this object is invalid";
+
+/******************************************************************
+ * SwXText
+ ******************************************************************/
+
+class SwXText::Impl
+{
+
+public:
+ SwXText & m_rThis;
+ SfxItemPropertySet const& m_rPropSet;
+ const enum CursorType m_eType;
+ SwDoc * m_pDoc;
+ bool m_bIsValid;
+
+ Impl( SwXText & rThis,
+ SwDoc *const pDoc, const enum CursorType eType)
+ : m_rThis(rThis)
+ , m_rPropSet(*aSwMapProvider.GetPropertySet(PROPERTY_MAP_TEXT))
+ , m_eType(eType)
+ , m_pDoc(pDoc)
+ , m_bIsValid(0 != pDoc)
+ {
+ }
+
+ uno::Reference< text::XTextRange >
+ finishOrAppendParagraph(
+ const bool bFinish,
+ const uno::Sequence< beans::PropertyValue >&
+ rCharacterAndParagraphProperties)
+ throw (lang::IllegalArgumentException, uno::RuntimeException);
+
+ sal_Int16 ComparePositions(
+ const uno::Reference<text::XTextRange>& xPos1,
+ const uno::Reference<text::XTextRange>& xPos2)
+ throw (lang::IllegalArgumentException, uno::RuntimeException);
+
+ bool CheckForOwnMember(const SwPaM & rPaM)
+ throw (lang::IllegalArgumentException, uno::RuntimeException);
+
+ void ConvertCell(
+ const bool bFirstCell,
+ const uno::Sequence< uno::Reference< text::XTextRange > > & rCell,
+ ::std::vector<SwNodeRange> & rRowNodes,
+ ::std::auto_ptr< SwPaM > & rpFirstPaM,
+ SwPaM & rLastPaM,
+ bool & rbExcept);
+
+};
+
+/* -----------------------------15.03.2002 12:39------------------------------
+
+ ---------------------------------------------------------------------------*/
+SwXText::SwXText(SwDoc *const pDoc, const enum CursorType eType)
+ : m_pImpl( new SwXText::Impl(*this, pDoc, eType) )
+{
+}
+/*-- 09.12.98 12:43:55---------------------------------------------------
+
+ -----------------------------------------------------------------------*/
+SwXText::~SwXText()
+{
+}
+
+/*-- 09.12.98 12:44:07---------------------------------------------------
+
+ -----------------------------------------------------------------------*/
+
+const SwDoc * SwXText::GetDoc() const
+{
+ return m_pImpl->m_pDoc;
+}
+ SwDoc * SwXText::GetDoc()
+{
+ return m_pImpl->m_pDoc;
+}
+
+bool SwXText::IsValid() const
+{
+ return m_pImpl->m_bIsValid;
+}
+
+void SwXText::Invalidate()
+{
+ m_pImpl->m_bIsValid = false;
+}
+
+void SwXText::SetDoc(SwDoc *const pDoc)
+{
+ OSL_ENSURE(!m_pImpl->m_pDoc || !pDoc,
+ "SwXText::SetDoc: already have a doc?");
+ m_pImpl->m_pDoc = pDoc;
+ m_pImpl->m_bIsValid = (0 != pDoc);
+}
+
+void
+SwXText::PrepareForAttach(uno::Reference< text::XTextRange > &, const SwPaM &)
+{
+}
+
+bool SwXText::CheckForOwnMemberMeta(const SwPaM &, const bool)
+ throw (lang::IllegalArgumentException, uno::RuntimeException)
+{
+ ASSERT(CURSOR_META != m_pImpl->m_eType, "should not be called!");
+ return false;
+}
+
+const SwStartNode *SwXText::GetStartNode() const
+{
+ return GetDoc()->GetNodes().GetEndOfContent().StartOfSectionNode();
+}
+
+uno::Reference< text::XTextCursor >
+SwXText::CreateCursor() throw (uno::RuntimeException)
+{
+ uno::Reference< text::XTextCursor > xRet;
+ if(IsValid())
+ {
+ SwNode& rNode = GetDoc()->GetNodes().GetEndOfContent();
+ SwPosition aPos(rNode);
+ xRet = static_cast<text::XWordCursor*>(
+ new SwXTextCursor(*GetDoc(), this, m_pImpl->m_eType, aPos));
+ xRet->gotoStart(sal_False);
+ }
+ return xRet;
+}
+
+/*-- 09.12.98 12:43:02---------------------------------------------------
+
+ -----------------------------------------------------------------------*/
+uno::Any SAL_CALL
+SwXText::queryInterface(const uno::Type& rType) throw (uno::RuntimeException)
+{
+ uno::Any aRet;
+ if (rType == text::XText::static_type())
+ {
+ aRet <<= uno::Reference< text::XText >(this);
+ }
+ else if (rType == text::XSimpleText::static_type())
+ {
+ aRet <<= uno::Reference< text::XSimpleText >(this);
+ }
+ else if (rType == text::XTextRange::static_type())
+ {
+ aRet <<= uno::Reference< text::XTextRange>(this);
+ }
+ else if (rType == text::XTextRangeCompare::static_type())
+ {
+ aRet <<= uno::Reference< text::XTextRangeCompare >(this);
+ }
+ else if (rType == lang::XTypeProvider::static_type())
+ {
+ aRet <<= uno::Reference< lang::XTypeProvider >(this);
+ }
+ else if (rType == text::XRelativeTextContentInsert::static_type())
+ {
+ aRet <<= uno::Reference< text::XRelativeTextContentInsert >(this);
+ }
+ else if (rType == text::XRelativeTextContentRemove::static_type())
+ {
+ aRet <<= uno::Reference< text::XRelativeTextContentRemove >(this);
+ }
+ else if (rType == beans::XPropertySet::static_type())
+ {
+ aRet <<= uno::Reference< beans::XPropertySet >(this);
+ }
+ else if (rType == lang::XUnoTunnel::static_type())
+ {
+ aRet <<= uno::Reference< lang::XUnoTunnel >(this);
+ }
+ else if (rType == text::XTextAppendAndConvert::static_type())
+ {
+ aRet <<= uno::Reference< text::XTextAppendAndConvert >(this);
+ }
+ else if (rType == text::XTextAppend::static_type())
+ {
+ aRet <<= uno::Reference< text::XTextAppend >(this);
+ }
+ else if (rType == text::XTextPortionAppend::static_type())
+ {
+ aRet <<= uno::Reference< text::XTextPortionAppend >(this);
+ }
+ else if (rType == text::XParagraphAppend::static_type())
+ {
+ aRet <<= uno::Reference< text::XParagraphAppend >(this);
+ }
+ else if (rType == text::XTextConvert::static_type() )
+ {
+ aRet <<= uno::Reference< text::XTextConvert >(this);
+ }
+ else if (rType == text::XTextContentAppend::static_type())
+ {
+ aRet <<= uno::Reference< text::XTextContentAppend >(this);
+ }
+ else if(rType == text::XTextCopy::static_type())
+ {
+ aRet <<= uno::Reference< text::XTextCopy >( this );
+ }
+ return aRet;
+}
+/* -----------------------------15.03.00 17:42--------------------------------
+
+ ---------------------------------------------------------------------------*/
+uno::Sequence< uno::Type > SAL_CALL
+SwXText::getTypes() throw (uno::RuntimeException)
+{
+ uno::Sequence< uno::Type > aRet(12);
+ uno::Type* pTypes = aRet.getArray();
+ pTypes[0] = text::XText::static_type();
+ pTypes[1] = text::XTextRangeCompare::static_type();
+ pTypes[2] = text::XRelativeTextContentInsert::static_type();
+ pTypes[3] = text::XRelativeTextContentRemove::static_type();
+ pTypes[4] = lang::XUnoTunnel::static_type();
+ pTypes[5] = beans::XPropertySet::static_type();
+ pTypes[6] = text::XTextPortionAppend::static_type();
+ pTypes[7] = text::XParagraphAppend::static_type();
+ pTypes[8] = text::XTextContentAppend::static_type();
+ pTypes[9] = text::XTextConvert::static_type();
+ pTypes[10] = text::XTextAppend::static_type();
+ pTypes[11] = text::XTextAppendAndConvert::static_type();
+
+ return aRet;
+}
+
+// belongs the range in the text ? insert it then.
+void SAL_CALL
+SwXText::insertString(const uno::Reference< text::XTextRange >& xTextRange,
+ const OUString& rString, sal_Bool bAbsorb)
+throw (uno::RuntimeException)
+{
+ vos::OGuard aGuard(Application::GetSolarMutex());
+
+ if (!xTextRange.is())
+ {
+ throw uno::RuntimeException();
+ }
+ if (!GetDoc())
+ {
+ throw uno::RuntimeException();
+ }
+ const uno::Reference<lang::XUnoTunnel> xRangeTunnel(xTextRange,
+ uno::UNO_QUERY);
+ SwXTextRange *const pRange =
+ ::sw::UnoTunnelGetImplementation<SwXTextRange>(xRangeTunnel);
+ OTextCursorHelper *const pCursor =
+ ::sw::UnoTunnelGetImplementation<OTextCursorHelper>(xRangeTunnel);
+ if ((!pRange || pRange ->GetDoc() != GetDoc()) &&
+ (!pCursor || pCursor->GetDoc() != GetDoc()))
+ {
+ throw uno::RuntimeException();
+ }
+
+ const SwStartNode *const pOwnStartNode = GetStartNode();
+ SwPaM aPam(GetDoc()->GetNodes());
+ const SwPaM * pPam(0);
+ if (pCursor)
+ {
+ pPam = pCursor->GetPaM();
+ }
+ else // pRange
+ {
+ if (pRange->GetPositions(aPam))
+ {
+ pPam = &aPam;
+ }
+ }
+ if (!pPam)
+ {
+ throw uno::RuntimeException();
+ }
+
+ const SwStartNode* pTmp(pPam->GetNode()->StartOfSectionNode());
+ while (pTmp && pTmp->IsSectionNode())
+ {
+ pTmp = pTmp->StartOfSectionNode();
+ }
+ if (!pOwnStartNode || (pOwnStartNode != pTmp))
+ {
+ throw uno::RuntimeException();
+ }
+
+ bool bForceExpandHints( false );
+ if (CURSOR_META == m_pImpl->m_eType)
+ {
+ try
+ {
+ bForceExpandHints = CheckForOwnMemberMeta(*pPam, bAbsorb);
+ }
+ catch (lang::IllegalArgumentException & iae)
+ {
+ // stupid method not allowed to throw iae
+ throw uno::RuntimeException(iae.Message, 0);
+ }
+ }
+ if (bAbsorb)
+ {
+ //!! scan for CR characters and inserting the paragraph breaks
+ //!! has to be done in the called function.
+ //!! Implemented in SwXTextRange::DeleteAndInsert
+ if (pCursor)
+ {
+ SwXTextCursor * const pTextCursor(
+ dynamic_cast<SwXTextCursor*>(pCursor) );
+ if (pTextCursor)
+ {
+ pTextCursor->DeleteAndInsert(rString, bForceExpandHints);
+ }
+ else
+ {
+ xTextRange->setString(rString);
+ }
+ }
+ else
+ {
+ pRange->DeleteAndInsert(rString, bForceExpandHints);
+ }
+ }
+ else
+ {
+ // create a PaM positioned before the parameter PaM,
+ // so the text is inserted before
+ UnoActionContext aContext(GetDoc());
+ SwPaM aInsertPam(*pPam->Start());
+ ::sw::GroupUndoGuard const undoGuard(GetDoc()->GetIDocumentUndoRedo());
+ SwUnoCursorHelper::DocInsertStringSplitCR(
+ *GetDoc(), aInsertPam, rString, bForceExpandHints );
+ }
+}
+
+/*-- 09.12.98 12:43:16---------------------------------------------------
+
+ -----------------------------------------------------------------------*/
+void SAL_CALL
+SwXText::insertControlCharacter(
+ const uno::Reference< text::XTextRange > & xTextRange,
+ sal_Int16 nControlCharacter, sal_Bool bAbsorb)
+throw (lang::IllegalArgumentException, uno::RuntimeException)
+{
+ vos::OGuard aGuard(Application::GetSolarMutex());
+
+ if (!xTextRange.is())
+ {
+ throw lang::IllegalArgumentException();
+ }
+ if (!GetDoc())
+ {
+ throw uno::RuntimeException();
+ }
+
+ SwUnoInternalPaM aPam(*GetDoc());
+ if (!::sw::XTextRangeToSwPaM(aPam, xTextRange))
+ {
+ throw uno::RuntimeException();
+ }
+ const bool bForceExpandHints(CheckForOwnMemberMeta(aPam, bAbsorb));
+
+ const enum IDocumentContentOperations::InsertFlags nInsertFlags =
+ (bForceExpandHints)
+ ? static_cast<IDocumentContentOperations::InsertFlags>(
+ IDocumentContentOperations::INS_FORCEHINTEXPAND |
+ IDocumentContentOperations::INS_EMPTYEXPAND)
+ : IDocumentContentOperations::INS_EMPTYEXPAND;
+
+ SwPaM aTmp(*aPam.Start());
+ if (bAbsorb && aPam.HasMark())
+ {
+ m_pImpl->m_pDoc->DeleteAndJoin(aPam);
+ }
+
+ sal_Unicode cIns = 0;
+ switch (nControlCharacter)
+ {
+ case text::ControlCharacter::PARAGRAPH_BREAK :
+ // a table cell now becomes an ordinary text cell!
+ m_pImpl->m_pDoc->ClearBoxNumAttrs( aTmp.GetPoint()->nNode );
+ m_pImpl->m_pDoc->SplitNode( *aTmp.GetPoint(), sal_False );
+ break;
+ case text::ControlCharacter::APPEND_PARAGRAPH:
+ {
+ m_pImpl->m_pDoc->ClearBoxNumAttrs( aTmp.GetPoint()->nNode );
+ m_pImpl->m_pDoc->AppendTxtNode( *aTmp.GetPoint() );
+
+ const uno::Reference<lang::XUnoTunnel> xRangeTunnel(
+ xTextRange, uno::UNO_QUERY);
+ SwXTextRange *const pRange =
+ ::sw::UnoTunnelGetImplementation<SwXTextRange>(xRangeTunnel);
+ OTextCursorHelper *const pCursor =
+ ::sw::UnoTunnelGetImplementation<OTextCursorHelper>(
+ xRangeTunnel);
+ if (pRange)
+ {
+ pRange->SetPositions(aTmp);
+ }
+ else if (pCursor)
+ {
+ SwPaM *const pCrsr = pCursor->GetPaM();
+ *pCrsr->GetPoint() = *aTmp.GetPoint();
+ pCrsr->DeleteMark();
+ }
+ }
+ break;
+ case text::ControlCharacter::LINE_BREAK: cIns = 10; break;
+ case text::ControlCharacter::SOFT_HYPHEN: cIns = CHAR_SOFTHYPHEN; break;
+ case text::ControlCharacter::HARD_HYPHEN: cIns = CHAR_HARDHYPHEN; break;
+ case text::ControlCharacter::HARD_SPACE: cIns = CHAR_HARDBLANK; break;
+ }
+ if (cIns)
+ {
+ m_pImpl->m_pDoc->InsertString( aTmp, cIns, nInsertFlags );
+ }
+
+ if (bAbsorb)
+ {
+ const uno::Reference<lang::XUnoTunnel> xRangeTunnel(
+ xTextRange, uno::UNO_QUERY);
+ SwXTextRange *const pRange =
+ ::sw::UnoTunnelGetImplementation<SwXTextRange>(xRangeTunnel);
+ OTextCursorHelper *const pCursor =
+ ::sw::UnoTunnelGetImplementation<OTextCursorHelper>(xRangeTunnel);
+
+ SwCursor aCrsr(*aTmp.GetPoint(),0,false);
+ SwUnoCursorHelper::SelectPam(aCrsr, true);
+ aCrsr.Left(1, CRSR_SKIP_CHARS, sal_False, sal_False);
+ //hier muss der uebergebene PaM umgesetzt werden:
+ if (pRange)
+ {
+ pRange->SetPositions(aCrsr);
+ }
+ else
+ {
+ SwPaM *const pUnoCrsr = pCursor->GetPaM();
+ *pUnoCrsr->GetPoint() = *aCrsr.GetPoint();
+ if (aCrsr.HasMark())
+ {
+ pUnoCrsr->SetMark();
+ *pUnoCrsr->GetMark() = *aCrsr.GetMark();
+ }
+ else
+ {
+ pUnoCrsr->DeleteMark();
+ }
+ }
+ }
+}
+
+/*-- 09.12.98 12:43:17---------------------------------------------------
+
+ -----------------------------------------------------------------------*/
+void SAL_CALL
+SwXText::insertTextContent(
+ const uno::Reference< text::XTextRange > & xRange,
+ const uno::Reference< text::XTextContent > & xContent,
+ sal_Bool bAbsorb)
+throw (lang::IllegalArgumentException, uno::RuntimeException)
+{
+ vos::OGuard aGuard(Application::GetSolarMutex());
+
+ if (!xRange.is())
+ {
+ lang::IllegalArgumentException aIllegal;
+ aIllegal.Message = C2U("first parameter invalid;");
+ throw aIllegal;
+ }
+ if (!xContent.is())
+ {
+ lang::IllegalArgumentException aIllegal;
+ aIllegal.Message += C2U("second parameter invalid");
+ throw aIllegal;
+ }
+ if(!GetDoc())
+ {
+ uno::RuntimeException aRuntime;
+ aRuntime.Message = C2U(cInvalidObject);
+ throw aRuntime;
+ }
+
+ SwUnoInternalPaM aPam(*GetDoc());
+ if (!::sw::XTextRangeToSwPaM(aPam, xRange))
+ {
+ lang::IllegalArgumentException aIllegal;
+ aIllegal.Message = C2U("first parameter invalid");
+ throw aIllegal;
+ }
+ // first test if the range is at the right position, then call
+ // xContent->attach
+ const SwStartNode* pOwnStartNode = GetStartNode();
+ SwStartNodeType eSearchNodeType = SwNormalStartNode;
+ switch (m_pImpl->m_eType)
+ {
+ case CURSOR_FRAME: eSearchNodeType = SwFlyStartNode; break;
+ case CURSOR_TBLTEXT: eSearchNodeType = SwTableBoxStartNode; break;
+ case CURSOR_FOOTNOTE: eSearchNodeType = SwFootnoteStartNode; break;
+ case CURSOR_HEADER: eSearchNodeType = SwHeaderStartNode; break;
+ case CURSOR_FOOTER: eSearchNodeType = SwFooterStartNode; break;
+ //case CURSOR_INVALID:
+ //case CURSOR_BODY:
+ default:
+ break;
+ }
+
+ const SwStartNode* pTmp =
+ aPam.GetNode()->FindSttNodeByType(eSearchNodeType);
+
+ // ignore SectionNodes
+ while (pTmp && pTmp->IsSectionNode())
+ {
+ pTmp = pTmp->StartOfSectionNode();
+ }
+ // if the document starts with a section
+ while (pOwnStartNode->IsSectionNode())
+ {
+ pOwnStartNode = pOwnStartNode->StartOfSectionNode();
+ }
+ // this checks if (this) and xRange are in the same text::XText interface
+ if (pOwnStartNode != pTmp)
+ {
+ uno::RuntimeException aRunException;
+ aRunException.Message = C2U("text interface and cursor not related");
+ throw aRunException;
+ }
+
+ const bool bForceExpandHints(CheckForOwnMemberMeta(aPam, bAbsorb));
+
+ // special treatment for Contents that do not replace the range, but
+ // instead are "overlaid"
+ const uno::Reference<lang::XUnoTunnel> xContentTunnel(xContent,
+ uno::UNO_QUERY);
+ if (!xContentTunnel.is())
+ {
+ lang::IllegalArgumentException aArgException;
+ aArgException.Message =
+ C2U("text content does not support lang::XUnoTunnel");
+ throw aArgException;
+ }
+ SwXDocumentIndexMark *const pDocumentIndexMark =
+ ::sw::UnoTunnelGetImplementation<SwXDocumentIndexMark>(xContentTunnel);
+ SwXTextSection *const pSection =
+ ::sw::UnoTunnelGetImplementation<SwXTextSection>(xContentTunnel);
+ SwXBookmark *const pBookmark =
+ ::sw::UnoTunnelGetImplementation<SwXBookmark>(xContentTunnel);
+ SwXReferenceMark *const pReferenceMark =
+ ::sw::UnoTunnelGetImplementation<SwXReferenceMark>(xContentTunnel);
+ SwXMeta *const pMeta =
+ ::sw::UnoTunnelGetImplementation<SwXMeta>(xContentTunnel);
+
+ const bool bAttribute = pBookmark || pDocumentIndexMark
+ || pSection || pReferenceMark || pMeta;
+
+ if (bAbsorb && !bAttribute)
+ {
+ xRange->setString(aEmptyStr);
+ }
+ uno::Reference< text::XTextRange > xTempRange =
+ (bAttribute && bAbsorb) ? xRange : xRange->getStart();
+ if (bForceExpandHints)
+ {
+ // if necessary, replace xTempRange with a new SwXTextCursor
+ PrepareForAttach(xTempRange, aPam);
+ }
+ xContent->attach(xTempRange);
+}
+
+/* -----------------------------10.07.00 15:40--------------------------------
+
+ ---------------------------------------------------------------------------*/
+void SAL_CALL
+SwXText::insertTextContentBefore(
+ const uno::Reference< text::XTextContent>& xNewContent,
+ const uno::Reference< text::XTextContent>& xSuccessor)
+throw (lang::IllegalArgumentException, uno::RuntimeException)
+{
+ vos::OGuard aGuard(Application::GetSolarMutex());
+
+ if(!GetDoc())
+ {
+ uno::RuntimeException aRuntime;
+ aRuntime.Message = C2U(cInvalidObject);
+ throw aRuntime;
+ }
+
+ const uno::Reference<lang::XUnoTunnel> xParaTunnel(xNewContent,
+ uno::UNO_QUERY);
+ SwXParagraph *const pPara =
+ ::sw::UnoTunnelGetImplementation<SwXParagraph>(xParaTunnel);
+ if (!pPara || !pPara->IsDescriptor() || !xSuccessor.is())
+ {
+ throw lang::IllegalArgumentException();
+ }
+
+ sal_Bool bRet = sal_False;
+ const uno::Reference<lang::XUnoTunnel> xSuccTunnel(xSuccessor,
+ uno::UNO_QUERY);
+ SwXTextSection *const pXSection =
+ ::sw::UnoTunnelGetImplementation<SwXTextSection>(xSuccTunnel);
+ SwXTextTable *const pXTable =
+ ::sw::UnoTunnelGetImplementation<SwXTextTable>(xSuccTunnel);
+ SwFrmFmt *const pTableFmt = (pXTable) ? pXTable->GetFrmFmt() : 0;
+ SwTxtNode * pTxtNode = 0;
+ if(pTableFmt && pTableFmt->GetDoc() == GetDoc())
+ {
+ SwTable *const pTable = SwTable::FindTable( pTableFmt );
+ SwTableNode *const pTblNode = pTable->GetTableNode();
+
+ const SwNodeIndex aTblIdx( *pTblNode, -1 );
+ SwPosition aBefore(aTblIdx);
+ bRet = GetDoc()->AppendTxtNode( aBefore );
+ pTxtNode = aBefore.nNode.GetNode().GetTxtNode();
+ }
+ else if (pXSection && pXSection->GetFmt() &&
+ pXSection->GetFmt()->GetDoc() == GetDoc())
+ {
+ SwSectionFmt *const pSectFmt = pXSection->GetFmt();
+ SwSectionNode *const pSectNode = pSectFmt->GetSectionNode();
+
+ const SwNodeIndex aSectIdx( *pSectNode, -1 );
+ SwPosition aBefore(aSectIdx);
+ bRet = GetDoc()->AppendTxtNode( aBefore );
+ pTxtNode = aBefore.nNode.GetNode().GetTxtNode();
+ }
+ if (!bRet || !pTxtNode)
+ {
+ throw lang::IllegalArgumentException();
+ }
+ pPara->attachToText(*this, *pTxtNode);
+}
+
+/* -----------------------------10.07.00 15:40--------------------------------
+
+ ---------------------------------------------------------------------------*/
+void SAL_CALL
+SwXText::insertTextContentAfter(
+ const uno::Reference< text::XTextContent>& xNewContent,
+ const uno::Reference< text::XTextContent>& xPredecessor)
+throw (lang::IllegalArgumentException, uno::RuntimeException)
+{
+ vos::OGuard aGuard(Application::GetSolarMutex());
+
+ if(!GetDoc())
+ {
+ throw uno::RuntimeException();
+ }
+
+ const uno::Reference<lang::XUnoTunnel> xParaTunnel(xNewContent,
+ uno::UNO_QUERY);
+ SwXParagraph *const pPara =
+ ::sw::UnoTunnelGetImplementation<SwXParagraph>(xParaTunnel);
+ if(!pPara || !pPara->IsDescriptor() || !xPredecessor.is())
+ {
+ throw lang::IllegalArgumentException();
+ }
+
+ const uno::Reference<lang::XUnoTunnel> xPredTunnel(xPredecessor,
+ uno::UNO_QUERY);
+ SwXTextSection *const pXSection =
+ ::sw::UnoTunnelGetImplementation<SwXTextSection>(xPredTunnel);
+ SwXTextTable *const pXTable =
+ ::sw::UnoTunnelGetImplementation<SwXTextTable>(xPredTunnel);
+ SwFrmFmt *const pTableFmt = (pXTable) ? pXTable->GetFrmFmt() : 0;
+ sal_Bool bRet = sal_False;
+ SwTxtNode * pTxtNode = 0;
+ if(pTableFmt && pTableFmt->GetDoc() == GetDoc())
+ {
+ SwTable *const pTable = SwTable::FindTable( pTableFmt );
+ SwTableNode *const pTblNode = pTable->GetTableNode();
+
+ SwEndNode *const pTableEnd = pTblNode->EndOfSectionNode();
+ SwPosition aTableEnd(*pTableEnd);
+ bRet = GetDoc()->AppendTxtNode( aTableEnd );
+ pTxtNode = aTableEnd.nNode.GetNode().GetTxtNode();
+ }
+ else if (pXSection && pXSection->GetFmt() &&
+ pXSection->GetFmt()->GetDoc() == GetDoc())
+ {
+ SwSectionFmt *const pSectFmt = pXSection->GetFmt();
+ SwSectionNode *const pSectNode = pSectFmt->GetSectionNode();
+ SwEndNode *const pEnd = pSectNode->EndOfSectionNode();
+ SwPosition aEnd(*pEnd);
+ bRet = GetDoc()->AppendTxtNode( aEnd );
+ pTxtNode = aEnd.nNode.GetNode().GetTxtNode();
+ }
+ if (!bRet || !pTxtNode)
+ {
+ throw lang::IllegalArgumentException();
+ }
+ pPara->attachToText(*this, *pTxtNode);
+}
+
+/* -----------------------------10.07.00 15:40--------------------------------
+
+ ---------------------------------------------------------------------------*/
+void SAL_CALL
+SwXText::removeTextContentBefore(
+ const uno::Reference< text::XTextContent>& xSuccessor)
+throw (lang::IllegalArgumentException, uno::RuntimeException)
+{
+ vos::OGuard aGuard(Application::GetSolarMutex());
+
+ if(!GetDoc())
+ {
+ uno::RuntimeException aRuntime;
+ aRuntime.Message = C2U(cInvalidObject);
+ throw aRuntime;
+ }
+
+ sal_Bool bRet = sal_False;
+ const uno::Reference<lang::XUnoTunnel> xSuccTunnel(xSuccessor,
+ uno::UNO_QUERY);
+ SwXTextSection *const pXSection =
+ ::sw::UnoTunnelGetImplementation<SwXTextSection>(xSuccTunnel);
+ SwXTextTable *const pXTable =
+ ::sw::UnoTunnelGetImplementation<SwXTextTable>(xSuccTunnel);
+ SwFrmFmt *const pTableFmt = (pXTable) ? pXTable->GetFrmFmt() : 0;
+ if(pTableFmt && pTableFmt->GetDoc() == GetDoc())
+ {
+ SwTable *const pTable = SwTable::FindTable( pTableFmt );
+ SwTableNode *const pTblNode = pTable->GetTableNode();
+
+ const SwNodeIndex aTblIdx( *pTblNode, -1 );
+ if(aTblIdx.GetNode().IsTxtNode())
+ {
+ SwPaM aBefore(aTblIdx);
+ bRet = GetDoc()->DelFullPara( aBefore );
+ }
+ }
+ else if (pXSection && pXSection->GetFmt() &&
+ pXSection->GetFmt()->GetDoc() == GetDoc())
+ {
+ SwSectionFmt *const pSectFmt = pXSection->GetFmt();
+ SwSectionNode *const pSectNode = pSectFmt->GetSectionNode();
+
+ const SwNodeIndex aSectIdx( *pSectNode, -1 );
+ if(aSectIdx.GetNode().IsTxtNode())
+ {
+ SwPaM aBefore(aSectIdx);
+ bRet = GetDoc()->DelFullPara( aBefore );
+ }
+ }
+ if(!bRet)
+ {
+ throw lang::IllegalArgumentException();
+ }
+}
+
+/* -----------------------------10.07.00 15:40--------------------------------
+
+ ---------------------------------------------------------------------------*/
+void SAL_CALL
+SwXText::removeTextContentAfter(
+ const uno::Reference< text::XTextContent>& xPredecessor)
+throw (lang::IllegalArgumentException, uno::RuntimeException)
+{
+ vos::OGuard aGuard(Application::GetSolarMutex());
+
+ if(!GetDoc())
+ {
+ uno::RuntimeException aRuntime;
+ aRuntime.Message = C2U(cInvalidObject);
+ throw aRuntime;
+ }
+
+ sal_Bool bRet = sal_False;
+ const uno::Reference<lang::XUnoTunnel> xPredTunnel(xPredecessor,
+ uno::UNO_QUERY);
+ SwXTextSection *const pXSection =
+ ::sw::UnoTunnelGetImplementation<SwXTextSection>(xPredTunnel);
+ SwXTextTable *const pXTable =
+ ::sw::UnoTunnelGetImplementation<SwXTextTable>(xPredTunnel);
+ SwFrmFmt *const pTableFmt = (pXTable) ? pXTable->GetFrmFmt() : 0;
+ if(pTableFmt && pTableFmt->GetDoc() == GetDoc())
+ {
+ SwTable *const pTable = SwTable::FindTable( pTableFmt );
+ SwTableNode *const pTblNode = pTable->GetTableNode();
+ SwEndNode *const pTableEnd = pTblNode->EndOfSectionNode();
+
+ const SwNodeIndex aTblIdx( *pTableEnd, 1 );
+ if(aTblIdx.GetNode().IsTxtNode())
+ {
+ SwPaM aPaM(aTblIdx);
+ bRet = GetDoc()->DelFullPara( aPaM );
+ }
+ }
+ else if (pXSection && pXSection->GetFmt() &&
+ pXSection->GetFmt()->GetDoc() == GetDoc())
+ {
+ SwSectionFmt *const pSectFmt = pXSection->GetFmt();
+ SwSectionNode *const pSectNode = pSectFmt->GetSectionNode();
+ SwEndNode *const pEnd = pSectNode->EndOfSectionNode();
+ const SwNodeIndex aSectIdx( *pEnd, 1 );
+ if(aSectIdx.GetNode().IsTxtNode())
+ {
+ SwPaM aAfter(aSectIdx);
+ bRet = GetDoc()->DelFullPara( aAfter );
+ }
+ }
+ if(!bRet)
+ {
+ throw lang::IllegalArgumentException();
+ }
+}
+
+/*-- 09.12.98 12:43:19---------------------------------------------------
+
+ -----------------------------------------------------------------------*/
+void SAL_CALL
+SwXText::removeTextContent(
+ const uno::Reference< text::XTextContent > & xContent)
+throw (container::NoSuchElementException, uno::RuntimeException)
+{
+ // forward: need no solar mutex here
+ if(!xContent.is())
+ {
+ uno::RuntimeException aRuntime;
+ aRuntime.Message = C2U("first parameter invalid");
+ throw aRuntime;
+ }
+ xContent->dispose();
+}
+
+/*-- 09.12.98 12:43:22---------------------------------------------------
+
+ -----------------------------------------------------------------------*/
+uno::Reference< text::XText > SAL_CALL
+SwXText::getText() throw (uno::RuntimeException)
+{
+ vos::OGuard aGuard(Application::GetSolarMutex());
+
+ const uno::Reference< text::XText > xRet(this);
+ return xRet;
+}
+
+/*-- 09.12.98 12:43:24---------------------------------------------------
+
+ -----------------------------------------------------------------------*/
+uno::Reference< text::XTextRange > SAL_CALL
+SwXText::getStart() throw (uno::RuntimeException)
+{
+ vos::OGuard aGuard(Application::GetSolarMutex());
+
+ const uno::Reference< text::XTextCursor > xRef = CreateCursor();
+ if(!xRef.is())
+ {
+ uno::RuntimeException aRuntime;
+ aRuntime.Message = C2U(cInvalidObject);
+ throw aRuntime;
+ }
+ xRef->gotoStart(sal_False);
+ const uno::Reference< text::XTextRange > xRet(xRef, uno::UNO_QUERY);
+ return xRet;
+}
+/*-- 09.12.98 12:43:27---------------------------------------------------
+
+ -----------------------------------------------------------------------*/
+uno::Reference< text::XTextRange > SAL_CALL
+SwXText::getEnd() throw (uno::RuntimeException)
+{
+ vos::OGuard aGuard(Application::GetSolarMutex());
+
+ const uno::Reference< text::XTextCursor > xRef = CreateCursor();
+ if(!xRef.is())
+ {
+ uno::RuntimeException aRuntime;
+ aRuntime.Message = C2U(cInvalidObject);
+ throw aRuntime;
+ }
+ xRef->gotoEnd(sal_False);
+ const uno::Reference< text::XTextRange > xRet(xRef, uno::UNO_QUERY);
+ return xRet;
+}
+
+/*-- 09.12.98 12:43:29---------------------------------------------------
+
+ -----------------------------------------------------------------------*/
+OUString SAL_CALL SwXText::getString() throw (uno::RuntimeException)
+{
+ vos::OGuard aGuard(Application::GetSolarMutex());
+
+ const uno::Reference< text::XTextCursor > xRet = CreateCursor();
+ if(!xRet.is())
+ {
+ uno::RuntimeException aRuntime;
+ aRuntime.Message = C2U(cInvalidObject);
+ throw aRuntime;
+ }
+ xRet->gotoEnd(sal_True);
+ return xRet->getString();
+}
+/*-- 09.12.98 12:43:30---------------------------------------------------
+
+ -----------------------------------------------------------------------*/
+void SAL_CALL
+SwXText::setString(const OUString& rString) throw (uno::RuntimeException)
+{
+ vos::OGuard aGuard(Application::GetSolarMutex());
+
+ if (!GetDoc())
+ {
+ uno::RuntimeException aRuntime;
+ aRuntime.Message = C2U(cInvalidObject);
+ throw aRuntime;
+ }
+
+ const SwStartNode* pStartNode = GetStartNode();
+ if (!pStartNode)
+ {
+ throw uno::RuntimeException();
+ }
+
+ GetDoc()->GetIDocumentUndoRedo().StartUndo(UNDO_START, NULL);
+ //insert an empty paragraph at the start and at the end to ensure that
+ //all tables and sections can be removed by the selecting text::XTextCursor
+ if (CURSOR_META != m_pImpl->m_eType)
+ {
+ SwPosition aStartPos(*pStartNode);
+ const SwEndNode* pEnd = pStartNode->EndOfSectionNode();
+ SwNodeIndex aEndIdx(*pEnd);
+ aEndIdx--;
+ //the inserting of nodes should only be done if really necessary
+ //to prevent #97924# (removes paragraph attributes when setting the text
+ //e.g. of a table cell
+ sal_Bool bInsertNodes = sal_False;
+ SwNodeIndex aStartIdx(*pStartNode);
+ do
+ {
+ aStartIdx++;
+ SwNode& rCurrentNode = aStartIdx.GetNode();
+ if(rCurrentNode.GetNodeType() == ND_SECTIONNODE
+ ||rCurrentNode.GetNodeType() == ND_TABLENODE)
+ {
+ bInsertNodes = sal_True;
+ break;
+ }
+ }
+ while(aStartIdx < aEndIdx);
+ if(bInsertNodes)
+ {
+ GetDoc()->AppendTxtNode( aStartPos );
+ SwPosition aEndPos(aEndIdx.GetNode());
+ SwPaM aPam(aEndPos);
+ GetDoc()->AppendTxtNode( *aPam.Start() );
+ }
+ }
+
+ const uno::Reference< text::XTextCursor > xRet = CreateCursor();
+ if(!xRet.is())
+ {
+ GetDoc()->GetIDocumentUndoRedo().EndUndo(UNDO_END, NULL);
+ uno::RuntimeException aRuntime;
+ aRuntime.Message = C2U(cInvalidObject);
+ throw aRuntime;
+ }
+ xRet->gotoEnd(sal_True);
+ xRet->setString(rString);
+ GetDoc()->GetIDocumentUndoRedo().EndUndo(UNDO_END, NULL);
+}
+
+//FIXME why is CheckForOwnMember duplicated in some insert methods?
+// Description: Checks if pRange/pCursor are member of the same text interface.
+// Only one of the pointers has to be set!
+bool SwXText::Impl::CheckForOwnMember(
+ const SwPaM & rPaM)
+throw (lang::IllegalArgumentException, uno::RuntimeException)
+{
+ const uno::Reference<text::XTextCursor> xOwnCursor(m_rThis.CreateCursor());
+
+ const uno::Reference<lang::XUnoTunnel> xTunnel(xOwnCursor, uno::UNO_QUERY);
+ OTextCursorHelper *const pOwnCursor =
+ ::sw::UnoTunnelGetImplementation<OTextCursorHelper>(xTunnel);
+ DBG_ASSERT(pOwnCursor, "OTextCursorHelper::getUnoTunnelId() ??? ");
+ const SwStartNode* pOwnStartNode =
+ pOwnCursor->GetPaM()->GetNode()->StartOfSectionNode();
+ SwStartNodeType eSearchNodeType = SwNormalStartNode;
+ switch (m_eType)
+ {
+ case CURSOR_FRAME: eSearchNodeType = SwFlyStartNode; break;
+ case CURSOR_TBLTEXT: eSearchNodeType = SwTableBoxStartNode; break;
+ case CURSOR_FOOTNOTE: eSearchNodeType = SwFootnoteStartNode; break;
+ case CURSOR_HEADER: eSearchNodeType = SwHeaderStartNode; break;
+ case CURSOR_FOOTER: eSearchNodeType = SwFooterStartNode; break;
+ //case CURSOR_INVALID:
+ //case CURSOR_BODY:
+ default:
+ ;
+ }
+
+ SwNode const*const pSrcNode(rPaM.GetNode());
+ if (!pSrcNode) { return false; }
+ const SwStartNode* pTmp = pSrcNode->FindSttNodeByType(eSearchNodeType);
+
+ //SectionNodes ueberspringen
+ while(pTmp && pTmp->IsSectionNode())
+ {
+ pTmp = pTmp->StartOfSectionNode();
+ }
+
+ //if the document starts with a section
+ while(pOwnStartNode->IsSectionNode())
+ {
+ pOwnStartNode = pOwnStartNode->StartOfSectionNode();
+ }
+
+ //this checks if (this) and xRange are in the same text::XText interface
+ return (pOwnStartNode == pTmp);
+}
+
+sal_Int16
+SwXText::Impl::ComparePositions(
+ const uno::Reference<text::XTextRange>& xPos1,
+ const uno::Reference<text::XTextRange>& xPos2)
+throw (lang::IllegalArgumentException, uno::RuntimeException)
+{
+ SwUnoInternalPaM aPam1(*m_pDoc);
+ SwUnoInternalPaM aPam2(*m_pDoc);
+
+ if (!::sw::XTextRangeToSwPaM(aPam1, xPos1) ||
+ !::sw::XTextRangeToSwPaM(aPam2, xPos2))
+ {
+ throw lang::IllegalArgumentException();
+ }
+ if (!CheckForOwnMember(aPam1) || !CheckForOwnMember(aPam2))
+ {
+ throw lang::IllegalArgumentException();
+ }
+
+ sal_Int16 nCompare = 0;
+ SwPosition const*const pStart1 = aPam1.Start();
+ SwPosition const*const pStart2 = aPam2.Start();
+ if (*pStart1 < *pStart2)
+ {
+ nCompare = 1;
+ }
+ else if (*pStart1 > *pStart2)
+ {
+ nCompare = -1;
+ }
+ else
+ {
+ DBG_ASSERT(*pStart1 == *pStart2,
+ "SwPositions should be equal here");
+ nCompare = 0;
+ }
+
+ return nCompare;
+}
+
+/*-- 28.03.00 10:37:22---------------------------------------------------
+
+ -----------------------------------------------------------------------*/
+sal_Int16 SAL_CALL
+SwXText::compareRegionStarts(
+ const uno::Reference<text::XTextRange>& xRange1,
+ const uno::Reference<text::XTextRange>& xRange2)
+throw (lang::IllegalArgumentException, uno::RuntimeException)
+{
+ vos::OGuard aGuard(Application::GetSolarMutex());
+
+ if (!xRange1.is() || !xRange2.is())
+ {
+ throw lang::IllegalArgumentException();
+ }
+ const uno::Reference<text::XTextRange> xStart1 = xRange1->getStart();
+ const uno::Reference<text::XTextRange> xStart2 = xRange2->getStart();
+
+ return m_pImpl->ComparePositions(xStart1, xStart2);
+}
+/*-- 28.03.00 10:37:25---------------------------------------------------
+
+ -----------------------------------------------------------------------*/
+sal_Int16 SAL_CALL
+SwXText::compareRegionEnds(
+ const uno::Reference<text::XTextRange>& xRange1,
+ const uno::Reference<text::XTextRange>& xRange2)
+throw (lang::IllegalArgumentException, uno::RuntimeException)
+{
+ vos::OGuard aGuard(Application::GetSolarMutex());
+
+ if (!xRange1.is() || !xRange2.is())
+ {
+ throw lang::IllegalArgumentException();
+ }
+ uno::Reference<text::XTextRange> xEnd1 = xRange1->getEnd();
+ uno::Reference<text::XTextRange> xEnd2 = xRange2->getEnd();
+
+ return m_pImpl->ComparePositions(xEnd1, xEnd2);
+}
+
+/*-- 15.03.2002 12:30:40---------------------------------------------------
+
+ -----------------------------------------------------------------------*/
+uno::Reference< beans::XPropertySetInfo > SAL_CALL
+SwXText::getPropertySetInfo() throw(uno::RuntimeException)
+{
+ vos::OGuard g(Application::GetSolarMutex());
+
+ static uno::Reference< beans::XPropertySetInfo > xInfo =
+ m_pImpl->m_rPropSet.getPropertySetInfo();
+ return xInfo;
+}
+
+/*-- 15.03.2002 12:30:42---------------------------------------------------
+
+ -----------------------------------------------------------------------*/
+void SAL_CALL
+SwXText::setPropertyValue(const ::rtl::OUString& /*aPropertyName*/,
+ const uno::Any& /*aValue*/)
+throw (beans::UnknownPropertyException, beans::PropertyVetoException,
+ lang::IllegalArgumentException, lang::WrappedTargetException,
+ uno::RuntimeException)
+{
+ throw lang::IllegalArgumentException();
+}
+/*-- 15.03.2002 12:30:42---------------------------------------------------
+
+ -----------------------------------------------------------------------*/
+uno::Any SAL_CALL
+SwXText::getPropertyValue(
+ const ::rtl::OUString& rPropertyName)
+throw (beans::UnknownPropertyException, lang::WrappedTargetException,
+ uno::RuntimeException)
+{
+ vos::OGuard aGuard(Application::GetSolarMutex());
+
+ if(!IsValid())
+ {
+ throw uno::RuntimeException();
+ }
+
+ SfxItemPropertySimpleEntry const*const pEntry =
+ m_pImpl->m_rPropSet.getPropertyMap()->getByName(rPropertyName);
+ if (!pEntry)
+ {
+ beans::UnknownPropertyException aExcept;
+ aExcept.Message = C2U("Unknown property: ");
+ aExcept.Message += rPropertyName;
+ throw aExcept;
+ }
+
+ uno::Any aRet;
+ switch (pEntry->nWID)
+ {
+// no code necessary - the redline is always located at the end node
+// case FN_UNO_REDLINE_NODE_START:
+// break;
+ case FN_UNO_REDLINE_NODE_END:
+ {
+ const SwRedlineTbl& rRedTbl = GetDoc()->GetRedlineTbl();
+ const sal_uInt16 nRedTblCount = rRedTbl.Count();
+ if (nRedTblCount > 0)
+ {
+ SwStartNode const*const pStartNode = GetStartNode();
+ const sal_uLong nOwnIndex = pStartNode->EndOfSectionIndex();
+ for (sal_uInt16 nRed = 0; nRed < nRedTblCount; nRed++)
+ {
+ SwRedline const*const pRedline = rRedTbl[nRed];
+ SwPosition const*const pRedStart = pRedline->Start();
+ const SwNodeIndex nRedNode = pRedStart->nNode;
+ if (nOwnIndex == nRedNode.GetIndex())
+ {
+ aRet <<= SwXRedlinePortion::CreateRedlineProperties(
+ *pRedline, sal_True);
+ break;
+ }
+ }
+ }
+ }
+ break;
+ }
+ return aRet;
+}
+
+/*-- 15.03.2002 12:30:42---------------------------------------------------
+
+ -----------------------------------------------------------------------*/
+void SAL_CALL
+SwXText::addPropertyChangeListener(
+ const ::rtl::OUString& /*rPropertyName*/,
+ const uno::Reference< beans::XPropertyChangeListener >& /*xListener*/)
+throw (beans::UnknownPropertyException, lang::WrappedTargetException,
+ uno::RuntimeException)
+{
+ OSL_ENSURE(false,
+ "SwXText::addPropertyChangeListener(): not implemented");
+}
+/*-- 15.03.2002 12:30:43---------------------------------------------------
+
+ -----------------------------------------------------------------------*/
+void SAL_CALL
+SwXText::removePropertyChangeListener(
+ const ::rtl::OUString& /*rPropertyName*/,
+ const uno::Reference< beans::XPropertyChangeListener >& /*xListener*/)
+throw (beans::UnknownPropertyException, lang::WrappedTargetException,
+ uno::RuntimeException)
+{
+ OSL_ENSURE(false,
+ "SwXText::removePropertyChangeListener(): not implemented");
+}
+/*-- 15.03.2002 12:30:43---------------------------------------------------
+
+ -----------------------------------------------------------------------*/
+void SAL_CALL
+SwXText::addVetoableChangeListener(
+ const ::rtl::OUString& /*rPropertyName*/,
+ const uno::Reference< beans::XVetoableChangeListener >& /*xListener*/)
+throw (beans::UnknownPropertyException, lang::WrappedTargetException,
+ uno::RuntimeException)
+{
+ OSL_ENSURE(false,
+ "SwXText::addVetoableChangeListener(): not implemented");
+}
+/*-- 15.03.2002 12:30:43---------------------------------------------------
+
+ -----------------------------------------------------------------------*/
+void SAL_CALL
+SwXText::removeVetoableChangeListener(
+ const ::rtl::OUString& /*rPropertyName*/,
+ const uno::Reference< beans::XVetoableChangeListener >& /*xListener*/)
+throw (beans::UnknownPropertyException, lang::WrappedTargetException,
+ uno::RuntimeException)
+{
+ OSL_ENSURE(false,
+ "SwXText::removeVetoableChangeListener(): not implemented");
+}
+
+/* -----------------------------08.01.01 09:07--------------------------------
+
+ ---------------------------------------------------------------------------*/
+const uno::Sequence< sal_Int8 > & SwXText::getUnoTunnelId()
+{
+ static uno::Sequence< sal_Int8 > aSeq = ::CreateUnoTunnelId();
+ return aSeq;
+}
+/* -----------------------------08.01.01 09:07--------------------------------
+
+ ---------------------------------------------------------------------------*/
+sal_Int64 SAL_CALL
+SwXText::getSomething(const uno::Sequence< sal_Int8 >& rId)
+throw (uno::RuntimeException)
+{
+ return ::sw::UnoTunnelImpl<SwXText>(rId, this);
+}
+
+/*-- 23.06.2006 08:56:30---------------------------------------------------
+
+ -----------------------------------------------------------------------*/
+uno::Reference< text::XTextRange > SAL_CALL
+SwXText::appendParagraph(
+ const uno::Sequence< beans::PropertyValue > & rProperties)
+throw (lang::IllegalArgumentException, uno::RuntimeException)
+{
+ vos::OGuard g(Application::GetSolarMutex());
+
+ return m_pImpl->finishOrAppendParagraph(false, rProperties);
+}
+/*-- 23.06.2006 08:56:22---------------------------------------------------
+
+ -----------------------------------------------------------------------*/
+uno::Reference< text::XTextRange > SAL_CALL
+SwXText::finishParagraph(
+ const uno::Sequence< beans::PropertyValue > & rProperties)
+throw (lang::IllegalArgumentException, uno::RuntimeException)
+{
+ vos::OGuard g(Application::GetSolarMutex());
+
+ return m_pImpl->finishOrAppendParagraph(true, rProperties);
+}
+
+/*-- 08.05.2006 13:26:26---------------------------------------------------
+
+ -----------------------------------------------------------------------*/
+uno::Reference< text::XTextRange >
+SwXText::Impl::finishOrAppendParagraph(
+ const bool bFinish,
+ const uno::Sequence< beans::PropertyValue > & rProperties)
+throw (lang::IllegalArgumentException, uno::RuntimeException)
+{
+ if (!m_bIsValid)
+ {
+ throw uno::RuntimeException();
+ }
+
+ const SwStartNode* pStartNode = m_rThis.GetStartNode();
+ if(!pStartNode)
+ {
+ throw uno::RuntimeException();
+ }
+
+ uno::Reference< text::XTextRange > xRet;
+ bool bIllegalException = false;
+ bool bRuntimeException = false;
+ ::rtl::OUString sMessage;
+ m_pDoc->GetIDocumentUndoRedo().StartUndo(UNDO_START , NULL);
+ // find end node, go backward - don't skip tables because the new
+ // paragraph has to be the last node
+ //aPam.Move( fnMoveBackward, fnGoNode );
+ SwPosition aInsertPosition(
+ SwNodeIndex( *pStartNode->EndOfSectionNode(), -1 ) );
+ SwPaM aPam(aInsertPosition);
+ m_pDoc->AppendTxtNode( *aPam.GetPoint() );
+ // remove attributes from the previous paragraph
+ m_pDoc->ResetAttrs(aPam);
+ // in case of finishParagraph the PaM needs to be moved to the
+ // previous paragraph
+ if (bFinish)
+ {
+ aPam.Move( fnMoveBackward, fnGoNode );
+ }
+ if (rProperties.getLength())
+ {
+ // now set the properties
+ SfxItemPropertySet const*const pParaPropSet =
+ aSwMapProvider.GetPropertySet(PROPERTY_MAP_PARAGRAPH);
+ SfxItemPropertyMap const*const pParagraphMap =
+ pParaPropSet->getPropertyMap();
+
+ const beans::PropertyValue* pValues = rProperties.getConstArray();
+
+ for (sal_Int32 nProp = 0; nProp < rProperties.getLength(); ++nProp)
+ {
+ if (!pParagraphMap->getByName(pValues[nProp].Name))
+ {
+ bIllegalException = true;
+ break;
+ }
+ try
+ {
+ SwUnoCursorHelper::SetPropertyValue(aPam, *pParaPropSet,
+ pValues[nProp].Name, pValues[nProp].Value);
+ }
+ catch (lang::IllegalArgumentException& rIllegal)
+ {
+ sMessage = rIllegal.Message;
+ bIllegalException = true;
+ break;
+ }
+ catch (uno::RuntimeException& rRuntime)
+ {
+ sMessage = rRuntime.Message;
+ bRuntimeException = true;
+ break;
+ }
+ }
+ }
+ m_pDoc->GetIDocumentUndoRedo().EndUndo(UNDO_END, NULL);
+ if (bIllegalException || bRuntimeException)
+ {
+ m_pDoc->GetIDocumentUndoRedo().Undo();
+ if (bIllegalException)
+ {
+ lang::IllegalArgumentException aEx;
+ aEx.Message = sMessage;
+ throw aEx;
+ }
+ else // if(bRuntimeException)
+ {
+ uno::RuntimeException aEx;
+ aEx.Message = sMessage;
+ throw aEx;
+ }
+ }
+ SwTxtNode *const pTxtNode( aPam.Start()->nNode.GetNode().GetTxtNode() );
+ OSL_ENSURE(pTxtNode, "no SwTxtNode?");
+ if (pTxtNode)
+ {
+ xRet.set(SwXParagraph::CreateXParagraph(*m_pDoc, *pTxtNode, &m_rThis),
+ uno::UNO_QUERY);
+ }
+
+ return xRet;
+}
+
+/*-- 08.05.2006 13:28:26---------------------------------------------------
+ Append text portions at the end of the last paragraph of the text
+ interface. Support of import filters.
+ -----------------------------------------------------------------------*/
+uno::Reference< text::XTextRange > SAL_CALL
+SwXText::appendTextPortion(
+ const ::rtl::OUString& rText,
+ const uno::Sequence< beans::PropertyValue > &
+ rCharacterAndParagraphProperties)
+throw (lang::IllegalArgumentException, uno::RuntimeException)
+{
+ vos::OGuard aGuard(Application::GetSolarMutex());
+
+ if(!IsValid())
+ {
+ throw uno::RuntimeException();
+ }
+ uno::Reference< text::XTextRange > xRet;
+ const uno::Reference< text::XTextCursor > xTextCursor = CreateCursor();
+ xTextCursor->gotoEnd(sal_False);
+
+ const uno::Reference< lang::XUnoTunnel > xRangeTunnel(
+ xTextCursor, uno::UNO_QUERY_THROW );
+ SwXTextCursor *const pTextCursor =
+ ::sw::UnoTunnelGetImplementation<SwXTextCursor>(xRangeTunnel);
+
+ bool bIllegalException = false;
+ bool bRuntimeException = false;
+ ::rtl::OUString sMessage;
+ m_pImpl->m_pDoc->GetIDocumentUndoRedo().StartUndo(UNDO_INSERT, NULL);
+
+// SwPaM aPam(*pStartNode->EndOfSectionNode());
+ //aPam.Move( fnMoveBackward, fnGoNode );
+ SwUnoCrsr *const pCursor = pTextCursor->GetCursor();
+ pCursor->MovePara( fnParaCurr, fnParaEnd );
+ m_pImpl->m_pDoc->DontExpandFmt( *pCursor->Start() );
+
+ if (rText.getLength())
+ {
+ const xub_StrLen nContentPos = pCursor->GetPoint()->nContent.GetIndex();
+ SwUnoCursorHelper::DocInsertStringSplitCR(
+ *m_pImpl->m_pDoc, *pCursor, rText, false);
+ SwUnoCursorHelper::SelectPam(*pCursor, true);
+ pCursor->GetPoint()->nContent = nContentPos;
+ }
+
+ if (rCharacterAndParagraphProperties.getLength())
+ {
+ SfxItemPropertyMap const*const pCursorMap =
+ aSwMapProvider.GetPropertySet(PROPERTY_MAP_TEXT_CURSOR)
+ ->getPropertyMap();
+ beans::PropertyValue const*const pValues =
+ rCharacterAndParagraphProperties.getConstArray();
+ SfxItemPropertySet const*const pCursorPropSet =
+ aSwMapProvider.GetPropertySet(PROPERTY_MAP_TEXT_CURSOR);
+ const sal_Int32 nLen(rCharacterAndParagraphProperties.getLength());
+ for (sal_Int32 nProp = 0; nProp < nLen; ++nProp)
+ {
+ if (!pCursorMap->getByName( pValues[nProp].Name ))
+ {
+ bIllegalException = true;
+ break;
+ }
+ try
+ {
+ SwUnoCursorHelper::SetPropertyValue(
+ *pCursor, *pCursorPropSet,
+ pValues[nProp].Name, pValues[nProp].Value,
+ nsSetAttrMode::SETATTR_NOFORMATATTR);
+ }
+ catch( lang::IllegalArgumentException& rIllegal )
+ {
+ sMessage = rIllegal.Message;
+ bIllegalException = true;
+ break;
+ }
+ catch( uno::RuntimeException& rRuntime )
+ {
+ sMessage = rRuntime.Message;
+ bRuntimeException = true;
+ break;
+ }
+ }
+ }
+ m_pImpl->m_pDoc->GetIDocumentUndoRedo().EndUndo(UNDO_INSERT, NULL);
+ if (bIllegalException || bRuntimeException)
+ {
+ m_pImpl->m_pDoc->GetIDocumentUndoRedo().Undo();
+ if (bIllegalException)
+ {
+ lang::IllegalArgumentException aEx;
+ aEx.Message = sMessage;
+ throw aEx;
+ }
+ else //if(bRuntimeException)
+ {
+ uno::RuntimeException aEx;
+ aEx.Message = sMessage;
+ throw aEx;
+ }
+ }
+ xRet = new SwXTextRange(*pCursor, this);
+ return xRet;
+}
+
+/*-- 11.05.2006 15:46:26---------------------------------------------------
+ enable appending text contents like graphic objects, shapes and so on
+ to support import filters
+ -----------------------------------------------------------------------*/
+uno::Reference< text::XTextRange > SAL_CALL
+SwXText::appendTextContent(
+ const uno::Reference< text::XTextContent >& xTextContent,
+ const uno::Sequence< beans::PropertyValue >&
+ rCharacterAndParagraphProperties)
+throw (lang::IllegalArgumentException, uno::RuntimeException)
+{
+ vos::OGuard aGuard(Application::GetSolarMutex());
+
+ if (!IsValid())
+ {
+ throw uno::RuntimeException();
+ }
+ SwStartNode const*const pStartNode = GetStartNode();
+ if(!pStartNode)
+ {
+ throw uno::RuntimeException();
+ }
+
+ uno::Reference< text::XTextRange > xRet;
+ m_pImpl->m_pDoc->GetIDocumentUndoRedo().StartUndo(UNDO_INSERT, NULL);
+ // find end node, go backward - don't skip tables because the
+ // new paragraph has to be the last node
+ SwPaM aPam(*pStartNode->EndOfSectionNode());
+ aPam.Move( fnMoveBackward, fnGoNode );
+ // set cursor to the end of the last text node
+ SwCursor aCursor( *aPam.Start(), 0, false );
+ xRet = new SwXTextRange(aCursor, this);
+ aCursor.MovePara( fnParaCurr, fnParaEnd );
+ m_pImpl->m_pDoc->DontExpandFmt( *aCursor.Start() );
+ // now attach the text content here
+ insertTextContent( xRet, xTextContent, false );
+ // now apply the properties to the anchor
+ if (rCharacterAndParagraphProperties.getLength())
+ {
+ try
+ {
+ const sal_Int32 nLen(rCharacterAndParagraphProperties.getLength());
+ const uno::Reference< beans::XPropertySet > xAnchor(
+ xTextContent->getAnchor(), uno::UNO_QUERY);
+ if (xAnchor.is())
+ {
+ for (sal_Int32 nElement = 0; nElement < nLen; ++nElement)
+ {
+ xAnchor->setPropertyValue(
+ rCharacterAndParagraphProperties[nElement].Name,
+ rCharacterAndParagraphProperties[nElement].Value);
+ }
+ }
+ }
+ catch (const uno::Exception&)
+ {
+ throw uno::RuntimeException();
+ }
+ }
+ m_pImpl->m_pDoc->GetIDocumentUndoRedo().EndUndo(UNDO_INSERT, NULL);
+ return xRet;
+}
+
+// move previously appended paragraphs into a text frames
+// to support import filters
+uno::Reference< text::XTextContent > SAL_CALL
+SwXText::convertToTextFrame(
+ const uno::Reference< text::XTextRange >& xStart,
+ const uno::Reference< text::XTextRange >& xEnd,
+ const uno::Sequence< beans::PropertyValue >& rFrameProperties)
+throw (lang::IllegalArgumentException, uno::RuntimeException)
+{
+ vos::OGuard aGuard(Application::GetSolarMutex());
+
+ if(!IsValid())
+ {
+ throw uno::RuntimeException();
+ }
+ uno::Reference< text::XTextContent > xRet;
+ SwUnoInternalPaM aStartPam(*GetDoc());
+ std::auto_ptr< SwUnoInternalPaM > pEndPam(new SwUnoInternalPaM(*GetDoc()));
+ if (!::sw::XTextRangeToSwPaM(aStartPam, xStart) ||
+ !::sw::XTextRangeToSwPaM(*pEndPam, xEnd))
+ {
+ throw lang::IllegalArgumentException();
+ }
+
+ const uno::Reference<lang::XUnoTunnel> xStartRangeTunnel(xStart,
+ uno::UNO_QUERY);
+ SwXTextRange *const pStartRange =
+ ::sw::UnoTunnelGetImplementation<SwXTextRange>(xStartRangeTunnel);
+ const uno::Reference<lang::XUnoTunnel> xEndRangeTunnel(xEnd,
+ uno::UNO_QUERY);
+ SwXTextRange *const pEndRange =
+ ::sw::UnoTunnelGetImplementation<SwXTextRange>(xEndRangeTunnel);
+ // bookmarks have to be removed before the referenced text node
+ // is deleted in DelFullPara
+ if (pStartRange)
+ {
+ pStartRange->Invalidate();
+ }
+ if (pEndRange)
+ {
+ pEndRange->Invalidate();
+ }
+
+ m_pImpl->m_pDoc->GetIDocumentUndoRedo().StartUndo( UNDO_START, NULL );
+ bool bIllegalException = false;
+ bool bRuntimeException = false;
+ ::rtl::OUString sMessage;
+ SwStartNode* pStartStartNode = aStartPam.GetNode()->StartOfSectionNode();
+ while (pStartStartNode && pStartStartNode->IsSectionNode())
+ {
+ pStartStartNode = pStartStartNode->StartOfSectionNode();
+ }
+ SwStartNode* pEndStartNode = pEndPam->GetNode()->StartOfSectionNode();
+ while (pEndStartNode && pEndStartNode->IsSectionNode())
+ {
+ pEndStartNode = pEndStartNode->StartOfSectionNode();
+ }
+ bool bParaAfterInserted = false;
+ bool bParaBeforeInserted = false;
+ if (pStartStartNode != pEndStartNode || pStartStartNode != GetStartNode())
+ {
+ // todo: if the start/end is in a table then insert a paragraph
+ // before/after, move the start/end nodes, then convert and
+ // remove the addtional paragraphs in the end
+ if (pStartStartNode->GetStartNodeType() == SwTableBoxStartNode)
+ {
+ SwTableNode *const pSartTableNode(pStartStartNode->FindTableNode());
+ const SwNodeIndex aTblIdx( *pSartTableNode, -1 );
+ SwPosition aBefore(aTblIdx);
+ bParaBeforeInserted = GetDoc()->AppendTxtNode( aBefore );
+ aStartPam.DeleteMark();
+ *aStartPam.GetPoint() = aBefore;
+ pStartStartNode = aStartPam.GetNode()->StartOfSectionNode();
+ }
+ if (pEndStartNode->GetStartNodeType() == SwTableBoxStartNode)
+ {
+ SwTableNode *const pEndTableNode = pEndStartNode->FindTableNode();
+ SwEndNode *const pTableEnd = pEndTableNode->EndOfSectionNode();
+ SwPosition aTableEnd(*pTableEnd);
+ bParaAfterInserted = GetDoc()->AppendTxtNode( aTableEnd );
+ pEndPam->DeleteMark();
+ *pEndPam->GetPoint() = aTableEnd;
+ pEndStartNode = pEndPam->GetNode()->StartOfSectionNode();
+ }
+ // now we should have the positions in the same hierarchy
+ if ((pStartStartNode != pEndStartNode) ||
+ (pStartStartNode != GetStartNode()))
+ {
+ // if not - remove the additional paragraphs and throw
+ if (bParaBeforeInserted)
+ {
+ SwCursor aDelete(*aStartPam.GetPoint(), 0, false);
+ aDelete.MovePara(fnParaCurr, fnParaStart);
+ aDelete.SetMark();
+ aDelete.MovePara(fnParaCurr, fnParaEnd);
+ GetDoc()->DelFullPara(aDelete);
+ }
+ if (bParaAfterInserted)
+ {
+ SwCursor aDelete(*pEndPam->GetPoint(), 0, false);
+ aDelete.MovePara(fnParaCurr, fnParaStart);
+ aDelete.SetMark();
+ aDelete.MovePara(fnParaCurr, fnParaEnd);
+ GetDoc()->DelFullPara(aDelete);
+ }
+ throw lang::IllegalArgumentException();
+ }
+ }
+
+ // make a selection from aStartPam to a EndPam
+ SwSelBoxes aBoxes;
+ SfxItemSet aFrameItemSet(m_pImpl->m_pDoc->GetAttrPool(),
+ RES_FRMATR_BEGIN, RES_FRMATR_END-1,
+ 0 );
+
+ aStartPam.SetMark();
+ *aStartPam.End() = *pEndPam->End();
+ pEndPam.reset(0);
+
+ SwXTextFrame *const pNewFrame = new SwXTextFrame(m_pImpl->m_pDoc);
+ const uno::Reference< text::XTextFrame > xNewFrame = pNewFrame;
+ pNewFrame->SetSelection( aStartPam );
+ try
+ {
+ const beans::PropertyValue* pValues = rFrameProperties.getConstArray();
+ for (sal_Int32 nProp = 0; nProp < rFrameProperties.getLength(); ++nProp)
+ {
+ pNewFrame->SwXFrame::setPropertyValue(
+ pValues[nProp].Name, pValues[nProp].Value);
+ }
+
+ { // has to be in a block to remove the SwIndexes before
+ // DelFullPara is called
+ const uno::Reference< text::XTextRange> xInsertTextRange =
+ new SwXTextRange(aStartPam, this);
+ pNewFrame->attach( xInsertTextRange );
+ pNewFrame->setName(m_pImpl->m_pDoc->GetUniqueFrameName());
+ }
+
+ if (!aStartPam.GetTxt().Len())
+ {
+ bool bMoved = false;
+ { // has to be in a block to remove the SwIndexes before
+ // DelFullPara is called
+ SwPaM aMovePam( *aStartPam.GetNode() );
+ if (aMovePam.Move( fnMoveForward, fnGoCntnt ))
+ {
+ // move the anchor to the next paragraph
+ SwFmtAnchor aNewAnchor(pNewFrame->GetFrmFmt()->GetAnchor());
+ aNewAnchor.SetAnchor( aMovePam.Start() );
+ m_pImpl->m_pDoc->SetAttr(
+ aNewAnchor, *pNewFrame->GetFrmFmt() );
+ }
+ bMoved = true;
+ }
+ if (bMoved)
+ {
+ aStartPam.DeleteMark();
+// SwPaM aDelPam( *aStartPam.GetNode() );
+ m_pImpl->m_pDoc->DelFullPara(aStartPam/*aDelPam*/);
+ }
+ }
+ }
+ catch (lang::IllegalArgumentException& rIllegal)
+ {
+ sMessage = rIllegal.Message;
+ bIllegalException = true;
+ }
+ catch (uno::RuntimeException& rRuntime)
+ {
+ sMessage = rRuntime.Message;
+ bRuntimeException = true;
+ }
+ xRet = pNewFrame;
+ if (bParaBeforeInserted || bParaAfterInserted)
+ {
+ const uno::Reference<text::XTextCursor> xFrameTextCursor =
+ pNewFrame->createTextCursor();
+ const uno::Reference<XUnoTunnel> xTunnel(xFrameTextCursor,
+ uno::UNO_QUERY);
+ SwXTextCursor *const pFrameCursor =
+ ::sw::UnoTunnelGetImplementation<SwXTextCursor>(xTunnel);
+ if (bParaBeforeInserted)
+ {
+ // todo: remove paragraph before frame
+ m_pImpl->m_pDoc->DelFullPara(*pFrameCursor->GetPaM());
+ }
+ if (bParaAfterInserted)
+ {
+ xFrameTextCursor->gotoEnd(sal_False);
+ m_pImpl->m_pDoc->DelFullPara(*pFrameCursor->GetPaM());
+ }
+ }
+
+ m_pImpl->m_pDoc->GetIDocumentUndoRedo().EndUndo(UNDO_END, NULL);
+ if (bIllegalException || bRuntimeException)
+ {
+ m_pImpl->m_pDoc->GetIDocumentUndoRedo().Undo();
+ if (bIllegalException)
+ {
+ lang::IllegalArgumentException aEx;
+ aEx.Message = sMessage;
+ throw aEx;
+ }
+ else //if(bRuntimeException)
+ {
+ uno::RuntimeException aEx;
+ aEx.Message = sMessage;
+ throw aEx;
+ }
+ }
+ return xRet;
+}
+
+/*-- 11.05.2006 15:46:26---------------------------------------------------
+ Move previously imported paragraphs into a new text table.
+
+ -----------------------------------------------------------------------*/
+struct VerticallyMergedCell
+{
+ std::vector<uno::Reference< beans::XPropertySet > > aCells;
+ sal_Int32 nLeftPosition;
+ bool bOpen;
+
+ VerticallyMergedCell(uno::Reference< beans::XPropertySet > const& rxCell,
+ const sal_Int32 nLeft)
+ : nLeftPosition( nLeft )
+ , bOpen( true )
+ {
+ aCells.push_back( rxCell );
+ }
+};
+#define COL_POS_FUZZY 2
+static bool lcl_SimilarPosition( const sal_Int32 nPos1, const sal_Int32 nPos2 )
+{
+ return abs( nPos1 - nPos2 ) < COL_POS_FUZZY;
+}
+
+void SwXText::copyText(
+ const uno::Reference< text::XTextCopy >& xSource )
+ throw ( uno::RuntimeException )
+{
+ uno::Reference< lang::XUnoTunnel > xTTunnel( xSource, uno::UNO_QUERY_THROW );
+ SwXText* pText = 0;
+ pText = reinterpret_cast< SwXText* >(
+ sal::static_int_cast< sal_IntPtr >( xTTunnel->getSomething( SwXText::getUnoTunnelId()) ));
+
+ uno::Reference< text::XText > xText( xSource, uno::UNO_QUERY_THROW );
+ uno::Reference< text::XTextCursor > xCursor = xText->createTextCursor( );
+ xCursor->gotoEnd( sal_True );
+
+ uno::Reference< lang::XUnoTunnel > xTunnel( xCursor, uno::UNO_QUERY_THROW );
+
+ OTextCursorHelper* pCursor = 0;
+ pCursor = reinterpret_cast< OTextCursorHelper* >(
+ sal::static_int_cast< sal_IntPtr >( xTunnel->getSomething( OTextCursorHelper::getUnoTunnelId()) ));
+ if ( pCursor )
+ {
+ SwNodeIndex rNdIndex( *GetStartNode( ), 1 );
+ SwPosition rPos( rNdIndex );
+ m_pImpl->m_pDoc->CopyRange( *pCursor->GetPaM( ), rPos, false );
+ }
+}
+
+void SwXText::Impl::ConvertCell(
+ const bool bFirstCell,
+ const uno::Sequence< uno::Reference< text::XTextRange > > & rCell,
+ ::std::vector<SwNodeRange> & rRowNodes,
+ ::std::auto_ptr< SwPaM > & rpFirstPaM,
+ SwPaM & rLastPaM,
+ bool & rbExcept)
+{
+ if (rCell.getLength() != 2)
+ {
+ throw lang::IllegalArgumentException();
+ }
+ const uno::Reference<text::XTextRange> xStartRange = rCell[0];
+ const uno::Reference<text::XTextRange> xEndRange = rCell[1];
+ SwUnoInternalPaM aStartCellPam(*m_pDoc);
+ SwUnoInternalPaM aEndCellPam(*m_pDoc);
+
+ // !!! TODO - PaMs in tables and sections do not work here -
+ // the same applies to PaMs in frames !!!
+
+ if (!::sw::XTextRangeToSwPaM(aStartCellPam, xStartRange) ||
+ !::sw::XTextRangeToSwPaM(aEndCellPam, xEndRange))
+ {
+ throw lang::IllegalArgumentException();
+ }
+
+ SwNodeRange aTmpRange(aStartCellPam.Start()->nNode,
+ aEndCellPam.End()->nNode);
+ SwNodeRange * pCorrectedRange =
+ m_pDoc->GetNodes().ExpandRangeForTableBox(aTmpRange);
+
+ if (pCorrectedRange != NULL)
+ {
+ SwPaM aNewStartPaM(pCorrectedRange->aStart, 0);
+ aStartCellPam = aNewStartPaM;
+
+ xub_StrLen nEndLen = 0;
+ SwTxtNode * pTxtNode = pCorrectedRange->aEnd.GetNode().GetTxtNode();
+ if (pTxtNode != NULL)
+ nEndLen = pTxtNode->Len();
+
+ SwPaM aNewEndPaM(pCorrectedRange->aEnd, nEndLen);
+ aEndCellPam = aNewEndPaM;
+ }
+
+ /** check the nodes between start and end
+ it is allowed to have pairs of StartNode/EndNodes
+ */
+ if (aStartCellPam.Start()->nNode < aEndCellPam.End()->nNode)
+ {
+ // increment on each StartNode and decrement on each EndNode
+ // we must reach zero at the end and must not go below zero
+ long nOpenNodeBlock = 0;
+ SwNodeIndex aCellIndex = aStartCellPam.Start()->nNode;
+ while (aCellIndex < aEndCellPam.End()->nNode.GetIndex())
+ {
+ if (aCellIndex.GetNode().IsStartNode())
+ {
+ ++nOpenNodeBlock;
+ }
+ else if (aCellIndex.GetNode().IsEndNode())
+ {
+ --nOpenNodeBlock;
+ }
+ if (nOpenNodeBlock < 0)
+ {
+ rbExcept = true;
+ break;
+ }
+ ++aCellIndex;
+ }
+ if (nOpenNodeBlock != 0)
+ {
+ rbExcept = true;
+ return;
+ }
+ }
+
+ /** The vector<vector> NodeRanges has to contain consecutive nodes.
+ In rTableRanges the ranges don't need to be full paragraphs but
+ they have to follow each other. To process the ranges they
+ have to be aligned on paragraph borders by inserting paragraph
+ breaks. Non-consecutive ranges must initiate an exception.
+ */
+ if (bFirstCell)
+ {
+ // align the beginning - if necessary
+ if (aStartCellPam.Start()->nContent.GetIndex())
+ {
+ m_pDoc->SplitNode(*aStartCellPam.Start(), sal_False);
+ }
+ }
+ else
+ {
+ // check the predecessor
+ const sal_uLong nLastNodeIndex = rLastPaM.End()->nNode.GetIndex();
+ const sal_uLong nStartCellNodeIndex =
+ aStartCellPam.Start()->nNode.GetIndex();
+ const sal_uLong nLastNodeEndIndex = rLastPaM.End()->nNode.GetIndex();
+ if (nLastNodeIndex == nStartCellNodeIndex)
+ {
+ // same node as predecessor then equal nContent?
+ if (rLastPaM.End()->nContent != aStartCellPam.Start()->nContent)
+ {
+ rbExcept = true;
+ }
+ else
+ {
+ m_pDoc->SplitNode(*aStartCellPam.Start(), sal_False);
+ }
+ }
+ else if (nStartCellNodeIndex == (nLastNodeEndIndex + 1))
+ {
+ // next paragraph - now the content index of the new should be 0
+ // and of the old one should be equal to the text length
+ // but if it isn't we don't care - the cell is being inserted on
+ // the node border anyway
+ }
+ else
+ {
+ rbExcept = true;
+ }
+ }
+ // now check if there's a need to insert another paragraph break
+ if (aEndCellPam.End()->nContent.GetIndex() <
+ aEndCellPam.End()->nNode.GetNode().GetTxtNode()->Len())
+ {
+ m_pDoc->SplitNode(*aEndCellPam.End(), sal_False);
+ // take care that the new start/endcell is moved to the right position
+ // aStartCellPam has to point to the start of the new (previous) node
+ // aEndCellPam has to point to the end of the new (previous) node
+ aStartCellPam.DeleteMark();
+ aStartCellPam.Move(fnMoveBackward, fnGoNode);
+ aStartCellPam.GetPoint()->nContent = 0;
+ aEndCellPam.DeleteMark();
+ aEndCellPam.Move(fnMoveBackward, fnGoNode);
+ aEndCellPam.GetPoint()->nContent =
+ aEndCellPam.GetNode()->GetTxtNode()->Len();
+ }
+
+ *rLastPaM.GetPoint() = *aEndCellPam.Start();
+ if (aStartCellPam.HasMark())
+ {
+ rLastPaM.SetMark();
+ *rLastPaM.GetMark() = *aEndCellPam.End();
+ }
+ else
+ {
+ rLastPaM.DeleteMark();
+ }
+
+ SwNodeRange aCellRange(aStartCellPam.Start()->nNode,
+ aEndCellPam.End()->nNode);
+ rRowNodes.push_back(aCellRange);
+ if (bFirstCell)
+ {
+ rpFirstPaM.reset(new SwPaM(*aStartCellPam.Start()));
+ }
+}
+
+typedef uno::Sequence< text::TableColumnSeparator > TableColumnSeparators;
+
+static void
+lcl_ApplyRowProperties(
+ uno::Sequence<beans::PropertyValue> const& rRowProperties,
+ uno::Any const& rRow,
+ TableColumnSeparators & rRowSeparators)
+{
+ uno::Reference< beans::XPropertySet > xRow;
+ rRow >>= xRow;
+ const beans::PropertyValue* pProperties = rRowProperties.getConstArray();
+ for (sal_Int32 nProperty = 0; nProperty < rRowProperties.getLength();
+ ++nProperty)
+ {
+ if (pProperties[ nProperty ].Name.equalsAsciiL(
+ RTL_CONSTASCII_STRINGPARAM("TableColumnSeparators")))
+ {
+ // add the separators to access the cell's positions
+ // for vertical merging later
+ TableColumnSeparators aSeparators;
+ pProperties[ nProperty ].Value >>= aSeparators;
+ rRowSeparators = aSeparators;
+ }
+ xRow->setPropertyValue(
+ pProperties[ nProperty ].Name, pProperties[ nProperty ].Value);
+ }
+}
+
+#ifdef DEBUG
+//-->debug cell properties of all rows
+static void
+lcl_DebugCellProperties(
+ const uno::Sequence< uno::Sequence< uno::Sequence<
+ beans::PropertyValue > > >& rCellProperties)
+{
+ ::rtl::OUString sNames;
+ for (sal_Int32 nDebugRow = 0; nDebugRow < rCellProperties.getLength();
+ ++nDebugRow)
+ {
+ const uno::Sequence< beans::PropertyValues > aDebugCurrentRow =
+ rCellProperties[nDebugRow];
+ sal_Int32 nDebugCells = aDebugCurrentRow.getLength();
+ (void) nDebugCells;
+ for (sal_Int32 nDebugCell = 0; nDebugCell < nDebugCells;
+ ++nDebugCell)
+ {
+ const uno::Sequence< beans::PropertyValue >&
+ rDebugCellProperties = aDebugCurrentRow[nDebugCell];
+ const sal_Int32 nDebugCellProperties =
+ rDebugCellProperties.getLength();
+ for (sal_Int32 nDebugProperty = 0;
+ nDebugProperty < nDebugCellProperties; ++nDebugProperty)
+ {
+ const ::rtl::OUString sName =
+ rDebugCellProperties[nDebugProperty].Name;
+ sNames += sName;
+ sNames += ::rtl::OUString('-');
+ }
+ sNames += ::rtl::OUString('+');
+ }
+ sNames += ::rtl::OUString('|');
+ }
+ (void)sNames;
+}
+//--<
+#endif
+
+
+static void
+lcl_ApplyCellProperties(
+ const sal_Int32 nCell,
+ TableColumnSeparators const& rRowSeparators,
+ const uno::Sequence< beans::PropertyValue >& rCellProperties,
+ uno::Reference< uno::XInterface > xCell,
+ ::std::vector<VerticallyMergedCell> & rMergedCells)
+{
+ const sal_Int32 nCellProperties = rCellProperties.getLength();
+ const uno::Reference< beans::XPropertySet > xCellPS(xCell, uno::UNO_QUERY);
+ for (sal_Int32 nProperty = 0; nProperty < nCellProperties; ++nProperty)
+ {
+ const OUString & rName = rCellProperties[nProperty].Name;
+ const uno::Any & rValue = rCellProperties[nProperty].Value;
+ if (rName.equalsAscii("VerticalMerge"))
+ {
+ // determine left border position
+ // add the cell to a queue of merged cells
+ sal_Bool bMerge = sal_False;
+ rValue >>= bMerge;
+ sal_Int32 nLeftPos = -1;
+ if (!nCell)
+ {
+ nLeftPos = 0;
+ }
+ else if (rRowSeparators.getLength() >= nCell)
+ {
+ const text::TableColumnSeparator* pSeparators =
+ rRowSeparators.getConstArray();
+ nLeftPos = pSeparators[nCell - 1].Position;
+ }
+ if (bMerge)
+ {
+ // 'close' all the cell with the same left position
+ // if separate vertical merges in the same column exist
+ if (rMergedCells.size())
+ {
+ std::vector<VerticallyMergedCell>::iterator aMergedIter =
+ rMergedCells.begin();
+ while (aMergedIter != rMergedCells.end())
+ {
+ if (lcl_SimilarPosition(aMergedIter->nLeftPosition,
+ nLeftPos))
+ {
+ aMergedIter->bOpen = false;
+ }
+ ++aMergedIter;
+ }
+ }
+ // add the new group of merged cells
+ rMergedCells.push_back(VerticallyMergedCell(xCellPS, nLeftPos));
+ }
+ else
+ {
+ // find the cell that
+ DBG_ASSERT(rMergedCells.size(),
+ "the first merged cell is missing");
+ if (rMergedCells.size())
+ {
+ std::vector<VerticallyMergedCell>::iterator aMergedIter =
+ rMergedCells.begin();
+#if OSL_DEBUG_LEVEL > 1
+ bool bDbgFound = false;
+#endif
+ while (aMergedIter != rMergedCells.end())
+ {
+ if (aMergedIter->bOpen &&
+ lcl_SimilarPosition(aMergedIter->nLeftPosition,
+ nLeftPos))
+ {
+ aMergedIter->aCells.push_back( xCellPS );
+#if OSL_DEBUG_LEVEL > 1
+ bDbgFound = true;
+#endif
+ }
+ ++aMergedIter;
+ }
+#if OSL_DEBUG_LEVEL > 1
+ DBG_ASSERT( bDbgFound,
+ "couldn't find first vertically merged cell" );
+#endif
+ }
+ }
+ }
+ else
+ {
+ try
+ {
+ xCellPS->setPropertyValue(rName, rValue);
+ }
+ catch (uno::Exception const& e)
+ {
+ // Apply the paragraph and char properties to the cell's content
+ const uno::Reference< text::XText > xCellText(xCell,
+ uno::UNO_QUERY);
+ const uno::Reference< text::XTextCursor > xCellCurs =
+ xCellText->createTextCursor();
+ xCellCurs->gotoStart( sal_False );
+ xCellCurs->gotoEnd( sal_True );
+ const uno::Reference< beans::XPropertySet > xCellTextProps(
+ xCellCurs, uno::UNO_QUERY);
+ xCellTextProps->setPropertyValue(rName, rValue);
+ }
+ }
+ }
+}
+
+static void
+lcl_MergeCells(::std::vector<VerticallyMergedCell> & rMergedCells)
+{
+ if (rMergedCells.size())
+ {
+ std::vector<VerticallyMergedCell>::iterator aMergedIter =
+ rMergedCells.begin();
+ while (aMergedIter != rMergedCells.end())
+ {
+ sal_Int32 nCellCount =
+ static_cast<sal_Int32>(aMergedIter->aCells.size());
+ std::vector<uno::Reference< beans::XPropertySet > >::iterator
+ aCellIter = aMergedIter->aCells.begin();
+ bool bFirstCell = true;
+ // the first of the cells gets the number of cells set as RowSpan
+ // the others get the inverted number of remaining merged cells
+ // (3,-2,-1)
+ while (aCellIter != aMergedIter->aCells.end())
+ {
+ (*aCellIter)->setPropertyValue(
+ C2U(SW_PROP_NAME_STR(UNO_NAME_ROW_SPAN)),
+ uno::makeAny(nCellCount));
+ if (bFirstCell)
+ {
+ nCellCount *= -1;
+ bFirstCell = false;
+ }
+ ++nCellCount;
+ ++aCellIter;
+ }
+ ++aMergedIter;
+ }
+ }
+}
+
+uno::Reference< text::XTextTable > SAL_CALL
+SwXText::convertToTable(
+ const uno::Sequence< uno::Sequence< uno::Sequence<
+ uno::Reference< text::XTextRange > > > >& rTableRanges,
+ const uno::Sequence< uno::Sequence< uno::Sequence<
+ beans::PropertyValue > > >& rCellProperties,
+ const uno::Sequence< uno::Sequence< beans::PropertyValue > >&
+ rRowProperties,
+ const uno::Sequence< beans::PropertyValue >& rTableProperties)
+throw (lang::IllegalArgumentException, uno::RuntimeException)
+{
+ vos::OGuard aGuard(Application::GetSolarMutex());
+
+ if(!IsValid())
+ {
+ throw uno::RuntimeException();
+ }
+
+ //at first collect the text ranges as SwPaMs
+ const uno::Sequence< uno::Sequence< uno::Reference< text::XTextRange > > >*
+ pTableRanges = rTableRanges.getConstArray();
+ std::auto_ptr < SwPaM > pFirstPaM;
+ std::vector< std::vector<SwNodeRange> > aTableNodes;
+ bool bExcept = false;
+ SwPaM aLastPaM(m_pImpl->m_pDoc->GetNodes());
+ for (sal_Int32 nRow = 0; !bExcept && (nRow < rTableRanges.getLength());
+ ++nRow)
+ {
+ std::vector<SwNodeRange> aRowNodes;
+ const uno::Sequence< uno::Reference< text::XTextRange > >* pRow =
+ pTableRanges[nRow].getConstArray();
+ const sal_Int32 nCells(pTableRanges[nRow].getLength());
+
+ for (sal_Int32 nCell = 0; nCell < nCells; ++nCell)
+ {
+ m_pImpl->ConvertCell((nCell == 0) && (nRow == 0), pRow[nCell],
+ aRowNodes, pFirstPaM, aLastPaM, bExcept);
+ }
+ aTableNodes.push_back(aRowNodes);
+ }
+
+ if(bExcept)
+ {
+ m_pImpl->m_pDoc->GetIDocumentUndoRedo().Undo();
+ throw lang::IllegalArgumentException();
+ }
+
+ std::vector< TableColumnSeparators >
+ aRowSeparators(rRowProperties.getLength());
+ std::vector<VerticallyMergedCell> aMergedCells;
+
+ SwTable const*const pTable = m_pImpl->m_pDoc->TextToTable( aTableNodes );
+ SwXTextTable *const pTextTable = new SwXTextTable( *pTable->GetFrmFmt() );
+ const uno::Reference< text::XTextTable > xRet = pTextTable;
+ const uno::Reference< beans::XPropertySet > xPrSet = pTextTable;
+ // set properties to the table
+ // catch lang::WrappedTargetException and lang::IndexOutOfBoundsException
+ try
+ {
+ //apply table properties
+ const beans::PropertyValue* pTableProperties =
+ rTableProperties.getConstArray();
+ for (sal_Int32 nProperty = 0; nProperty < rTableProperties.getLength();
+ ++nProperty)
+ {
+ try
+ {
+ xPrSet->setPropertyValue( pTableProperties[nProperty].Name,
+ pTableProperties[nProperty].Value );
+ }
+ catch ( uno::Exception const& e )
+ {
+#if DEBUG
+ std::clog << "Exception when setting property: ";
+ std::clog << rtl::OUStringToOString(
+ pTableProperties[nProperty].Name, RTL_TEXTENCODING_UTF8)
+ .getStr();
+ std::clog << ". Message: ";
+ std::clog << rtl::OUStringToOString( e.Message,
+ RTL_TEXTENCODING_UTF8 ).getStr();
+ std::clog << std::endl;
+#endif
+ }
+ }
+
+ //apply row properties
+ const uno::Reference< table::XTableRows > xRows = xRet->getRows();
+
+ const beans::PropertyValues* pRowProperties =
+ rRowProperties.getConstArray();
+ for (sal_Int32 nRow = 0; nRow < xRows->getCount(); ++nRow)
+ {
+ if( nRow >= rRowProperties.getLength())
+ {
+ break;
+ }
+ lcl_ApplyRowProperties(pRowProperties[nRow],
+ xRows->getByIndex(nRow), aRowSeparators[nRow]);
+ }
+
+#ifdef DEBUG
+ lcl_DebugCellProperties(rCellProperties);
+#endif
+
+ //apply cell properties
+ for (sal_Int32 nRow = 0; nRow < rCellProperties.getLength(); ++nRow)
+ {
+ const uno::Sequence< beans::PropertyValues > aCurrentRow =
+ rCellProperties[nRow];
+ sal_Int32 nCells = aCurrentRow.getLength();
+ for (sal_Int32 nCell = 0; nCell < nCells; ++nCell)
+ {
+ lcl_ApplyCellProperties(nCell,
+ aRowSeparators[nRow], aCurrentRow[nCell],
+ pTextTable->getCellByPosition(nCell, nRow),
+ aMergedCells);
+ }
+ }
+ // now that the cell properties are set the vertical merge values
+ // have to be applied
+ lcl_MergeCells(aMergedCells);
+ }
+ catch( const lang::WrappedTargetException& rWrapped )
+ {
+ (void)rWrapped;
+ }
+ catch ( const lang::IndexOutOfBoundsException& rBounds )
+ {
+ (void)rBounds;
+ }
+
+ return xRet;
+}
+
+/******************************************************************
+ * SwXBodyText
+ ******************************************************************/
+SwXBodyText::SwXBodyText(SwDoc *const pDoc)
+ : SwXText(pDoc, CURSOR_BODY)
+{
+}
+
+/*-- 10.12.98 11:17:27---------------------------------------------------
+
+ -----------------------------------------------------------------------*/
+SwXBodyText::~SwXBodyText()
+{
+
+}
+/* -----------------------------06.04.00 16:33--------------------------------
+
+ ---------------------------------------------------------------------------*/
+OUString SAL_CALL
+SwXBodyText::getImplementationName() throw (uno::RuntimeException)
+{
+ return C2U("SwXBodyText");
+}
+/* -----------------------------06.04.00 16:33--------------------------------
+
+ ---------------------------------------------------------------------------*/
+static char const*const g_ServicesBodyText[] =
+{
+ "com.sun.star.text.Text",
+};
+static const size_t g_nServicesBodyText(
+ sizeof(g_ServicesBodyText)/sizeof(g_ServicesBodyText[0]));
+
+sal_Bool SAL_CALL SwXBodyText::supportsService(const OUString& rServiceName)
+throw (uno::RuntimeException)
+{
+ return ::sw::SupportsServiceImpl(
+ g_nServicesBodyText, g_ServicesBodyText, rServiceName);
+}
+
+uno::Sequence< OUString > SAL_CALL
+SwXBodyText::getSupportedServiceNames() throw (uno::RuntimeException)
+{
+ return ::sw::GetSupportedServiceNamesImpl(
+ g_nServicesBodyText, g_ServicesBodyText);
+}
+
+/*-- 10.12.98 11:17:27---------------------------------------------------
+
+ -----------------------------------------------------------------------*/
+uno::Any SAL_CALL
+SwXBodyText::queryAggregation(const uno::Type& rType)
+throw (uno::RuntimeException)
+{
+ uno::Any aRet;
+ if (rType == container::XEnumerationAccess::static_type())
+ {
+ aRet <<= uno::Reference< container::XEnumerationAccess >(this);
+ }
+ else if (rType == container::XElementAccess::static_type())
+ {
+ aRet <<= uno::Reference< container::XElementAccess >(this);
+ }
+ else if (rType == lang::XServiceInfo::static_type())
+ {
+ aRet <<= uno::Reference< lang::XServiceInfo >(this);
+ }
+ else
+ {
+ aRet = SwXText::queryInterface( rType );
+ }
+ if(aRet.getValueType() == ::getCppuVoidType())
+ {
+ aRet = OWeakAggObject::queryAggregation( rType );
+ }
+ return aRet;
+}
+
+/*-- 10.12.98 11:17:28---------------------------------------------------
+
+ -----------------------------------------------------------------------*/
+uno::Sequence< uno::Type > SAL_CALL
+SwXBodyText::getTypes() throw (uno::RuntimeException)
+{
+ const uno::Sequence< uno::Type > aTypes = SwXBodyText_Base::getTypes();
+ const uno::Sequence< uno::Type > aTextTypes = SwXText::getTypes();
+ return ::comphelper::concatSequences(aTypes, aTextTypes);
+}
+/* -----------------------------21.03.00 15:39--------------------------------
+
+ ---------------------------------------------------------------------------*/
+uno::Sequence< sal_Int8 > SAL_CALL
+SwXBodyText::getImplementationId() throw (uno::RuntimeException)
+{
+ vos::OGuard aGuard(Application::GetSolarMutex());
+ static uno::Sequence< sal_Int8 > aId( 16 );
+ static sal_Bool bInit = sal_False;
+ if(!bInit)
+ {
+ rtl_createUuid( (sal_uInt8 *)(aId.getArray() ), 0, sal_True );
+ bInit = sal_True;
+ }
+ return aId;
+}
+/*-- 10.12.98 11:17:28---------------------------------------------------
+
+ -----------------------------------------------------------------------*/
+uno::Any SAL_CALL
+SwXBodyText::queryInterface(const uno::Type& rType)
+throw (uno::RuntimeException)
+{
+ const uno::Any ret = SwXText::queryInterface(rType);
+ return (ret.getValueType() == ::getCppuVoidType())
+ ? SwXBodyText_Base::queryInterface(rType)
+ : ret;
+}
+/* -----------------------------05.01.00 11:07--------------------------------
+
+ ---------------------------------------------------------------------------*/
+SwXTextCursor * SwXBodyText::CreateTextCursor(const bool bIgnoreTables)
+{
+ if(!IsValid())
+ {
+ return 0;
+ }
+
+ // the cursor has to skip tables contained in this text
+ SwPaM aPam(GetDoc()->GetNodes().GetEndOfContent());
+ aPam.Move( fnMoveBackward, fnGoDoc );
+ if (!bIgnoreTables)
+ {
+ SwTableNode * pTblNode = aPam.GetNode()->FindTableNode();
+ SwCntntNode * pCont = 0;
+ while (pTblNode)
+ {
+ aPam.GetPoint()->nNode = *pTblNode->EndOfSectionNode();
+ pCont = GetDoc()->GetNodes().GoNext(&aPam.GetPoint()->nNode);
+ pTblNode = pCont->FindTableNode();
+ }
+ if (pCont)
+ {
+ aPam.GetPoint()->nContent.Assign(pCont, 0);
+ }
+ }
+ return new SwXTextCursor(*GetDoc(), this, CURSOR_BODY, *aPam.GetPoint());
+}
+
+/*-- 10.12.98 11:17:29---------------------------------------------------
+
+ -----------------------------------------------------------------------*/
+uno::Reference< text::XTextCursor > SAL_CALL
+SwXBodyText::createTextCursor() throw (uno::RuntimeException)
+{
+ vos::OGuard aGuard(Application::GetSolarMutex());
+
+ const uno::Reference< text::XTextCursor > xRef(
+ static_cast<text::XWordCursor*>(CreateTextCursor(false)) );
+ if (!xRef.is())
+ {
+ uno::RuntimeException aRuntime;
+ aRuntime.Message = C2U(cInvalidObject);
+ throw aRuntime;
+ }
+ return xRef;
+}
+/*-- 10.12.98 11:17:29---------------------------------------------------
+
+ -----------------------------------------------------------------------*/
+uno::Reference< text::XTextCursor > SAL_CALL
+SwXBodyText::createTextCursorByRange(
+ const uno::Reference< text::XTextRange > & xTextPosition)
+throw (uno::RuntimeException)
+{
+ vos::OGuard aGuard(Application::GetSolarMutex());
+
+ if(!IsValid())
+ {
+ uno::RuntimeException aRuntime;
+ aRuntime.Message = C2U(cInvalidObject);
+ throw aRuntime;
+ }
+
+ uno::Reference< text::XTextCursor > aRef;
+ SwUnoInternalPaM aPam(*GetDoc());
+ if (::sw::XTextRangeToSwPaM(aPam, xTextPosition))
+ {
+ SwNode& rNode = GetDoc()->GetNodes().GetEndOfContent();
+
+ SwStartNode* p1 = aPam.GetNode()->StartOfSectionNode();
+ //document starts with a section?
+ while(p1->IsSectionNode())
+ {
+ p1 = p1->StartOfSectionNode();
+ }
+ SwStartNode *const p2 = rNode.StartOfSectionNode();
+
+ if(p1 == p2)
+ {
+ aRef = static_cast<text::XWordCursor*>(
+ new SwXTextCursor(*GetDoc(), this, CURSOR_BODY,
+ *aPam.GetPoint(), aPam.GetMark()));
+ }
+ }
+ if(!aRef.is())
+ {
+ throw uno::RuntimeException();
+ }
+ return aRef;
+}
+
+/*-- 10.12.98 11:17:30---------------------------------------------------
+
+ -----------------------------------------------------------------------*/
+uno::Reference< container::XEnumeration > SAL_CALL
+SwXBodyText::createEnumeration()
+throw (uno::RuntimeException)
+{
+ vos::OGuard aGuard(Application::GetSolarMutex());
+
+ if (!IsValid())
+ {
+ uno::RuntimeException aRuntime;
+ aRuntime.Message = C2U(cInvalidObject);
+ throw aRuntime;
+ }
+
+ SwNode& rNode = GetDoc()->GetNodes().GetEndOfContent();
+ SwPosition aPos(rNode);
+ ::std::auto_ptr<SwUnoCrsr> pUnoCursor(
+ GetDoc()->CreateUnoCrsr(aPos, sal_False));
+ pUnoCursor->Move(fnMoveBackward, fnGoDoc);
+ const uno::Reference< container::XEnumeration > xRet
+ = new SwXParagraphEnumeration(this, pUnoCursor, CURSOR_BODY);
+ return xRet;
+}
+
+/* -----------------18.12.98 13:36-------------------
+ *
+ * --------------------------------------------------*/
+uno::Type SAL_CALL
+SwXBodyText::getElementType() throw (uno::RuntimeException)
+{
+ return text::XTextRange::static_type();
+}
+/* -----------------18.12.98 13:36-------------------
+ *
+ * --------------------------------------------------*/
+sal_Bool SAL_CALL
+SwXBodyText::hasElements() throw (uno::RuntimeException)
+{
+ vos::OGuard aGuard(Application::GetSolarMutex());
+
+ if (!IsValid())
+ {
+ uno::RuntimeException aRuntime;
+ aRuntime.Message = C2U(cInvalidObject);
+ throw aRuntime;
+ }
+
+ return sal_True;
+}
+
+/******************************************************************
+ * SwXHeadFootText
+ ******************************************************************/
+
+class SwXHeadFootText::Impl
+ : public SwClient
+{
+
+public:
+
+ bool m_bIsHeader;
+
+ Impl( SwXHeadFootText & /*rThis*/,
+ SwFrmFmt & rHeadFootFmt, const bool bIsHeader)
+ : SwClient(& rHeadFootFmt)
+ , m_bIsHeader(bIsHeader)
+ {
+ }
+
+ SwFrmFmt * GetHeadFootFmt() const {
+ return static_cast<SwFrmFmt*>(
+ const_cast<SwModify*>(GetRegisteredIn()));
+ }
+
+ SwFrmFmt & GetHeadFootFmtOrThrow() {
+ SwFrmFmt *const pFmt( GetHeadFootFmt() );
+ if (!pFmt) {
+ throw uno::RuntimeException(OUString(RTL_CONSTASCII_USTRINGPARAM(
+ "SwXHeadFootText: disposed or invalid")), 0);
+ }
+ return *pFmt;
+ }
+
+ // SwClient
+ virtual void Modify(SfxPoolItem *pOld, SfxPoolItem *pNew);
+
+};
+
+/*-- 11.12.98 10:14:51---------------------------------------------------
+
+ -----------------------------------------------------------------------*/
+void SwXHeadFootText::Impl::Modify(SfxPoolItem *pOld, SfxPoolItem *pNew)
+{
+ ClientModify(this, pOld, pNew);
+}
+
+bool SwXHeadFootText::IsXHeadFootText(SwClient *const pClient)
+{
+ return 0 != dynamic_cast<SwXHeadFootText::Impl*>(pClient);
+}
+
+uno::Reference< text::XText >
+SwXHeadFootText::CreateXHeadFootText(
+ SwFrmFmt & rHeadFootFmt, const bool bIsHeader)
+{
+ // re-use existing SwXHeadFootText
+ // #i105557#: do not iterate over the registered clients: race condition
+ uno::Reference< text::XText > xText(rHeadFootFmt.GetXObject(),
+ uno::UNO_QUERY);
+ if (!xText.is())
+ {
+ SwXHeadFootText *const pXHFT(
+ new SwXHeadFootText(rHeadFootFmt, bIsHeader));
+ xText.set(pXHFT);
+ rHeadFootFmt.SetXObject(xText);
+ }
+ return xText;
+}
+
+/*-- 11.12.98 10:14:48---------------------------------------------------
+
+ -----------------------------------------------------------------------*/
+SwXHeadFootText::SwXHeadFootText(SwFrmFmt & rHeadFootFmt, const bool bIsHeader)
+ : SwXText(rHeadFootFmt.GetDoc(),
+ (bIsHeader) ? CURSOR_HEADER : CURSOR_FOOTER)
+ , m_pImpl( new SwXHeadFootText::Impl(*this, rHeadFootFmt, bIsHeader) )
+{
+}
+
+/*-- 11.12.98 10:14:48---------------------------------------------------
+
+ -----------------------------------------------------------------------*/
+SwXHeadFootText::~SwXHeadFootText()
+{
+}
+
+/* -----------------------------06.04.00 16:40--------------------------------
+
+ ---------------------------------------------------------------------------*/
+OUString SAL_CALL
+SwXHeadFootText::getImplementationName() throw (uno::RuntimeException)
+{
+ return C2U("SwXHeadFootText");
+}
+
+/* -----------------------------06.04.00 16:40--------------------------------
+
+ ---------------------------------------------------------------------------*/
+static char const*const g_ServicesHeadFootText[] =
+{
+ "com.sun.star.text.Text",
+};
+static const size_t g_nServicesHeadFootText(
+ sizeof(g_ServicesHeadFootText)/sizeof(g_ServicesHeadFootText[0]));
+
+sal_Bool SAL_CALL SwXHeadFootText::supportsService(const OUString& rServiceName)
+throw (uno::RuntimeException)
+{
+ return ::sw::SupportsServiceImpl(
+ g_nServicesHeadFootText, g_ServicesHeadFootText, rServiceName);
+}
+
+uno::Sequence< OUString > SAL_CALL
+SwXHeadFootText::getSupportedServiceNames() throw (uno::RuntimeException)
+{
+ return ::sw::GetSupportedServiceNamesImpl(
+ g_nServicesHeadFootText, g_ServicesHeadFootText);
+}
+
+/*-- 11.12.98 10:14:49---------------------------------------------------
+
+ -----------------------------------------------------------------------*/
+const SwStartNode *SwXHeadFootText::GetStartNode() const
+{
+ const SwStartNode *pSttNd = 0;
+ SwFrmFmt *const pHeadFootFmt = m_pImpl->GetHeadFootFmt();
+ if(pHeadFootFmt)
+ {
+ const SwFmtCntnt& rFlyCntnt = pHeadFootFmt->GetCntnt();
+ if( rFlyCntnt.GetCntntIdx() )
+ {
+ pSttNd = rFlyCntnt.GetCntntIdx()->GetNode().GetStartNode();
+ }
+ }
+ return pSttNd;
+}
+
+uno::Reference< text::XTextCursor >
+SwXHeadFootText::CreateCursor() throw (uno::RuntimeException)
+{
+ return createTextCursor();
+}
+/* -----------------------------21.03.00 15:39--------------------------------
+
+ ---------------------------------------------------------------------------*/
+uno::Sequence< uno::Type > SAL_CALL
+SwXHeadFootText::getTypes() throw (uno::RuntimeException)
+{
+ const uno::Sequence< uno::Type > aTypes = SwXHeadFootText_Base::getTypes();
+ const uno::Sequence< uno::Type > aTextTypes = SwXText::getTypes();
+ return ::comphelper::concatSequences(aTypes, aTextTypes);
+}
+
+/* -----------------------------21.03.00 15:39--------------------------------
+
+ ---------------------------------------------------------------------------*/
+uno::Sequence< sal_Int8 > SAL_CALL
+SwXHeadFootText::getImplementationId() throw (uno::RuntimeException)
+{
+ vos::OGuard aGuard(Application::GetSolarMutex());
+ static uno::Sequence< sal_Int8 > aId( 16 );
+ static sal_Bool bInit = sal_False;
+ if(!bInit)
+ {
+ rtl_createUuid( (sal_uInt8 *)(aId.getArray() ), 0, sal_True );
+ bInit = sal_True;
+ }
+ return aId;
+}
+/* -----------------------------21.03.00 15:46--------------------------------
+
+ ---------------------------------------------------------------------------*/
+uno::Any SAL_CALL
+SwXHeadFootText::queryInterface(const uno::Type& rType)
+throw (uno::RuntimeException)
+{
+ const uno::Any ret = SwXHeadFootText_Base::queryInterface(rType);
+ return (ret.getValueType() == ::getCppuVoidType())
+ ? SwXText::queryInterface(rType)
+ : ret;
+}
+
+/*-- 11.12.98 10:14:50---------------------------------------------------
+
+ -----------------------------------------------------------------------*/
+uno::Reference< text::XTextCursor > SAL_CALL
+SwXHeadFootText::createTextCursor() throw (uno::RuntimeException)
+{
+ vos::OGuard aGuard(Application::GetSolarMutex());
+
+ SwFrmFmt & rHeadFootFmt( m_pImpl->GetHeadFootFmtOrThrow() );
+
+ uno::Reference< text::XTextCursor > xRet;
+ const SwFmtCntnt& rFlyCntnt = rHeadFootFmt.GetCntnt();
+ const SwNode& rNode = rFlyCntnt.GetCntntIdx()->GetNode();
+ SwPosition aPos(rNode);
+ SwXTextCursor *const pXCursor = new SwXTextCursor(*GetDoc(), this,
+ (m_pImpl->m_bIsHeader) ? CURSOR_HEADER : CURSOR_FOOTER, aPos);
+ SwUnoCrsr *const pUnoCrsr = pXCursor->GetCursor();
+ pUnoCrsr->Move(fnMoveForward, fnGoNode);
+
+ // save current start node to be able to check if there is content
+ // after the table - otherwise the cursor would be in the body text!
+ SwStartNode const*const pOwnStartNode = rNode.FindSttNodeByType(
+ (m_pImpl->m_bIsHeader) ? SwHeaderStartNode : SwFooterStartNode);
+ // is there a table here?
+ SwTableNode* pTblNode = pUnoCrsr->GetNode()->FindTableNode();
+ SwCntntNode* pCont = 0;
+ while (pTblNode)
+ {
+ pUnoCrsr->GetPoint()->nNode = *pTblNode->EndOfSectionNode();
+ pCont = GetDoc()->GetNodes().GoNext(&pUnoCrsr->GetPoint()->nNode);
+ pTblNode = pCont->FindTableNode();
+ }
+ if (pCont)
+ {
+ pUnoCrsr->GetPoint()->nContent.Assign(pCont, 0);
+ }
+ SwStartNode const*const pNewStartNode =
+ pUnoCrsr->GetNode()->FindSttNodeByType(
+ (m_pImpl->m_bIsHeader) ? SwHeaderStartNode : SwFooterStartNode);
+ if (!pNewStartNode || (pNewStartNode != pOwnStartNode))
+ {
+ uno::RuntimeException aExcept;
+ aExcept.Message = S2U("no text available");
+ throw aExcept;
+ }
+ xRet = static_cast<text::XWordCursor*>(pXCursor);
+ return xRet;
+}
+
+/*-- 11.12.98 10:14:50---------------------------------------------------
+
+ -----------------------------------------------------------------------*/
+uno::Reference< text::XTextCursor > SAL_CALL
+SwXHeadFootText::createTextCursorByRange(
+ const uno::Reference< text::XTextRange > & xTextPosition)
+throw (uno::RuntimeException)
+{
+ vos::OGuard aGuard(Application::GetSolarMutex());
+
+ SwFrmFmt & rHeadFootFmt( m_pImpl->GetHeadFootFmtOrThrow() );
+
+ SwUnoInternalPaM aPam(*GetDoc());
+ if (!::sw::XTextRangeToSwPaM(aPam, xTextPosition))
+ {
+ uno::RuntimeException aRuntime;
+ aRuntime.Message = C2U(cInvalidObject);
+ throw aRuntime;
+ }
+
+ uno::Reference< text::XTextCursor > xRet;
+ SwNode& rNode = rHeadFootFmt.GetCntnt().GetCntntIdx()->GetNode();
+ SwPosition aPos(rNode);
+ SwPaM aHFPam(aPos);
+ aHFPam.Move(fnMoveForward, fnGoNode);
+ SwStartNode *const pOwnStartNode = aHFPam.GetNode()->FindSttNodeByType(
+ (m_pImpl->m_bIsHeader) ? SwHeaderStartNode : SwFooterStartNode);
+ SwStartNode *const p1 = aPam.GetNode()->FindSttNodeByType(
+ (m_pImpl->m_bIsHeader) ? SwHeaderStartNode : SwFooterStartNode);
+ if (p1 == pOwnStartNode)
+ {
+ xRet = static_cast<text::XWordCursor*>(
+ new SwXTextCursor(*GetDoc(), this,
+ (m_pImpl->m_bIsHeader) ? CURSOR_HEADER : CURSOR_FOOTER,
+ *aPam.GetPoint(), aPam.GetMark()));
+ }
+ return xRet;
+}
+
+/* -----------------19.03.99 15:44-------------------
+ *
+ * --------------------------------------------------*/
+uno::Reference< container::XEnumeration > SAL_CALL
+SwXHeadFootText::createEnumeration()
+throw (uno::RuntimeException)
+{
+ vos::OGuard aGuard(Application::GetSolarMutex());
+
+ SwFrmFmt & rHeadFootFmt( m_pImpl->GetHeadFootFmtOrThrow() );
+
+ uno::Reference< container::XEnumeration > aRef;
+ const SwFmtCntnt& rFlyCntnt = rHeadFootFmt.GetCntnt();
+ const SwNode& rNode = rFlyCntnt.GetCntntIdx()->GetNode();
+ SwPosition aPos(rNode);
+ ::std::auto_ptr<SwUnoCrsr> pUnoCursor(
+ GetDoc()->CreateUnoCrsr(aPos, sal_False));
+ pUnoCursor->Move(fnMoveForward, fnGoNode);
+ aRef = new SwXParagraphEnumeration(this, pUnoCursor,
+ (m_pImpl->m_bIsHeader) ? CURSOR_HEADER : CURSOR_FOOTER);
+
+ return aRef;
+}
+
+/* -----------------19.03.99 15:50-------------------
+ *
+ * --------------------------------------------------*/
+uno::Type SAL_CALL
+SwXHeadFootText::getElementType() throw (uno::RuntimeException)
+{
+ return text::XTextRange::static_type();
+}
+/* -----------------19.03.99 15:50-------------------
+ *
+ * --------------------------------------------------*/
+sal_Bool SAL_CALL SwXHeadFootText::hasElements() throw (uno::RuntimeException)
+{
+ return sal_True;
+}
+