xref: /AOO41X/main/cui/source/dialogs/cuifmsearch.cxx (revision 8809db7a87f97847b57a57f4cd2b0104b2b83182)
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 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_cui.hxx"
26 
27 #include <tools/debug.hxx>
28 #include <vcl/msgbox.hxx>
29 #include <vcl/svapp.hxx>
30 #include <tools/shl.hxx>
31 #include <dialmgr.hxx>
32 #include <sfx2/tabdlg.hxx>
33 #include <osl/mutex.hxx>
34 #include <sfx2/app.hxx>
35 #include <cuires.hrc>
36 #include <svl/filerec.hxx>
37 #include <svx/fmsrccfg.hxx>
38 #include <svx/fmsrcimp.hxx>
39 #include "fmsearch.hrc"
40 #include "cuifmsearch.hxx"
41 #include <svx/srchdlg.hxx>
42 #include <svl/cjkoptions.hxx>
43 #include <com/sun/star/i18n/TransliterationModules.hpp>
44 #include <comphelper/processfactory.hxx>
45 #include <svx/svxdlg.hxx>
46 
47 using namespace ::com::sun::star::uno;
48 using namespace ::com::sun::star::i18n;
49 using namespace ::svxform;
50 using namespace ::com::sun::star::sdbc;
51 using namespace ::com::sun::star::util;
52 
53 #define MAX_HISTORY_ENTRIES     50
54 
55 //------------------------------------------------------------------------
56 void FmSearchDialog::initCommon( const Reference< XResultSet >& _rxCursor )
57 {
58     // init the engine
59     DBG_ASSERT( m_pSearchEngine, "FmSearchDialog::initCommon: have no engine!" );
60     m_pSearchEngine->SetProgressHandler(LINK(this, FmSearchDialog, OnSearchProgress));
61 
62     // some layout changes according to available CJK options
63     SvtCJKOptions aCJKOptions;
64     if (!aCJKOptions.IsJapaneseFindEnabled())
65     {
66         sal_Int32 nUpper = m_cbApprox.GetPosPixel().Y();
67         sal_Int32 nDifference = m_aSoundsLikeCJKSettings.GetPosPixel().Y() - nUpper;
68 
69         // hide the options for the japanese search
70         Control* pFieldsToMove[] = { &m_flState, &m_ftRecordLabel, &m_ftRecord, &m_ftHint };
71         implMoveControls(pFieldsToMove, sizeof(pFieldsToMove)/sizeof(pFieldsToMove[0]), nDifference, &m_flOptions);
72 
73         m_aSoundsLikeCJK.Hide();
74         m_aSoundsLikeCJKSettings.Hide();
75     }
76 
77     if (!aCJKOptions.IsCJKFontEnabled())
78     {
79         m_aHalfFullFormsCJK.Hide();
80 
81         // never ignore the width (ignoring is expensive) if the option is not available at all
82         // 04.12.2001 - 91973 - fs@openoffice.org
83         m_pSearchEngine->SetIgnoreWidthCJK( sal_False );
84     }
85 
86     // some initial record texts
87     m_ftRecord.SetText( String::CreateFromInt32( _rxCursor->getRow() ) );
88     m_pbClose.SetHelpText(String());
89 }
90 
91 //------------------------------------------------------------------------
92 FmSearchDialog::FmSearchDialog(Window* pParent, const UniString& sInitialText, const ::std::vector< String >& _rContexts, sal_Int16 nInitialContext,
93     const Link& lnkContextSupplier)
94     :ModalDialog(pParent, CUI_RES(RID_SVXDLG_SEARCHFORM))
95     ,m_flSearchFor              (this, CUI_RES(FL_SEARCHFOR))
96     ,m_rbSearchForText          (this, CUI_RES(RB_SEARCHFORTEXT))
97     ,m_rbSearchForNull          (this, CUI_RES(RB_SEARCHFORNULL))
98     ,m_rbSearchForNotNull       (this, CUI_RES(RB_SEARCHFORNOTNULL))
99     ,m_cmbSearchText            (this, CUI_RES(CMB_SEARCHTEXT))
100     ,m_flWhere                  (this, CUI_RES(FL_WHERE))
101     ,m_ftForm                   (this, CUI_RES(FT_FORM))
102     ,m_lbForm                   (this, CUI_RES(LB_FORM))
103     ,m_rbAllFields              (this, CUI_RES(RB_ALLFIELDS))
104     ,m_rbSingleField            (this, CUI_RES(RB_SINGLEFIELD))
105     ,m_lbField                  (this, CUI_RES(LB_FIELD))
106     ,m_flOptions                (this, CUI_RES(FL_OPTIONS))
107     ,m_ftPosition               (this, CUI_RES(FT_POSITION))
108     ,m_lbPosition               (this, CUI_RES(LB_POSITION))
109     ,m_cbUseFormat              (this, CUI_RES(CB_USEFORMATTER))
110     ,m_cbCase                   (this, CUI_RES(CB_CASE))
111     ,m_cbBackwards              (this, CUI_RES(CB_BACKWARD))
112     ,m_cbStartOver              (this, CUI_RES(CB_STARTOVER))
113     ,m_cbWildCard               (this, CUI_RES(CB_WILDCARD))
114     ,m_cbRegular                (this, CUI_RES(CB_REGULAR))
115     ,m_cbApprox                 (this, CUI_RES(CB_APPROX))
116     ,m_pbApproxSettings         (this, CUI_RES(PB_APPROXSETTINGS))
117     ,m_aHalfFullFormsCJK        (this, CUI_RES(CB_HALFFULLFORMS))
118     ,m_aSoundsLikeCJK           (this, CUI_RES(CB_SOUNDSLIKECJK))
119     ,m_aSoundsLikeCJKSettings   (this, CUI_RES(PB_SOUNDSLIKESETTINGS))
120     ,m_flState                  (this, CUI_RES(FL_STATE))
121     ,m_ftRecordLabel            (this, CUI_RES(FT_RECORDLABEL))
122     ,m_ftRecord                 (this, CUI_RES(FT_RECORD))
123     ,m_ftHint                   (this, CUI_RES(FT_HINT))
124     ,m_pbSearchAgain            (this, CUI_RES(PB_SEARCH))
125     ,m_pbClose                  (this, CUI_RES(1))
126     ,m_pbHelp                   (this, CUI_RES(1))
127     ,m_sSearch                  ( m_pbSearchAgain.GetText() )
128     ,m_sCancel                  ( Button::GetStandardText( BUTTON_CANCEL ) )
129     ,m_pPreSearchFocus( NULL )
130     ,m_lnkContextSupplier(lnkContextSupplier)
131     ,m_pConfig( NULL )
132 {
133     DBG_ASSERT(m_lnkContextSupplier.IsSet(), "FmSearchDialog::FmSearchDialog : have no ContextSupplier !");
134 
135     // erst mal die Informationen fuer den initialen Kontext
136     FmSearchContext fmscInitial;
137     fmscInitial.nContext = nInitialContext;
138     m_lnkContextSupplier.Call(&fmscInitial);
139     DBG_ASSERT(fmscInitial.xCursor.is(), "FmSearchDialog::FmSearchDialog : invalid data supplied by ContextSupplier !");
140     DBG_ASSERT(fmscInitial.strUsedFields.GetTokenCount(';') == (xub_StrLen)fmscInitial.arrFields.size(),
141         "FmSearchDialog::FmSearchDialog : invalid data supplied by ContextSupplied !");
142 #if (OSL_DEBUG_LEVEL > 1) || defined DBG_UTIL
143     for (sal_Int32 i=0; i<(sal_Int32)fmscInitial.arrFields.size(); ++i)
144         DBG_ASSERT(fmscInitial.arrFields.at(i).is(), "FmSearchDialog::FmSearchDialog : invalid data supplied by ContextSupplier !");
145 #endif // (OSL_DEBUG_LEVEL > 1) || DBG_UTIL
146 
147     for (   ::std::vector< String >::const_iterator context = _rContexts.begin();
148             context != _rContexts.end();
149             ++context
150         )
151     {
152         m_arrContextFields.push_back(String());
153         m_lbForm.InsertEntry(*context);
154     }
155     m_lbForm.SelectEntryPos(nInitialContext);
156 
157     m_lbForm.SetSelectHdl(LINK(this, FmSearchDialog, OnContextSelection));
158 
159     if (m_arrContextFields.size() == 1)
160     {   // remove the context selection listbox and rearrange the controls accordingly
161         sal_Int32 nUpper = m_lbForm.GetPosPixel().Y();
162         sal_Int32 nDifference = m_rbAllFields.GetPosPixel().Y() - nUpper;
163 
164         // move all controls below the affected ones up
165         Control* pFieldsToMove[] = { &m_rbAllFields, &m_rbSingleField, &m_lbField, &m_flOptions, &m_ftPosition, &m_lbPosition,
166                 &m_cbUseFormat, &m_cbCase, &m_cbBackwards, &m_cbStartOver, &m_cbWildCard, &m_cbRegular, &m_cbApprox,
167                 &m_pbApproxSettings, &m_aHalfFullFormsCJK, &m_aSoundsLikeCJK, &m_aSoundsLikeCJKSettings,
168                 &m_flState, &m_ftRecordLabel, &m_ftRecord, &m_ftHint };
169 
170         implMoveControls(pFieldsToMove, sizeof(pFieldsToMove)/sizeof(pFieldsToMove[0]), nDifference, &m_flWhere);
171 
172         Point pt = m_rbAllFields.GetPosPixel();
173         pt.X() = m_ftForm.GetPosPixel().X();
174         m_rbAllFields.SetPosPixel( pt );
175         pt = m_rbSingleField.GetPosPixel();
176         pt.X() = m_ftForm.GetPosPixel().X();
177         m_rbSingleField.SetPosPixel( pt );
178 
179         // hide dispensable controls
180         m_ftForm.Hide();
181         m_lbForm.Hide();
182     }
183 
184     m_pSearchEngine = new FmSearchEngine(
185         ::comphelper::getProcessServiceFactory(), fmscInitial.xCursor, fmscInitial.strUsedFields, fmscInitial.arrFields, SM_ALLOWSCHEDULE );
186     initCommon( fmscInitial.xCursor );
187 
188     if (fmscInitial.sFieldDisplayNames.Len() != 0)
189     {   // use the display names if supplied
190         DBG_ASSERT(fmscInitial.sFieldDisplayNames.GetTokenCount() == fmscInitial.strUsedFields.GetTokenCount(),
191             "FmSearchDialog::FmSearchDialog : invalid initial context description !");
192         Init(fmscInitial.sFieldDisplayNames, sInitialText);
193     }
194     else
195         Init(fmscInitial.strUsedFields, sInitialText);
196 }
197 
198 //------------------------------------------------------------------------
199 void FmSearchDialog::implMoveControls(
200             Control** _ppControls,
201             sal_Int32 _nControls,
202             sal_Int32 _nUp,
203             Control* /*_pToResize*/)
204 {
205     for (sal_Int32 i=0; i<_nControls; ++i)
206     {
207         Point pt = _ppControls[i]->GetPosPixel();
208         pt.Y() -= _nUp;
209         _ppControls[i]->SetPosPixel(pt);
210     }
211 
212     // resize myself
213     Size sz = GetSizePixel();
214     sz.Height() -= _nUp;
215     SetSizePixel(sz);
216 }
217 
218 //------------------------------------------------------------------------
219 FmSearchDialog::~FmSearchDialog()
220 {
221     if (m_aDelayedPaint.IsActive())
222         m_aDelayedPaint.Stop();
223 
224     SaveParams();
225 
226     if (m_pConfig)
227     {
228         delete m_pConfig;
229         m_pConfig = NULL;
230     }
231 
232     delete m_pSearchEngine;
233 }
234 
235 //------------------------------------------------------------------------
236 void FmSearchDialog::Init(const UniString& strVisibleFields, const UniString& sInitialText)
237 {
238     // die Initialisierung all der Controls
239     m_rbSearchForText.SetClickHdl(LINK(this, FmSearchDialog, OnClickedFieldRadios));
240     m_rbSearchForNull.SetClickHdl(LINK(this, FmSearchDialog, OnClickedFieldRadios));
241     m_rbSearchForNotNull.SetClickHdl(LINK(this, FmSearchDialog, OnClickedFieldRadios));
242 
243     m_rbAllFields.SetClickHdl(LINK(this, FmSearchDialog, OnClickedFieldRadios));
244     m_rbSingleField.SetClickHdl(LINK(this, FmSearchDialog, OnClickedFieldRadios));
245 
246     m_pbSearchAgain.SetClickHdl(LINK(this, FmSearchDialog, OnClickedSearchAgain));
247     m_pbApproxSettings.SetClickHdl(LINK(this, FmSearchDialog, OnClickedSpecialSettings));
248     m_aSoundsLikeCJKSettings.SetClickHdl(LINK(this, FmSearchDialog, OnClickedSpecialSettings));
249 
250     m_lbPosition.SetSelectHdl(LINK(this, FmSearchDialog, OnPositionSelected));
251     m_lbField.SetSelectHdl(LINK(this, FmSearchDialog, OnFieldSelected));
252 
253     m_cmbSearchText.SetModifyHdl(LINK(this, FmSearchDialog, OnSearchTextModified));
254     m_cmbSearchText.EnableAutocomplete(sal_False);
255 
256     m_cbUseFormat.SetToggleHdl(LINK(this, FmSearchDialog, OnCheckBoxToggled));
257     m_cbBackwards.SetToggleHdl(LINK(this, FmSearchDialog, OnCheckBoxToggled));
258     m_cbStartOver.SetToggleHdl(LINK(this, FmSearchDialog, OnCheckBoxToggled));
259     m_cbCase.SetToggleHdl(LINK(this, FmSearchDialog, OnCheckBoxToggled));
260     m_cbWildCard.SetToggleHdl(LINK(this, FmSearchDialog, OnCheckBoxToggled));
261     m_cbRegular.SetToggleHdl(LINK(this, FmSearchDialog, OnCheckBoxToggled));
262     m_cbApprox.SetToggleHdl(LINK(this, FmSearchDialog, OnCheckBoxToggled));
263     m_aHalfFullFormsCJK.SetToggleHdl(LINK(this, FmSearchDialog, OnCheckBoxToggled));
264     m_aSoundsLikeCJK.SetToggleHdl(LINK(this, FmSearchDialog, OnCheckBoxToggled));
265 
266     // die Listboxen fuellen
267     // die Methoden des Feldvergleiches
268     sal_uInt16 nResIds[] = {
269         RID_STR_SEARCH_ANYWHERE,
270         RID_STR_SEARCH_BEGINNING,
271         RID_STR_SEARCH_END,
272         RID_STR_SEARCH_WHOLE
273     };
274     for ( size_t i=0; i<sizeof(nResIds)/sizeof(nResIds[0]); ++i )
275         m_lbPosition.InsertEntry( String( CUI_RES( nResIds[i] ) ) );
276     m_lbPosition.SelectEntryPos(MATCHING_ANYWHERE);
277 
278     // die Feld-Listbox
279     for (sal_uInt16 i=0; i<strVisibleFields.GetTokenCount(';'); ++i)
280         m_lbField.InsertEntry(strVisibleFields.GetToken(i, ';'));
281 
282 
283     m_pConfig = new FmSearchConfigItem;
284     LoadParams();
285 
286     m_cmbSearchText.SetText(sInitialText);
287     // wenn die Edit-Zeile den Text veraendert hat (weil er zum Beispiel Steuerzeichen enthielt, wie das bei Memofeldern der Fall
288     // sein kann), nehme ich einen leeren UniString
289     UniString sRealSetText = m_cmbSearchText.GetText();
290     if (!sRealSetText.Equals(sInitialText))
291         m_cmbSearchText.SetText(UniString());
292     LINK(this, FmSearchDialog, OnSearchTextModified).Call(&m_cmbSearchText);
293 
294     // initial die ganzen UI-Elemente fuer die Suche an
295     m_aDelayedPaint.SetTimeoutHdl(LINK(this, FmSearchDialog, OnDelayedPaint));
296     m_aDelayedPaint.SetTimeout(500);
297     EnableSearchUI(sal_True);
298 
299     if ( m_rbSearchForText.IsChecked() )
300         m_cmbSearchText.GrabFocus();
301 
302     FreeResource();
303 }
304 
305 //------------------------------------------------------------------------
306 sal_Bool FmSearchDialog::Close()
307 {
308     // Wenn der Close-Button disabled ist und man im Dialog ESC drueckt, dann wird irgendwo vom Frame trotzdem Close aufgerufen,
309     // was ich allerdings nicht will, wenn ich gerade mitten in einer (eventuell in einem extra Thread laufenden) Suche bin
310     if (!m_pbClose.IsEnabled())
311         return sal_False;
312     return ModalDialog::Close();
313 }
314 
315 //------------------------------------------------------------------------
316 IMPL_LINK(FmSearchDialog, OnClickedFieldRadios, Button*, pButton)
317 {
318     if ((pButton == &m_rbSearchForText) || (pButton == &m_rbSearchForNull) || (pButton == &m_rbSearchForNotNull))
319     {
320         EnableSearchForDependees(sal_True);
321     }
322     else
323         // die Feldlistbox entsprechend en- oder disablen
324         if (pButton == &m_rbSingleField)
325         {
326             m_lbField.Enable();
327             m_pSearchEngine->RebuildUsedFields(m_lbField.GetSelectEntryPos());
328         }
329         else
330         {
331             m_lbField.Disable();
332             m_pSearchEngine->RebuildUsedFields(-1);
333         }
334 
335     return 0;
336 }
337 
338 //------------------------------------------------------------------------
339 IMPL_LINK(FmSearchDialog, OnClickedSearchAgain, Button*, EMPTYARG)
340 {
341     if (m_pbClose.IsEnabled())
342     {   // der Button hat die Funktion 'Suchen'
343         UniString strThisRoundText = m_cmbSearchText.GetText();
344         // zur History dazu
345         m_cmbSearchText.RemoveEntry(strThisRoundText);
346         m_cmbSearchText.InsertEntry(strThisRoundText, 0);
347             // das Remove/Insert stellt a) sicher, dass der UniString nicht zweimal auftaucht, b), dass die zuletzt gesuchten Strings am
348             // Anfang stehen
349         // und die Listenlaenge beschraenken
350         while (m_cmbSearchText.GetEntryCount() > MAX_HISTORY_ENTRIES)
351             m_cmbSearchText.RemoveEntry(m_cmbSearchText.GetEntryCount()-1);
352 
353         // den 'Ueberlauf'-Hint rausnehmen
354         m_ftHint.SetText(UniString());
355         m_ftHint.Invalidate();
356 
357         if (m_cbStartOver.IsChecked())
358         {
359             m_cbStartOver.Check(sal_False);
360             EnableSearchUI(sal_False);
361             if (m_rbSearchForText.IsChecked())
362                 m_pSearchEngine->StartOver(strThisRoundText);
363             else
364                 m_pSearchEngine->StartOverSpecial(m_rbSearchForNull.IsChecked());
365         }
366         else
367         {
368             EnableSearchUI(sal_False);
369             if (m_rbSearchForText.IsChecked())
370                 m_pSearchEngine->SearchNext(strThisRoundText);
371             else
372                 m_pSearchEngine->SearchNextSpecial(m_rbSearchForNull.IsChecked());
373         }
374     }
375     else
376     {   // der Button hat die Fukntion 'Abbrechen'
377         DBG_ASSERT(m_pSearchEngine->GetSearchMode() != SM_BRUTE, "FmSearchDialog, OnClickedSearchAgain : falscher Modus !");
378             // der CancelButton wird normalerweise nur disabled, wenn ich in einem Thread oder mit Reschedule arbeite
379         m_pSearchEngine->CancelSearch();
380             // mein ProgressHandler wird gerufen, wenn es wirklich zu Ende ist, das hier war nur eine Anforderung
381     }
382     return 0;
383 }
384 
385 //------------------------------------------------------------------------
386 IMPL_LINK(FmSearchDialog, OnClickedSpecialSettings, Button*, pButton )
387 {
388     if (&m_pbApproxSettings == pButton)
389     {
390         AbstractSvxSearchSimilarityDialog* pDlg = NULL;
391 
392         SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
393         if ( pFact )
394             pDlg = pFact->CreateSvxSearchSimilarityDialog( this, m_pSearchEngine->GetLevRelaxed(), m_pSearchEngine->GetLevOther(),
395                         m_pSearchEngine->GetLevShorter(), m_pSearchEngine->GetLevLonger() );
396         DBG_ASSERT( pDlg, "FmSearchDialog, OnClickedSpecialSettings: could not load the dialog!" );
397 
398         if ( pDlg && pDlg->Execute() == RET_OK )
399         {
400             m_pSearchEngine->SetLevRelaxed( pDlg->IsRelaxed() );
401             m_pSearchEngine->SetLevOther( pDlg->GetOther() );
402             m_pSearchEngine->SetLevShorter(pDlg->GetShorter() );
403             m_pSearchEngine->SetLevLonger( pDlg->GetLonger() );
404         }
405         delete pDlg;
406     }
407     else if (&m_aSoundsLikeCJKSettings == pButton)
408     {
409         SfxItemSet aSet( SFX_APP()->GetPool() );
410         //CHINA001 SvxJSearchOptionsDialog aDlg( this, aSet, RID_SVXPAGE_JSEARCH_OPTIONS, m_pSearchEngine->GetTransliterationFlags() );
411         SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
412         if(pFact)
413         {
414             AbstractSvxJSearchOptionsDialog* aDlg = pFact->CreateSvxJSearchOptionsDialog( this, aSet, m_pSearchEngine->GetTransliterationFlags() );
415             DBG_ASSERT(aDlg, "Dialogdiet fail!");//CHINA001
416             aDlg->Execute(); //CHINA001 aDlg.Execute();
417 
418 
419             sal_Int32 nFlags = aDlg->GetTransliterationFlags(); //CHINA001 sal_Int32 nFlags = aDlg.GetTransliterationFlags();
420             m_pSearchEngine->SetTransliterationFlags(nFlags);
421 
422             m_cbCase.Check(m_pSearchEngine->GetCaseSensitive());
423             OnCheckBoxToggled( &m_cbCase );
424             m_aHalfFullFormsCJK.Check( !m_pSearchEngine->GetIgnoreWidthCJK() );
425             OnCheckBoxToggled( &m_aHalfFullFormsCJK );
426             delete aDlg; //add for CHINA001
427         }
428     }
429 
430     return 0;
431 }
432 
433 //------------------------------------------------------------------------
434 IMPL_LINK(FmSearchDialog, OnSearchTextModified, ComboBox*, EMPTYARG)
435 {
436     if ((m_cmbSearchText.GetText().Len() != 0) || !m_rbSearchForText.IsChecked())
437         m_pbSearchAgain.Enable();
438     else
439         m_pbSearchAgain.Disable();
440 
441     m_pSearchEngine->InvalidatePreviousLoc();
442     return 0;
443 }
444 
445 //------------------------------------------------------------------------
446 IMPL_LINK(FmSearchDialog, OnPositionSelected, ListBox*, pBox)
447 {
448     (void) pBox; // avoid warning
449     DBG_ASSERT(pBox->GetSelectEntryCount() == 1, "FmSearchDialog::OnMethodSelected : unerwartet : nicht genau ein Eintrag selektiert !");
450 
451     m_pSearchEngine->SetPosition(m_lbPosition.GetSelectEntryPos());
452     return 0;
453 }
454 
455 //------------------------------------------------------------------------
456 IMPL_LINK(FmSearchDialog, OnFieldSelected, ListBox*, pBox)
457 {
458     (void) pBox; // avoid warning
459     DBG_ASSERT(pBox->GetSelectEntryCount() == 1, "FmSearchDialog::OnFieldSelected : unerwartet : nicht genau ein Eintrag selektiert !");
460 
461     m_pSearchEngine->RebuildUsedFields(m_rbAllFields.IsChecked() ? -1 : (sal_Int16)m_lbField.GetSelectEntryPos());
462         // ruft auch m_pSearchEngine->InvalidatePreviousLoc auf
463 
464     sal_Int32 nCurrentContext = m_lbForm.GetSelectEntryPos();
465     if (nCurrentContext != LISTBOX_ENTRY_NOTFOUND)
466         m_arrContextFields[nCurrentContext] = UniString(m_lbField.GetSelectEntry());
467     return 0;
468 }
469 
470 //------------------------------------------------------------------------
471 IMPL_LINK(FmSearchDialog, OnCheckBoxToggled, CheckBox*, pBox)
472 {
473     sal_Bool bChecked = pBox->IsChecked();
474 
475     // Formatter oder case -> an die Engine weiterreichen
476     if (pBox == &m_cbUseFormat)
477         m_pSearchEngine->SetFormatterUsing(bChecked);
478     else if (pBox == &m_cbCase)
479         m_pSearchEngine->SetCaseSensitive(bChecked);
480     // Richtung -> weiterreichen und Checkbox-Text fuer StartOver neu setzen
481     else if (pBox == &m_cbBackwards)
482     {
483         m_cbStartOver.SetText( String( CUI_RES( bChecked ? RID_STR_FROM_BOTTOM : RID_STR_FROM_TOP ) ) );
484         m_pSearchEngine->SetDirection(!bChecked);
485     }
486     // Aehnlichkeitssuche oder regulaerer Ausdruck
487     else if ((pBox == &m_cbApprox) || (pBox == &m_cbRegular) || (pBox == &m_cbWildCard))
488     {
489         // die beiden jeweils anderen Boxes disablen oder enablen
490         CheckBox* pBoxes[] = { &m_cbWildCard, &m_cbRegular, &m_cbApprox };
491         for (sal_uInt32 i=0; i<sizeof(pBoxes)/sizeof(CheckBox*); ++i)
492         {
493             if (pBoxes[i] != pBox)
494             {
495                 if (bChecked)
496                     pBoxes[i]->Disable();
497                 else
498                     pBoxes[i]->Enable();
499             }
500         }
501 
502         // an die Engine weiterreichen
503         m_pSearchEngine->SetWildcard(m_cbWildCard.IsEnabled() ? m_cbWildCard.IsChecked() : sal_False);
504         m_pSearchEngine->SetRegular(m_cbRegular.IsEnabled() ? m_cbRegular.IsChecked() : sal_False);
505         m_pSearchEngine->SetLevenshtein(m_cbApprox.IsEnabled() ? m_cbApprox.IsChecked() : sal_False);
506             // (Boxes, die disabled sind, muessen als sal_False an die Engine gehen)
507 
508         // die Position-Listbox anpassen (ist bei Wildcard-Suche nicht erlaubt)
509         if (pBox == &m_cbWildCard)
510         {
511             if (bChecked)
512             {
513                 m_ftPosition.Disable();
514                 m_lbPosition.Disable();
515             }
516             else
517             {
518                 m_ftPosition.Enable();
519                 m_lbPosition.Enable();
520             }
521         }
522 
523         // und den Button fuer die Aehnlichkeitssuche
524         if (pBox == &m_cbApprox)
525         {
526             if (bChecked)
527                 m_pbApproxSettings.Enable();
528             else
529                 m_pbApproxSettings.Disable();
530         }
531     }
532     else if (pBox == &m_aHalfFullFormsCJK)
533     {
534         // forward to the search engine
535         m_pSearchEngine->SetIgnoreWidthCJK( !bChecked );
536     }
537     else if (pBox == &m_aSoundsLikeCJK)
538     {
539         m_aSoundsLikeCJKSettings.Enable(bChecked);
540 
541         // two other buttons which depend on this one
542         sal_Bool bEnable =  (   m_rbSearchForText.IsChecked()
543                             &&  !m_aSoundsLikeCJK.IsChecked()
544                             )
545                          || !SvtCJKOptions().IsJapaneseFindEnabled();
546         m_cbCase.Enable(bEnable);
547         m_aHalfFullFormsCJK.Enable(bEnable);
548 
549         // forward to the search engine
550         m_pSearchEngine->SetTransliteration( bChecked );
551     }
552 
553     return 0;
554 }
555 
556 //------------------------------------------------------------------------
557 void FmSearchDialog::InitContext(sal_Int16 nContext)
558 {
559     FmSearchContext fmscContext;
560     fmscContext.nContext = nContext;
561 
562 #ifdef DBG_UTIL
563     sal_uInt32 nResult =
564 #endif
565     m_lnkContextSupplier.Call(&fmscContext);
566     DBG_ASSERT(nResult > 0, "FmSearchDialog::InitContext : ContextSupplier didn't give me any controls !");
567 
568     // packen wir zuerst die Feld-Namen in die entsprechende Listbox
569     m_lbField.Clear();
570 
571     if (fmscContext.sFieldDisplayNames.Len() != 0)
572     {
573         // use the display names if supplied
574         DBG_ASSERT(fmscContext.sFieldDisplayNames.GetTokenCount() == fmscContext.strUsedFields.GetTokenCount(),
575             "FmSearchDialog::InitContext : invalid context description supplied !");
576         for (xub_StrLen i=0; i<fmscContext.sFieldDisplayNames.GetTokenCount(); ++i)
577             m_lbField.InsertEntry(fmscContext.sFieldDisplayNames.GetToken(i));
578     }
579     else
580         // else use the field names
581         for (xub_StrLen i=0; i<fmscContext.strUsedFields.GetTokenCount(); ++i)
582             m_lbField.InsertEntry(fmscContext.strUsedFields.GetToken(i));
583 
584     if (nContext < (sal_Int32)m_arrContextFields.size() && m_arrContextFields[nContext].Len())
585     {
586         m_lbField.SelectEntry(m_arrContextFields[nContext]);
587     }
588     else
589     {
590         m_lbField.SelectEntryPos(0);
591         if (m_rbSingleField.IsChecked() && (m_lbField.GetEntryCount() > 1))
592             m_lbField.GrabFocus();
593     }
594 
595     // dann geben wir der Engine Bescheid
596     m_pSearchEngine->SwitchToContext(fmscContext.xCursor, fmscContext.strUsedFields, fmscContext.arrFields,
597         m_rbAllFields.IsChecked() ? -1 : 0);
598 
599     // und die Position des neuen Cursors anzeigen
600     m_ftRecord.SetText(String::CreateFromInt32(fmscContext.xCursor->getRow()));
601 }
602 
603 //------------------------------------------------------------------------
604 IMPL_LINK( FmSearchDialog, OnContextSelection, ListBox*, pBox)
605 {
606     InitContext(pBox->GetSelectEntryPos());
607     return 0L;
608 }
609 
610 //------------------------------------------------------------------------
611 void FmSearchDialog::EnableSearchUI(sal_Bool bEnable)
612 {
613     // wenn die Controls disabled werden sollen, schalte ich mal eben kurz ihr Paint aus und verzoegert wieder an
614     if (!bEnable)
615         EnableControlPaint(sal_False);
616     else
617     {   // beim Enablen teste ich, ob der Timer fuer das delayed paint aktiv ist und stoppe ihn wenn noetig
618         if (m_aDelayedPaint.IsActive())
619             m_aDelayedPaint.Stop();
620     }
621     // (das ganze geht unten noch weiter)
622     // diese kleine Verrenkung fuehrt hoffentlich dazu, dass es nicht flackert, wenn man die SearchUI schnell hintereinander
623     // aus- und wieder einschaltet (wie das bei einem kurzen Suchvorgang zwangslaeufig der Fall ist)
624 
625     if ( !bEnable )
626     {
627         // if one of my children has the focus, remember it
628         // 104332 - 2002-10-17 - fs@openoffice.org
629         Window* pFocusWindow = Application::GetFocusWindow( );
630         if ( pFocusWindow && IsChild( pFocusWindow ) )
631             m_pPreSearchFocus = pFocusWindow;
632         else
633             m_pPreSearchFocus = NULL;
634     }
635 
636     // der Suchen-Button hat einen Doppelfunktion, seinen Text entsprechend anpassen
637     String sButtonText( bEnable ? m_sSearch : m_sCancel );
638     m_pbSearchAgain.SetText( sButtonText );
639 
640     // jetzt Controls en- oder disablen
641     if (m_pSearchEngine->GetSearchMode() != SM_BRUTE)
642     {
643         m_flSearchFor.Enable        (bEnable);
644         m_rbSearchForText.Enable    (bEnable);
645         m_rbSearchForNull.Enable    (bEnable);
646         m_rbSearchForNotNull.Enable (bEnable);
647         m_flWhere.Enable            (bEnable);
648         m_ftForm.Enable             (bEnable);
649         m_lbForm.Enable             (bEnable);
650         m_rbAllFields.Enable        (bEnable);
651         m_rbSingleField.Enable      (bEnable);
652         m_lbField.Enable            (bEnable && m_rbSingleField.IsChecked());
653         m_flOptions.Enable          (bEnable);
654         m_cbBackwards.Enable        (bEnable);
655         m_cbStartOver.Enable        (bEnable);
656         m_pbClose.Enable            (bEnable);
657         EnableSearchForDependees    (bEnable);
658 
659         if ( !bEnable )
660         {   // this means we're preparing for starting a search
661             // In this case, EnableSearchForDependees disabled the search button
662             // But as we're about to use it for cancelling the search, we really need to enable it, again
663             // 07.12.2001 - 95246 - fs@openoffice.org
664             m_pbSearchAgain.Enable( sal_True );
665         }
666     }
667 
668     // und den Rest fuer das delayed paint
669     if (!bEnable)
670         m_aDelayedPaint.Start();
671     else
672         EnableControlPaint(sal_True);
673 
674     if ( bEnable )
675     {   // restore focus
676         // 104332 - 2002-10-17 - fs@openoffice.org
677         if ( m_pPreSearchFocus )
678         {
679             m_pPreSearchFocus->GrabFocus();
680             if ( WINDOW_EDIT == m_pPreSearchFocus->GetType() )
681             {
682                 Edit* pEdit = static_cast< Edit* >( m_pPreSearchFocus );
683                 pEdit->SetSelection( Selection( 0, pEdit->GetText().Len() ) );
684             }
685         }
686         m_pPreSearchFocus = NULL;
687     }
688 
689 }
690 
691 //------------------------------------------------------------------------
692 void FmSearchDialog::EnableSearchForDependees(sal_Bool bEnable)
693 {
694     sal_Bool bSearchingForText = m_rbSearchForText.IsChecked();
695     m_pbSearchAgain.Enable(bEnable && (!bSearchingForText || (m_cmbSearchText.GetText().Len() != 0)));
696 
697     bEnable = bEnable && bSearchingForText;
698 
699     sal_Bool bEnableRedundants = !m_aSoundsLikeCJK.IsChecked() || !SvtCJKOptions().IsJapaneseFindEnabled();
700 
701     m_cmbSearchText.Enable          (bEnable);
702     m_ftPosition.Enable             (bEnable && !m_cbWildCard.IsChecked());
703     m_cbWildCard.Enable             (bEnable && !m_cbRegular.IsChecked() && !m_cbApprox.IsChecked());
704     m_cbRegular.Enable              (bEnable && !m_cbWildCard.IsChecked() && !m_cbApprox.IsChecked());
705     m_cbApprox.Enable               (bEnable && !m_cbWildCard.IsChecked() && !m_cbRegular.IsChecked());
706     m_pbApproxSettings.Enable       (bEnable && m_cbApprox.IsChecked());
707     m_aHalfFullFormsCJK.Enable      (bEnable && bEnableRedundants);
708     m_aSoundsLikeCJK.Enable         (bEnable);
709     m_aSoundsLikeCJKSettings.Enable (bEnable && m_aSoundsLikeCJK.IsChecked());
710     m_lbPosition.Enable             (bEnable && !m_cbWildCard.IsChecked());
711     m_cbUseFormat.Enable            (bEnable);
712     m_cbCase.Enable                 (bEnable && bEnableRedundants);
713 }
714 
715 //------------------------------------------------------------------------
716 void FmSearchDialog::EnableControlPaint(sal_Bool bEnable)
717 {
718     Control* pAffectedControls[] = { &m_flSearchFor, &m_rbSearchForText, &m_cmbSearchText, &m_rbSearchForNull, &m_rbSearchForNotNull,
719         &m_rbSearchForText, &m_flWhere, &m_rbAllFields, &m_rbSingleField, &m_lbField, &m_flOptions, &m_ftPosition, &m_lbPosition,
720         &m_cbUseFormat, &m_cbCase, &m_cbBackwards, &m_cbStartOver, &m_cbWildCard, &m_cbRegular, &m_cbApprox, &m_pbApproxSettings,
721         &m_pbSearchAgain, &m_pbClose };
722 
723     if (!bEnable)
724         for (sal_uInt32 i=0; i<sizeof(pAffectedControls)/sizeof(pAffectedControls[0]); ++i)
725         {
726             pAffectedControls[i]->SetUpdateMode(bEnable);
727             pAffectedControls[i]->EnablePaint(bEnable);
728         }
729     else
730         for (sal_uInt32 i=0; i<sizeof(pAffectedControls)/sizeof(pAffectedControls[0]); ++i)
731         {
732             pAffectedControls[i]->EnablePaint(bEnable);
733             pAffectedControls[i]->SetUpdateMode(bEnable);
734         }
735 }
736 
737 //------------------------------------------------------------------------
738 IMPL_LINK(FmSearchDialog, OnDelayedPaint, void*, EMPTYARG)
739 {
740     EnableControlPaint(sal_True);
741     return 0L;
742 }
743 
744 //------------------------------------------------------------------------
745 void FmSearchDialog::OnFound(const ::com::sun::star::uno::Any& aCursorPos, sal_Int16 nFieldPos)
746 {
747     FmFoundRecordInformation friInfo;
748     friInfo.nContext = m_lbForm.GetSelectEntryPos();
749         // wenn ich keine Suche in Kontexten mache, steht hier was ungueltiges drin, aber dann ist es auch egal
750     friInfo.aPosition = aCursorPos;
751     if (m_rbAllFields.IsChecked())
752         friInfo.nFieldPos = nFieldPos;
753     else
754         friInfo.nFieldPos = m_lbField.GetSelectEntryPos();
755         // das setzt natuerlich voraus, dass ich wirklich in dem Feld gesucht habe, dass in der Listbox ausgewaehlt ist,
756         // genau das wird auch in RebuildUsedFields sichergestellt
757 
758     // dem Handler Bescheid sagen
759     m_lnkFoundHandler.Call(&friInfo);
760 
761     // und wieder Focus auf mich
762     m_cmbSearchText.GrabFocus();
763 }
764 
765 //------------------------------------------------------------------------
766 IMPL_LINK(FmSearchDialog, OnSearchProgress, FmSearchProgress*, pProgress)
767 {
768     ::vos::OGuard aGuard( Application::GetSolarMutex() );
769         // diese eine Methode Thread-sicher machen (das ist ein Overkill, die ganze restliche Applikation dafuer zu blockieren,
770         // aber im Augenblick haben wir kein anderes Sicherheitskonpzept)
771 
772     switch (pProgress->aSearchState)
773     {
774         case FmSearchProgress::STATE_PROGRESS:
775             if (pProgress->bOverflow)
776             {
777                 String sHint( CUI_RES( m_cbBackwards.IsChecked() ? RID_STR_OVERFLOW_BACKWARD : RID_STR_OVERFLOW_FORWARD ) );
778                 m_ftHint.SetText( sHint );
779                 m_ftHint.Invalidate();
780             }
781 
782             m_ftRecord.SetText(String::CreateFromInt32(1 + pProgress->nCurrentRecord));
783             m_ftRecord.Invalidate();
784             break;
785 
786         case FmSearchProgress::STATE_PROGRESS_COUNTING:
787             m_ftHint.SetText(CUI_RESSTR(RID_STR_SEARCH_COUNTING));
788             m_ftHint.Invalidate();
789 
790             m_ftRecord.SetText(String::CreateFromInt32(pProgress->nCurrentRecord));
791             m_ftRecord.Invalidate();
792             break;
793 
794         case FmSearchProgress::STATE_SUCCESSFULL:
795             OnFound(pProgress->aBookmark, (sal_Int16)pProgress->nFieldIndex);
796             EnableSearchUI(sal_True);
797             break;
798 
799         case FmSearchProgress::STATE_ERROR:
800         case FmSearchProgress::STATE_NOTHINGFOUND:
801         {
802             sal_uInt16 nErrorId = (FmSearchProgress::STATE_ERROR == pProgress->aSearchState)
803                 ? RID_SVXERR_SEARCH_GENERAL_ERROR
804                 : RID_SVXERR_SEARCH_NORECORD;
805             ErrorBox(this, CUI_RES(nErrorId)).Execute();
806         }
807             // KEIN break !
808         case FmSearchProgress::STATE_CANCELED:
809             EnableSearchUI(sal_True);
810             if (m_lnkCanceledNotFoundHdl.IsSet())
811             {
812                 FmFoundRecordInformation friInfo;
813                 friInfo.nContext = m_lbForm.GetSelectEntryPos();
814                     // wenn ich keine Suche in Kontexten mache, steht hier was ungueltiges drin, aber dann ist es auch egal
815                 friInfo.aPosition = pProgress->aBookmark;
816                 m_lnkCanceledNotFoundHdl.Call(&friInfo);
817             }
818             break;
819     }
820 
821     m_ftRecord.SetText(String::CreateFromInt32(1 + pProgress->nCurrentRecord));
822 
823     return 0L;
824 }
825 
826 //------------------------------------------------------------------------
827 void FmSearchDialog::LoadParams()
828 {
829     FmSearchParams aParams(m_pConfig->getParams());
830 
831     const ::rtl::OUString* pHistory     =                   aParams.aHistory.getConstArray();
832     const ::rtl::OUString* pHistoryEnd  =   pHistory    +   aParams.aHistory.getLength();
833     for (; pHistory != pHistoryEnd; ++pHistory)
834         m_cmbSearchText.InsertEntry( *pHistory );
835 
836     // die Einstellungen nehme ich an meinen UI-Elementen vor und rufe dann einfach den entsprechenden Change-Handler auf,
837     // dadurch werden die Daten an die SearchEngine weitergereicht und alle abhaengigen Enstellungen vorgenommen
838 
839     // aktuelles Feld
840     sal_uInt16 nInitialField = m_lbField.GetEntryPos( String( aParams.sSingleSearchField ) );
841     if (nInitialField == COMBOBOX_ENTRY_NOTFOUND)
842         nInitialField = 0;
843     m_lbField.SelectEntryPos(nInitialField);
844     LINK(this, FmSearchDialog, OnFieldSelected).Call(&m_lbField);
845     // alle/einzelnes Feld (NACH dem Selektieren des Feldes, da OnClickedFieldRadios dort einen gueltigen Eintrag erwartet)
846     if (aParams.bAllFields)
847     {
848         m_rbSingleField.Check(sal_False);
849         m_rbAllFields.Check(sal_True);
850         LINK(this, FmSearchDialog, OnClickedFieldRadios).Call(&m_rbAllFields);
851         // OnClickedFieldRadios ruft auch um RebuildUsedFields
852     }
853     else
854     {
855         m_rbAllFields.Check(sal_False);
856         m_rbSingleField.Check(sal_True);
857         LINK(this, FmSearchDialog, OnClickedFieldRadios).Call(&m_rbSingleField);
858     }
859 
860     // Position im Feld
861     m_lbPosition.SelectEntryPos(aParams.nPosition);
862     LINK(this, FmSearchDialog, OnPositionSelected).Call(&m_lbPosition);
863 
864     // Feld-Formatierung/Case-Sensitivitaet/Richtung
865     m_cbUseFormat.Check(aParams.bUseFormatter);
866     m_cbCase.Check( aParams.isCaseSensitive() );
867     m_cbBackwards.Check(aParams.bBackwards);
868     LINK(this, FmSearchDialog, OnCheckBoxToggled).Call(&m_cbUseFormat);
869     LINK(this, FmSearchDialog, OnCheckBoxToggled).Call(&m_cbCase);
870     LINK(this, FmSearchDialog, OnCheckBoxToggled).Call(&m_cbBackwards);
871 
872     m_aHalfFullFormsCJK.Check( !aParams.isIgnoreWidthCJK( ) );  // BEWARE: this checkbox has a inverse semantics!
873     m_aSoundsLikeCJK.Check( aParams.bSoundsLikeCJK );
874     LINK(this, FmSearchDialog, OnCheckBoxToggled).Call(&m_aHalfFullFormsCJK);
875     LINK(this, FmSearchDialog, OnCheckBoxToggled).Call(&m_aSoundsLikeCJK);
876 
877     // die drei Checkboxen fuer spezielle Sucharten
878     // erst mal alle ruecksetzen
879     m_cbWildCard.Check(sal_False);
880     m_cbRegular.Check(sal_False);
881     m_cbApprox.Check(sal_False);
882     LINK(this, FmSearchDialog, OnCheckBoxToggled).Call(&m_cbWildCard);
883     LINK(this, FmSearchDialog, OnCheckBoxToggled).Call(&m_cbRegular);
884     LINK(this, FmSearchDialog, OnCheckBoxToggled).Call(&m_cbApprox);
885 
886     // dann die richtige setzen
887     CheckBox* pToCheck = NULL;
888     if (aParams.bWildcard)
889         pToCheck = &m_cbWildCard;
890     if (aParams.bRegular)
891         pToCheck = &m_cbRegular;
892     if (aParams.bApproxSearch)
893         pToCheck = &m_cbApprox;
894     if (aParams.bSoundsLikeCJK)
895         pToCheck = &m_aSoundsLikeCJK;
896     if (pToCheck)
897     {
898         pToCheck->Check(sal_True);
899         LINK(this, FmSearchDialog, OnCheckBoxToggled).Call(pToCheck);
900     }
901 
902     // die Levenshtein-Parameter direkt an der SearchEngine setzen
903     m_pSearchEngine->SetLevRelaxed(aParams.bLevRelaxed);
904     m_pSearchEngine->SetLevOther(aParams.nLevOther);
905     m_pSearchEngine->SetLevShorter(aParams.nLevShorter);
906     m_pSearchEngine->SetLevLonger(aParams.nLevLonger);
907 
908     m_pSearchEngine->SetTransliterationFlags( aParams.getTransliterationFlags( ) );
909 
910     m_rbSearchForText.Check(sal_False);
911     m_rbSearchForNull.Check(sal_False);
912     m_rbSearchForNotNull.Check(sal_False);
913     switch (aParams.nSearchForType)
914     {
915         case 1: m_rbSearchForNull.Check(sal_True); break;
916         case 2: m_rbSearchForNotNull.Check(sal_True); break;
917         default: m_rbSearchForText.Check(sal_True); break;
918     }
919     LINK(this, FmSearchDialog, OnClickedFieldRadios).Call(&m_rbSearchForText);
920 }
921 
922 //------------------------------------------------------------------------
923 void FmSearchDialog::SaveParams() const
924 {
925     if (!m_pConfig)
926         return;
927 
928     FmSearchParams aCurrentSettings;
929 
930     aCurrentSettings.aHistory.realloc( m_cmbSearchText.GetEntryCount() );
931     ::rtl::OUString* pHistory = aCurrentSettings.aHistory.getArray();
932     for (sal_uInt16 i=0; i<m_cmbSearchText.GetEntryCount(); ++i, ++pHistory)
933         *pHistory = m_cmbSearchText.GetEntry(i);
934 
935     aCurrentSettings.sSingleSearchField         = m_lbField.GetSelectEntry();
936     aCurrentSettings.bAllFields                 = m_rbAllFields.IsChecked();
937     aCurrentSettings.nPosition                  = m_pSearchEngine->GetPosition();
938     aCurrentSettings.bUseFormatter              = m_pSearchEngine->GetFormatterUsing();
939     aCurrentSettings.setCaseSensitive           ( m_pSearchEngine->GetCaseSensitive() );
940     aCurrentSettings.bBackwards                 = !m_pSearchEngine->GetDirection();
941     aCurrentSettings.bWildcard                  = m_pSearchEngine->GetWildcard();
942     aCurrentSettings.bRegular                   = m_pSearchEngine->GetRegular();
943     aCurrentSettings.bApproxSearch              = m_pSearchEngine->GetLevenshtein();
944     aCurrentSettings.bLevRelaxed                = m_pSearchEngine->GetLevRelaxed();
945     aCurrentSettings.nLevOther                  = m_pSearchEngine->GetLevOther();
946     aCurrentSettings.nLevShorter                = m_pSearchEngine->GetLevShorter();
947     aCurrentSettings.nLevLonger                 = m_pSearchEngine->GetLevLonger();
948 
949     aCurrentSettings.bSoundsLikeCJK             = m_pSearchEngine->GetTransliteration();
950     aCurrentSettings.setTransliterationFlags    ( m_pSearchEngine->GetTransliterationFlags() );
951 
952     if (m_rbSearchForNull.IsChecked())
953         aCurrentSettings.nSearchForType = 1;
954     else if (m_rbSearchForNotNull.IsChecked())
955         aCurrentSettings.nSearchForType = 2;
956     else
957         aCurrentSettings.nSearchForType = 0;
958 
959     m_pConfig->setParams( aCurrentSettings );
960 }
961 
962