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