summaryrefslogtreecommitdiff
path: root/linguistic
diff options
context:
space:
mode:
authorIvo Hinkelmann <ihi@openoffice.org>2008-07-16 12:46:41 +0000
committerIvo Hinkelmann <ihi@openoffice.org>2008-07-16 12:46:41 +0000
commit9951ea69fd0e68c8d3547c0a35c5c8ec89c0b9b5 (patch)
tree9a5530ef631f73de00d64ef78d7a33df38d9b425 /linguistic
parent7053d083e2be25e836418dd738260c6ec2f8e424 (diff)
INTEGRATION: CWS tl55 (1.3.8); FILE MERGED
2008/07/01 13:21:19 tl 1.3.8.25: #i85999# grammar checking framework 2008/07/01 13:17:58 tl 1.3.8.24: #i85999# grammar checking framework 2008/07/01 07:51:33 tl 1.3.8.23: #i85999# grammar checking framework 2008/06/30 11:53:11 os 1.3.8.22: #i85999# iteration fixed for dialog access 2008/06/29 11:35:00 tl 1.3.8.21: #i85999# grammar checking framework 2008/06/25 14:13:24 tl 1.3.8.20: #i85999# grammar checking framework 2008/06/25 14:11:42 tl 1.3.8.19: #i85999# grammar checking framework 2008/06/25 07:07:02 tl 1.3.8.18: #i85999# grammar checking framework 2008/06/25 06:30:05 tl 1.3.8.17: #i85999# grammar checking framework 2008/06/24 10:24:13 os 1.3.8.16: #83776# additional locals fixed 2008/06/19 14:55:09 tl 1.3.8.15: #i85999# grammar checking framework 2008/06/16 11:34:42 tl 1.3.8.14: #i85999# grammar checking framework 2008/06/13 15:20:17 tl 1.3.8.13: #i85999# grammart checking framework 2008/06/11 10:40:56 tl 1.3.8.12: #i85999# grammar checking framework 2008/06/11 10:02:16 tl 1.3.8.11: #i85999# grammar checking framework 2008/06/11 09:02:00 tl 1.3.8.10: #i85999# MAC line ends removed 2008/06/11 08:17:41 mba 1.3.8.9: some fixes 2008/06/07 15:24:21 tl 1.3.8.8: #i85999# grammar checking framework 2008/05/31 16:47:55 tl 1.3.8.7: #i85999# grammar checking framework 2008/05/31 12:33:10 tl 1.3.8.6: #i85999# grammar checking framework 2008/05/27 11:17:52 tl 1.3.8.5: #i85999# improve grammar checking framework 2008/05/23 11:00:13 tl 1.3.8.4: #158047# customer specific extension 2008/05/23 05:54:46 tl 1.3.8.3: #158047# customer specific extension 2008/05/22 14:00:59 tl 1.3.8.2: #158047# customer specific extension 2008/05/21 09:59:51 tl 1.3.8.1: #158047# customer specific extension
Diffstat (limited to 'linguistic')
-rw-r--r--linguistic/source/gciterator.cxx1198
1 files changed, 828 insertions, 370 deletions
diff --git a/linguistic/source/gciterator.cxx b/linguistic/source/gciterator.cxx
index 6a7b011274ec..a22beb032c38 100644
--- a/linguistic/source/gciterator.cxx
+++ b/linguistic/source/gciterator.cxx
@@ -7,7 +7,7 @@
* OpenOffice.org - a multi-platform office productivity suite
*
* $RCSfile: gciterator.cxx,v $
- * $Revision: 1.3 $
+ * $Revision: 1.4 $
*
* This file is part of OpenOffice.org.
*
@@ -29,238 +29,424 @@
************************************************************************/
#include "precompiled_linguistic.hxx"
-#include <sal/config.h>
-#include <com/sun/star/uno/XComponentContext.hpp>
-#include <cppuhelper/implbase4.hxx>
+#include <com/sun/star/container/XContentEnumerationAccess.hpp>
+#include <com/sun/star/container/XEnumeration.hpp>
+#include <com/sun/star/container/XNameAccess.hpp>
+#include <com/sun/star/container/XNameContainer.hpp>
+#include <com/sun/star/container/XNameReplace.hpp>
+#include <com/sun/star/i18n/XBreakIterator.hpp>
+#include <com/sun/star/lang/XComponent.hpp>
+#include <com/sun/star/lang/XServiceInfo.hpp>
+#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <com/sun/star/linguistic2/XSupportedLocales.hpp>
+#include <com/sun/star/linguistic2/XGrammarChecker.hpp>
#include <com/sun/star/linguistic2/XGrammarCheckingIterator.hpp>
-#include <deque>
+#include <com/sun/star/linguistic2/SingleGrammarError.hpp>
+#include <com/sun/star/linguistic2/GrammarCheckingResult.hpp>
+#include <com/sun/star/linguistic2/LinguServiceEvent.hpp>
+#include <com/sun/star/linguistic2/LinguServiceEventFlags.hpp>
+#include <com/sun/star/registry/XRegistryKey.hpp>
#include <com/sun/star/text/TextMarkupType.hpp>
+#include <com/sun/star/text/XTextMarkup.hpp>
#include <com/sun/star/text/XFlatParagraph.hpp>
#include <com/sun/star/text/XFlatParagraphIterator.hpp>
-#include <map>
-#include <com/sun/star/i18n/XBreakIterator.hpp>
-#include <vcl/unohelp.hxx>
+#include <com/sun/star/uno/XComponentContext.hpp>
+#include <com/sun/star/lang/XSingleComponentFactory.hpp>
-#include <osl/mutex.hxx>
-#include <vcl/svapp.hxx>
+#include <sal/config.h>
#include <osl/conditn.hxx>
+#include <osl/thread.hxx>
#include <cppuhelper/implbase4.hxx>
-#include <com/sun/star/lang/XComponent.hpp>
-#include <com/sun/star/lang/XServiceInfo.hpp>
-#include <com/sun/star/linguistic2/XGrammarCheckingResultListener.hpp>
-#include <com/sun/star/linguistic2/XGrammarChecker.hpp>
-#include <com/sun/star/linguistic2/XGrammarCheckingResultBroadcaster.hpp>
-#include "misc.hxx"
-#include "defs.hxx"
+#include <cppuhelper/implementationentry.hxx>
+#include <cppuhelper/interfacecontainer.h>
+#include <cppuhelper/extract.hxx>
#include <cppuhelper/factory.hxx>
-#include <com/sun/star/registry/XRegistryKey.hpp>
-#include <com/sun/star/lang/XMultiServiceFactory.hpp>
+#include <vcl/unohelp.hxx>
+#include <i18npool/mslangid.hxx>
+#include <unotools/processfactory.hxx>
-#include <com/sun/star/linguistic2/SingleGrammarError.hpp>
+#include <deque>
+#include <map>
+#include <vector>
+
+#include "misc.hxx"
+#include "defs.hxx"
+#include "lngopt.hxx"
#include "gciterator.hxx"
-#include "grammarchecker.hxx"
-#include <unotools/processfactory.hxx>
-#include <com/sun/star/container/XContentEnumerationAccess.hpp>
-#include <com/sun/star/container/XEnumeration.hpp>
-#include <cppuhelper/interfacecontainer.h>
-#include <com/sun/star/lang/XMultiServiceFactory.hpp>
-#include <cppuhelper/factory.hxx>
-#include "lngopt.hxx"
-#include <com/sun/star/linguistic2/XSupportedLocales.hpp>
+using ::rtl::OUString;
+using namespace ::com::sun::star;
-#include <vcl/unohelp.hxx>
-#include <com/sun/star/linguistic2/SingleGrammarError.hpp>
-#include <com/sun/star/linguistic2/GrammarCheckingResult.hpp>
-#include <cppuhelper/extract.hxx>
-#include <i18npool/mslangid.hxx>
-#include <osl/thread.hxx>
-#include <com/sun/star/text/XTextMarkup.hpp>
+// forward declarations
+static ::rtl::OUString GrammarCheckingIterator_getImplementationName() throw();
+static uno::Sequence< OUString > GrammarCheckingIterator_getSupportedServiceNames() throw();
-using namespace ::utl;
-using namespace ::rtl;
-using namespace ::com::sun::star;
-using namespace linguistic;
+//////////////////////////////////////////////////////////////////////
extern "C" void workerfunc (void * gci)
{
- ((GrammarCheckingIterator*)gci)->dequeueAndCheck();
+ ((GrammarCheckingIterator*)gci)->DequeueAndCheck();
+}
+
+static lang::Locale lcl_GetPrimaryLanguageOfSentence(
+ uno::Reference< text::XFlatParagraph > xFlatPara,
+ sal_Int32 nStartIndex )
+{
+ //get the language of the first word
+ return xFlatPara->getLanguageOfText( nStartIndex, 1 );
+}
+
+//////////////////////////////////////////////////////////////////////
+/*
+class MyThread : punlic osl::Thread
+{
+ void run ()
+ {
+ DequeueAndCheck();
+ }
+
+ void own_terminate ()
+ {
+ m_bEnd = true;
+ wait (3000);
+ terminate ();
+ }
+}
+
+MyThread m_aQueue;
+
+vois startGrammarChecking()
+{
+ if (!m_aQueue.isRunning ())
+ m_aQueue.create ();
}
-////////////////////////////////////////////////////////////
+void stopGrammarChecking ()
+{
+ if (m_aQueue.isRunning ())
+ m_aQueue.own_terminate ();
+}
+*/
-GrammarCheckingIterator::GrammarCheckingIterator( /* uno::Reference< uno::XComponentContext > const & context */ ) :
- /*m_xContext(context)*/
+GrammarCheckingIterator::GrammarCheckingIterator( const uno::Reference< lang::XMultiServiceFactory > & rxMgr ) :
+ m_xMSF( rxMgr ),
m_bEnd( sal_False ),
- m_nDocID( 0 )
+ m_bGCServicesChecked( sal_False ),
+ m_nDocIdCounter( 0 ),
+ m_nCurCheckedDocId( - 1 ),
+ m_nLastEndOfSentencePos( -1 ),
+ m_aMutex(),
+ m_aEventListeners( m_aMutex ),
+ m_aNotifyListeners( m_aMutex )
{
- osl_createThread(workerfunc, this);
+ osl_createThread( workerfunc, this );
}
+
GrammarCheckingIterator::~GrammarCheckingIterator()
{
+ ::osl::Guard< ::osl::Mutex > aGuard( m_aMutex );
}
-//create new DocID
-const ::sal_Int32 GrammarCheckingIterator::NextDocId()
-{
- osl::Guard< osl::Mutex > aGuard(GetMutex());
- m_nDocID += 1;
- return m_nDocID;
+sal_Int32 GrammarCheckingIterator::NextDocId()
+{
+ ::osl::Guard< ::osl::Mutex > aGuard( m_aMutex );
+ m_nDocIdCounter += 1;
+ return m_nDocIdCounter;
}
-lang::Locale getPrimaryLanguageOfSentence( uno::Reference< text::XFlatParagraph > xFlatPara, sal_Int32 nStartIndex )
+
+sal_Int32 GrammarCheckingIterator::GetOrCreateDocId(
+ const uno::Reference< lang::XComponent > &xComponent )
{
- (void) nStartIndex;
- //get the language of the first word
- return xFlatPara->getLanguageOfText(nStartIndex, 1);//nStartIndex
+ // internal method; will always be called with locked mutex
+
+ sal_Int32 nRes = -1;
+ if (xComponent.is())
+ {
+ if (m_aDocIdMap.find( xComponent ) != m_aDocIdMap.end())
+ {
+ // add new entry
+ nRes = m_aDocIdMap[ xComponent ];
+ xComponent->addEventListener( this );
+ }
+ else // return already existing entry
+ {
+ nRes = NextDocId();
+ m_aDocIdMap[ xComponent ] = nRes;
+ }
+ }
+ return nRes;
}
+
void GrammarCheckingIterator::AddEntry(
uno::WeakReference< text::XFlatParagraphIterator > xFlatParaIterator,
uno::WeakReference< text::XFlatParagraph > xFlatPara,
- sal_Int32 nDocID,
+ sal_Int32 nDocId,
sal_Int32 nStartIndex,
sal_Bool bAutomatic )
{
- osl::Guard< osl::Mutex > aGuard(GetMutex());
+ // we may not need/have a xFlatParaIterator (e.g. if checkGrammarAtPos was called)
+ // but we always need a xFlatPara...
+ uno::Reference< text::XFlatParagraph > xPara( xFlatPara );
+ if (xPara.is())
+ {
+ FPEntry aNewFPEntry;
+ aNewFPEntry.m_xParaIterator = xFlatParaIterator;
+ aNewFPEntry.m_xPara = xFlatPara;
+ aNewFPEntry.m_nDocId = nDocId;
+ aNewFPEntry.m_nStartIndex = nStartIndex;
+ aNewFPEntry.m_bAutomatic = bAutomatic;
+
+ // add new entry to the end of this queue
+ ::osl::Guard< ::osl::Mutex > aGuard( m_aMutex );
+ m_aFPEntriesQueue.push_back( aNewFPEntry );
+
+ // wake up the thread in order to do grammar checking
+ m_aWakeUpThread.set();
+ }
+}
+
+
+void GrammarCheckingIterator::ProcessResult(
+ const linguistic2::GrammarCheckingResult &rRes,
+ sal_Int32 nSentenceStartPos,
+ const uno::Reference< text::XFlatParagraphIterator > &rxFlatParagraphIterator,
+ bool bIsAutomaticChecking )
+{
+ DBG_ASSERT( rRes.xFlatParagraph.is(), "xFlatParagraph is missing" );
+
+ sal_Bool bContinueWithNextPara = sal_False;
+ if (!rRes.xFlatParagraph.is() || rRes.xFlatParagraph->isModified())
+ {
+ // if paragraph was modified/deleted meanwhile continue with the next one...
+ bContinueWithNextPara = sal_True;
+ }
+ else // paragraph is still unchanged...
+ {
+ // mark found errors...
+ bool bBoundariesOk = 0 <= nSentenceStartPos && nSentenceStartPos <= rRes.nEndOfSentencePos;
+ DBG_ASSERT( bBoundariesOk, "inconsistent sentence boundaries" );
+ uno::Sequence< linguistic2::SingleGrammarError > aErrors = rRes.aGrammarErrors;
+ if (aErrors.getLength() > 0 && bBoundariesOk)
+ {
+ for (sal_Int16 i = 0; i < aErrors.getLength(); ++i)
+ {
+ linguistic2::SingleGrammarError aError = aErrors[aErrors.getLength() - 1 - i];
- FPEntry aNewFPEntry;
- aNewFPEntry.m_xParaIterator = xFlatParaIterator;
- aNewFPEntry.m_xPara = xFlatPara;
- aNewFPEntry.m_nDocID = nDocID;
- aNewFPEntry.m_nStartIndex = nStartIndex;
- aNewFPEntry.m_bAutomatic = bAutomatic;
+ OUString aIdentifier;
+ uno::Reference< container::XStringKeyMap > xStringKeyMap;
+
+ // display the grammar error mark
+ rRes.xFlatParagraph->commitTextMarkup( aError.nErrorType, aIdentifier, aError.nErrorStart, aError.nErrorLength, xStringKeyMap );
+
+ // commit sentence markup to identify sentence boundaries
+ const sal_Int32 nSentenceLength = rRes.nEndOfSentencePos - nSentenceStartPos;
+ rRes.xFlatParagraph->commitTextMarkup( text::TextMarkupType::SENTENCE, aIdentifier, nSentenceStartPos, nSentenceLength, xStringKeyMap );
+ }
+ }
+
+ // other sentences left to be checked in this paragraph?
+ if (rRes.nEndOfSentencePos < rRes.aText.getLength())
+ {
+ AddEntry( rxFlatParagraphIterator, rRes.xFlatParagraph, rRes.nDocumentId, rRes.nEndOfSentencePos, bIsAutomaticChecking );
+ }
+ else // current paragraph finished
+ {
+ // set "already checked" flag for the current flat paragraph
+ if (rRes.xFlatParagraph.is())
+ rRes.xFlatParagraph->setChecked( text::TextMarkupType::GRAMMAR, true );
- // add new entry to the end of this queue
- m_aFPQueue.push_back(aNewFPEntry);
+ bContinueWithNextPara = sal_True;
+ }
+ }
- // wake up the thread in order to do grammar checking
- m_aCondition.set();
+ if (bContinueWithNextPara)
+ {
+ // we need to continue with the next paragraph
+ uno::Reference< text::XFlatParagraph > xFlatParaNext;
+ if (rxFlatParagraphIterator.is())
+ xFlatParaNext = rxFlatParagraphIterator->getNextPara();
+ {
+ AddEntry( rxFlatParagraphIterator, xFlatParaNext, rRes.nDocumentId, 0, bIsAutomaticChecking );
+ }
+ }
}
-//doGrammarChecking_Impl
-void GrammarCheckingIterator::doGrammarChecking_Impl(
- sal_Int32 nDocId,
- const uno::Reference< text::XFlatParagraph > & xFlatPara,
- const lang::Locale & rLocale,
- sal_Int32 nStartOfSentencePos,
- sal_Int32 nSuggestedSentenceEndPos)
+
+uno::Reference< linguistic2::XGrammarChecker > GrammarCheckingIterator::GetGrammarChecker(
+ const lang::Locale &rLocale )
{
- //check the locale
- /*if(m_aGCLocales.size() == 0)
+ (void) rLocale;
+ uno::Reference< linguistic2::XGrammarChecker > xRes;
+
+ // ---- THREAD SAFE START ----
+ ::osl::Guard< ::osl::Mutex > aGuard( m_aMutex );
+
+ // check supported locales for each grammarchecker if not already done
+ if (!m_bGCServicesChecked)
{
- GetAvailableGCSvcs_Impl();
+ //GetAvailableGCSvcs_Impl();
+ //GetConfiguredGCSvcs_Impl();
+ GetMatchingGCSvcs_Impl();
+ m_bGCServicesChecked = sal_True;
}
- for (GCLocales_t::const_iterator it = m_aGCLocales.begin(); it != m_aGCLocales.end(); ++ it)
+
+ const LanguageType nLang = MsLangId::convertLocaleToLanguage( rLocale );
+ GCImplNames_t::const_iterator aLangIt( m_aGCImplNamesByLang.find( nLang ) );
+ if (aLangIt != m_aGCImplNamesByLang.end()) // matching configured language found?
{
- uno::Sequence< lang::Locale > aLocales = it->second;
- for (sal_Int32 i=0; i<aLocales.getLength(); ++i)
+ OUString aSvcImplName( aLangIt->second );
+ GCReferences_t::const_iterator aImplNameIt( m_aGCReferencesByService.find( aSvcImplName ) );
+ if (aImplNameIt != m_aGCReferencesByService.end()) // matching impl name found?
+ {
+ xRes = aImplNameIt->second;
+ }
+ else // the service is to be instatiated here for the first time...
{
- if( MsLangId::convertLocaleToLanguage(aLocales[i]) == MsLangId::convertLocaleToLanguage(rLocale))
+ try
+ {
+ uno::Reference< lang::XMultiServiceFactory > xMgr(
+ utl::getProcessServiceFactory(), uno::UNO_QUERY_THROW );
+ uno::Reference< linguistic2::XGrammarChecker > xGC(
+ xMgr->createInstance( aSvcImplName ), uno::UNO_QUERY_THROW );
+ uno::Reference< linguistic2::XSupportedLocales > xSuppLoc( xGC, uno::UNO_QUERY_THROW );
+
+ if (xSuppLoc->hasLocale( rLocale ))
+ {
+ m_aGCReferencesByService[ aSvcImplName ] = xGC;
+ xRes = xGC;
+
+ uno::Reference< linguistic2::XLinguServiceEventBroadcaster > xBC( xGC, uno::UNO_QUERY );
+ if (xBC.is())
+ xBC->addLinguServiceEventListener( this );
+ }
+ else
+ {
+ DBG_ASSERT( 0, "grammar checker does not support required locale" );
+ }
+ }
+ catch (uno::Exception &)
{
- GrammarChecker* pGC=new GrammarChecker();
- pGC->addGrammarCheckingResultListener((XGrammarCheckingResultListener *) this);
- pGC->doGrammarChecking(nDocId, xFlatPara, rLocale, nStartOfSentencePos, nSuggestedSentenceEndPos);//rFlatParaText
- break;
+ DBG_ASSERT( 0, "instantiating grammar checker failed" );
}
}
- }*/
- GrammarChecker* pGC=new GrammarChecker();
- pGC->addGrammarCheckingResultListener((XGrammarCheckingResultListener *) this);
- pGC->doGrammarChecking(nDocId, xFlatPara, rLocale, nStartOfSentencePos, nSuggestedSentenceEndPos);//rFlatParaText
+ }
+ // ---- THREAD SAFE END ----
+ return xRes;
}
-//get every element from the queue and check it
-void GrammarCheckingIterator::dequeueAndCheck()
+void GrammarCheckingIterator::DequeueAndCheck()
{
+ uno::Sequence< sal_Int32 > aLangPortions;
+ uno::Sequence< lang::Locale > aLangPortionsLocale;
+
// ---- THREAD SAFE START ----
- osl::ResettableGuard< osl::Mutex > aGuard(GetMutex());
- bool bEnd( m_bEnd );
- aGuard.clear();
+ bool bEnd = false;
+ {
+ ::osl::Guard< ::osl::Mutex > aGuard( m_aMutex );
+ bEnd = m_bEnd;
+ }
// ---- THREAD SAFE END ----
- while( !bEnd )
+ while (!bEnd)
{
// ---- THREAD SAFE START ----
- aGuard.reset();
- bool bQueueEmpty = m_aFPQueue.empty();
- aGuard.clear();
+ bool bQueueEmpty = false;
+ {
+ ::osl::Guard< ::osl::Mutex > aGuard( m_aMutex );
+ bQueueEmpty = m_aFPEntriesQueue.empty();
+ }
// ---- THREAD SAFE END ----
- if( !bQueueEmpty )
+ if (!bQueueEmpty)
{
+ uno::Reference< text::XFlatParagraphIterator > xFPIterator;
+ uno::Reference< text::XFlatParagraph > xFlatPara;
+ FPEntry aFPEntryItem;
+ sal_Int32 nCurDocId = - 1;
+ sal_Bool bModified = sal_False;
// ---- THREAD SAFE START ----
- aGuard.reset();
-
- FPEntry aFPEntryItem = m_aFPQueue.front();
-
- uno::Reference< text::XFlatParagraphIterator > xFPIterator( uno::Reference< text::XFlatParagraphIterator >( aFPEntryItem.m_xParaIterator ), uno::UNO_QUERY);
+ {
+ ::osl::Guard< ::osl::Mutex > aGuard( m_aMutex );
+ aFPEntryItem = m_aFPEntriesQueue.front();
+ xFPIterator = aFPEntryItem.m_xParaIterator;
+ xFlatPara = aFPEntryItem.m_xPara;
+ m_nCurCheckedDocId = aFPEntryItem.m_nDocId;
+ nCurDocId = m_nCurCheckedDocId;
+
+ m_aFPEntriesQueue.pop_front();
+ }
+ // ---- THREAD SAFE END ----
- uno::Reference< text::XFlatParagraph > xFlatPara( uno::Reference< text::XFlatParagraph >( aFPEntryItem.m_xPara ), uno::UNO_QUERY );
- if(xFlatPara.is())
+ if (xFlatPara.is() && xFPIterator.is())
{
- OUString aCurTxt = xFlatPara->getText();
- sal_Int32 nEndPos=aCurTxt.getLength();
- lang::Locale aCurLocale=getPrimaryLanguageOfSentence(xFlatPara, 0);
- sal_Int32 nCurDocID=aFPEntryItem.m_nDocID;
+ OUString aCurTxt( xFlatPara->getText() );
+ lang::Locale aCurLocale = lcl_GetPrimaryLanguageOfSentence( xFlatPara, aFPEntryItem.m_nStartIndex );
- sal_Int32 nStartPos=aFPEntryItem.m_nStartIndex;
- while(nStartPos<nEndPos)
+ bModified = xFlatPara->isModified();
+ if (!bModified)
{
+ // ---- THREAD SAFE START ----
+ ::osl::ClearableGuard< ::osl::Mutex > aGuard( m_aMutex );
- sal_Int32 nCurEndPos=getSuggestedEndOfSentence( aCurTxt, nStartPos, aCurLocale);
- ////////////////////////////////////////////////
- //..............doGrammarChecking...............
- ////////////////////////////////////////////////
- doGrammarChecking_Impl(nCurDocID, xFlatPara, aCurLocale, nStartPos, nCurEndPos);
-
- nStartPos=nCurEndPos+1;
+ sal_Int32 nStartPos = aFPEntryItem.m_nStartIndex;
+ sal_Int32 nSuggestedEnd = GetSuggestedEndOfSentence( aCurTxt, nStartPos, aCurLocale );
- //update the startIndex of the entry
- aFPEntryItem.m_nStartIndex=nStartPos;
- m_aFPQueue.pop_front();
- m_aFPQueue.push_front(aFPEntryItem);
- }
- //remove the first element from the queue
- m_aFPQueue.pop_front();
+ linguistic2::GrammarCheckingResult aRes;
-
-
- if(xFlatPara->isModified( ))
- {
- //there is something unprocessed left in the current flat paragraph
- //add this flat paragraph to the end of the queue
- AddEntry( xFPIterator, xFlatPara, nCurDocID, 0, aFPEntryItem.m_bAutomatic );
+ uno::Reference< linguistic2::XGrammarChecker > xGC( GetGrammarChecker( aCurLocale ), uno::UNO_QUERY );
+ if (xGC.is())
+ {
+ aGuard.clear();
+ aRes = xGC->doGrammarChecking( nCurDocId, aCurTxt, aCurLocale, nStartPos, nSuggestedEnd, aLangPortions, aLangPortionsLocale );
+ aRes.xFlatParagraph = xFlatPara;
+ aRes.nStartOfSentencePos = nStartPos;
+ }
+ else
+ {
+ // no grammar checker -> no error
+ // but we need to provide the data below in order to continue with the next sentence
+ aRes.nDocumentId = nCurDocId;
+ aRes.xFlatParagraph = xFlatPara;
+ aRes.aText = aCurTxt;
+ aRes.aLocale = aCurLocale;
+ aRes.nStartOfSentencePos = nStartPos;
+ aRes.nEndOfSentencePos = nSuggestedEnd;
+ }
+ ProcessResult( aRes, nStartPos, xFPIterator, aFPEntryItem.m_bAutomatic );
+ // ---- THREAD SAFE END ----
}
else
{
- //set "alread checked" flag for the current flat paragraph
- //get the next flat paragraph to create a new entry
-
- xFlatPara->setChecked(text::TextMarkupType::GRAMMAR, true);
- uno::Reference< text::XFlatParagraph > xFlatParaNext = xFPIterator->getNextPara( );//getParaAfter( xFlatPara );//
- if( xFlatParaNext.is() )
- {
- AddEntry(xFPIterator, xFlatParaNext, nCurDocID, 0, aFPEntryItem.m_bAutomatic);
- }
+ // the paragraph changed meanwhile... (and maybe is still edited)
+ // thus we simply continue to ask for the next to be checked.
+ uno::Reference< text::XFlatParagraph > xFlatParaNext( xFPIterator->getNextPara() );
+ AddEntry( xFPIterator, xFlatParaNext, nCurDocId, 0, aFPEntryItem.m_bAutomatic );
}
}
- aGuard.clear();
+
+ // ---- THREAD SAFE START ----
+ {
+ ::osl::Guard< ::osl::Mutex > aGuard( m_aMutex );
+ m_nCurCheckedDocId = -1;
+ }
// ---- THREAD SAFE END ----
}
else
{
// ---- THREAD SAFE START ----
- aGuard.reset();
- // Check queue state again
- if ( m_aFPQueue.empty() )
- m_aCondition.reset();
- aGuard.clear();
+ {
+ ::osl::Guard< ::osl::Mutex > aGuard( m_aMutex );
+ // Check queue state again
+ if (m_aFPEntriesQueue.empty())
+ m_aWakeUpThread.reset();
+ }
// ---- THREAD SAFE END ----
//if the queue is empty
@@ -268,352 +454,601 @@ void GrammarCheckingIterator::dequeueAndCheck()
// mutex. Otherwise you would keep out other threads
// to add entries to the queue! A condition is thread-
// safe implemented.
- m_aCondition.wait();
+ m_aWakeUpThread.wait();
}
// ---- THREAD SAFE START ----
- aGuard.reset();
- bEnd = m_bEnd;
- aGuard.clear();
+ {
+ ::osl::Guard< ::osl::Mutex > aGuard( m_aMutex );
+ bEnd = m_bEnd;
+ }
// ---- THREAD SAFE END ----
}
+
+ //!! This one must be the very last statement to call in this function !!
+ m_aRequestEndThread.set();
}
-// linguistic2::XGrammarCheckingIterator:
void SAL_CALL GrammarCheckingIterator::startGrammarChecking(
- const uno::Reference< ::uno::XInterface > & xDoc,
- const uno::Reference< text::XFlatParagraphIteratorProvider > & xIteratorProvider,
- ::sal_Bool bAutomatic)
- throw (uno::RuntimeException, lang::IllegalArgumentException)
+ const uno::Reference< ::uno::XInterface > & xDoc,
+ const uno::Reference< text::XFlatParagraphIteratorProvider > & xIteratorProvider,
+ sal_Bool bAutomatic)
+throw (uno::RuntimeException, lang::IllegalArgumentException)
{
- (void) xDoc;
-
- /******************************************************************
- Add a returned value for this function????
- *******************************************************************/
- // TODO: Insert your implementation for "startGrammarChecking" here.
-
- // Create new entry and push it to the global queue
- osl::Guard< osl::Mutex > aGuard(GetMutex());
- uno::Reference<text::XFlatParagraphIterator> xFPIterator=
- xIteratorProvider->getFlatParagraphIterator(
- text::TextMarkupType::GRAMMAR,bAutomatic);
+ // get paragraph to start checking with
+ uno::Reference<text::XFlatParagraphIterator> xFPIterator = xIteratorProvider->getFlatParagraphIterator(
+ text::TextMarkupType::GRAMMAR, bAutomatic );
+ uno::Reference< text::XFlatParagraph > xPara( xFPIterator.is()? xFPIterator->getFirstPara() : NULL );
+ uno::Reference< lang::XComponent > xComponent( xDoc, uno::UNO_QUERY );
- uno::Reference< text::XFlatParagraph > xPara= xFPIterator->getFirstPara();
- if(xPara.is())
+ // ---- THREAD SAFE START ----
+ ::osl::Guard< ::osl::Mutex > aGuard( m_aMutex );
+ if (xPara.is() && xComponent.is())
{
- ::sal_Int32 nDocID = NextDocId();
- m_aDocMap[xDoc]=nDocID;
- AddEntry(xFPIterator, xPara, nDocID, 0, bAutomatic);
+ sal_Int32 nDocId = GetOrCreateDocId( xComponent );
+
+ // create new entry and add it to queue
+ AddEntry( xFPIterator, xPara, nDocId, 0, bAutomatic );
}
+ // ---- THREAD SAFE END ----
}
-void SAL_CALL GrammarCheckingIterator::checkGrammarAtPos(
- const uno::Reference< ::uno::XInterface > & xDoc,
- const uno::Reference< text::XFlatParagraph > & xStartPara,
- sal_Int32 nPosInPara)
- throw (uno::RuntimeException, lang::IllegalArgumentException)
+
+linguistic2::GrammarCheckingResult SAL_CALL GrammarCheckingIterator::checkGrammarAtPos(
+ const uno::Reference< uno::XInterface >& xDoc,
+ const uno::Reference< text::XFlatParagraph >& xFlatPara,
+ const OUString& rText,
+ const lang::Locale& rLocale,
+ sal_Int32 nStartOfSentencePos,
+ sal_Int32 nSuggestedEndOfSentencePos,
+ sal_Int32 nErrorPosInPara )
+throw (lang::IllegalArgumentException, uno::RuntimeException)
{
+ (void) rLocale;
- // TODO: Insert your implementation for "checkGrammarAtPos" here.
+ // for the context menu...
- //for the context menu
- OUString aTxt = xStartPara->getText();
- //sal_Int32 nEndPos=rTxt.getLength();
- lang::Locale aLocale=getPrimaryLanguageOfSentence(xStartPara, nPosInPara);
- uno::Reference< i18n::XBreakIterator > xBreakIterator;
- if(!xBreakIterator.is())
- {
- xBreakIterator=vcl::unohelper::CreateBreakIterator();
- }
- if(xBreakIterator.is())
+ linguistic2::GrammarCheckingResult aRes;
+
+ uno::Reference< lang::XComponent > xComponent( xDoc, uno::UNO_QUERY );
+ if (xFlatPara.is() && xComponent.is() &&
+ ( nErrorPosInPara < 0 || nErrorPosInPara < rText.getLength()))
{
- sal_Int32 nStartPosition=xBreakIterator->beginOfSentence(aTxt, nPosInPara, aLocale);;
- sal_Int32 nEndPosition=xBreakIterator->endOfSentence(aTxt, nStartPosition, aLocale);
+ uno::Sequence< sal_Int32 > aLangPortions;
+ uno::Sequence< lang::Locale > aLangPortionsLocale;
+
+ // iterate through paragraph until we find the sentence we are interested in
+ linguistic2::GrammarCheckingResult aTmpRes;
+ sal_Int32 nStartPos = nErrorPosInPara > 0 ? 0 : nStartOfSentencePos;
+ bool bFound = false;
+ do
+ {
+ lang::Locale aCurLocale = lcl_GetPrimaryLanguageOfSentence( xFlatPara, nStartPos );
+ sal_Int32 nOldStartOfSentencePos = nStartPos;
+ uno::Reference< linguistic2::XGrammarChecker > xGC;
+ sal_Int32 nDocId = -1;
+
+ // ---- THREAD SAFE START ----
+ {
+ ::osl::ClearableGuard< ::osl::Mutex > aGuard( m_aMutex );
+ nDocId = GetOrCreateDocId( xComponent );
+ nSuggestedEndOfSentencePos = GetSuggestedEndOfSentence( rText, nStartPos, aCurLocale );
+
+ xGC = GetGrammarChecker( aCurLocale );
+ }
+ // ---- THREAD SAFE START ----
+ sal_Int32 nEndPos = -1;
+ if (xGC.is())
+ {
+ aTmpRes = xGC->doGrammarChecking( nDocId, rText, aCurLocale, nStartPos, nSuggestedEndOfSentencePos, aLangPortions, aLangPortionsLocale );
+ aTmpRes.xFlatParagraph = xFlatPara;
+ aTmpRes.nStartOfSentencePos = nStartPos;
+ nEndPos = aTmpRes.nEndOfSentencePos;
+
+ if ((nErrorPosInPara< 0 || nStartPos <= nErrorPosInPara) && nErrorPosInPara < nEndPos)
+ bFound = true;
+ }
+ if (nEndPos == -1) // no result from grammar checker
+ nEndPos = nSuggestedEndOfSentencePos;
+ nStartPos = nEndPos;
- ////////////////////////////////////////////////
- //..............doGrammarChecking...............
- ////////////////////////////////////////////////
+ // prevent endless loop by forcefully advancing if needs be...
+ if (nStartPos <= nOldStartOfSentencePos)
+ {
+ DBG_ASSERT( 0, "end-of-sentence detection failed?" );
+ nStartPos = nOldStartOfSentencePos + 1;
+ }
+ }
+ while (!bFound && nStartPos < rText.getLength());
- sal_Int32 nDocID=m_aDocMap[xDoc];
- doGrammarChecking_Impl(nDocID, xStartPara, aLocale, nStartPosition, nEndPosition);//aTxt
+ if (bFound && !xFlatPara->isModified())
+ aRes = aTmpRes;
}
+
+ return aRes;
}
-sal_Int32 GrammarCheckingIterator::getSuggestedEndOfSentence( const OUString aText, sal_Int32 nSentenceStartPos, const lang::Locale aLocale )
+
+
+sal_Int32 GrammarCheckingIterator::GetSuggestedEndOfSentence(
+ const OUString &rText,
+ sal_Int32 nSentenceStartPos,
+ const lang::Locale &rLocale )
{
- // TODO: Exchange the default return implementation for "getEndOfSentence" !!!
- // Exchange the default return implementation.
- // NOTE: Default initialized polymorphic structs can cause problems because of
- // missing default initialization of primitive types of some C++ compilers or
- // different Any initialization in Java and C++ polymorphic structs.
+ // internal method; will always be called with locked mutex
uno::Reference< i18n::XBreakIterator > xBreakIterator;
- if(!xBreakIterator.is())
+ if (!m_xBreakIterator.is())
{
- xBreakIterator=vcl::unohelper::CreateBreakIterator();
+ m_xBreakIterator = vcl::unohelper::CreateBreakIterator();
}
- sal_Int32 nEndPosition=0;
- if(xBreakIterator.is())
+ sal_Int32 nTextLen = rText.getLength();
+ sal_Int32 nEndPosition = nTextLen;
+ if (m_xBreakIterator.is())
{
- nEndPosition=xBreakIterator->endOfSentence(aText, nSentenceStartPos, aLocale);
+ sal_Int32 nTmpStartPos = nSentenceStartPos;
+ do
+ {
+ nEndPosition = nTextLen;
+ if (nTmpStartPos < nTextLen)
+ nEndPosition = m_xBreakIterator->endOfSentence( rText, nTmpStartPos, rLocale );
+ ++nTmpStartPos;
+ }
+ while (nEndPosition <= nSentenceStartPos && nEndPosition < nTextLen);
+ if (nEndPosition > nTextLen)
+ nEndPosition = nTextLen;
}
return nEndPosition;
}
-sal_Int32 SAL_CALL GrammarCheckingIterator::getEndOfSentence( sal_Int32 nSentenceStartPos )
- throw (uno::RuntimeException, lang::IllegalArgumentException)
-{
- // TODO: Exchange the default return implementation for "getEndOfSentence" !!!
- // Exchange the default return implementation.
- // NOTE: Default initialized polymorphic structs can cause problems because of
- // missing default initialization of primitive types of some C++ compilers or
- // different Any initialization in Java and C++ polymorphic structs.
+sal_Int32 SAL_CALL GrammarCheckingIterator::getEndOfSentence(
+ const uno::Reference< text::XFlatParagraph >& xFlatPara,
+ sal_Int32 nSentenceStartPos )
+throw (lang::IllegalArgumentException, uno::RuntimeException)
+{
+ ::osl::Guard< ::osl::Mutex > aGuard( m_aMutex );
+ (void) xFlatPara;
(void)nSentenceStartPos;
- /*uno::Reference< i18n::XBreakIterator > xBreakIterator;
- if(!xBreakIterator.is())
- {
- xBreakIterator=vcl::unohelper::CreateBreakIterator();
- }
- sal_Int32 nEndPosition=0;
- if(xBreakIterator.is())
- {
+ return 0;
+}
+
+
+sal_Bool SAL_CALL GrammarCheckingIterator::isGrammarChecking(
+ const uno::Reference< uno::XInterface >& xDoc,
+ sal_Bool bAutomatic )
+throw (uno::RuntimeException)
+{
+ // ---- THREAD SAFE START ----
+ ::osl::Guard< ::osl::Mutex > aGuard( m_aMutex );
+
+ (void) bAutomatic;
+ sal_Bool bRes = sal_False;
- struct FPEntry aNewFPEntry=m_aFPQueue.front();
- uno::Reference< text::XFlatParagraph > xFlatPara( uno::Reference< text::XFlatParagraph >( aNewFPEntry.xPara ), uno::UNO_QUERY );
- if(xFlatPara.is())
+ uno::Reference< lang::XComponent > xComponent( xDoc, uno::UNO_QUERY );
+ if (xComponent.is())
+ {
+ sal_Int32 nDocId = m_aDocIdMap[ xComponent ];
+ if (m_nCurCheckedDocId >= 0 && m_nCurCheckedDocId == nDocId)
+ bRes = sal_True;
+ else if (m_aDocIdMap.find( xComponent ) != m_aDocIdMap.end())
+ {
+ sal_Int32 nSize = m_aFPEntriesQueue.size();
+ for (sal_Int32 i = 0; i < nSize && !bRes; ++i)
{
- OUString aCurTxt = xFlatPara->getText();
- lang::Locale aCurLocale=getPrimaryLanguageOfSentence(xFlatPara, 0);
- nEndPosition=xBreakIterator->endOfSentence(aCurTxt, nSentenceStartPos, aCurLocale);
+ if (nDocId == m_aFPEntriesQueue[i].m_nDocId /*&& m_aFPEntriesQueue[i].m_bAutomatic == bAutomatic*/)
+ bRes = sal_True;
}
+ }
}
- return nEndPosition;*/
- return 0;
+ // ---- THREAD SAFE END ----
+ return bRes;
}
-::sal_Bool SAL_CALL GrammarCheckingIterator::isChecking( const uno::Reference< ::uno::XInterface > & xDoc )
- throw (uno::RuntimeException)
+
+void SAL_CALL GrammarCheckingIterator::processLinguServiceEvent(
+ const linguistic2::LinguServiceEvent& rLngSvcEvent )
+throw (uno::RuntimeException)
{
- // TODO: Exchange the default return implementation for "isChecking" !!!
- // Exchange the default return implementation.
- // NOTE: Default initialized polymorphic structs can cause problems because of
- // missing default initialization of primitive types of some C++ compilers or
- // different Any initialization in Java and C++ polymorphic structs.
- osl::Guard< osl::Mutex > aGuard(GetMutex());
- sal_Bool bCheck=sal_False;
- if(m_aDocMap.find(xDoc) != m_aDocMap.end())
+ if (rLngSvcEvent.nEvent == linguistic2::LinguServiceEventFlags::GRAMMAR_CHECK_AGAIN)
{
- sal_Int32 nDocID = m_aDocMap[xDoc];
- if(!m_aFPQueue.empty())
+ try
{
- sal_Int32 nSize = m_aFPQueue.size();
- for( sal_Int32 i=0; i < nSize; ++i )
- {
- FPEntry aNewFPEntry = m_aFPQueue[i];
- if( nDocID == aNewFPEntry.m_nDocID )
- {
- return true;
- }
- }
+ uno::Reference< uno::XInterface > xThis(*this);
+ linguistic2::LinguServiceEvent aEvent( xThis, linguistic2::LinguServiceEventFlags::GRAMMAR_CHECK_AGAIN );
+ m_aNotifyListeners.notifyEach(
+ &linguistic2::XLinguServiceEventListener::processLinguServiceEvent,
+ aEvent);
+ }
+ catch (uno::RuntimeException &)
+ {
+ throw;
+ }
+ catch (::uno::Exception &rE)
+ {
+ (void) rE;
+ // ignore
+ DBG_WARNING1("processLinguServiceEvent: exception:\n%s",
+ OUStringToOString(rE.Message, RTL_TEXTENCODING_UTF8).getStr());
}
}
- return bCheck;
+}
+
+sal_Bool SAL_CALL GrammarCheckingIterator::addLinguServiceEventListener(
+ const uno::Reference< linguistic2::XLinguServiceEventListener >& xListener )
+throw (uno::RuntimeException)
+{
+ if (xListener.is())
+ {
+// ::osl::Guard< ::osl::Mutex > aGuard( m_aMutex );
+ m_aNotifyListeners.addInterface( xListener );
+ }
+ return sal_True;
}
-// linguistic2::XGrammarCheckingResultListener:
-::sal_Bool SAL_CALL GrammarCheckingIterator::GrammarCheckingFinished( const linguistic2::GrammarCheckingResult & aRes )
- throw (uno::RuntimeException, lang::IllegalArgumentException)
+
+sal_Bool SAL_CALL GrammarCheckingIterator::removeLinguServiceEventListener(
+ const uno::Reference< linguistic2::XLinguServiceEventListener >& xListener )
+throw (uno::RuntimeException)
{
- // TODO: Exchange the default return implementation for "GrammarCheckingFinished" !!!
- // Exchange the default return implementation.
- // NOTE: Default initialized polymorphic structs can cause problems because of
- // missing default initialization of primitive types of some C++ compilers or
- // different Any initialization in Java and C++ polymorphic structs.
+ if (xListener.is())
+ {
+// ::osl::Guard< ::osl::Mutex > aGuard( m_aMutex );
+ m_aNotifyListeners.removeInterface( xListener );
+ }
+ return sal_True;
+}
- //mark the error sign
- uno::Sequence< linguistic2::SingleGrammarError > aErrors=aRes.aGrammarErrors;
- if(aErrors.getLength()>0)
+void SAL_CALL GrammarCheckingIterator::dispose()
+throw (uno::RuntimeException)
+{
+ lang::EventObject aEvt( (linguistic2::XGrammarCheckingIterator *) this );
+ m_aEventListeners.disposeAndClear( aEvt );
+
+ //
+ // now end the thread...
+ //
+ m_aRequestEndThread.reset();
+ // ---- THREAD SAFE START ----
{
- for( sal_Int16 i=0; i < aErrors.getLength(); ++i)
- {
+ ::osl::Guard< ::osl::Mutex > aGuard( m_aMutex );
+ m_bEnd = sal_True;
+ }
+ // ---- THREAD SAFE END ----
+ m_aWakeUpThread.set();
+ const TimeValue aTime = { 3, 0 }; // wait 3 seconds...
+ m_aRequestEndThread.wait( &aTime );
+ // if the call ends because of time-out we will end anyway...
+
+
+ // ---- THREAD SAFE START ----
+ {
+ ::osl::Guard< ::osl::Mutex > aGuard( m_aMutex );
- linguistic2::SingleGrammarError aError = aErrors[aErrors.getLength()-1-i];
- ///////////////////////////////////////////////////////////////////////////////////////////////
- //spelling checkers and grammar checkers spontaneously simultaneously check the same sentence//
- //linguistic::GetLinguProperties()????????????????????????????????????????????????????????????
- ///////////////////////////////////////////////////////////////////////////////////////////////
+ // releaase all UNO references
- uno::Sequence< beans::PropertyValue > aAttributes;
- OUString aIdentifier;
- uno::Reference< container::XStringKeyMap > xStringKeyMap;
- //display the grammar error mark
- aRes.xPara->commitTextMarkup(aError.nErrorType, aIdentifier ,aError.nErrorStart ,aError.nErrorLen, xStringKeyMap);
+ m_xMSF.clear();
+ m_xBreakIterator.clear();
- }
+ // clear containers with UNO references AND have those references released
+ GCReferences_t aTmpEmpty1;
+ DocMap_t aTmpEmpty2;
+ FPQueue_t aTmpEmpty3;
+ m_aGCReferencesByService.swap( aTmpEmpty1 );
+ m_aDocIdMap.swap( aTmpEmpty2 );
+ m_aFPEntriesQueue.swap( aTmpEmpty3 );
}
+ // ---- THREAD SAFE END ----
+}
+
+
+void SAL_CALL GrammarCheckingIterator::addEventListener(
+ const uno::Reference< lang::XEventListener >& xListener )
+throw (uno::RuntimeException)
+{
+ if (xListener.is())
+ {
+// ::osl::Guard< ::osl::Mutex > aGuard( m_aMutex );
+ m_aEventListeners.addInterface( xListener );
+ }
+}
- sal_Bool bResult=aRes.nEndOfSentencePos < aRes.xPara->getText().getLength();
- aRes.xPara->setChecked(text::TextMarkupType::GRAMMAR, bResult);
- return bResult;
+
+void SAL_CALL GrammarCheckingIterator::removeEventListener(
+ const uno::Reference< lang::XEventListener >& xListener )
+throw (uno::RuntimeException)
+{
+ if (xListener.is())
+ {
+// ::osl::Guard< ::osl::Mutex > aGuard( m_aMutex );
+ m_aEventListeners.removeInterface( xListener );
+ }
}
-/*// linguistic2::XGrammarCheckingResultListener:
-void SAL_CALL GrammarCheckingIterator::processGrammarCheckingResult(
- com::sun::star::linguistic2::GrammarCheckingResult aRes,
- sal_Bool bLastInCurrentPara)
- throw (uno::RuntimeException)
+
+void SAL_CALL GrammarCheckingIterator::disposing( const lang::EventObject &rSource )
+throw (uno::RuntimeException)
{
- (void) aRes;
- (void) bLastInCurrentPara;
-}*/
+ // if the component (document) is disposing release all references
+ //!! There is no need to remove entries from the queue that are from this document
+ //!! since the respectives xFlatParagraphs should become invalid (isModified() == true)
+ //!! and the call to xFlatParagraphIterator->getNextPara() will result in an empty reference.
+ //!! And if an entry is currently checked by a grammar checker upon return the results
+ //!! should be ignored.
+ //!! All of the above resulting in that we only have to get rid of all references here.
+ uno::Reference< lang::XComponent > xDoc( rSource.Source, uno::UNO_QUERY );
+ if (xDoc.is())
+ {
+ // ---- THREAD SAFE START ----
+ ::osl::Guard< ::osl::Mutex > aGuard( m_aMutex );
+ m_aDocIdMap.erase( xDoc );
+ // ---- THREAD SAFE END ----
+ }
+}
+
-void SAL_CALL GrammarCheckingIterator::dispose( ) throw (uno::RuntimeException)
+uno::Reference< util::XChangesBatch > GrammarCheckingIterator::GetUpdateAccess() const
{
+ if (!m_xUpdateAccess.is())
+ {
+ try
+ {
+ // get configuration provider
+ uno::Reference< lang::XMultiServiceFactory > xConfigurationProvider;
+ uno::Reference< lang::XMultiServiceFactory > xMgr = utl::getProcessServiceFactory();
+ if (xMgr.is())
+ {
+ xConfigurationProvider = uno::Reference< lang::XMultiServiceFactory > (
+ xMgr->createInstance( OUString( RTL_CONSTASCII_USTRINGPARAM(
+ "com.sun.star.configuration.ConfigurationProvider" ) ) ),
+ uno::UNO_QUERY_THROW ) ;
+ }
+ // get configuration update access
+ beans::PropertyValue aValue;
+ aValue.Name = A2OU( "nodepath" );
+ aValue.Value = uno::makeAny( A2OU("org.openoffice.Office.Linguistic/ServiceManager") );
+ uno::Sequence< uno::Any > aProps(1);
+ aProps[0] <<= aValue;
+ m_xUpdateAccess = uno::Reference< util::XChangesBatch >(
+ xConfigurationProvider->createInstanceWithArguments(
+ A2OU( "com.sun.star.configuration.ConfigurationUpdateAccess" ), aProps ),
+ uno::UNO_QUERY_THROW );
+ }
+ catch (uno::Exception &)
+ {
+ }
+ }
+
+ return m_xUpdateAccess;
}
-void SAL_CALL GrammarCheckingIterator::addEventListener( const uno::Reference< lang::XEventListener >& xListener )
- throw (uno::RuntimeException)
+/*
+void GrammarCheckingIterator::GetConfiguredGCSvcs_Impl()
{
- (void) xListener;
+ GCImplNames_t aTmpGCImplNamesByLang;
+
+ try
+ {
+ // get node names (locale iso strings) for configured grammar checkers
+ uno::Reference< container::XNameAccess > xNA( GetUpdateAccess(), uno::UNO_QUERY_THROW );
+ xNA.set( xNA->getByName( A2OU("GrammarCheckerList") ), uno::UNO_QUERY_THROW );
+ const uno::Sequence< OUString > aElementNames( xNA->getElementNames() );
+ const OUString *pElementNames = aElementNames.getConstArray();
+
+ sal_Int32 nLen = aElementNames.getLength();
+ for (sal_Int32 i = 0; i < nLen; ++i)
+ {
+ uno::Sequence< OUString > aImplNames;
+ uno::Any aTmp( xNA->getByName( pElementNames[i] ) );
+ if (aTmp >>= aImplNames)
+ {
+ if (aImplNames.getLength() > 0)
+ {
+ // only the first entry is used, there should be only one grammar checker per language
+ const OUString aImplName( aImplNames[0] );
+ const LanguageType nLang = MsLangId::convertIsoStringToLanguage( pElementNames[i] );
+ aTmpGCImplNamesByLang[ nLang ] = aImplName;
+ }
+ }
+ else
+ {
+ DBG_ASSERT( 0, "failed to get aImplNames. Wrong type?" );
+ }
+ }
+ }
+ catch (uno::Exception &)
+ {
+ DBG_ASSERT( 0, "exception caught. Failed to get configured services" );
+ }
+
+ {
+ // ---- THREAD SAFE START ----
+ ::osl::Guard< ::osl::Mutex > aGuard( m_aMutex );
+ m_aGCImplNamesByLang = aTmpGCImplNamesByLang;
+ // ---- THREAD SAFE END ----
+ }
}
+*/
-void SAL_CALL GrammarCheckingIterator::removeEventListener( const uno::Reference< lang::XEventListener >& xListener )
- throw (uno::RuntimeException)
+void GrammarCheckingIterator::GetMatchingGCSvcs_Impl()
{
- (void) xListener;
+ GCImplNames_t aTmpGCImplNamesByLang;
+
+ try
+ {
+ // get node names (locale iso strings) for configured grammar checkers
+ uno::Reference< container::XNameAccess > xNA( GetUpdateAccess(), uno::UNO_QUERY_THROW );
+ xNA.set( xNA->getByName( A2OU("GrammarCheckers") ), uno::UNO_QUERY_THROW );
+ const uno::Sequence< OUString > aGCImplNames( xNA->getElementNames() );
+ const OUString *pGCImplNames = aGCImplNames.getConstArray();
+
+ sal_Int32 nLen = aGCImplNames.getLength();
+ for (sal_Int32 i = 0; i < nLen; ++i)
+ {
+ uno::Reference< container::XNameAccess > xTmpNA( xNA->getByName( pGCImplNames[i] ), uno::UNO_QUERY_THROW );
+ uno::Any aTmp( xTmpNA->getByName( A2OU("Locales") ) );
+ uno::Sequence< OUString > aIsoLocaleNames;
+ if (aTmp >>= aIsoLocaleNames)
+ {
+ const OUString *pIsoLocaleNames = aIsoLocaleNames.getConstArray();
+ for (sal_Int32 k = 0; k < aIsoLocaleNames.getLength(); ++k)
+ {
+ // if there are more grammar checkers for one language, for the time being,
+ // the last one found here will win...
+ const LanguageType nLang = MsLangId::convertIsoStringToLanguage( pIsoLocaleNames[k] );
+ aTmpGCImplNamesByLang[ nLang ] = pGCImplNames[i];
+ }
+ }
+ else
+ {
+ DBG_ASSERT( 0, "failed to get aImplNames. Wrong type?" );
+ }
+ }
+ }
+ catch (uno::Exception &)
+ {
+ DBG_ASSERT( 0, "exception caught. Failed to get matching grammar checker services" );
+ }
+
+ {
+ // ---- THREAD SAFE START ----
+ ::osl::Guard< ::osl::Mutex > aGuard( m_aMutex );
+ m_aGCImplNamesByLang = aTmpGCImplNamesByLang;
+ // ---- THREAD SAFE END ----
+ }
}
-const void GrammarCheckingIterator::GetAvailableGCSvcs_Impl()
+
+/*
+void GrammarCheckingIterator::GetAvailableGCSvcs_Impl()
{
- uno::Reference< lang::XMultiServiceFactory > xFac( getProcessServiceFactory() );
- if (xFac.is())
+ // internal method; will always be called with locked mutex
+ if (m_xMSF.is())
{
- uno::Reference< container::XContentEnumerationAccess > xEnumAccess( xFac, uno::UNO_QUERY );
+ uno::Reference< container::XContentEnumerationAccess > xEnumAccess( m_xMSF, uno::UNO_QUERY );
uno::Reference< container::XEnumeration > xEnum;
if (xEnumAccess.is())
- xEnum = xEnumAccess->createContentEnumeration(
- A2OU( "com.sun.star.lingu2.GrammarChecker" ) );//SN_SPELLCHECKER
+ xEnum = xEnumAccess->createContentEnumeration( A2OU( SN_GRAMMARCHECKER ) );
if (xEnum.is())
{
while (xEnum->hasMoreElements())
{
uno::Any aCurrent = xEnum->nextElement();
+ uno::Reference< lang::XSingleComponentFactory > xCompFactory;
uno::Reference< lang::XSingleServiceFactory > xFactory;
- if (!::cppu::extractInterface( xFactory, aCurrent ))
- continue;
+ uno::Reference< uno::XComponentContext > xContext;
+ uno::Reference< beans::XPropertySet > xProps( m_xMSF, uno::UNO_QUERY );
+ xProps->getPropertyValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DefaultContext" ))) >>= xContext;
- uno::Reference< linguistic2::XGrammarChecker > xSvc( xFactory->createInstance(), uno::UNO_QUERY );
- if (xSvc.is())
+ if ( xContext.is() &&
+ (cppu::extractInterface( xCompFactory, aCurrent ) ||
+ cppu::extractInterface( xFactory, aCurrent )) )
{
- OUString aImplName;
- //uno::Sequence< INT16 > aLanguages;
- uno::Reference< XServiceInfo > xInfo( xSvc, uno::UNO_QUERY );
- if (xInfo.is())
- aImplName = xInfo->getImplementationName();
- DBG_ASSERT( aImplName.getLength(),
- "empty implementation name" );
- uno::Reference< linguistic2::XSupportedLocales > xSuppLoc( xSvc, uno::UNO_QUERY );
- DBG_ASSERT( xSuppLoc.is(), "interfaces not supported" );
- if (xSuppLoc.is()) {
- uno::Sequence< lang::Locale > aLocaleSequence(xSuppLoc->getLocales());
- m_aGCLocales[aImplName]=aLocaleSequence;
- //aLanguages = LocaleSeqToLangSeq( aLocaleSequence );
+ try
+ {
+ uno::Reference< linguistic2::XGrammarChecker > xSvc( ( xCompFactory.is() ? xCompFactory->createInstanceWithContext( xContext ) : xFactory->createInstance() ), uno::UNO_QUERY );
+ if (xSvc.is())
+ {
+ OUString aImplName;
+ uno::Reference< XServiceInfo > xInfo( xSvc, uno::UNO_QUERY );
+ if (xInfo.is())
+ aImplName = xInfo->getImplementationName();
+ DBG_ASSERT( aImplName.getLength(), "empty implementation name" );
+ uno::Reference< linguistic2::XSupportedLocales > xSuppLoc( xSvc, uno::UNO_QUERY );
+ DBG_ASSERT( xSuppLoc.is(), "interfaces not supported" );
+ if (xSuppLoc.is() && aImplName.getLength() > 0)
+ {
+ uno::Sequence< lang::Locale > aLocaleSequence( xSuppLoc->getLocales() );
+ // ---- THREAD SAFE START ----
+ ::osl::Guard< ::osl::Mutex > aGuard( m_aMutex );
+ m_aGCLocalesByService[ aImplName ] = aLocaleSequence;
+ m_aGCReferencesByService[ aImplName ] = xSvc;
+ // ---- THREAD SAFE END ----
+ }
+ }
+ }
+ catch (uno::Exception &)
+ {
+ DBG_ASSERT( 0, "instantiating grammar checker failed" );
}
-
- //pAvailSpellSvcs->Insert( new SvcInfo( aImplName, aLanguages ),
- // pAvailSpellSvcs->Count() );
- //m_aGCLocales[aImplName]=aLocaleSequence;//aLanguages;
}
}
}
}
}
+*/
-sal_Bool SAL_CALL GrammarCheckingIterator::supportsService( const OUString& ServiceName ) throw(uno::RuntimeException)
-{
- osl::Guard< osl::Mutex > aGuard(GetMutex());
+sal_Bool SAL_CALL GrammarCheckingIterator::supportsService(
+ const OUString & rServiceName )
+throw(uno::RuntimeException)
+{
uno::Sequence< OUString > aSNL = getSupportedServiceNames();
const OUString * pArray = aSNL.getConstArray();
for( INT32 i = 0; i < aSNL.getLength(); ++i )
- if( pArray[i] == ServiceName )
+ if( pArray[i] == rServiceName )
return TRUE;
return FALSE;
}
-uno::Sequence< OUString > GrammarCheckingIterator::getSupportedServiceNames_Static() throw()
-{
- //osl::Guard< osl::Mutex > aGuard(GetMutex());
- uno::Sequence< OUString > aSNS( 1 ); // auch mehr als 1 Service moeglich
- aSNS.getArray()[0] = A2OU( "com.sun.star.linguistic2.GrammarCheckingIterator" );//SN_LINGU_SERVCICE_MANAGER
- return aSNS;
+OUString SAL_CALL GrammarCheckingIterator::getImplementationName( ) throw (uno::RuntimeException)
+{
+ return GrammarCheckingIterator_getImplementationName();
}
-uno::Sequence< OUString > SAL_CALL GrammarCheckingIterator::getSupportedServiceNames() throw(uno::RuntimeException)
+
+uno::Sequence< OUString > SAL_CALL GrammarCheckingIterator::getSupportedServiceNames( ) throw (uno::RuntimeException)
{
- osl::Guard< osl::Mutex > aGuard(GetMutex());
- return getSupportedServiceNames_Static();
+ return GrammarCheckingIterator_getSupportedServiceNames();
}
-OUString SAL_CALL GrammarCheckingIterator::getImplementationName() throw(uno::RuntimeException)
+
+///////////////////////////////////////////////////////////////////////////
+
+
+static OUString GrammarCheckingIterator_getImplementationName() throw()
{
- osl::Guard< osl::Mutex > aGuard(GetMutex());
- return getImplementationName_Static();
+ return A2OU( "com.sun.star.lingu2.GrammarCheckingIterator" );
}
-sal_Bool SAL_CALL GrammarCheckingIterator_writeInfo( void * /*pServiceManager*/, registry::XRegistryKey * pRegistryKey )
-{
- try
- {
- String aImpl( '/' );
- aImpl += GrammarCheckingIterator::getImplementationName_Static().getStr();
- aImpl.AppendAscii( "/UNO/SERVICES" );
- uno::Reference< registry::XRegistryKey > xNewKey =
- pRegistryKey->createKey( aImpl );
- uno::Sequence< OUString > aServices = GrammarCheckingIterator::getSupportedServiceNames_Static();
- for( INT32 i = 0; i < aServices.getLength(); ++i )
- xNewKey->createKey( aServices.getConstArray()[i] );
- return sal_True;
- }
- catch(uno::Exception &)
- {
- return sal_False;
- }
+static uno::Sequence< OUString > GrammarCheckingIterator_getSupportedServiceNames() throw()
+{
+ uno::Sequence< OUString > aSNS( 1 );
+ aSNS.getArray()[0] = A2OU( "com.sun.star.linguistic2.GrammarCheckingIterator" );
+ return aSNS;
}
-uno::Reference< uno::XInterface > SAL_CALL GrammarCheckingIterator_CreateInstance(
- const uno::Reference< lang::XMultiServiceFactory > & /*rSMgr*/ )
- throw(uno::Exception)
+
+static uno::Reference< uno::XInterface > SAL_CALL GrammarCheckingIterator_createInstance(
+ const uno::Reference< lang::XMultiServiceFactory > & rxSMgr )
+throw(uno::Exception)
{
- uno::Reference< uno::XInterface > xService = (cppu::OWeakObject*) new GrammarCheckingIterator;
- return xService;
+ return static_cast< ::cppu::OWeakObject * >(new GrammarCheckingIterator( rxSMgr ));
}
+
void * SAL_CALL GrammarCheckingIterator_getFactory(
- const sal_Char * pImplName,
- lang::XMultiServiceFactory * pServiceManager,
+ const sal_Char *pImplName,
+ lang::XMultiServiceFactory *pServiceManager,
void * /*pRegistryKey*/ )
{
-
void * pRet = 0;
- if ( !GrammarCheckingIterator::getImplementationName_Static().compareToAscii( pImplName ) )
+ if ( !GrammarCheckingIterator_getImplementationName().compareToAscii( pImplName ) )
{
uno::Reference< lang::XSingleServiceFactory > xFactory =
cppu::createOneInstanceFactory(
pServiceManager,
- GrammarCheckingIterator::getImplementationName_Static(),
- GrammarCheckingIterator_CreateInstance,
- GrammarCheckingIterator::getSupportedServiceNames_Static());
+ GrammarCheckingIterator_getImplementationName(),
+ GrammarCheckingIterator_createInstance,
+ GrammarCheckingIterator_getSupportedServiceNames());
// acquire, because we return an interface pointer instead of a reference
xFactory->acquire();
pRet = xFactory.get();
@@ -621,3 +1056,26 @@ void * SAL_CALL GrammarCheckingIterator_getFactory(
return pRet;
}
+
+sal_Bool SAL_CALL GrammarCheckingIterator_writeInfo(
+ void * /*pServiceManager*/,
+ registry::XRegistryKey * pRegistryKey )
+{
+ try
+ {
+ OUString aImpl( '/' );
+ aImpl += GrammarCheckingIterator_getImplementationName().getStr();
+ aImpl += A2OU( "/UNO/SERVICES" );
+ uno::Reference< registry::XRegistryKey > xNewKey = pRegistryKey->createKey( aImpl );
+ uno::Sequence< OUString > aServices = GrammarCheckingIterator_getSupportedServiceNames();
+ for( sal_Int32 i = 0; i < aServices.getLength(); i++ )
+ xNewKey->createKey( aServices.getConstArray()[i] );
+
+ return sal_True;
+ }
+ catch (uno::Exception &)
+ {
+ return sal_False;
+ }
+}
+