xref: /trunk/main/cui/source/dialogs/cuifmsearch.cxx (revision c47da6ea)
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 //------------------------------------------------------------------------
initCommon(const Reference<XResultSet> & _rxCursor)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 //------------------------------------------------------------------------
FmSearchDialog(Window * pParent,const UniString & sInitialText,const::std::vector<String> & _rContexts,sal_Int16 nInitialContext,const Link & lnkContextSupplier)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 //------------------------------------------------------------------------
implMoveControls(Control ** _ppControls,sal_Int32 _nControls,sal_Int32 _nUp,Control *)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 //------------------------------------------------------------------------
~FmSearchDialog()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 //------------------------------------------------------------------------
Init(const UniString & strVisibleFields,const UniString & sInitialText)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 	m_cmbSearchText.SetGetFocusHdl(LINK(this, FmSearchDialog, OnFocusGrabbed));
256 
257 	m_cbUseFormat.SetToggleHdl(LINK(this, FmSearchDialog, OnCheckBoxToggled));
258 	m_cbBackwards.SetToggleHdl(LINK(this, FmSearchDialog, OnCheckBoxToggled));
259 	m_cbStartOver.SetToggleHdl(LINK(this, FmSearchDialog, OnCheckBoxToggled));
260 	m_cbCase.SetToggleHdl(LINK(this, FmSearchDialog, OnCheckBoxToggled));
261 	m_cbWildCard.SetToggleHdl(LINK(this, FmSearchDialog, OnCheckBoxToggled));
262 	m_cbRegular.SetToggleHdl(LINK(this, FmSearchDialog, OnCheckBoxToggled));
263 	m_cbApprox.SetToggleHdl(LINK(this, FmSearchDialog, OnCheckBoxToggled));
264 	m_aHalfFullFormsCJK.SetToggleHdl(LINK(this, FmSearchDialog, OnCheckBoxToggled));
265 	m_aSoundsLikeCJK.SetToggleHdl(LINK(this, FmSearchDialog, OnCheckBoxToggled));
266 
267 	// die Listboxen fuellen
268 	// die Methoden des Feldvergleiches
269     sal_uInt16 nResIds[] = {
270         RID_STR_SEARCH_ANYWHERE,
271         RID_STR_SEARCH_BEGINNING,
272         RID_STR_SEARCH_END,
273         RID_STR_SEARCH_WHOLE
274     };
275     for ( size_t i=0; i<sizeof(nResIds)/sizeof(nResIds[0]); ++i )
276 		m_lbPosition.InsertEntry( String( CUI_RES( nResIds[i] ) ) );
277 	m_lbPosition.SelectEntryPos(MATCHING_ANYWHERE);
278 
279 	// die Feld-Listbox
280 	for (sal_uInt16 i=0; i<strVisibleFields.GetTokenCount(';'); ++i)
281 		m_lbField.InsertEntry(strVisibleFields.GetToken(i, ';'));
282 
283 
284 	m_pConfig = new FmSearchConfigItem;
285 	LoadParams();
286 
287 	m_cmbSearchText.SetText(sInitialText);
288 	// wenn die Edit-Zeile den Text veraendert hat (weil er zum Beispiel Steuerzeichen enthielt, wie das bei Memofeldern der Fall
289 	// sein kann), nehme ich einen leeren UniString
290 	UniString sRealSetText = m_cmbSearchText.GetText();
291 	if (!sRealSetText.Equals(sInitialText))
292 		m_cmbSearchText.SetText(UniString());
293 	LINK(this, FmSearchDialog, OnSearchTextModified).Call(&m_cmbSearchText);
294 
295 	// initial die ganzen UI-Elemente fuer die Suche an
296 	m_aDelayedPaint.SetTimeoutHdl(LINK(this, FmSearchDialog, OnDelayedPaint));
297 	m_aDelayedPaint.SetTimeout(500);
298 	EnableSearchUI(sal_True);
299 
300 	if ( m_rbSearchForText.IsChecked() )
301 		m_cmbSearchText.GrabFocus();
302 
303 	FreeResource();
304 }
305 
306 //------------------------------------------------------------------------
Close()307 sal_Bool FmSearchDialog::Close()
308 {
309 	// Wenn der Close-Button disabled ist und man im Dialog ESC drueckt, dann wird irgendwo vom Frame trotzdem Close aufgerufen,
310 	// was ich allerdings nicht will, wenn ich gerade mitten in einer (eventuell in einem extra Thread laufenden) Suche bin
311 	if (!m_pbClose.IsEnabled())
312 		return sal_False;
313 	return ModalDialog::Close();
314 }
315 
316 //------------------------------------------------------------------------
IMPL_LINK(FmSearchDialog,OnClickedFieldRadios,Button *,pButton)317 IMPL_LINK(FmSearchDialog, OnClickedFieldRadios, Button*, pButton)
318 {
319 	if ((pButton == &m_rbSearchForText) || (pButton == &m_rbSearchForNull) || (pButton == &m_rbSearchForNotNull))
320 	{
321 		EnableSearchForDependees(sal_True);
322 	}
323 	else
324 		// die Feldlistbox entsprechend en- oder disablen
325 		if (pButton == &m_rbSingleField)
326 		{
327 			m_lbField.Enable();
328 			m_pSearchEngine->RebuildUsedFields(m_lbField.GetSelectEntryPos());
329 		}
330 		else
331 		{
332 			m_lbField.Disable();
333 			m_pSearchEngine->RebuildUsedFields(-1);
334 		}
335 
336 	return 0;
337 }
338 
339 //------------------------------------------------------------------------
IMPL_LINK(FmSearchDialog,OnClickedSearchAgain,Button *,EMPTYARG)340 IMPL_LINK(FmSearchDialog, OnClickedSearchAgain, Button*, EMPTYARG)
341 {
342 	if (m_pbClose.IsEnabled())
343 	{	// der Button hat die Funktion 'Suchen'
344 		UniString strThisRoundText = m_cmbSearchText.GetText();
345 		// zur History dazu
346 		m_cmbSearchText.RemoveEntry(strThisRoundText);
347 		m_cmbSearchText.InsertEntry(strThisRoundText, 0);
348 			// das Remove/Insert stellt a) sicher, dass der UniString nicht zweimal auftaucht, b), dass die zuletzt gesuchten Strings am
349 			// Anfang stehen
350 		// und die Listenlaenge beschraenken
351 		while (m_cmbSearchText.GetEntryCount() > MAX_HISTORY_ENTRIES)
352 			m_cmbSearchText.RemoveEntry(m_cmbSearchText.GetEntryCount()-1);
353 
354 		// den 'Ueberlauf'-Hint rausnehmen
355 		m_ftHint.SetText(UniString());
356 		m_ftHint.Invalidate();
357 
358 		if (m_cbStartOver.IsChecked())
359 		{
360 			m_cbStartOver.Check(sal_False);
361 			EnableSearchUI(sal_False);
362 			if (m_rbSearchForText.IsChecked())
363 				m_pSearchEngine->StartOver(strThisRoundText);
364 			else
365 				m_pSearchEngine->StartOverSpecial(m_rbSearchForNull.IsChecked());
366 		}
367 		else
368 		{
369 			EnableSearchUI(sal_False);
370 			if (m_rbSearchForText.IsChecked())
371 				m_pSearchEngine->SearchNext(strThisRoundText);
372 			else
373 				m_pSearchEngine->SearchNextSpecial(m_rbSearchForNull.IsChecked());
374 		}
375 	}
376 	else
377 	{	// der Button hat die Funktion 'Abbrechen'
378 		DBG_ASSERT(m_pSearchEngine->GetSearchMode() != SM_BRUTE, "FmSearchDialog, OnClickedSearchAgain : falscher Modus !");
379 			// der CancelButton wird normalerweise nur disabled, wenn ich in einem Thread oder mit Reschedule arbeite
380 		m_pSearchEngine->CancelSearch();
381 			// mein ProgressHandler wird gerufen, wenn es wirklich zu Ende ist, das hier war nur eine Anforderung
382 	}
383 	return 0;
384 }
385 
386 //------------------------------------------------------------------------
IMPL_LINK(FmSearchDialog,OnClickedSpecialSettings,Button *,pButton)387 IMPL_LINK(FmSearchDialog, OnClickedSpecialSettings, Button*, pButton )
388 {
389 	if (&m_pbApproxSettings == pButton)
390 	{
391         AbstractSvxSearchSimilarityDialog* pDlg = NULL;
392 
393         SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
394 		if ( pFact )
395 		    pDlg = pFact->CreateSvxSearchSimilarityDialog( this, m_pSearchEngine->GetLevRelaxed(), m_pSearchEngine->GetLevOther(),
396 						m_pSearchEngine->GetLevShorter(), m_pSearchEngine->GetLevLonger() );
397         DBG_ASSERT( pDlg, "FmSearchDialog, OnClickedSpecialSettings: could not load the dialog!" );
398 
399         if ( pDlg && pDlg->Execute() == RET_OK )
400 		{
401 			m_pSearchEngine->SetLevRelaxed( pDlg->IsRelaxed() );
402 			m_pSearchEngine->SetLevOther( pDlg->GetOther() );
403 			m_pSearchEngine->SetLevShorter(pDlg->GetShorter() );
404 			m_pSearchEngine->SetLevLonger( pDlg->GetLonger() );
405 		}
406 		delete pDlg;
407 	}
408 	else if (&m_aSoundsLikeCJKSettings == pButton)
409 	{
410 		SfxItemSet aSet( SFX_APP()->GetPool() );
411 		//CHINA001 SvxJSearchOptionsDialog aDlg( this, aSet, RID_SVXPAGE_JSEARCH_OPTIONS, m_pSearchEngine->GetTransliterationFlags() );
412 		SvxAbstractDialogFactory* pFact = SvxAbstractDialogFactory::Create();
413 		if(pFact)
414 		{
415 			AbstractSvxJSearchOptionsDialog* aDlg = pFact->CreateSvxJSearchOptionsDialog( this, aSet, m_pSearchEngine->GetTransliterationFlags() );
416 			DBG_ASSERT(aDlg, "Dialogdiet fail!");//CHINA001
417 			aDlg->Execute(); //CHINA001 aDlg.Execute();
418 
419 
420 			sal_Int32 nFlags = aDlg->GetTransliterationFlags(); //CHINA001 sal_Int32 nFlags = aDlg.GetTransliterationFlags();
421 			m_pSearchEngine->SetTransliterationFlags(nFlags);
422 
423 			m_cbCase.Check(m_pSearchEngine->GetCaseSensitive());
424 			OnCheckBoxToggled( &m_cbCase );
425 			m_aHalfFullFormsCJK.Check( !m_pSearchEngine->GetIgnoreWidthCJK() );
426 			OnCheckBoxToggled( &m_aHalfFullFormsCJK );
427 			delete aDlg; //add for CHINA001
428 		}
429 	}
430 
431 	return 0;
432 }
433 
434 //------------------------------------------------------------------------
IMPL_LINK(FmSearchDialog,OnSearchTextModified,ComboBox *,EMPTYARG)435 IMPL_LINK(FmSearchDialog, OnSearchTextModified, ComboBox*, EMPTYARG)
436 {
437 	if ((m_cmbSearchText.GetText().Len() != 0) || !m_rbSearchForText.IsChecked())
438 		m_pbSearchAgain.Enable();
439 	else
440 		m_pbSearchAgain.Disable();
441 
442 	m_pSearchEngine->InvalidatePreviousLoc();
443 	return 0;
444 }
445 
446 //------------------------------------------------------------------------
IMPL_LINK(FmSearchDialog,OnFocusGrabbed,ComboBox *,EMPTYARG)447 IMPL_LINK(FmSearchDialog, OnFocusGrabbed, ComboBox*, EMPTYARG)
448 {
449     m_cmbSearchText.SetSelection( Selection( SELECTION_MIN, SELECTION_MAX ) );
450     return 0;
451 }
452 
453 //------------------------------------------------------------------------
IMPL_LINK(FmSearchDialog,OnPositionSelected,ListBox *,pBox)454 IMPL_LINK(FmSearchDialog, OnPositionSelected, ListBox*, pBox)
455 {
456     (void) pBox; // avoid warning
457 	DBG_ASSERT(pBox->GetSelectEntryCount() == 1, "FmSearchDialog::OnMethodSelected : unerwartet : nicht genau ein Eintrag selektiert !");
458 
459 	m_pSearchEngine->SetPosition(m_lbPosition.GetSelectEntryPos());
460 	return 0;
461 }
462 
463 //------------------------------------------------------------------------
IMPL_LINK(FmSearchDialog,OnFieldSelected,ListBox *,pBox)464 IMPL_LINK(FmSearchDialog, OnFieldSelected, ListBox*, pBox)
465 {
466     (void) pBox; // avoid warning
467 	DBG_ASSERT(pBox->GetSelectEntryCount() == 1, "FmSearchDialog::OnFieldSelected : unerwartet : nicht genau ein Eintrag selektiert !");
468 
469 	m_pSearchEngine->RebuildUsedFields(m_rbAllFields.IsChecked() ? -1 : (sal_Int16)m_lbField.GetSelectEntryPos());
470 		// ruft auch m_pSearchEngine->InvalidatePreviousLoc auf
471 
472     sal_Int32 nCurrentContext = m_lbForm.GetSelectEntryPos();
473 	if (nCurrentContext != LISTBOX_ENTRY_NOTFOUND)
474 		m_arrContextFields[nCurrentContext] = UniString(m_lbField.GetSelectEntry());
475 	return 0;
476 }
477 
478 //------------------------------------------------------------------------
IMPL_LINK(FmSearchDialog,OnCheckBoxToggled,CheckBox *,pBox)479 IMPL_LINK(FmSearchDialog, OnCheckBoxToggled, CheckBox*, pBox)
480 {
481 	sal_Bool bChecked = pBox->IsChecked();
482 
483 	// Formatter oder case -> an die Engine weiterreichen
484 	if (pBox == &m_cbUseFormat)
485 		m_pSearchEngine->SetFormatterUsing(bChecked);
486 	else if (pBox == &m_cbCase)
487 		m_pSearchEngine->SetCaseSensitive(bChecked);
488 	// Richtung -> weiterreichen und Checkbox-Text fuer StartOver neu setzen
489 	else if (pBox == &m_cbBackwards)
490 	{
491         m_cbStartOver.SetText( String( CUI_RES( bChecked ? RID_STR_FROM_BOTTOM : RID_STR_FROM_TOP ) ) );
492 		m_pSearchEngine->SetDirection(!bChecked);
493 	}
494 	// Aehnlichkeitssuche oder regulaerer Ausdruck
495 	else if ((pBox == &m_cbApprox) || (pBox == &m_cbRegular) || (pBox == &m_cbWildCard))
496 	{
497 		// die beiden jeweils anderen Boxes disablen oder enablen
498 		CheckBox* pBoxes[] = { &m_cbWildCard, &m_cbRegular, &m_cbApprox };
499         for (sal_uInt32 i=0; i<sizeof(pBoxes)/sizeof(CheckBox*); ++i)
500         {
501 			if (pBoxes[i] != pBox)
502 			{
503 				if (bChecked)
504 					pBoxes[i]->Disable();
505 				else
506 					pBoxes[i]->Enable();
507 			}
508         }
509 
510 		// an die Engine weiterreichen
511 		m_pSearchEngine->SetWildcard(m_cbWildCard.IsEnabled() ? m_cbWildCard.IsChecked() : sal_False);
512 		m_pSearchEngine->SetRegular(m_cbRegular.IsEnabled() ? m_cbRegular.IsChecked() : sal_False);
513 		m_pSearchEngine->SetLevenshtein(m_cbApprox.IsEnabled() ? m_cbApprox.IsChecked() : sal_False);
514 			// (Boxes, die disabled sind, muessen als sal_False an die Engine gehen)
515 
516 		// die Position-Listbox anpassen (ist bei Wildcard-Suche nicht erlaubt)
517 		if (pBox == &m_cbWildCard)
518 		{
519 			if (bChecked)
520 			{
521 				m_ftPosition.Disable();
522 				m_lbPosition.Disable();
523 			}
524 			else
525 			{
526 				m_ftPosition.Enable();
527 				m_lbPosition.Enable();
528 			}
529 		}
530 
531 		// und den Button fuer die Aehnlichkeitssuche
532 		if (pBox == &m_cbApprox)
533 		{
534 			if (bChecked)
535 				m_pbApproxSettings.Enable();
536 			else
537 				m_pbApproxSettings.Disable();
538 		}
539 	}
540 	else if (pBox == &m_aHalfFullFormsCJK)
541 	{
542 		// forward to the search engine
543 		m_pSearchEngine->SetIgnoreWidthCJK( !bChecked );
544 	}
545 	else if (pBox == &m_aSoundsLikeCJK)
546 	{
547 		m_aSoundsLikeCJKSettings.Enable(bChecked);
548 
549 		// two other buttons which depend on this one
550 		sal_Bool bEnable =	(	m_rbSearchForText.IsChecked()
551 							&&	!m_aSoundsLikeCJK.IsChecked()
552 							)
553 						 ||	!SvtCJKOptions().IsJapaneseFindEnabled();
554 		m_cbCase.Enable(bEnable);
555 		m_aHalfFullFormsCJK.Enable(bEnable);
556 
557 		// forward to the search engine
558 		m_pSearchEngine->SetTransliteration( bChecked );
559 	}
560 
561 	return 0;
562 }
563 
564 //------------------------------------------------------------------------
InitContext(sal_Int16 nContext)565 void FmSearchDialog::InitContext(sal_Int16 nContext)
566 {
567 	FmSearchContext fmscContext;
568 	fmscContext.nContext = nContext;
569 
570 #ifdef DBG_UTIL
571 	sal_uInt32 nResult =
572 #endif
573     m_lnkContextSupplier.Call(&fmscContext);
574 	DBG_ASSERT(nResult > 0, "FmSearchDialog::InitContext : ContextSupplier didn't give me any controls !");
575 
576 	// packen wir zuerst die Feld-Namen in die entsprechende Listbox
577 	m_lbField.Clear();
578 
579 	if (fmscContext.sFieldDisplayNames.Len() != 0)
580 	{
581 		// use the display names if supplied
582 		DBG_ASSERT(fmscContext.sFieldDisplayNames.GetTokenCount() == fmscContext.strUsedFields.GetTokenCount(),
583 			"FmSearchDialog::InitContext : invalid context description supplied !");
584 		for (xub_StrLen i=0; i<fmscContext.sFieldDisplayNames.GetTokenCount(); ++i)
585 			m_lbField.InsertEntry(fmscContext.sFieldDisplayNames.GetToken(i));
586 	}
587 	else
588 		// else use the field names
589 		for (xub_StrLen i=0; i<fmscContext.strUsedFields.GetTokenCount(); ++i)
590 			m_lbField.InsertEntry(fmscContext.strUsedFields.GetToken(i));
591 
592 	if (nContext < (sal_Int32)m_arrContextFields.size() && m_arrContextFields[nContext].Len())
593 	{
594 		m_lbField.SelectEntry(m_arrContextFields[nContext]);
595 	}
596 	else
597 	{
598 		m_lbField.SelectEntryPos(0);
599 		if (m_rbSingleField.IsChecked() && (m_lbField.GetEntryCount() > 1))
600 			m_lbField.GrabFocus();
601 	}
602 
603 	// dann geben wir der Engine Bescheid
604 	m_pSearchEngine->SwitchToContext(fmscContext.xCursor, fmscContext.strUsedFields, fmscContext.arrFields,
605 		m_rbAllFields.IsChecked() ? -1 : 0);
606 
607 	// und die Position des neuen Cursors anzeigen
608 	m_ftRecord.SetText(String::CreateFromInt32(fmscContext.xCursor->getRow()));
609 }
610 
611 //------------------------------------------------------------------------
IMPL_LINK(FmSearchDialog,OnContextSelection,ListBox *,pBox)612 IMPL_LINK( FmSearchDialog, OnContextSelection, ListBox*, pBox)
613 {
614 	InitContext(pBox->GetSelectEntryPos());
615 	return 0L;
616 }
617 
618 //------------------------------------------------------------------------
EnableSearchUI(sal_Bool bEnable)619 void FmSearchDialog::EnableSearchUI(sal_Bool bEnable)
620 {
621 	// wenn die Controls disabled werden sollen, schalte ich mal eben kurz ihr Paint aus und verzoegert wieder an
622 	if (!bEnable)
623 		EnableControlPaint(sal_False);
624 	else
625 	{	// beim Enablen teste ich, ob der Timer fuer das delayed paint aktiv ist und stoppe ihn wenn noetig
626 		if (m_aDelayedPaint.IsActive())
627 			m_aDelayedPaint.Stop();
628 	}
629 	// (das ganze geht unten noch weiter)
630 	// diese kleine Verrenkung fuehrt hoffentlich dazu, dass es nicht flackert, wenn man die SearchUI schnell hintereinander
631 	// aus- und wieder einschaltet (wie das bei einem kurzen Suchvorgang zwangslaeufig der Fall ist)
632 
633 	if ( !bEnable )
634 	{
635 		// if one of my children has the focus, remember it
636 		// 104332 - 2002-10-17 - fs@openoffice.org
637 		Window* pFocusWindow = Application::GetFocusWindow( );
638 		if ( pFocusWindow && IsChild( pFocusWindow ) )
639 			m_pPreSearchFocus = pFocusWindow;
640 		else
641 			m_pPreSearchFocus = NULL;
642 	}
643 
644 	// der Suchen-Button hat einen Doppelfunktion, seinen Text entsprechend anpassen
645     String sButtonText( bEnable ? m_sSearch : m_sCancel );
646 	m_pbSearchAgain.SetText( sButtonText );
647 
648 	// jetzt Controls en- oder disablen
649 	if (m_pSearchEngine->GetSearchMode() != SM_BRUTE)
650 	{
651         m_flSearchFor.Enable        (bEnable);
652 		m_rbSearchForText.Enable	(bEnable);
653 		m_rbSearchForNull.Enable	(bEnable);
654 		m_rbSearchForNotNull.Enable	(bEnable);
655         m_flWhere.Enable            (bEnable);
656 		m_ftForm.Enable				(bEnable);
657 		m_lbForm.Enable				(bEnable);
658 		m_rbAllFields.Enable		(bEnable);
659 		m_rbSingleField.Enable		(bEnable);
660 		m_lbField.Enable			(bEnable && m_rbSingleField.IsChecked());
661         m_flOptions.Enable          (bEnable);
662 		m_cbBackwards.Enable		(bEnable);
663 		m_cbStartOver.Enable		(bEnable);
664 		m_pbClose.Enable			(bEnable);
665 		EnableSearchForDependees	(bEnable);
666 
667 		if ( !bEnable )
668 		{	// this means we're preparing for starting a search
669 			// In this case, EnableSearchForDependees disabled the search button
670 			// But as we're about to use it for cancelling the search, we really need to enable it, again
671 			// 07.12.2001 - 95246 - fs@openoffice.org
672 			m_pbSearchAgain.Enable( sal_True );
673 		}
674 	}
675 
676 	// und den Rest fuer das delayed paint
677 	if (!bEnable)
678 		m_aDelayedPaint.Start();
679 	else
680 		EnableControlPaint(sal_True);
681 
682 	if ( bEnable )
683 	{	// restore focus
684 		// 104332 - 2002-10-17 - fs@openoffice.org
685 		if ( m_pPreSearchFocus )
686 		{
687 			m_pPreSearchFocus->GrabFocus();
688 			if ( WINDOW_EDIT == m_pPreSearchFocus->GetType() )
689 			{
690 				Edit* pEdit = static_cast< Edit* >( m_pPreSearchFocus );
691 				pEdit->SetSelection( Selection( 0, pEdit->GetText().Len() ) );
692 			}
693 		}
694 		m_pPreSearchFocus = NULL;
695 	}
696 
697 }
698 
699 //------------------------------------------------------------------------
EnableSearchForDependees(sal_Bool bEnable)700 void FmSearchDialog::EnableSearchForDependees(sal_Bool bEnable)
701 {
702 	sal_Bool bSearchingForText = m_rbSearchForText.IsChecked();
703 	m_pbSearchAgain.Enable(bEnable && (!bSearchingForText || (m_cmbSearchText.GetText().Len() != 0)));
704 
705 	bEnable = bEnable && bSearchingForText;
706 
707 	sal_Bool bEnableRedundants = !m_aSoundsLikeCJK.IsChecked() || !SvtCJKOptions().IsJapaneseFindEnabled();
708 
709 	m_cmbSearchText.Enable			(bEnable);
710 	m_ftPosition.Enable				(bEnable && !m_cbWildCard.IsChecked());
711 	m_cbWildCard.Enable				(bEnable && !m_cbRegular.IsChecked() && !m_cbApprox.IsChecked());
712 	m_cbRegular.Enable				(bEnable && !m_cbWildCard.IsChecked() && !m_cbApprox.IsChecked());
713 	m_cbApprox.Enable				(bEnable && !m_cbWildCard.IsChecked() && !m_cbRegular.IsChecked());
714 	m_pbApproxSettings.Enable		(bEnable && m_cbApprox.IsChecked());
715 	m_aHalfFullFormsCJK.Enable		(bEnable && bEnableRedundants);
716 	m_aSoundsLikeCJK.Enable			(bEnable);
717 	m_aSoundsLikeCJKSettings.Enable	(bEnable && m_aSoundsLikeCJK.IsChecked());
718 	m_lbPosition.Enable				(bEnable && !m_cbWildCard.IsChecked());
719 	m_cbUseFormat.Enable			(bEnable);
720 	m_cbCase.Enable					(bEnable && bEnableRedundants);
721 }
722 
723 //------------------------------------------------------------------------
EnableControlPaint(sal_Bool bEnable)724 void FmSearchDialog::EnableControlPaint(sal_Bool bEnable)
725 {
726     Control* pAffectedControls[] = { &m_flSearchFor, &m_rbSearchForText, &m_cmbSearchText, &m_rbSearchForNull, &m_rbSearchForNotNull,
727         &m_rbSearchForText, &m_flWhere, &m_rbAllFields, &m_rbSingleField, &m_lbField, &m_flOptions, &m_ftPosition, &m_lbPosition,
728 		&m_cbUseFormat, &m_cbCase, &m_cbBackwards, &m_cbStartOver, &m_cbWildCard, &m_cbRegular, &m_cbApprox, &m_pbApproxSettings,
729 		&m_pbSearchAgain, &m_pbClose };
730 
731 	if (!bEnable)
732         for (sal_uInt32 i=0; i<sizeof(pAffectedControls)/sizeof(pAffectedControls[0]); ++i)
733 		{
734 			pAffectedControls[i]->SetUpdateMode(bEnable);
735 			pAffectedControls[i]->EnablePaint(bEnable);
736 		}
737 	else
738         for (sal_uInt32 i=0; i<sizeof(pAffectedControls)/sizeof(pAffectedControls[0]); ++i)
739 		{
740 			pAffectedControls[i]->EnablePaint(bEnable);
741 			pAffectedControls[i]->SetUpdateMode(bEnable);
742 		}
743 }
744 
745 //------------------------------------------------------------------------
IMPL_LINK(FmSearchDialog,OnDelayedPaint,void *,EMPTYARG)746 IMPL_LINK(FmSearchDialog, OnDelayedPaint, void*, EMPTYARG)
747 {
748 	EnableControlPaint(sal_True);
749 	return 0L;
750 }
751 
752 //------------------------------------------------------------------------
OnFound(const::com::sun::star::uno::Any & aCursorPos,sal_Int16 nFieldPos)753 void FmSearchDialog::OnFound(const ::com::sun::star::uno::Any& aCursorPos, sal_Int16 nFieldPos)
754 {
755 	FmFoundRecordInformation friInfo;
756 	friInfo.nContext = m_lbForm.GetSelectEntryPos();
757 		// wenn ich keine Suche in Kontexten mache, steht hier was ungueltiges drin, aber dann ist es auch egal
758 	friInfo.aPosition = aCursorPos;
759 	if (m_rbAllFields.IsChecked())
760 		friInfo.nFieldPos = nFieldPos;
761 	else
762 		friInfo.nFieldPos = m_lbField.GetSelectEntryPos();
763 		// das setzt natuerlich voraus, dass ich wirklich in dem Feld gesucht habe, dass in der Listbox ausgewaehlt ist,
764 		// genau das wird auch in RebuildUsedFields sichergestellt
765 
766 	// dem Handler Bescheid sagen
767     m_lnkFoundHandler.Call(&friInfo);
768 
769 	// und wieder Focus auf mich
770 	m_cmbSearchText.GrabFocus();
771 }
772 
773 //------------------------------------------------------------------------
IMPL_LINK(FmSearchDialog,OnSearchProgress,FmSearchProgress *,pProgress)774 IMPL_LINK(FmSearchDialog, OnSearchProgress, FmSearchProgress*, pProgress)
775 {
776 	::vos::OGuard aGuard( Application::GetSolarMutex() );
777 		// diese eine Methode Thread-sicher machen (das ist ein Overkill, die ganze restliche Applikation dafuer zu blockieren,
778 		// aber im Augenblick haben wir kein anderes Sicherheitskonzept)
779 
780 	switch (pProgress->aSearchState)
781 	{
782 		case FmSearchProgress::STATE_PROGRESS:
783 			if (pProgress->bOverflow)
784 			{
785                 String sHint( CUI_RES( m_cbBackwards.IsChecked() ? RID_STR_OVERFLOW_BACKWARD : RID_STR_OVERFLOW_FORWARD ) );
786 				m_ftHint.SetText( sHint );
787 				m_ftHint.Invalidate();
788 			}
789 
790 			m_ftRecord.SetText(String::CreateFromInt32(1 + pProgress->nCurrentRecord));
791 			m_ftRecord.Invalidate();
792 			break;
793 
794 		case FmSearchProgress::STATE_PROGRESS_COUNTING:
795 			m_ftHint.SetText(CUI_RESSTR(RID_STR_SEARCH_COUNTING));
796 			m_ftHint.Invalidate();
797 
798 			m_ftRecord.SetText(String::CreateFromInt32(pProgress->nCurrentRecord));
799 			m_ftRecord.Invalidate();
800 			break;
801 
802 		case FmSearchProgress::STATE_SUCCESSFULL:
803 			OnFound(pProgress->aBookmark, (sal_Int16)pProgress->nFieldIndex);
804 			EnableSearchUI(sal_True);
805 			break;
806 
807 		case FmSearchProgress::STATE_ERROR:
808 		case FmSearchProgress::STATE_NOTHINGFOUND:
809 		{
810 			sal_uInt16 nErrorId = (FmSearchProgress::STATE_ERROR == pProgress->aSearchState)
811 				? RID_SVXERR_SEARCH_GENERAL_ERROR
812 				: RID_SVXERR_SEARCH_NORECORD;
813 			ErrorBox(this, CUI_RES(nErrorId)).Execute();
814 		}
815 			// KEIN break !
816 		case FmSearchProgress::STATE_CANCELED:
817 			EnableSearchUI(sal_True);
818 			if (m_lnkCanceledNotFoundHdl.IsSet())
819 			{
820 				FmFoundRecordInformation friInfo;
821 				friInfo.nContext = m_lbForm.GetSelectEntryPos();
822 					// wenn ich keine Suche in Kontexten mache, steht hier was ungueltiges drin, aber dann ist es auch egal
823 				friInfo.aPosition = pProgress->aBookmark;
824 				m_lnkCanceledNotFoundHdl.Call(&friInfo);
825 			}
826 			break;
827 	}
828 
829 	m_ftRecord.SetText(String::CreateFromInt32(1 + pProgress->nCurrentRecord));
830 
831 	return 0L;
832 }
833 
834 //------------------------------------------------------------------------
LoadParams()835 void FmSearchDialog::LoadParams()
836 {
837 	FmSearchParams aParams(m_pConfig->getParams());
838 
839 	const ::rtl::OUString* pHistory		=					aParams.aHistory.getConstArray();
840 	const ::rtl::OUString* pHistoryEnd	=	pHistory	+	aParams.aHistory.getLength();
841 	for (; pHistory != pHistoryEnd; ++pHistory)
842 		m_cmbSearchText.InsertEntry( *pHistory );
843 
844 	// die Einstellungen nehme ich an meinen UI-Elementen vor und rufe dann einfach den entsprechenden Change-Handler auf,
845 	// dadurch werden die Daten an die SearchEngine weitergereicht und alle abhaengigen Enstellungen vorgenommen
846 
847 	// aktuelles Feld
848 	sal_uInt16 nInitialField = m_lbField.GetEntryPos( String( aParams.sSingleSearchField ) );
849 	if (nInitialField == COMBOBOX_ENTRY_NOTFOUND)
850 		nInitialField = 0;
851 	m_lbField.SelectEntryPos(nInitialField);
852 	LINK(this, FmSearchDialog, OnFieldSelected).Call(&m_lbField);
853 	// alle/einzelnes Feld (NACH dem Selektieren des Feldes, da OnClickedFieldRadios dort einen gueltigen Eintrag erwartet)
854 	if (aParams.bAllFields)
855 	{
856 		m_rbSingleField.Check(sal_False);
857 		m_rbAllFields.Check(sal_True);
858 		LINK(this, FmSearchDialog, OnClickedFieldRadios).Call(&m_rbAllFields);
859 		// OnClickedFieldRadios ruft auch um RebuildUsedFields
860 	}
861 	else
862 	{
863 		m_rbAllFields.Check(sal_False);
864 		m_rbSingleField.Check(sal_True);
865 		LINK(this, FmSearchDialog, OnClickedFieldRadios).Call(&m_rbSingleField);
866 	}
867 
868 	// Position im Feld
869 	m_lbPosition.SelectEntryPos(aParams.nPosition);
870 	LINK(this, FmSearchDialog, OnPositionSelected).Call(&m_lbPosition);
871 
872 	// Feld-Formatierung/Case-Sensitivitaet/Richtung
873 	m_cbUseFormat.Check(aParams.bUseFormatter);
874 	m_cbCase.Check( aParams.isCaseSensitive() );
875 	m_cbBackwards.Check(aParams.bBackwards);
876 	LINK(this, FmSearchDialog, OnCheckBoxToggled).Call(&m_cbUseFormat);
877 	LINK(this, FmSearchDialog, OnCheckBoxToggled).Call(&m_cbCase);
878 	LINK(this, FmSearchDialog, OnCheckBoxToggled).Call(&m_cbBackwards);
879 
880 	m_aHalfFullFormsCJK.Check( !aParams.isIgnoreWidthCJK( ) );	// BEWARE: this checkbox has a inverse semantics!
881 	m_aSoundsLikeCJK.Check( aParams.bSoundsLikeCJK );
882 	LINK(this, FmSearchDialog, OnCheckBoxToggled).Call(&m_aHalfFullFormsCJK);
883 	LINK(this, FmSearchDialog, OnCheckBoxToggled).Call(&m_aSoundsLikeCJK);
884 
885 	// die drei Checkboxen fuer spezielle Sucharten
886 	// erst mal alle ruecksetzen
887 	m_cbWildCard.Check(sal_False);
888 	m_cbRegular.Check(sal_False);
889 	m_cbApprox.Check(sal_False);
890 	LINK(this, FmSearchDialog, OnCheckBoxToggled).Call(&m_cbWildCard);
891 	LINK(this, FmSearchDialog, OnCheckBoxToggled).Call(&m_cbRegular);
892 	LINK(this, FmSearchDialog, OnCheckBoxToggled).Call(&m_cbApprox);
893 
894 	// dann die richtige setzen
895 	CheckBox* pToCheck = NULL;
896 	if (aParams.bWildcard)
897 		pToCheck = &m_cbWildCard;
898 	if (aParams.bRegular)
899 		pToCheck = &m_cbRegular;
900 	if (aParams.bApproxSearch)
901 		pToCheck = &m_cbApprox;
902 	if (aParams.bSoundsLikeCJK)
903 		pToCheck = &m_aSoundsLikeCJK;
904 	if (pToCheck)
905 	{
906 		pToCheck->Check(sal_True);
907 		LINK(this, FmSearchDialog, OnCheckBoxToggled).Call(pToCheck);
908 	}
909 
910 	// die Levenshtein-Parameter direkt an der SearchEngine setzen
911 	m_pSearchEngine->SetLevRelaxed(aParams.bLevRelaxed);
912 	m_pSearchEngine->SetLevOther(aParams.nLevOther);
913 	m_pSearchEngine->SetLevShorter(aParams.nLevShorter);
914 	m_pSearchEngine->SetLevLonger(aParams.nLevLonger);
915 
916 	m_pSearchEngine->SetTransliterationFlags( aParams.getTransliterationFlags( ) );
917 
918 	m_rbSearchForText.Check(sal_False);
919 	m_rbSearchForNull.Check(sal_False);
920 	m_rbSearchForNotNull.Check(sal_False);
921 	switch (aParams.nSearchForType)
922 	{
923 		case 1: m_rbSearchForNull.Check(sal_True); break;
924 		case 2: m_rbSearchForNotNull.Check(sal_True); break;
925 		default: m_rbSearchForText.Check(sal_True); break;
926 	}
927 	LINK(this, FmSearchDialog, OnClickedFieldRadios).Call(&m_rbSearchForText);
928 }
929 
930 //------------------------------------------------------------------------
SaveParams() const931 void FmSearchDialog::SaveParams() const
932 {
933 	if (!m_pConfig)
934 		return;
935 
936 	FmSearchParams aCurrentSettings;
937 
938 	aCurrentSettings.aHistory.realloc( m_cmbSearchText.GetEntryCount() );
939 	::rtl::OUString* pHistory = aCurrentSettings.aHistory.getArray();
940 	for (sal_uInt16 i=0; i<m_cmbSearchText.GetEntryCount(); ++i, ++pHistory)
941 		*pHistory = m_cmbSearchText.GetEntry(i);
942 
943 	aCurrentSettings.sSingleSearchField			= m_lbField.GetSelectEntry();
944 	aCurrentSettings.bAllFields					= m_rbAllFields.IsChecked();
945 	aCurrentSettings.nPosition					= m_pSearchEngine->GetPosition();
946 	aCurrentSettings.bUseFormatter				= m_pSearchEngine->GetFormatterUsing();
947 	aCurrentSettings.setCaseSensitive			( m_pSearchEngine->GetCaseSensitive() );
948 	aCurrentSettings.bBackwards					= !m_pSearchEngine->GetDirection();
949 	aCurrentSettings.bWildcard					= m_pSearchEngine->GetWildcard();
950 	aCurrentSettings.bRegular					= m_pSearchEngine->GetRegular();
951 	aCurrentSettings.bApproxSearch				= m_pSearchEngine->GetLevenshtein();
952 	aCurrentSettings.bLevRelaxed				= m_pSearchEngine->GetLevRelaxed();
953 	aCurrentSettings.nLevOther					= m_pSearchEngine->GetLevOther();
954 	aCurrentSettings.nLevShorter				= m_pSearchEngine->GetLevShorter();
955 	aCurrentSettings.nLevLonger					= m_pSearchEngine->GetLevLonger();
956 
957 	aCurrentSettings.bSoundsLikeCJK				= m_pSearchEngine->GetTransliteration();
958 	aCurrentSettings.setTransliterationFlags	( m_pSearchEngine->GetTransliterationFlags() );
959 
960 	if (m_rbSearchForNull.IsChecked())
961 		aCurrentSettings.nSearchForType = 1;
962 	else if (m_rbSearchForNotNull.IsChecked())
963 		aCurrentSettings.nSearchForType = 2;
964 	else
965 		aCurrentSettings.nSearchForType = 0;
966 
967 	m_pConfig->setParams( aCurrentSettings );
968 }
969 
970