summaryrefslogtreecommitdiff
path: root/sw/source/core/unocore/unotextmarkup.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'sw/source/core/unocore/unotextmarkup.cxx')
-rw-r--r--sw/source/core/unocore/unotextmarkup.cxx486
1 files changed, 486 insertions, 0 deletions
diff --git a/sw/source/core/unocore/unotextmarkup.cxx b/sw/source/core/unocore/unotextmarkup.cxx
new file mode 100644
index 000000000000..a02085f261b6
--- /dev/null
+++ b/sw/source/core/unocore/unotextmarkup.cxx
@@ -0,0 +1,486 @@
+/*************************************************************************
+ *
+ * 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 <unotextmarkup.hxx>
+
+#include <vos/mutex.hxx>
+#include <vcl/svapp.hxx>
+#include <SwSmartTagMgr.hxx>
+#include <com/sun/star/text/TextMarkupType.hpp>
+#include <com/sun/star/text/TextMarkupDescriptor.hpp>
+#include <com/sun/star/container/XStringKeyMap.hpp>
+#include <ndtxt.hxx>
+#include <SwGrammarMarkUp.hxx>
+
+#include <IGrammarContact.hxx>
+
+using namespace ::com::sun::star;
+
+/*
+ * SwXTextMarkup
+ */
+SwXTextMarkup::SwXTextMarkup( SwTxtNode& rTxtNode, const ModelToViewHelper::ConversionMap* pMap )
+ : mpTxtNode( &rTxtNode ), mpConversionMap( pMap )
+{
+ mpTxtNode->Add(this);
+}
+
+SwXTextMarkup::~SwXTextMarkup()
+{
+ delete mpConversionMap;
+}
+
+uno::Reference< container::XStringKeyMap > SAL_CALL SwXTextMarkup::getMarkupInfoContainer() throw (uno::RuntimeException)
+{
+ vos::OGuard aGuard(Application::GetSolarMutex());
+
+ uno::Reference< container::XStringKeyMap > xProp = new SwXStringKeyMap;
+ return xProp;
+}
+
+void SAL_CALL SwXTextMarkup::commitTextMarkup(
+ ::sal_Int32 nType,
+ const ::rtl::OUString & rIdentifier,
+ ::sal_Int32 nStart,
+ ::sal_Int32 nLength,
+ const uno::Reference< container::XStringKeyMap > & xMarkupInfoContainer)
+ throw (uno::RuntimeException)
+{
+ vos::OGuard aGuard(Application::GetSolarMutex());
+
+ // paragraph already dead or modified?
+ if ( !mpTxtNode || nLength <= 0 )
+ return;
+
+ if ( nType == text::TextMarkupType::SMARTTAG &&
+ !SwSmartTagMgr::Get().IsSmartTagTypeEnabled( rIdentifier ) )
+ return;
+
+ // get appropriate list to use...
+ SwWrongList* pWList = 0;
+ bool bRepaint = false;
+ if ( nType == text::TextMarkupType::SPELLCHECK )
+ {
+ pWList = mpTxtNode->GetWrong();
+ if ( !pWList )
+ {
+ pWList = new SwWrongList( WRONGLIST_SPELL );
+ mpTxtNode->SetWrong( pWList );
+ }
+ }
+ else if ( nType == text::TextMarkupType::PROOFREADING || nType == text::TextMarkupType::SENTENCE )
+ {
+ IGrammarContact *pGrammarContact = getGrammarContact( *mpTxtNode );
+ if( pGrammarContact )
+ {
+ pWList = pGrammarContact->getGrammarCheck( *mpTxtNode, true );
+ ASSERT( pWList, "GrammarContact _has_ to deliver a wrong list" )
+ }
+ else
+ {
+ pWList = mpTxtNode->GetGrammarCheck();
+ if ( !pWList )
+ {
+ mpTxtNode->SetGrammarCheck( new SwGrammarMarkUp() );
+ pWList = mpTxtNode->GetGrammarCheck();
+ }
+ }
+ bRepaint = pWList == mpTxtNode->GetGrammarCheck();
+ if( pWList->GetBeginInv() < STRING_LEN )
+ ((SwGrammarMarkUp*)pWList)->ClearGrammarList();
+ }
+ else if ( nType == text::TextMarkupType::SMARTTAG )
+ {
+ pWList = mpTxtNode->GetSmartTags();
+ if ( !pWList )
+ {
+ pWList = new SwWrongList( WRONGLIST_SMARTTAG );
+ mpTxtNode->SetSmartTags( pWList );
+ }
+ }
+ else
+ {
+ ASSERT( false, "Unknown mark-up type" )
+ return;
+ }
+
+
+ const ModelToViewHelper::ModelPosition aStartPos =
+ ModelToViewHelper::ConvertToModelPosition( mpConversionMap, nStart );
+ const ModelToViewHelper::ModelPosition aEndPos =
+ ModelToViewHelper::ConvertToModelPosition( mpConversionMap, nStart + nLength - 1);
+
+ const bool bStartInField = aStartPos.mbIsField;
+ const bool bEndInField = aEndPos.mbIsField;
+ bool bCommit = false;
+
+ if ( bStartInField && bEndInField && aStartPos.mnPos == aEndPos.mnPos )
+ {
+ nStart = aStartPos.mnSubPos;
+ const xub_StrLen nFieldPosModel = static_cast< xub_StrLen >(aStartPos.mnPos);
+ const USHORT nInsertPos = pWList->GetWrongPos( nFieldPosModel );
+
+ SwWrongList* pSubList = pWList->SubList( nInsertPos );
+ if ( !pSubList )
+ {
+ if( nType == text::TextMarkupType::PROOFREADING || nType == text::TextMarkupType::SENTENCE )
+ pSubList = new SwGrammarMarkUp();
+ else
+ pSubList = new SwWrongList( pWList->GetWrongListType() );
+ pWList->InsertSubList( nFieldPosModel, 1, nInsertPos, pSubList );
+ }
+
+ pWList = pSubList;
+ bCommit = true;
+ }
+ else if ( !bStartInField && !bEndInField )
+ {
+ nStart = aStartPos.mnPos;
+ bCommit = true;
+ nLength = aEndPos.mnPos + 1 - aStartPos.mnPos;
+ }
+ else if( nType == text::TextMarkupType::PROOFREADING || nType == text::TextMarkupType::SENTENCE )
+ {
+ bCommit = true;
+ nStart = aStartPos.mnPos;
+ sal_Int32 nEnd = aEndPos.mnPos;
+ if( bStartInField && nType != text::TextMarkupType::SENTENCE )
+ {
+ const xub_StrLen nFieldPosModel = static_cast< xub_StrLen >(aStartPos.mnPos);
+ const USHORT nInsertPos = pWList->GetWrongPos( nFieldPosModel );
+ SwWrongList* pSubList = pWList->SubList( nInsertPos );
+ if ( !pSubList )
+ {
+ pSubList = new SwGrammarMarkUp();
+ pWList->InsertSubList( nFieldPosModel, 1, nInsertPos, pSubList );
+ }
+ const sal_uInt32 nTmpStart = ModelToViewHelper::ConvertToViewPosition( mpConversionMap, aStartPos.mnPos );
+ const sal_uInt32 nTmpLen = ModelToViewHelper::ConvertToViewPosition( mpConversionMap, aStartPos.mnPos + 1 )
+ - nTmpStart - aStartPos.mnSubPos;
+ if( nTmpLen > 0 )
+ {
+ if( nType == text::TextMarkupType::SENTENCE )
+ {
+ ((SwGrammarMarkUp*)pSubList)->setSentence( static_cast< xub_StrLen >(aStartPos.mnSubPos) );
+ bCommit = false;
+ }
+ else
+ pSubList->Insert( rIdentifier, xMarkupInfoContainer,
+ static_cast< xub_StrLen >(aStartPos.mnSubPos), static_cast< xub_StrLen >(nTmpLen) );
+ }
+ ++nStart;
+ }
+ if( bEndInField && nType != text::TextMarkupType::SENTENCE )
+ {
+ const xub_StrLen nFieldPosModel = static_cast< xub_StrLen >(aEndPos.mnPos);
+ const USHORT nInsertPos = pWList->GetWrongPos( nFieldPosModel );
+ SwWrongList* pSubList = pWList->SubList( nInsertPos );
+ if ( !pSubList )
+ {
+ pSubList = new SwGrammarMarkUp();
+ pWList->InsertSubList( nFieldPosModel, 1, nInsertPos, pSubList );
+ }
+ const sal_uInt32 nTmpLen = aEndPos.mnSubPos + 1;
+ pSubList->Insert( rIdentifier, xMarkupInfoContainer, 0, static_cast< xub_StrLen >(nTmpLen) );
+ }
+ else
+ ++nEnd;
+ if( nEnd > nStart )
+ nLength = nEnd - nStart;
+ else
+ bCommit = false;
+ }
+
+ if ( bCommit )
+ {
+ if( nType == text::TextMarkupType::SENTENCE )
+ ((SwGrammarMarkUp*)pWList)->setSentence( static_cast< xub_StrLen >(nStart) );
+ else
+ pWList->Insert( rIdentifier, xMarkupInfoContainer,
+ static_cast< xub_StrLen >(nStart), static_cast< xub_StrLen >(nLength) );
+ }
+
+ if( bRepaint )
+ finishGrammarCheck( *mpTxtNode );
+}
+
+
+void lcl_commitGrammarMarkUp(
+ const ModelToViewHelper::ConversionMap* pConversionMap,
+ SwGrammarMarkUp* pWList,
+ ::sal_Int32 nType,
+ const ::rtl::OUString & rIdentifier,
+ ::sal_Int32 nStart,
+ ::sal_Int32 nLength,
+ const uno::Reference< container::XStringKeyMap > & xMarkupInfoContainer)
+{
+ ASSERT( nType == text::TextMarkupType::PROOFREADING || nType == text::TextMarkupType::SENTENCE, "Wrong mark-up type" )
+ const ModelToViewHelper::ModelPosition aStartPos =
+ ModelToViewHelper::ConvertToModelPosition( pConversionMap, nStart );
+ const ModelToViewHelper::ModelPosition aEndPos =
+ ModelToViewHelper::ConvertToModelPosition( pConversionMap, nStart + nLength - 1);
+
+ const bool bStartInField = aStartPos.mbIsField;
+ const bool bEndInField = aEndPos.mbIsField;
+ bool bCommit = false;
+
+ if ( bStartInField && bEndInField && aStartPos.mnPos == aEndPos.mnPos )
+ {
+ nStart = aStartPos.mnSubPos;
+ const xub_StrLen nFieldPosModel = static_cast< xub_StrLen >(aStartPos.mnPos);
+ const USHORT nInsertPos = pWList->GetWrongPos( nFieldPosModel );
+
+ SwGrammarMarkUp* pSubList = (SwGrammarMarkUp*)pWList->SubList( nInsertPos );
+ if ( !pSubList )
+ {
+ pSubList = new SwGrammarMarkUp();
+ pWList->InsertSubList( nFieldPosModel, 1, nInsertPos, pSubList );
+ }
+
+ pWList = pSubList;
+ bCommit = true;
+ }
+ else if ( !bStartInField && !bEndInField )
+ {
+ nStart = aStartPos.mnPos;
+ bCommit = true;
+ nLength = aEndPos.mnPos + 1 - aStartPos.mnPos;
+ }
+ else
+ {
+ bCommit = true;
+ nStart = aStartPos.mnPos;
+ sal_Int32 nEnd = aEndPos.mnPos;
+ if( bStartInField && nType != text::TextMarkupType::SENTENCE )
+ {
+ const xub_StrLen nFieldPosModel = static_cast< xub_StrLen >(aStartPos.mnPos);
+ const USHORT nInsertPos = pWList->GetWrongPos( nFieldPosModel );
+ SwGrammarMarkUp* pSubList = (SwGrammarMarkUp*)pWList->SubList( nInsertPos );
+ if ( !pSubList )
+ {
+ pSubList = new SwGrammarMarkUp();
+ pWList->InsertSubList( nFieldPosModel, 1, nInsertPos, pSubList );
+ }
+ const sal_uInt32 nTmpStart = ModelToViewHelper::ConvertToViewPosition( pConversionMap, aStartPos.mnPos );
+ const sal_uInt32 nTmpLen = ModelToViewHelper::ConvertToViewPosition( pConversionMap, aStartPos.mnPos + 1 )
+ - nTmpStart - aStartPos.mnSubPos;
+ if( nTmpLen > 0 )
+ pSubList->Insert( rIdentifier, xMarkupInfoContainer,
+ static_cast< xub_StrLen >(aStartPos.mnSubPos), static_cast< xub_StrLen >(nTmpLen) );
+ ++nStart;
+ }
+ if( bEndInField && nType != text::TextMarkupType::SENTENCE )
+ {
+ const xub_StrLen nFieldPosModel = static_cast< xub_StrLen >(aEndPos.mnPos);
+ const USHORT nInsertPos = pWList->GetWrongPos( nFieldPosModel );
+ SwGrammarMarkUp* pSubList = (SwGrammarMarkUp*)pWList->SubList( nInsertPos );
+ if ( !pSubList )
+ {
+ pSubList = new SwGrammarMarkUp();
+ pWList->InsertSubList( nFieldPosModel, 1, nInsertPos, pSubList );
+ }
+ const sal_uInt32 nTmpLen = aEndPos.mnSubPos + 1;
+ pSubList->Insert( rIdentifier, xMarkupInfoContainer, 0, static_cast< xub_StrLen >(nTmpLen) );
+ }
+ else
+ ++nEnd;
+ if( nEnd > nStart )
+ nLength = nEnd - nStart;
+ else
+ bCommit = false;
+ }
+
+ if ( bCommit )
+ {
+ if( nType == text::TextMarkupType::SENTENCE )
+ ((SwGrammarMarkUp*)pWList)->setSentence( static_cast< xub_StrLen >(nStart+nLength) );
+ else
+ pWList->Insert( rIdentifier, xMarkupInfoContainer,
+ static_cast< xub_StrLen >(nStart), static_cast< xub_StrLen >(nLength) );
+ }
+}
+
+
+void SAL_CALL SwXTextMarkup::commitMultiTextMarkup(
+ const uno::Sequence< text::TextMarkupDescriptor > &rMarkups )
+throw (lang::IllegalArgumentException, uno::RuntimeException)
+{
+ vos::OGuard aGuard(Application::GetSolarMutex());
+
+ // paragraph already dead or modified?
+ if ( !mpTxtNode )
+ return;
+
+ // check for equal length of all sequnces
+ sal_Int32 nLen = rMarkups.getLength();
+
+ // for grammar checking there should be exactly one sentence markup
+ // and 0..n grammar markups.
+ // Different markups are not expected but may be applied anyway since
+ // that should be no problem...
+ // but it has to be implemented, at the moment only this function is for
+ // grammar markups and sentence markup only!
+ sal_Int32 nSentenceMarkUpIndex = -1;
+ const text::TextMarkupDescriptor *pMarkups = rMarkups.getConstArray();
+ sal_Int32 i;
+ for( i = 0; i < nLen; ++i )
+ {
+ if (pMarkups[i].nType == text::TextMarkupType::SENTENCE)
+ {
+ if (nSentenceMarkUpIndex == -1)
+ nSentenceMarkUpIndex = i;
+ else // there is already one sentence markup
+ throw lang::IllegalArgumentException();
+ }
+ else if( pMarkups[i].nType != text::TextMarkupType::PROOFREADING )
+ return;
+ }
+
+ if( nSentenceMarkUpIndex == -1 )
+ return;
+
+ // get appropriate list to use...
+ SwGrammarMarkUp* pWList = 0;
+ bool bRepaint = false;
+ IGrammarContact *pGrammarContact = getGrammarContact( *mpTxtNode );
+ if( pGrammarContact )
+ {
+ pWList = pGrammarContact->getGrammarCheck( *mpTxtNode, true );
+ ASSERT( pWList, "GrammarContact _has_ to deliver a wrong list" )
+ }
+ else
+ {
+ pWList = mpTxtNode->GetGrammarCheck();
+ if ( !pWList )
+ {
+ mpTxtNode->SetGrammarCheck( new SwGrammarMarkUp() );
+ pWList = mpTxtNode->GetGrammarCheck();
+ pWList->SetInvalid( 0, STRING_LEN );
+ }
+ }
+ bRepaint = pWList == mpTxtNode->GetGrammarCheck();
+
+ bool bAcceptGrammarError = false;
+ if( pWList->GetBeginInv() < STRING_LEN )
+ {
+ const ModelToViewHelper::ModelPosition aSentenceEnd =
+ ModelToViewHelper::ConvertToModelPosition( mpConversionMap,
+ pMarkups[nSentenceMarkUpIndex].nOffset + pMarkups[nSentenceMarkUpIndex].nLength );
+ bAcceptGrammarError = (xub_StrLen)aSentenceEnd.mnPos > pWList->GetBeginInv();
+ pWList->ClearGrammarList( (xub_StrLen)aSentenceEnd.mnPos );
+ }
+
+ if( bAcceptGrammarError )
+ {
+ for( i = 0; i < nLen; ++i )
+ {
+ const text::TextMarkupDescriptor &rDesc = pMarkups[i];
+ lcl_commitGrammarMarkUp( mpConversionMap, pWList, rDesc.nType,
+ rDesc.aIdentifier, rDesc.nOffset, rDesc.nLength, rDesc.xMarkupInfoContainer );
+ }
+ }
+ else
+ {
+ bRepaint = false;
+ i = nSentenceMarkUpIndex;
+ const text::TextMarkupDescriptor &rDesc = pMarkups[i];
+ lcl_commitGrammarMarkUp( mpConversionMap, pWList, rDesc.nType,
+ rDesc.aIdentifier, rDesc.nOffset, rDesc.nLength, rDesc.xMarkupInfoContainer );
+ }
+
+ if( bRepaint )
+ finishGrammarCheck( *mpTxtNode );
+
+ return;
+}
+
+
+void SwXTextMarkup::Modify( SfxPoolItem* /*pOld*/, SfxPoolItem* /*pNew*/ )
+{
+ // FME 2007-07-16 #i79641# In my opinion this is perfectly legal,
+ // therefore I remove the assertion in SwModify::_Remove()
+ if ( pRegisteredIn )
+ pRegisteredIn->Remove( this );
+ // <--
+
+ vos::OGuard aGuard(Application::GetSolarMutex());
+ mpTxtNode = 0;
+}
+
+/*
+ * SwXStringKeyMap
+ */
+SwXStringKeyMap::SwXStringKeyMap()
+{
+}
+
+uno::Any SAL_CALL SwXStringKeyMap::getValue(const ::rtl::OUString & aKey) throw (uno::RuntimeException, container::NoSuchElementException)
+{
+ std::map< rtl::OUString, uno::Any >::const_iterator aIter = maMap.find( aKey );
+ if ( aIter == maMap.end() )
+ throw container::NoSuchElementException();
+
+ return (*aIter).second;
+}
+
+::sal_Bool SAL_CALL SwXStringKeyMap::hasValue(const ::rtl::OUString & aKey) throw (uno::RuntimeException)
+{
+ return maMap.find( aKey ) != maMap.end();
+}
+
+void SAL_CALL SwXStringKeyMap::insertValue(const ::rtl::OUString & aKey, const uno::Any & aValue) throw (uno::RuntimeException, lang::IllegalArgumentException, container::ElementExistException)
+{
+ std::map< rtl::OUString, uno::Any >::const_iterator aIter = maMap.find( aKey );
+ if ( aIter != maMap.end() )
+ throw container::ElementExistException();
+
+ maMap[ aKey ] = aValue;
+}
+
+::sal_Int32 SAL_CALL SwXStringKeyMap::getCount() throw (uno::RuntimeException)
+{
+ return maMap.size();
+}
+
+::rtl::OUString SAL_CALL SwXStringKeyMap::getKeyByIndex(::sal_Int32 nIndex) throw (uno::RuntimeException, lang::IndexOutOfBoundsException)
+{
+ if ( (sal_uInt32)nIndex >= maMap.size() )
+ throw lang::IndexOutOfBoundsException();
+
+ return ::rtl::OUString();
+}
+
+uno::Any SAL_CALL SwXStringKeyMap::getValueByIndex(::sal_Int32 nIndex) throw (uno::RuntimeException, lang::IndexOutOfBoundsException)
+{
+ if ( (sal_uInt32)nIndex >= maMap.size() )
+ throw lang::IndexOutOfBoundsException();
+
+ return uno::Any();
+}
+