1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_unotools.hxx"
30 
31 #include <unotools/searchopt.hxx>
32 #include <tools/solar.h>
33 #include <tools/debug.hxx>
34 #include <unotools/configitem.hxx>
35 #include <com/sun/star/i18n/TransliterationModules.hpp>
36 #include <com/sun/star/uno/Sequence.hxx>
37 #include <com/sun/star/uno/Any.h>
38 #include <rtl/logfile.hxx>
39 
40 
41 using namespace rtl;
42 using namespace utl;
43 using namespace com::sun::star::uno;
44 using namespace com::sun::star::i18n;
45 
46 #define MAX_FLAGS_OFFSET	25
47 
48 //////////////////////////////////////////////////////////////////////
49 
50 
51 class SvtSearchOptions_Impl : public ConfigItem
52 {
53 	sal_Int32	nFlags;
54 	sal_Bool	bModified;
55 
56 	// disallow copy-constructor and assignment-operator for now
57 	SvtSearchOptions_Impl( const SvtSearchOptions_Impl & );
58 	SvtSearchOptions_Impl & operator = ( const SvtSearchOptions_Impl & );
59 
60 protected:
61 	sal_Bool			IsModified() const { return bModified; }
62     using ConfigItem::SetModified;
63 	void			SetModified( sal_Bool bVal );
64 	sal_Bool			Load();
65 	sal_Bool			Save();
66 
67 	Sequence< OUString >	GetPropertyNames() const;
68 
69 public:
70 	SvtSearchOptions_Impl();
71 	virtual ~SvtSearchOptions_Impl();
72 
73 	// ConfigItem
74 	virtual void	Commit();
75     virtual void    Notify( const com::sun::star::uno::Sequence< rtl::OUString >& aPropertyNames );
76 
77 	sal_Bool			GetFlag( sal_uInt16 nOffset ) const;
78 	void			SetFlag( sal_uInt16 nOffset, sal_Bool bVal );
79 };
80 
81 
82 
83 SvtSearchOptions_Impl::SvtSearchOptions_Impl() :
84 	ConfigItem( OUString::createFromAscii( "Office.Common/SearchOptions" ) )
85 {
86     RTL_LOGFILE_CONTEXT(aLog, "unotools SvtSearchOptions_Impl::SvtSearchOptions_Impl()");
87 	nFlags = 0x0003FFFF;	// set all options values to 'true'
88 	Load();
89 	SetModified( sal_False );
90 }
91 
92 
93 SvtSearchOptions_Impl::~SvtSearchOptions_Impl()
94 {
95 	Commit();
96 }
97 
98 
99 void SvtSearchOptions_Impl::Commit()
100 {
101 	if (IsModified())
102 		Save();
103 }
104 
105 void SvtSearchOptions_Impl::Notify( const Sequence< rtl::OUString >&  )
106 {
107 }
108 
109 
110 sal_Bool SvtSearchOptions_Impl::GetFlag( sal_uInt16 nOffset ) const
111 {
112 	DBG_ASSERT( nOffset <= MAX_FLAGS_OFFSET, "offset out of range");
113 	return ((nFlags >> nOffset) & 0x01) ? sal_True : sal_False;
114 }
115 
116 
117 void SvtSearchOptions_Impl::SetFlag( sal_uInt16 nOffset, sal_Bool bVal )
118 {
119 	DBG_ASSERT( nOffset <= MAX_FLAGS_OFFSET, "offset out of range");
120 	sal_Int32 nOldFlags = nFlags;
121 	sal_Int32 nMask = ((sal_Int32) 1)  << nOffset;
122 	if (bVal)
123 		nFlags |= nMask;
124 	else
125 		nFlags &= ~nMask;
126 	if (nFlags != nOldFlags)
127 		SetModified( sal_True );
128 }
129 
130 
131 void SvtSearchOptions_Impl::SetModified( sal_Bool bVal )
132 {
133     bModified = bVal;
134 	if (bModified)
135 	{
136 		ConfigItem::SetModified();
137 	}
138 }
139 
140 
141 Sequence< OUString > SvtSearchOptions_Impl::GetPropertyNames() const
142 {
143 	static const char* aPropNames[ MAX_FLAGS_OFFSET + 1 ] =
144 	{
145 		"IsWholeWordsOnly",						//  0
146 		"IsBackwards",							//  1
147 		"IsUseRegularExpression",				//  2
148 		//"IsCurrentSelectionOnly",				// interactively set or not...
149 		"IsSearchForStyles",					//  3
150 		"IsSimilaritySearch",					//  4
151 		"IsUseAsianOptions",					//  5
152 		"IsMatchCase",							//  6
153 		"Japanese/IsMatchFullHalfWidthForms",	//  7
154 		"Japanese/IsMatchHiraganaKatakana",		//  8
155 		"Japanese/IsMatchContractions",			//  9
156 		"Japanese/IsMatchMinusDashCho-on",		// 10
157 		"Japanese/IsMatchRepeatCharMarks",		// 11
158 		"Japanese/IsMatchVariantFormKanji",		// 12
159 		"Japanese/IsMatchOldKanaForms",			// 13
160 		"Japanese/IsMatch_DiZi_DuZu",			// 14
161 		"Japanese/IsMatch_BaVa_HaFa",			// 15
162 		"Japanese/IsMatch_TsiThiChi_DhiZi",		// 16
163 		"Japanese/IsMatch_HyuIyu_ByuVyu",		// 17
164 		"Japanese/IsMatch_SeShe_ZeJe",			// 18
165 		"Japanese/IsMatch_IaIya",				// 19
166 		"Japanese/IsMatch_KiKu",				// 20
167 		"Japanese/IsIgnorePunctuation",			// 21
168 		"Japanese/IsIgnoreWhitespace",			// 22
169 		"Japanese/IsIgnoreProlongedSoundMark",		// 23
170 		"Japanese/IsIgnoreMiddleDot",			// 24
171 		"IsNotes"					// 25
172 	};
173 
174     const int nCount = sizeof( aPropNames ) / sizeof( aPropNames[0] );
175 	Sequence< OUString > aNames( nCount );
176 	OUString* pNames = aNames.getArray();
177 	for (sal_Int32 i = 0;  i < nCount;  ++i)
178 		pNames[i] = OUString::createFromAscii( aPropNames[i] );
179 
180 	return aNames;
181 }
182 
183 
184 sal_Bool SvtSearchOptions_Impl::Load()
185 {
186 	sal_Bool bSucc = sal_False;
187 
188 	Sequence< OUString > aNames = GetPropertyNames();
189 	sal_Int32 nProps = aNames.getLength();
190 
191 	const Sequence< Any > aValues = GetProperties( aNames );
192 	DBG_ASSERT( aValues.getLength() == aNames.getLength(),
193 			"GetProperties failed" );
194 	//EnableNotification( aNames );
195 
196 	if (nProps  &&  aValues.getLength() == nProps)
197 	{
198 		bSucc = sal_True;
199 
200 		const Any* pValues = aValues.getConstArray();
201 		for (sal_uInt16 i = 0;  i < nProps;  ++i)
202 		{
203 			const Any &rVal = pValues[i];
204 			DBG_ASSERT( rVal.hasValue(), "property value missing" );
205 			if (rVal.hasValue())
206 			{
207 				sal_Bool bVal = sal_Bool();
208 				if (rVal >>= bVal)
209 				{
210 					if (i <= MAX_FLAGS_OFFSET)
211 					{
212 						// use index in sequence as flag index
213 						SetFlag( i, bVal );
214 					}
215 					else {
216 						DBG_ERROR( "unexpected index" );
217                     }
218 				}
219 				else
220 				{
221 					DBG_ERROR( "unexpected type" );
222 					bSucc = sal_False;
223 				}
224 			}
225 			else
226 			{
227 				DBG_ERROR( "value missing" );
228 				bSucc = sal_False;
229 			}
230 		}
231 	}
232 	DBG_ASSERT( bSucc, "LoadConfig failed" );
233 
234 	return bSucc;
235 }
236 
237 
238 sal_Bool SvtSearchOptions_Impl::Save()
239 {
240 	sal_Bool bSucc = sal_False;
241 
242 	const Sequence< OUString > aNames = GetPropertyNames();
243 	sal_Int32 nProps = aNames.getLength();
244 
245 	Sequence< Any > aValues( nProps );
246 	Any *pValue = aValues.getArray();
247 
248 	DBG_ASSERT( nProps == MAX_FLAGS_OFFSET + 1,
249 			"unexpected size of index" );
250 	if (nProps  &&  nProps == MAX_FLAGS_OFFSET + 1)
251 	{
252 		for (sal_uInt16 i = 0;  i < nProps;  ++i)
253 			pValue[i] <<= (sal_Bool) GetFlag(i);
254 		bSucc |= PutProperties( aNames, aValues );
255 	}
256 
257 	if (bSucc)
258 		SetModified( sal_False );
259 
260 	return bSucc;
261 }
262 
263 
264 //////////////////////////////////////////////////////////////////////
265 
266 SvtSearchOptions::SvtSearchOptions()
267 {
268 	pImpl = new SvtSearchOptions_Impl;
269 }
270 
271 
272 SvtSearchOptions::~SvtSearchOptions()
273 {
274 	delete pImpl;
275 }
276 
277 
278 sal_Int32 SvtSearchOptions::GetTransliterationFlags() const
279 {
280 	sal_Int32 nRes = 0;
281 
282     if (!IsMatchCase()) // 'IsMatchCase' means act case sensitive
283 		nRes |= TransliterationModules_IGNORE_CASE;
284     if ( IsMatchFullHalfWidthForms())
285 		nRes |= TransliterationModules_IGNORE_WIDTH;
286     if ( IsMatchHiraganaKatakana())
287 		nRes |= TransliterationModules_IGNORE_KANA;
288     if ( IsMatchContractions())
289 		nRes |= TransliterationModules_ignoreSize_ja_JP;
290     if ( IsMatchMinusDashChoon())
291 		nRes |= TransliterationModules_ignoreMinusSign_ja_JP;
292     if ( IsMatchRepeatCharMarks())
293 		nRes |= TransliterationModules_ignoreIterationMark_ja_JP;
294     if ( IsMatchVariantFormKanji())
295 		nRes |= TransliterationModules_ignoreTraditionalKanji_ja_JP;
296     if ( IsMatchOldKanaForms())
297 		nRes |= TransliterationModules_ignoreTraditionalKana_ja_JP;
298     if ( IsMatchDiziDuzu())
299 		nRes |= TransliterationModules_ignoreZiZu_ja_JP;
300     if ( IsMatchBavaHafa())
301 		nRes |= TransliterationModules_ignoreBaFa_ja_JP;
302     if ( IsMatchTsithichiDhizi())
303 		nRes |= TransliterationModules_ignoreTiJi_ja_JP;
304     if ( IsMatchHyuiyuByuvyu())
305 		nRes |= TransliterationModules_ignoreHyuByu_ja_JP;
306     if ( IsMatchSesheZeje())
307 		nRes |= TransliterationModules_ignoreSeZe_ja_JP;
308     if ( IsMatchIaiya())
309 		nRes |= TransliterationModules_ignoreIandEfollowedByYa_ja_JP;
310     if ( IsMatchKiku())
311 		nRes |= TransliterationModules_ignoreKiKuFollowedBySa_ja_JP;
312 	if ( IsIgnorePunctuation())
313 		nRes |= TransliterationModules_ignoreSeparator_ja_JP;
314 	if ( IsIgnoreWhitespace())
315 		nRes |= TransliterationModules_ignoreSpace_ja_JP;
316 	if ( IsIgnoreProlongedSoundMark())
317 		nRes |= TransliterationModules_ignoreProlongedSoundMark_ja_JP;
318 	if ( IsIgnoreMiddleDot())
319 		nRes |= TransliterationModules_ignoreMiddleDot_ja_JP;
320 
321 	return nRes;
322 }
323 
324 
325 sal_Bool SvtSearchOptions::IsWholeWordsOnly() const
326 {
327 	return pImpl->GetFlag( 0 );
328 }
329 
330 
331 void SvtSearchOptions::SetWholeWordsOnly( sal_Bool bVal )
332 {
333 	pImpl->SetFlag( 0, bVal );
334 }
335 
336 
337 sal_Bool SvtSearchOptions::IsBackwards() const
338 {
339 	return pImpl->GetFlag( 1 );
340 }
341 
342 
343 void SvtSearchOptions::SetBackwards( sal_Bool bVal )
344 {
345 	pImpl->SetFlag( 1, bVal );
346 }
347 
348 
349 sal_Bool SvtSearchOptions::IsUseRegularExpression() const
350 {
351 	return pImpl->GetFlag( 2 );
352 }
353 
354 
355 void SvtSearchOptions::SetUseRegularExpression( sal_Bool bVal )
356 {
357 	pImpl->SetFlag( 2, bVal );
358 }
359 
360 
361 sal_Bool SvtSearchOptions::IsSearchForStyles() const
362 {
363 	return pImpl->GetFlag( 3 );
364 }
365 
366 
367 void SvtSearchOptions::SetSearchForStyles( sal_Bool bVal )
368 {
369 	pImpl->SetFlag( 3, bVal );
370 }
371 
372 
373 sal_Bool SvtSearchOptions::IsSimilaritySearch() const
374 {
375 	return pImpl->GetFlag( 4 );
376 }
377 
378 
379 void SvtSearchOptions::SetSimilaritySearch( sal_Bool bVal )
380 {
381 	pImpl->SetFlag( 4, bVal );
382 }
383 
384 
385 sal_Bool SvtSearchOptions::IsUseAsianOptions() const
386 {
387 	return pImpl->GetFlag( 5 );
388 }
389 
390 
391 void SvtSearchOptions::SetUseAsianOptions( sal_Bool bVal )
392 {
393 	pImpl->SetFlag( 5, bVal );
394 }
395 
396 
397 sal_Bool SvtSearchOptions::IsMatchCase() const
398 {
399 	return pImpl->GetFlag( 6 );
400 }
401 
402 
403 void SvtSearchOptions::SetMatchCase( sal_Bool bVal )
404 {
405 	pImpl->SetFlag( 6, bVal );
406 }
407 
408 
409 sal_Bool SvtSearchOptions::IsMatchFullHalfWidthForms() const
410 {
411 	return pImpl->GetFlag( 7 );
412 }
413 
414 
415 void SvtSearchOptions::SetMatchFullHalfWidthForms( sal_Bool bVal )
416 {
417 	pImpl->SetFlag( 7, bVal );
418 }
419 
420 
421 sal_Bool SvtSearchOptions::IsMatchHiraganaKatakana() const
422 {
423 	return pImpl->GetFlag( 8 );
424 }
425 
426 
427 void SvtSearchOptions::SetMatchHiraganaKatakana( sal_Bool bVal )
428 {
429 	pImpl->SetFlag( 8, bVal );
430 }
431 
432 
433 sal_Bool SvtSearchOptions::IsMatchContractions() const
434 {
435 	return pImpl->GetFlag( 9 );
436 }
437 
438 
439 void SvtSearchOptions::SetMatchContractions( sal_Bool bVal )
440 {
441 	pImpl->SetFlag( 9, bVal );
442 }
443 
444 
445 sal_Bool SvtSearchOptions::IsMatchMinusDashChoon() const
446 {
447 	return pImpl->GetFlag( 10 );
448 }
449 
450 
451 void SvtSearchOptions::SetMatchMinusDashChoon( sal_Bool bVal )
452 {
453 	pImpl->SetFlag( 10, bVal );
454 }
455 
456 
457 sal_Bool SvtSearchOptions::IsMatchRepeatCharMarks() const
458 {
459 	return pImpl->GetFlag( 11 );
460 }
461 
462 
463 void SvtSearchOptions::SetMatchRepeatCharMarks( sal_Bool bVal )
464 {
465 	pImpl->SetFlag( 11, bVal );
466 }
467 
468 
469 sal_Bool SvtSearchOptions::IsMatchVariantFormKanji() const
470 {
471 	return pImpl->GetFlag( 12 );
472 }
473 
474 
475 void SvtSearchOptions::SetMatchVariantFormKanji( sal_Bool bVal )
476 {
477 	pImpl->SetFlag( 12, bVal );
478 }
479 
480 
481 sal_Bool SvtSearchOptions::IsMatchOldKanaForms() const
482 {
483 	return pImpl->GetFlag( 13 );
484 }
485 
486 
487 void SvtSearchOptions::SetMatchOldKanaForms( sal_Bool bVal )
488 {
489 	pImpl->SetFlag( 13, bVal );
490 }
491 
492 
493 sal_Bool SvtSearchOptions::IsMatchDiziDuzu() const
494 {
495 	return pImpl->GetFlag( 14 );
496 }
497 
498 
499 void SvtSearchOptions::SetMatchDiziDuzu( sal_Bool bVal )
500 {
501 	pImpl->SetFlag( 14, bVal );
502 }
503 
504 
505 sal_Bool SvtSearchOptions::IsMatchBavaHafa() const
506 {
507 	return pImpl->GetFlag( 15 );
508 }
509 
510 
511 void SvtSearchOptions::SetMatchBavaHafa( sal_Bool bVal )
512 {
513 	pImpl->SetFlag( 15, bVal );
514 }
515 
516 
517 sal_Bool SvtSearchOptions::IsMatchTsithichiDhizi() const
518 {
519 	return pImpl->GetFlag( 16 );
520 }
521 
522 
523 void SvtSearchOptions::SetMatchTsithichiDhizi( sal_Bool bVal )
524 {
525 	pImpl->SetFlag( 16, bVal );
526 }
527 
528 
529 sal_Bool SvtSearchOptions::IsMatchHyuiyuByuvyu() const
530 {
531 	return pImpl->GetFlag( 17 );
532 }
533 
534 
535 void SvtSearchOptions::SetMatchHyuiyuByuvyu( sal_Bool bVal )
536 {
537 	pImpl->SetFlag( 17, bVal );
538 }
539 
540 
541 sal_Bool SvtSearchOptions::IsMatchSesheZeje() const
542 {
543 	return pImpl->GetFlag( 18 );
544 }
545 
546 
547 void SvtSearchOptions::SetMatchSesheZeje( sal_Bool bVal )
548 {
549 	pImpl->SetFlag( 18, bVal );
550 }
551 
552 
553 sal_Bool SvtSearchOptions::IsMatchIaiya() const
554 {
555 	return pImpl->GetFlag( 19 );
556 }
557 
558 
559 void SvtSearchOptions::SetMatchIaiya( sal_Bool bVal )
560 {
561 	pImpl->SetFlag( 19, bVal );
562 }
563 
564 
565 sal_Bool SvtSearchOptions::IsMatchKiku() const
566 {
567 	return pImpl->GetFlag( 20 );
568 }
569 
570 
571 void SvtSearchOptions::SetMatchKiku( sal_Bool bVal )
572 {
573 	pImpl->SetFlag( 20, bVal );
574 }
575 
576 
577 sal_Bool SvtSearchOptions::IsIgnorePunctuation() const
578 {
579 	return pImpl->GetFlag( 21 );
580 }
581 
582 
583 void SvtSearchOptions::SetIgnorePunctuation( sal_Bool bVal )
584 {
585 	pImpl->SetFlag( 21, bVal );
586 }
587 
588 
589 sal_Bool SvtSearchOptions::IsIgnoreWhitespace() const
590 {
591 	return pImpl->GetFlag( 22 );
592 }
593 
594 
595 void SvtSearchOptions::SetIgnoreWhitespace( sal_Bool bVal )
596 {
597 	pImpl->SetFlag( 22, bVal );
598 }
599 
600 
601 sal_Bool SvtSearchOptions::IsIgnoreProlongedSoundMark() const
602 {
603 	return pImpl->GetFlag( 23 );
604 }
605 
606 
607 void SvtSearchOptions::SetIgnoreProlongedSoundMark( sal_Bool bVal )
608 {
609 	pImpl->SetFlag( 23, bVal );
610 }
611 
612 
613 sal_Bool SvtSearchOptions::IsIgnoreMiddleDot() const
614 {
615 	return pImpl->GetFlag( 24 );
616 }
617 
618 
619 void SvtSearchOptions::SetIgnoreMiddleDot( sal_Bool bVal )
620 {
621 	pImpl->SetFlag( 24, bVal );
622 }
623 
624 sal_Bool SvtSearchOptions::IsNotes() const
625 {
626         return pImpl->GetFlag( 25 );
627 }
628 
629 
630 void SvtSearchOptions::SetNotes( sal_Bool bVal )
631 {
632         pImpl->SetFlag( 25, bVal );
633 }
634 
635 //////////////////////////////////////////////////////////////////////
636 
637