Coverage Report

Created: 2025-11-16 09:57

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libreoffice/unotools/source/config/searchopt.cxx
Line
Count
Source
1
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2
/*
3
 * This file is part of the LibreOffice project.
4
 *
5
 * This Source Code Form is subject to the terms of the Mozilla Public
6
 * License, v. 2.0. If a copy of the MPL was not distributed with this
7
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8
 *
9
 * This file incorporates work covered by the following license notice:
10
 *
11
 *   Licensed to the Apache Software Foundation (ASF) under one or more
12
 *   contributor license agreements. See the NOTICE file distributed
13
 *   with this work for additional information regarding copyright
14
 *   ownership. The ASF licenses this file to you under the Apache
15
 *   License, Version 2.0 (the "License"); you may not use this file
16
 *   except in compliance with the License. You may obtain a copy of
17
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
18
 */
19
20
#include <sal/config.h>
21
22
#include <unotools/searchopt.hxx>
23
#include <tools/debug.hxx>
24
#include <unotools/configitem.hxx>
25
#include <com/sun/star/uno/Sequence.hxx>
26
#include <com/sun/star/uno/Any.h>
27
#include <osl/diagnose.h>
28
#include <i18nutil/transliteration.hxx>
29
30
using namespace utl;
31
using namespace com::sun::star::uno;
32
33
0
#define MAX_FLAGS_OFFSET    29
34
35
class SvtSearchOptions_Impl : public ConfigItem
36
{
37
    sal_Int32   nFlags;
38
    bool    bModified;
39
40
    SvtSearchOptions_Impl(const SvtSearchOptions_Impl&) = delete;
41
    SvtSearchOptions_Impl& operator=(const SvtSearchOptions_Impl&) = delete;
42
43
    // ConfigItem
44
    virtual void    ImplCommit() override;
45
46
protected:
47
0
    bool            IsModified() const { return bModified; }
48
    using ConfigItem::SetModified;
49
    void            SetModified( bool bVal );
50
    void            Load();
51
    bool            Save();
52
53
    static Sequence< OUString >    GetPropertyNames();
54
55
public:
56
    SvtSearchOptions_Impl();
57
    virtual ~SvtSearchOptions_Impl() override;
58
59
    virtual void    Notify( const css::uno::Sequence< OUString >& aPropertyNames ) override;
60
61
    bool            GetFlag( sal_uInt16 nOffset ) const;
62
    void            SetFlag( sal_uInt16 nOffset, bool bVal );
63
    void            SetSearchAlgorithm( sal_uInt16 nOffset, bool bVal );
64
};
65
66
SvtSearchOptions_Impl::SvtSearchOptions_Impl() :
67
16
    ConfigItem( u"Office.Common/SearchOptions"_ustr ),
68
16
    nFlags(0x0003FFFF) // set all options values to 'true'
69
70
16
{
71
16
    Load();
72
16
    SetModified( false );
73
16
}
74
75
SvtSearchOptions_Impl::~SvtSearchOptions_Impl()
76
16
{
77
16
    assert(!IsModified()); // should have been committed
78
16
}
79
80
void SvtSearchOptions_Impl::ImplCommit()
81
0
{
82
0
    if (IsModified())
83
0
        Save();
84
0
}
85
86
void SvtSearchOptions_Impl::Notify( const Sequence< OUString >&  )
87
0
{
88
0
}
89
90
bool SvtSearchOptions_Impl::GetFlag( sal_uInt16 nOffset ) const
91
448
{
92
448
    DBG_ASSERT( nOffset <= MAX_FLAGS_OFFSET, "offset out of range");
93
448
    return ((nFlags >> nOffset) & 0x01) != 0;
94
448
}
95
96
void SvtSearchOptions_Impl::SetFlag( sal_uInt16 nOffset, bool bVal )
97
0
{
98
0
    DBG_ASSERT( nOffset <= MAX_FLAGS_OFFSET, "offset out of range");
99
0
    sal_Int32 nOldFlags = nFlags;
100
0
    sal_Int32 nMask = (sal_Int32(1))  << nOffset;
101
0
    if (bVal)
102
0
        nFlags |= nMask;
103
0
    else
104
0
        nFlags &= ~nMask;
105
0
    if (nFlags != nOldFlags)
106
0
        SetModified( true );
107
0
}
108
109
void SvtSearchOptions_Impl::SetModified( bool bVal )
110
16
{
111
16
    bModified = bVal;
112
16
    if (bModified)
113
0
    {
114
0
        ConfigItem::SetModified();
115
0
    }
116
16
}
117
118
Sequence< OUString > SvtSearchOptions_Impl::GetPropertyNames()
119
16
{
120
16
    static constexpr OUString aPropNames[ MAX_FLAGS_OFFSET + 1 ] =
121
16
    {
122
16
        u"IsWholeWordsOnly"_ustr,                     //  0
123
16
        u"IsBackwards"_ustr,                          //  1
124
16
        u"IsUseRegularExpression"_ustr,               //  2
125
        //"IsCurrentSelectionOnly",             // interactively set or not...
126
16
        u"IsSearchForStyles"_ustr,                    //  3
127
16
        u"IsSimilaritySearch"_ustr,                   //  4
128
16
        u"IsUseAsianOptions"_ustr,                    //  5
129
16
        u"IsMatchCase"_ustr,                          //  6
130
16
        u"Japanese/IsMatchFullHalfWidthForms"_ustr,   //  7
131
16
        u"Japanese/IsMatchHiraganaKatakana"_ustr,     //  8
132
16
        u"Japanese/IsMatchContractions"_ustr,         //  9
133
16
        u"Japanese/IsMatchMinusDashCho-on"_ustr,      // 10
134
16
        u"Japanese/IsMatchRepeatCharMarks"_ustr,      // 11
135
16
        u"Japanese/IsMatchVariantFormKanji"_ustr,     // 12
136
16
        u"Japanese/IsMatchOldKanaForms"_ustr,         // 13
137
16
        u"Japanese/IsMatch_DiZi_DuZu"_ustr,           // 14
138
16
        u"Japanese/IsMatch_BaVa_HaFa"_ustr,           // 15
139
16
        u"Japanese/IsMatch_TsiThiChi_DhiZi"_ustr,     // 16
140
16
        u"Japanese/IsMatch_HyuIyu_ByuVyu"_ustr,       // 17
141
16
        u"Japanese/IsMatch_SeShe_ZeJe"_ustr,          // 18
142
16
        u"Japanese/IsMatch_IaIya"_ustr,               // 19
143
16
        u"Japanese/IsMatch_KiKu"_ustr,                // 20
144
16
        u"Japanese/IsIgnorePunctuation"_ustr,         // 21
145
16
        u"Japanese/IsIgnoreWhitespace"_ustr,          // 22
146
16
        u"Japanese/IsIgnoreProlongedSoundMark"_ustr,  // 23
147
16
        u"Japanese/IsIgnoreMiddleDot"_ustr,           // 24
148
16
        u"IsNotes"_ustr,                              // 25
149
16
        u"IsIgnoreDiacritics_CTL"_ustr,               // 26
150
16
        u"IsIgnoreKashida_CTL"_ustr,                  // 27
151
16
        u"IsSearchFormatted"_ustr,                    // 28
152
16
        u"IsUseWildcard"_ustr                         // 29
153
16
    };
154
155
16
    Sequence< OUString > aNames(std::size(aPropNames));
156
16
    OUString* pNames = aNames.getArray();
157
496
    for (std::size_t i = 0;  i < std::size(aPropNames); ++i)
158
480
        pNames[i] = aPropNames[i];
159
160
16
    return aNames;
161
16
}
162
163
void SvtSearchOptions_Impl::SetSearchAlgorithm( sal_uInt16 nOffset, bool bVal )
164
0
{
165
0
    if (bVal)
166
0
    {
167
        // Search algorithms are mutually exclusive.
168
0
        if (nOffset != 2 && GetFlag(2))
169
0
            SetFlag( 2, false );
170
0
        if (nOffset != 4 && GetFlag(4))
171
0
            SetFlag( 4, false );
172
0
        if (nOffset != 29 && GetFlag(29))
173
0
            SetFlag( 29, false );
174
0
    }
175
0
    SetFlag( nOffset, bVal );
176
0
}
177
178
void SvtSearchOptions_Impl::Load()
179
16
{
180
16
    bool bSucc = false;
181
182
16
    Sequence< OUString > aNames = GetPropertyNames();
183
16
    sal_Int32 nProps = aNames.getLength();
184
185
16
    const Sequence< Any > aValues = GetProperties( aNames );
186
16
    DBG_ASSERT( aValues.getLength() == aNames.getLength(),
187
16
            "GetProperties failed" );
188
    //EnableNotification( aNames );
189
190
16
    if (nProps  &&  aValues.getLength() == nProps)
191
16
    {
192
16
        bSucc = true;
193
194
16
        const Any* pValues = aValues.getConstArray();
195
496
        for (sal_Int32 i = 0;  i < nProps;  ++i)
196
480
        {
197
480
            const Any &rVal = pValues[i];
198
480
            DBG_ASSERT( rVal.hasValue(), "property value missing" );
199
480
            if (rVal.hasValue())
200
0
            {
201
0
                bool bVal = bool();
202
0
                if (rVal >>= bVal)
203
0
                {
204
0
                    if (i <= MAX_FLAGS_OFFSET)
205
0
                    {
206
                        // use index in sequence as flag index
207
0
                        SetFlag( i, bVal );
208
0
                    }
209
0
                    else {
210
0
                        OSL_FAIL( "unexpected index" );
211
0
                    }
212
0
                }
213
0
                else
214
0
                {
215
0
                    OSL_FAIL( "unexpected type" );
216
0
                    bSucc = false;
217
0
                }
218
0
            }
219
480
            else
220
480
            {
221
480
                OSL_FAIL( "value missing" );
222
480
                bSucc = false;
223
480
            }
224
480
        }
225
16
    }
226
16
    DBG_ASSERT( bSucc, "LoadConfig failed" );
227
16
}
228
229
bool SvtSearchOptions_Impl::Save()
230
0
{
231
0
    bool bSucc = false;
232
233
0
    const Sequence< OUString > aNames = GetPropertyNames();
234
0
    sal_Int32 nProps = aNames.getLength();
235
236
0
    Sequence< Any > aValues( nProps );
237
0
    Any *pValue = aValues.getArray();
238
239
0
    DBG_ASSERT( nProps == MAX_FLAGS_OFFSET + 1,
240
0
            "unexpected size of index" );
241
0
    if (nProps == MAX_FLAGS_OFFSET + 1)
242
0
    {
243
0
        for (sal_Int32 i = 0;  i < nProps;  ++i)
244
0
            pValue[i] <<= GetFlag(i);
245
0
        bSucc |= PutProperties( aNames, aValues );
246
0
    }
247
248
0
    if (bSucc)
249
0
        SetModified( false );
250
251
0
    return bSucc;
252
0
}
253
254
SvtSearchOptions::SvtSearchOptions()
255
16
    : pImpl( new SvtSearchOptions_Impl )
256
16
{
257
16
}
258
259
SvtSearchOptions::~SvtSearchOptions()
260
16
{
261
16
}
262
263
void SvtSearchOptions::Commit()
264
0
{
265
0
    pImpl->Commit();
266
0
}
267
268
TransliterationFlags SvtSearchOptions::GetTransliterationFlags() const
269
0
{
270
0
    TransliterationFlags nRes = TransliterationFlags::NONE;
271
272
0
    if (!IsMatchCase()) // 'IsMatchCase' means act case sensitive
273
0
        nRes |= TransliterationFlags::IGNORE_CASE;
274
0
    if ( IsMatchFullHalfWidthForms())
275
0
        nRes |= TransliterationFlags::IGNORE_WIDTH;
276
0
    if ( IsMatchHiraganaKatakana())
277
0
        nRes |= TransliterationFlags::IGNORE_KANA;
278
0
    if ( IsMatchContractions())
279
0
        nRes |= TransliterationFlags::ignoreSize_ja_JP;
280
0
    if ( IsMatchMinusDashChoon())
281
0
        nRes |= TransliterationFlags::ignoreMinusSign_ja_JP;
282
0
    if ( IsMatchRepeatCharMarks())
283
0
        nRes |= TransliterationFlags::ignoreIterationMark_ja_JP;
284
0
    if ( IsMatchVariantFormKanji())
285
0
        nRes |= TransliterationFlags::ignoreTraditionalKanji_ja_JP;
286
0
    if ( IsMatchOldKanaForms())
287
0
        nRes |= TransliterationFlags::ignoreTraditionalKana_ja_JP;
288
0
    if ( IsMatchDiziDuzu())
289
0
        nRes |= TransliterationFlags::ignoreZiZu_ja_JP;
290
0
    if ( IsMatchBavaHafa())
291
0
        nRes |= TransliterationFlags::ignoreBaFa_ja_JP;
292
0
    if ( IsMatchTsithichiDhizi())
293
0
        nRes |= TransliterationFlags::ignoreTiJi_ja_JP;
294
0
    if ( IsMatchHyuiyuByuvyu())
295
0
        nRes |= TransliterationFlags::ignoreHyuByu_ja_JP;
296
0
    if ( IsMatchSesheZeje())
297
0
        nRes |= TransliterationFlags::ignoreSeZe_ja_JP;
298
0
    if ( IsMatchIaiya())
299
0
        nRes |= TransliterationFlags::ignoreIandEfollowedByYa_ja_JP;
300
0
    if ( IsMatchKiku())
301
0
        nRes |= TransliterationFlags::ignoreKiKuFollowedBySa_ja_JP;
302
0
    if ( IsIgnorePunctuation())
303
0
        nRes |= TransliterationFlags::ignoreSeparator_ja_JP;
304
0
    if ( IsIgnoreWhitespace())
305
0
        nRes |= TransliterationFlags::ignoreSpace_ja_JP;
306
0
    if ( IsIgnoreProlongedSoundMark())
307
0
        nRes |= TransliterationFlags::ignoreProlongedSoundMark_ja_JP;
308
0
    if ( IsIgnoreMiddleDot())
309
0
        nRes |= TransliterationFlags::ignoreMiddleDot_ja_JP;
310
0
    if ( IsIgnoreDiacritics_CTL())
311
0
        nRes |= TransliterationFlags::IGNORE_DIACRITICS_CTL;
312
0
    if ( IsIgnoreKashida_CTL())
313
0
        nRes |= TransliterationFlags::IGNORE_KASHIDA_CTL;
314
0
    return nRes;
315
0
}
316
317
bool SvtSearchOptions::IsWholeWordsOnly() const
318
16
{
319
16
    return pImpl->GetFlag( 0 );
320
16
}
321
322
void SvtSearchOptions::SetWholeWordsOnly( bool bVal )
323
0
{
324
0
    pImpl->SetFlag( 0, bVal );
325
0
}
326
327
bool SvtSearchOptions::IsBackwards() const
328
16
{
329
16
    return pImpl->GetFlag( 1 );
330
16
}
331
332
void SvtSearchOptions::SetBackwards( bool bVal )
333
0
{
334
0
    pImpl->SetFlag( 1, bVal );
335
0
}
336
337
bool SvtSearchOptions::IsUseRegularExpression() const
338
16
{
339
16
    return pImpl->GetFlag( 2 );
340
16
}
341
342
void SvtSearchOptions::SetUseRegularExpression( bool bVal )
343
0
{
344
0
    pImpl->SetSearchAlgorithm( 2, bVal );
345
0
}
346
347
void SvtSearchOptions::SetSearchForStyles( bool bVal )
348
0
{
349
0
    pImpl->SetFlag( 3, bVal );
350
0
}
351
352
bool SvtSearchOptions::IsSimilaritySearch() const
353
16
{
354
16
    return pImpl->GetFlag( 4 );
355
16
}
356
357
void SvtSearchOptions::SetSimilaritySearch( bool bVal )
358
0
{
359
0
    pImpl->SetSearchAlgorithm( 4, bVal );
360
0
}
361
362
bool SvtSearchOptions::IsUseAsianOptions() const
363
16
{
364
16
    return pImpl->GetFlag( 5 );
365
16
}
366
367
void SvtSearchOptions::SetUseAsianOptions( bool bVal )
368
0
{
369
0
    pImpl->SetFlag( 5, bVal );
370
0
}
371
372
bool SvtSearchOptions::IsMatchCase() const
373
16
{
374
16
    return pImpl->GetFlag( 6 );
375
16
}
376
377
void SvtSearchOptions::SetMatchCase( bool bVal )
378
0
{
379
0
    pImpl->SetFlag( 6, bVal );
380
0
}
381
382
bool SvtSearchOptions::IsMatchFullHalfWidthForms() const
383
16
{
384
16
    return pImpl->GetFlag( 7 );
385
16
}
386
387
void SvtSearchOptions::SetMatchFullHalfWidthForms( bool bVal )
388
0
{
389
0
    pImpl->SetFlag( 7, bVal );
390
0
}
391
392
bool SvtSearchOptions::IsMatchHiraganaKatakana() const
393
16
{
394
16
    return pImpl->GetFlag( 8 );
395
16
}
396
397
void SvtSearchOptions::SetMatchHiraganaKatakana( bool bVal )
398
0
{
399
0
    pImpl->SetFlag( 8, bVal );
400
0
}
401
402
bool SvtSearchOptions::IsMatchContractions() const
403
16
{
404
16
    return pImpl->GetFlag( 9 );
405
16
}
406
407
void SvtSearchOptions::SetMatchContractions( bool bVal )
408
0
{
409
0
    pImpl->SetFlag( 9, bVal );
410
0
}
411
412
bool SvtSearchOptions::IsMatchMinusDashChoon() const
413
16
{
414
16
    return pImpl->GetFlag( 10 );
415
16
}
416
417
void SvtSearchOptions::SetMatchMinusDashChoon( bool bVal )
418
0
{
419
0
    pImpl->SetFlag( 10, bVal );
420
0
}
421
422
bool SvtSearchOptions::IsMatchRepeatCharMarks() const
423
16
{
424
16
    return pImpl->GetFlag( 11 );
425
16
}
426
427
void SvtSearchOptions::SetMatchRepeatCharMarks( bool bVal )
428
0
{
429
0
    pImpl->SetFlag( 11, bVal );
430
0
}
431
432
bool SvtSearchOptions::IsMatchVariantFormKanji() const
433
16
{
434
16
    return pImpl->GetFlag( 12 );
435
16
}
436
437
void SvtSearchOptions::SetMatchVariantFormKanji( bool bVal )
438
0
{
439
0
    pImpl->SetFlag( 12, bVal );
440
0
}
441
442
bool SvtSearchOptions::IsMatchOldKanaForms() const
443
16
{
444
16
    return pImpl->GetFlag( 13 );
445
16
}
446
447
void SvtSearchOptions::SetMatchOldKanaForms( bool bVal )
448
0
{
449
0
    pImpl->SetFlag( 13, bVal );
450
0
}
451
452
bool SvtSearchOptions::IsMatchDiziDuzu() const
453
16
{
454
16
    return pImpl->GetFlag( 14 );
455
16
}
456
457
void SvtSearchOptions::SetMatchDiziDuzu( bool bVal )
458
0
{
459
0
    pImpl->SetFlag( 14, bVal );
460
0
}
461
462
bool SvtSearchOptions::IsMatchBavaHafa() const
463
16
{
464
16
    return pImpl->GetFlag( 15 );
465
16
}
466
467
void SvtSearchOptions::SetMatchBavaHafa( bool bVal )
468
0
{
469
0
    pImpl->SetFlag( 15, bVal );
470
0
}
471
472
bool SvtSearchOptions::IsMatchTsithichiDhizi() const
473
16
{
474
16
    return pImpl->GetFlag( 16 );
475
16
}
476
477
void SvtSearchOptions::SetMatchTsithichiDhizi( bool bVal )
478
0
{
479
0
    pImpl->SetFlag( 16, bVal );
480
0
}
481
482
bool SvtSearchOptions::IsMatchHyuiyuByuvyu() const
483
16
{
484
16
    return pImpl->GetFlag( 17 );
485
16
}
486
487
void SvtSearchOptions::SetMatchHyuiyuByuvyu( bool bVal )
488
0
{
489
0
    pImpl->SetFlag( 17, bVal );
490
0
}
491
492
bool SvtSearchOptions::IsMatchSesheZeje() const
493
16
{
494
16
    return pImpl->GetFlag( 18 );
495
16
}
496
497
void SvtSearchOptions::SetMatchSesheZeje( bool bVal )
498
0
{
499
0
    pImpl->SetFlag( 18, bVal );
500
0
}
501
502
bool SvtSearchOptions::IsMatchIaiya() const
503
16
{
504
16
    return pImpl->GetFlag( 19 );
505
16
}
506
507
void SvtSearchOptions::SetMatchIaiya( bool bVal )
508
0
{
509
0
    pImpl->SetFlag( 19, bVal );
510
0
}
511
512
bool SvtSearchOptions::IsMatchKiku() const
513
16
{
514
16
    return pImpl->GetFlag( 20 );
515
16
}
516
517
void SvtSearchOptions::SetMatchKiku( bool bVal )
518
0
{
519
0
    pImpl->SetFlag( 20, bVal );
520
0
}
521
522
bool SvtSearchOptions::IsIgnorePunctuation() const
523
16
{
524
16
    return pImpl->GetFlag( 21 );
525
16
}
526
527
void SvtSearchOptions::SetIgnorePunctuation( bool bVal )
528
0
{
529
0
    pImpl->SetFlag( 21, bVal );
530
0
}
531
532
bool SvtSearchOptions::IsIgnoreWhitespace() const
533
16
{
534
16
    return pImpl->GetFlag( 22 );
535
16
}
536
537
void SvtSearchOptions::SetIgnoreWhitespace( bool bVal )
538
0
{
539
0
    pImpl->SetFlag( 22, bVal );
540
0
}
541
542
bool SvtSearchOptions::IsIgnoreProlongedSoundMark() const
543
16
{
544
16
    return pImpl->GetFlag( 23 );
545
16
}
546
547
void SvtSearchOptions::SetIgnoreProlongedSoundMark( bool bVal )
548
0
{
549
0
    pImpl->SetFlag( 23, bVal );
550
0
}
551
552
bool SvtSearchOptions::IsIgnoreMiddleDot() const
553
16
{
554
16
    return pImpl->GetFlag( 24 );
555
16
}
556
557
void SvtSearchOptions::SetIgnoreMiddleDot( bool bVal )
558
0
{
559
0
    pImpl->SetFlag( 24, bVal );
560
0
}
561
562
bool SvtSearchOptions::IsNotes() const
563
16
{
564
16
    return pImpl->GetFlag( 25 );
565
16
}
566
567
void SvtSearchOptions::SetNotes( bool bVal )
568
0
{
569
0
    pImpl->SetFlag( 25, bVal );
570
0
}
571
572
bool SvtSearchOptions::IsIgnoreDiacritics_CTL() const
573
16
{
574
16
    return pImpl->GetFlag( 26 );
575
16
}
576
577
void SvtSearchOptions::SetIgnoreDiacritics_CTL( bool bVal )
578
0
{
579
0
    pImpl->SetFlag( 26, bVal );
580
0
}
581
582
bool SvtSearchOptions::IsIgnoreKashida_CTL() const
583
16
{
584
16
    return pImpl->GetFlag( 27 );
585
16
}
586
587
void SvtSearchOptions::SetIgnoreKashida_CTL( bool bVal )
588
0
{
589
0
    pImpl->SetFlag( 27, bVal );
590
0
}
591
592
bool SvtSearchOptions::IsSearchFormatted() const
593
0
{
594
0
    return pImpl->GetFlag( 28 );
595
0
}
596
597
void SvtSearchOptions::SetSearchFormatted( bool bVal )
598
0
{
599
0
    pImpl->SetFlag( 28, bVal );
600
0
}
601
602
bool SvtSearchOptions::IsUseWildcard() const
603
16
{
604
16
    return pImpl->GetFlag( 29 );
605
16
}
606
607
void SvtSearchOptions::SetUseWildcard( bool bVal )
608
0
{
609
0
    pImpl->SetSearchAlgorithm( 29, bVal );
610
0
}
611
612
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */