1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 #include "precompiled_linguistic.hxx"
24 
25 #include <sal/config.h>
26 #include <com/sun/star/uno/XComponentContext.hpp>
27 #include <cppuhelper/implbase1.hxx>
28 #include <com/sun/star/linguistic2/XGrammarChecker.hpp>
29 #include <com/sun/star/i18n/XBreakIterator.hpp>
30 #include <cppuhelper/implbase4.hxx>
31 #include <com/sun/star/lang/XComponent.hpp>
32 #include <com/sun/star/lang/XServiceInfo.hpp>
33 #include "linguistic/misc.hxx"
34 #include "defs.hxx"
35 #include <cppuhelper/factory.hxx>
36 #include <com/sun/star/registry/XRegistryKey.hpp>
37 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
38 
39 #include <cppuhelper/interfacecontainer.h>
40 #include <com/sun/star/container/XContentEnumerationAccess.hpp>
41 #include <com/sun/star/container/XEnumeration.hpp>
42 #include <com/sun/star/linguistic2/XSupportedLocales.hpp>
43 #include <com/sun/star/linguistic2/SingleGrammarError.hpp>
44 #include <com/sun/star/linguistic2/GrammarCheckingResult.hpp>
45 #include "lngopt.hxx"
46 #include <comphelper/extract.hxx>
47 #include <unotools/processfactory.hxx>
48 #include <map>
49 #include <com/sun/star/text/TextMarkupType.hpp>
50 
51 #include "grammarchecker.hxx"
52 
53 using namespace ::utl;
54 using namespace ::rtl;
55 using namespace ::com::sun::star;
56 
57 ////////////////////////////////////////////////////////////
58 
GrammarChecker()59 GrammarChecker::GrammarChecker( /*uno::Reference< uno::XComponentContext > const & context*/ )
60     /*m_xContext(context)*/
61 {}
62 
~GrammarChecker()63 GrammarChecker::~GrammarChecker()
64 {
65 }
66 
67 
isSpellChecker()68 sal_Bool SAL_CALL GrammarChecker::isSpellChecker() throw (uno::RuntimeException)
69 {
70     osl::Guard< osl::Mutex > aGuard(GetMutex());
71 	return sal_False;
72 }
73 
74 
hasLocale(const lang::Locale & aLocale)75 sal_Bool SAL_CALL GrammarChecker::hasLocale( const lang::Locale & aLocale ) throw (uno::RuntimeException)
76 {
77     osl::Guard< osl::Mutex > aGuard(GetMutex());
78     (void) aLocale;
79 	return sal_False;
80 }
81 
getLocales()82 uno::Sequence< lang::Locale > SAL_CALL GrammarChecker::getLocales(  ) throw (uno::RuntimeException)
83 {
84     osl::Guard< osl::Mutex > aGuard(GetMutex());
85     return uno::Sequence< lang::Locale >();
86 }
87 
88 
startDocument(sal_Int32 nDocId)89 void SAL_CALL GrammarChecker::startDocument(sal_Int32 nDocId)
90     throw (uno::RuntimeException, lang::IllegalArgumentException)
91 {
92     osl::Guard< osl::Mutex > aGuard(GetMutex());
93     (void) nDocId;
94 }
95 
startParagraph(sal_Int32 nDocId)96 void SAL_CALL GrammarChecker::startParagraph(sal_Int32 nDocId)
97 	throw (uno::RuntimeException, lang::IllegalArgumentException)
98 {
99     osl::Guard< osl::Mutex > aGuard(GetMutex());
100     (void) nDocId;
101 }
102 
endParagraph(sal_Int32 nDocId)103 void SAL_CALL GrammarChecker::endParagraph( sal_Int32 nDocId )
104     throw (uno::RuntimeException, lang::IllegalArgumentException)
105 {
106     osl::Guard< osl::Mutex > aGuard(GetMutex());
107     (void) nDocId;
108 }
109 
endDocument(sal_Int32 nDocId)110 void SAL_CALL GrammarChecker::endDocument(sal_Int32 nDocId)
111     throw (uno::RuntimeException, lang::IllegalArgumentException)
112 {
113     osl::Guard< osl::Mutex > aGuard(GetMutex());
114     (void) nDocId;
115 }
116 
doGrammarChecking(sal_Int32 nDocId,const rtl::OUString & rText,const lang::Locale & rLocale,sal_Int32 nStartOfSentencePos,sal_Int32 nSuggestedSentenceEndPos,const uno::Sequence<::sal_Int32> & rLanguagePortions,const uno::Sequence<lang::Locale> & rLanguagePortionsLocales)117 linguistic2::GrammarCheckingResult SAL_CALL GrammarChecker::doGrammarChecking(
118         sal_Int32 nDocId,
119         const rtl::OUString& rText,
120         const lang::Locale& rLocale,
121         sal_Int32 nStartOfSentencePos,
122         sal_Int32 nSuggestedSentenceEndPos,
123         const uno::Sequence< ::sal_Int32 >& rLanguagePortions,
124         const uno::Sequence< lang::Locale >& rLanguagePortionsLocales )
125     throw (lang::IllegalArgumentException, uno::RuntimeException)
126 {
127     osl::Guard< osl::Mutex > aGuard(GetMutex());
128 
129     (void) rLanguagePortions;
130     (void) rLanguagePortionsLocales;
131 
132     linguistic2::GrammarCheckingResult  aRes;
133     aRes.nDocumentId                = nDocId;
134     aRes.aText                      = rText;
135     aRes.aLocale                    = rLocale;
136     aRes.nEndOfSentencePos          = nSuggestedSentenceEndPos;
137     aRes.xGrammarChecker            = this;
138     aRes.aGrammarErrors             = GrammarCheckingInDummy( nDocId, rText, rLocale, nStartOfSentencePos, nSuggestedSentenceEndPos );;
139 
140     return aRes;
141 }
142 
GrammarCheckingInDummy(sal_Int32 nDocId,const OUString & rFlatParaText,const lang::Locale & rLocale,sal_Int32 nStartOfSentencePos,sal_Int32 nSuggestedSentenceEndPos)143 uno::Sequence< linguistic2::SingleGrammarError > GrammarChecker::GrammarCheckingInDummy(
144 	sal_Int32 nDocId,
145     const OUString & rFlatParaText,
146     const lang::Locale & rLocale,
147     sal_Int32 nStartOfSentencePos,
148     sal_Int32 nSuggestedSentenceEndPos )
149 {
150 	(void) nDocId;
151     (void) rFlatParaText;
152     (void) rLocale;
153     (void) nStartOfSentencePos;
154     (void) nSuggestedSentenceEndPos;
155 
156 
157     typedef std::map< OUString, uno::Sequence<OUString> > Error_t;
158 	Error_t aError;
159     uno::Sequence< OUString > aSuggestion(1);
160     OUString *pSeggestion = aSuggestion.getArray();
161 	pSeggestion[0] = OUString::createFromAscii("Modified");
162 
163     aError[OUString::createFromAscii("GrammarError")]  = aSuggestion;
164     aError[OUString::createFromAscii("Grammar Error")] = aSuggestion;
165 
166 	typedef std::vector< linguistic2::SingleGrammarError> ErrorVector_t;
167 	ErrorVector_t aErrorVector;
168 
169     OUString aText = rFlatParaText.copy( nStartOfSentencePos, nSuggestedSentenceEndPos - nStartOfSentencePos );
170 	sal_Int32 nIndexOf = 0;
171 	for(Error_t::const_iterator it = aError.begin(); it != aError.end(); ++it)
172 	{
173 
174         while(nIndexOf >= 0)
175 		{
176             nIndexOf=aText.indexOf(it->first, nIndexOf);
177 			if(nIndexOf > -1)
178 			{
179 				//error found
180 				linguistic2::SingleGrammarError aErr;
181                 aErr.nErrorStart        = nIndexOf + nStartOfSentencePos;
182 				nIndexOf += it->first.getLength();
183                 aErr.nErrorLength       = it->first.getLength();
184                 aErr.nErrorType         = text::TextMarkupType::GRAMMAR;
185                 aErr.nErrorLevel        = 0;
186                 aErr.aShortComment      = OUString();
187                 aErr.aFullComment       = OUString();
188                 aErr.aNewLocale         = rLocale;
189                 aErr.aSuggestions       = it->second;
190 
191                 aErrorVector.push_back( aErr );
192 			}
193 		}
194 		nIndexOf = 0;
195 	}
196 
197 	sal_Int32 nCount = aErrorVector.size();
198 	uno::Sequence< linguistic2::SingleGrammarError > aErrors( nCount );
199 	if( nCount > 0 )
200 	{
201 		linguistic2::SingleGrammarError* pErrors = aErrors.getArray();
202 		for (sal_Int32 i=0; i < nCount; ++i)
203 		{
204 			pErrors[i] = aErrorVector[i];
205 		}
206 	}
207 	return aErrors;
208 }
209 
210 
hasOptionsDialog()211 sal_Bool SAL_CALL GrammarChecker::hasOptionsDialog(  ) throw (uno::RuntimeException)
212 {
213     osl::Guard< osl::Mutex > aGuard(GetMutex());
214     return sal_False;
215 }
216 
runOptionsDialog()217 void SAL_CALL GrammarChecker::runOptionsDialog()
218     throw (uno::RuntimeException)
219 {
220     osl::Guard< osl::Mutex > aGuard(GetMutex());
221 }
222 
dispose()223 void SAL_CALL GrammarChecker::dispose(  ) throw (uno::RuntimeException)
224 {
225     osl::Guard< osl::Mutex > aGuard(GetMutex());
226 }
227 
addEventListener(const uno::Reference<lang::XEventListener> & xListener)228 void SAL_CALL GrammarChecker::addEventListener( const uno::Reference< lang::XEventListener >& xListener )
229     throw (uno::RuntimeException)
230 {
231     osl::Guard< osl::Mutex > aGuard(GetMutex());
232     (void) xListener;
233 }
234 
removeEventListener(const uno::Reference<lang::XEventListener> & xListener)235 void SAL_CALL GrammarChecker::removeEventListener( const uno::Reference< lang::XEventListener >& xListener )
236     throw (uno::RuntimeException)
237 {
238     osl::Guard< osl::Mutex > aGuard(GetMutex());
239     (void) xListener;
240 }
241 
supportsService(const OUString & ServiceName)242 sal_Bool SAL_CALL GrammarChecker::supportsService( const OUString& ServiceName ) throw(uno::RuntimeException)
243 {
244 	osl::Guard< osl::Mutex > aGuard(GetMutex());
245 
246 	uno::Sequence< OUString > aSNL = getSupportedServiceNames();
247 	const OUString * pArray = aSNL.getConstArray();
248 	for( sal_Int32 i = 0; i < aSNL.getLength(); ++i )
249 		if( pArray[i] == ServiceName )
250 			return sal_True;
251 	return sal_False;
252 }
253 
getSupportedServiceNames_Static()254 uno::Sequence< OUString > GrammarChecker::getSupportedServiceNames_Static(  ) throw()
255 {
256 	//osl::Guard< osl::Mutex > aGuard(GetMutex());
257 
258 	uno::Sequence< OUString > aSNS( 1 );	// auch mehr als 1 Service moeglich
259 	aSNS.getArray()[0] = A2OU( "com.sun.star.linguistic2.GrammarChecker" );//SN_LINGU_SERVCICE_MANAGER
260 	return aSNS;
261 }
262 
getSupportedServiceNames()263 uno::Sequence< OUString > SAL_CALL GrammarChecker::getSupportedServiceNames(  ) throw(uno::RuntimeException)
264 {
265 	osl::Guard< osl::Mutex > aGuard(GetMutex());
266 	return getSupportedServiceNames_Static();
267 }
268 
getImplementationName()269 OUString SAL_CALL GrammarChecker::getImplementationName(  ) throw(uno::RuntimeException)
270 {
271 	osl::Guard< osl::Mutex > aGuard(GetMutex());
272 	return getImplementationName_Static();
273 }
274 
GrammarChecker_CreateInstance(const uno::Reference<lang::XMultiServiceFactory> &)275 uno::Reference< uno::XInterface > SAL_CALL GrammarChecker_CreateInstance(
276         const uno::Reference< lang::XMultiServiceFactory > & /*rSMgr*/ )
277     throw(uno::Exception)
278 {
279     uno::Reference< uno::XInterface > xService = (cppu::OWeakObject*) new GrammarChecker;
280 	return xService;
281 }
282 
GrammarChecker_getFactory(const sal_Char * pImplName,lang::XMultiServiceFactory * pServiceManager,void *)283 void * SAL_CALL GrammarChecker_getFactory( const sal_Char * pImplName, lang::XMultiServiceFactory * pServiceManager, void * /*pRegistryKey*/ )
284 {
285 
286 	void * pRet = 0;
287 	if ( !GrammarChecker::getImplementationName_Static().compareToAscii( pImplName ) )
288 	{
289         uno::Reference< lang::XSingleServiceFactory > xFactory =
290 			cppu::createOneInstanceFactory(
291 				pServiceManager,
292 				GrammarChecker::getImplementationName_Static(),
293 				GrammarChecker_CreateInstance,
294 				GrammarChecker::getSupportedServiceNames_Static());
295 		// acquire, because we return an interface pointer instead of a reference
296 		xFactory->acquire();
297 		pRet = xFactory.get();
298 	}
299 	return pRet;
300 }
301 
302