xref: /trunk/main/svx/source/form/fmsrcimp.cxx (revision 86e1cf34)
1f6e50924SAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3f6e50924SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4f6e50924SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5f6e50924SAndrew Rist  * distributed with this work for additional information
6f6e50924SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7f6e50924SAndrew Rist  * to you under the Apache License, Version 2.0 (the
8f6e50924SAndrew Rist  * "License"); you may not use this file except in compliance
9f6e50924SAndrew Rist  * with the License.  You may obtain a copy of the License at
10f6e50924SAndrew Rist  *
11f6e50924SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12f6e50924SAndrew Rist  *
13f6e50924SAndrew Rist  * Unless required by applicable law or agreed to in writing,
14f6e50924SAndrew Rist  * software distributed under the License is distributed on an
15f6e50924SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16f6e50924SAndrew Rist  * KIND, either express or implied.  See the License for the
17f6e50924SAndrew Rist  * specific language governing permissions and limitations
18f6e50924SAndrew Rist  * under the License.
19f6e50924SAndrew Rist  *
20f6e50924SAndrew Rist  *************************************************************/
21f6e50924SAndrew Rist 
22f6e50924SAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_svx.hxx"
26cdf0e10cSrcweir 
27cdf0e10cSrcweir #ifndef _SVX_FMRESIDS_HRC
28cdf0e10cSrcweir #include "svx/fmresids.hrc"
29cdf0e10cSrcweir #endif
30cdf0e10cSrcweir #include "svx/fmtools.hxx"
31cdf0e10cSrcweir #include "svx/fmsrccfg.hxx"
32cdf0e10cSrcweir #include <tools/debug.hxx>
33cdf0e10cSrcweir #include <tools/diagnose_ex.h>
34cdf0e10cSrcweir #include <tools/wldcrd.hxx>
35cdf0e10cSrcweir #include <vcl/msgbox.hxx>
36cdf0e10cSrcweir #include <tools/shl.hxx>
37cdf0e10cSrcweir #include <svx/dialmgr.hxx>
38cdf0e10cSrcweir #include <cppuhelper/servicefactory.hxx>
39cdf0e10cSrcweir #include <vcl/svapp.hxx>
40cdf0e10cSrcweir #include <unotools/textsearch.hxx>
41cdf0e10cSrcweir #include <com/sun/star/util/SearchOptions.hpp>
42cdf0e10cSrcweir #include <com/sun/star/util/SearchAlgorithms.hpp>
43cdf0e10cSrcweir #include <com/sun/star/util/SearchResult.hpp>
44cdf0e10cSrcweir #include <com/sun/star/util/SearchFlags.hpp>
45cdf0e10cSrcweir #include <com/sun/star/lang/Locale.hpp>
46cdf0e10cSrcweir #include <com/sun/star/i18n/TransliterationModules.hpp>
47cdf0e10cSrcweir #include <com/sun/star/i18n/CollatorOptions.hpp>
48cdf0e10cSrcweir 
49cdf0e10cSrcweir #ifndef _COM_SUN_STAR_SDDB_XCOLUMNSSUPPLIER_HPP_
50cdf0e10cSrcweir #include <com/sun/star/sdbcx/XColumnsSupplier.hpp>
51cdf0e10cSrcweir #endif
52cdf0e10cSrcweir #include <com/sun/star/util/XNumberFormatter.hpp>
53cdf0e10cSrcweir #include <com/sun/star/util/NumberFormat.hpp>
54cdf0e10cSrcweir #include <com/sun/star/util/XNumberFormatsSupplier.hpp>
55cdf0e10cSrcweir #include <com/sun/star/util/XNumberFormats.hpp>
56cdf0e10cSrcweir #include <comphelper/processfactory.hxx>
57cdf0e10cSrcweir 
58cdf0e10cSrcweir #ifndef _SVX_FMPROP_HRC
59cdf0e10cSrcweir #include "fmprop.hrc"
60cdf0e10cSrcweir #endif
61cdf0e10cSrcweir #include "fmservs.hxx"
62cdf0e10cSrcweir #include "svx/fmsrcimp.hxx"
63cdf0e10cSrcweir #include <svx/fmsearch.hxx>
64cdf0e10cSrcweir 
65cdf0e10cSrcweir #include <comphelper/numbers.hxx>
66cdf0e10cSrcweir #include <unotools/syslocale.hxx>
67cdf0e10cSrcweir 
68cdf0e10cSrcweir #define EQUAL_BOOKMARKS(a, b) a == b
69cdf0e10cSrcweir 
70cdf0e10cSrcweir #define IFACECAST(c)          ((const Reference< XInterface >&)c)
71cdf0e10cSrcweir  // SUN C52 has some ambiguities without this cast ....
72cdf0e10cSrcweir 
73cdf0e10cSrcweir using namespace ::com::sun::star::uno;
74cdf0e10cSrcweir using namespace ::com::sun::star::util;
75cdf0e10cSrcweir using namespace ::com::sun::star::lang;
76cdf0e10cSrcweir using namespace ::com::sun::star::sdbc;
77cdf0e10cSrcweir using namespace ::com::sun::star::i18n;
78cdf0e10cSrcweir using namespace ::com::sun::star::beans;
79cdf0e10cSrcweir using namespace ::svxform;
80cdf0e10cSrcweir 
81cdf0e10cSrcweir 
82cdf0e10cSrcweir //========================================================================
83cdf0e10cSrcweir // = FmSearchThread
84cdf0e10cSrcweir //------------------------------------------------------------------------
run()85cdf0e10cSrcweir void FmSearchThread::run()
86cdf0e10cSrcweir {
87cdf0e10cSrcweir     m_pEngine->SearchNextImpl();
88cdf0e10cSrcweir };
89cdf0e10cSrcweir 
90cdf0e10cSrcweir //------------------------------------------------------------------------
onTerminated()91cdf0e10cSrcweir void FmSearchThread::onTerminated()
92cdf0e10cSrcweir {
93cdf0e10cSrcweir     if (m_aTerminationHdl.IsSet())
94cdf0e10cSrcweir         m_aTerminationHdl.Call(this);
95cdf0e10cSrcweir     delete this;
96cdf0e10cSrcweir }
97cdf0e10cSrcweir 
98cdf0e10cSrcweir //========================================================================
99cdf0e10cSrcweir // = FmRecordCountListener
100cdf0e10cSrcweir 
101cdf0e10cSrcweir //  SMART_UNO_IMPLEMENTATION(FmRecordCountListener, UsrObject);
102cdf0e10cSrcweir 
103cdf0e10cSrcweir DBG_NAME(FmRecordCountListener);
104cdf0e10cSrcweir //------------------------------------------------------------------------
FmRecordCountListener(const Reference<::com::sun::star::sdbc::XResultSet> & dbcCursor)105cdf0e10cSrcweir FmRecordCountListener::FmRecordCountListener(const Reference< ::com::sun::star::sdbc::XResultSet > & dbcCursor)
106cdf0e10cSrcweir {
107cdf0e10cSrcweir     DBG_CTOR(FmRecordCountListener,NULL);
108cdf0e10cSrcweir 
109cdf0e10cSrcweir     m_xListening = Reference< ::com::sun::star::beans::XPropertySet > (dbcCursor, UNO_QUERY);
110cdf0e10cSrcweir     if (!m_xListening.is())
111cdf0e10cSrcweir         return;
112cdf0e10cSrcweir 
113cdf0e10cSrcweir     if (::comphelper::getBOOL(m_xListening->getPropertyValue(FM_PROP_ROWCOUNTFINAL)))
114cdf0e10cSrcweir     {
115cdf0e10cSrcweir         m_xListening = NULL;
116cdf0e10cSrcweir         // there's nothing to do as the record count is already known
117cdf0e10cSrcweir         return;
118cdf0e10cSrcweir     }
119cdf0e10cSrcweir 
120cdf0e10cSrcweir     m_xListening->addPropertyChangeListener(FM_PROP_ROWCOUNT, (::com::sun::star::beans::XPropertyChangeListener*)this);
121cdf0e10cSrcweir }
122cdf0e10cSrcweir 
123cdf0e10cSrcweir //------------------------------------------------------------------------
SetPropChangeHandler(const Link & lnk)124cdf0e10cSrcweir Link FmRecordCountListener::SetPropChangeHandler(const Link& lnk)
125cdf0e10cSrcweir {
126cdf0e10cSrcweir     Link lnkReturn = m_lnkWhoWantsToKnow;
127cdf0e10cSrcweir     m_lnkWhoWantsToKnow = lnk;
128cdf0e10cSrcweir 
129cdf0e10cSrcweir     if (m_xListening.is())
130cdf0e10cSrcweir         NotifyCurrentCount();
131cdf0e10cSrcweir 
132cdf0e10cSrcweir     return lnkReturn;
133cdf0e10cSrcweir }
134cdf0e10cSrcweir 
135cdf0e10cSrcweir //------------------------------------------------------------------------
~FmRecordCountListener()136cdf0e10cSrcweir FmRecordCountListener::~FmRecordCountListener()
137cdf0e10cSrcweir {
138cdf0e10cSrcweir 
139cdf0e10cSrcweir     DBG_DTOR(FmRecordCountListener,NULL);
140cdf0e10cSrcweir }
141cdf0e10cSrcweir 
142cdf0e10cSrcweir //------------------------------------------------------------------------
DisConnect()143cdf0e10cSrcweir void FmRecordCountListener::DisConnect()
144cdf0e10cSrcweir {
145cdf0e10cSrcweir     if(m_xListening.is())
146cdf0e10cSrcweir         m_xListening->removePropertyChangeListener(FM_PROP_ROWCOUNT, (::com::sun::star::beans::XPropertyChangeListener*)this);
147cdf0e10cSrcweir     m_xListening = NULL;
148cdf0e10cSrcweir }
149cdf0e10cSrcweir 
150cdf0e10cSrcweir //------------------------------------------------------------------------
disposing(const::com::sun::star::lang::EventObject &)151cdf0e10cSrcweir void SAL_CALL FmRecordCountListener::disposing(const ::com::sun::star::lang::EventObject& /*Source*/) throw( RuntimeException )
152cdf0e10cSrcweir {
153cdf0e10cSrcweir     DBG_ASSERT(m_xListening.is(), "FmRecordCountListener::disposing should never have been called without a propset !");
154cdf0e10cSrcweir     DisConnect();
155cdf0e10cSrcweir }
156cdf0e10cSrcweir 
157cdf0e10cSrcweir //------------------------------------------------------------------------
NotifyCurrentCount()158cdf0e10cSrcweir void FmRecordCountListener::NotifyCurrentCount()
159cdf0e10cSrcweir {
160cdf0e10cSrcweir     if (m_lnkWhoWantsToKnow.IsSet())
161cdf0e10cSrcweir     {
162cdf0e10cSrcweir         DBG_ASSERT(m_xListening.is(), "FmRecordCountListener::NotifyCurrentCount : I have no propset ... !?");
163cdf0e10cSrcweir         void* pTheCount = (void*)::comphelper::getINT32(m_xListening->getPropertyValue(FM_PROP_ROWCOUNT));
164cdf0e10cSrcweir         m_lnkWhoWantsToKnow.Call(pTheCount);
165cdf0e10cSrcweir     }
166cdf0e10cSrcweir }
167cdf0e10cSrcweir 
168cdf0e10cSrcweir //------------------------------------------------------------------------
propertyChange(const::com::sun::star::beans::PropertyChangeEvent &)169cdf0e10cSrcweir void FmRecordCountListener::propertyChange(const  ::com::sun::star::beans::PropertyChangeEvent& /*evt*/) throw(::com::sun::star::uno::RuntimeException)
170cdf0e10cSrcweir {
171cdf0e10cSrcweir     NotifyCurrentCount();
172cdf0e10cSrcweir }
173cdf0e10cSrcweir 
174cdf0e10cSrcweir //========================================================================
175cdf0e10cSrcweir // FmSearchEngine - local classes
176cdf0e10cSrcweir //------------------------------------------------------------------------
SimpleTextWrapper(const Reference<::com::sun::star::awt::XTextComponent> & _xText)177cdf0e10cSrcweir SimpleTextWrapper::SimpleTextWrapper(const Reference< ::com::sun::star::awt::XTextComponent > & _xText)
178cdf0e10cSrcweir     :ControlTextWrapper(_xText.get())
179cdf0e10cSrcweir     ,m_xText(_xText)
180cdf0e10cSrcweir {
181cdf0e10cSrcweir     DBG_ASSERT(m_xText.is(), "FmSearchEngine::SimpleTextWrapper::SimpleTextWrapper : invalid argument !");
182cdf0e10cSrcweir }
183cdf0e10cSrcweir 
184cdf0e10cSrcweir //------------------------------------------------------------------------
getCurrentText() const185cdf0e10cSrcweir ::rtl::OUString SimpleTextWrapper::getCurrentText() const
186cdf0e10cSrcweir {
187cdf0e10cSrcweir     return m_xText->getText();
188cdf0e10cSrcweir }
189cdf0e10cSrcweir 
190cdf0e10cSrcweir //------------------------------------------------------------------------
ListBoxWrapper(const Reference<::com::sun::star::awt::XListBox> & _xBox)191cdf0e10cSrcweir ListBoxWrapper::ListBoxWrapper(const Reference< ::com::sun::star::awt::XListBox > & _xBox)
192cdf0e10cSrcweir     :ControlTextWrapper(_xBox.get())
193cdf0e10cSrcweir     ,m_xBox(_xBox)
194cdf0e10cSrcweir {
195cdf0e10cSrcweir     DBG_ASSERT(m_xBox.is(), "FmSearchEngine::ListBoxWrapper::ListBoxWrapper : invalid argument !");
196cdf0e10cSrcweir }
197cdf0e10cSrcweir 
198cdf0e10cSrcweir //------------------------------------------------------------------------
getCurrentText() const199cdf0e10cSrcweir ::rtl::OUString ListBoxWrapper::getCurrentText() const
200cdf0e10cSrcweir {
201cdf0e10cSrcweir     return m_xBox->getSelectedItem();
202cdf0e10cSrcweir }
203cdf0e10cSrcweir 
204cdf0e10cSrcweir //------------------------------------------------------------------------
CheckBoxWrapper(const Reference<::com::sun::star::awt::XCheckBox> & _xBox)205cdf0e10cSrcweir CheckBoxWrapper::CheckBoxWrapper(const Reference< ::com::sun::star::awt::XCheckBox > & _xBox)
206cdf0e10cSrcweir     :ControlTextWrapper(_xBox.get())
207cdf0e10cSrcweir     ,m_xBox(_xBox)
208cdf0e10cSrcweir {
209cdf0e10cSrcweir     DBG_ASSERT(m_xBox.is(), "FmSearchEngine::CheckBoxWrapper::CheckBoxWrapper : invalid argument !");
210cdf0e10cSrcweir }
211cdf0e10cSrcweir 
212cdf0e10cSrcweir //------------------------------------------------------------------------
getCurrentText() const213cdf0e10cSrcweir ::rtl::OUString CheckBoxWrapper::getCurrentText() const
214cdf0e10cSrcweir {
215cdf0e10cSrcweir     switch ((TriState)m_xBox->getState())
216cdf0e10cSrcweir     {
217cdf0e10cSrcweir         case STATE_NOCHECK: return rtl::OUString::createFromAscii("0");
218cdf0e10cSrcweir         case STATE_CHECK: return rtl::OUString::createFromAscii("1");
219cdf0e10cSrcweir         default: break;
220cdf0e10cSrcweir     }
221cdf0e10cSrcweir     return rtl::OUString();
222cdf0e10cSrcweir }
223cdf0e10cSrcweir 
224cdf0e10cSrcweir //========================================================================
225cdf0e10cSrcweir // = FmSearchEngine
226cdf0e10cSrcweir //------------------------------------------------------------------------
MoveCursor()227cdf0e10cSrcweir sal_Bool FmSearchEngine::MoveCursor()
228cdf0e10cSrcweir {
229cdf0e10cSrcweir     sal_Bool bSuccess = sal_True;
230cdf0e10cSrcweir     try
231cdf0e10cSrcweir     {
232cdf0e10cSrcweir         if (m_bForward)
233cdf0e10cSrcweir             if (m_xSearchCursor.isLast())
234cdf0e10cSrcweir                 m_xSearchCursor.first();
235cdf0e10cSrcweir             else
236cdf0e10cSrcweir                 m_xSearchCursor.next();
237cdf0e10cSrcweir         else
238cdf0e10cSrcweir             if (m_xSearchCursor.isFirst())
239cdf0e10cSrcweir             {
240cdf0e10cSrcweir                 FmRecordCountListener* prclListener = new FmRecordCountListener(m_xSearchCursor);
241cdf0e10cSrcweir                 prclListener->acquire();
242cdf0e10cSrcweir                 prclListener->SetPropChangeHandler(LINK(this, FmSearchEngine, OnNewRecordCount));
243cdf0e10cSrcweir 
244cdf0e10cSrcweir                 m_xSearchCursor.last();
245cdf0e10cSrcweir 
246cdf0e10cSrcweir                 prclListener->DisConnect();
247cdf0e10cSrcweir                 prclListener->release();
248cdf0e10cSrcweir             }
249cdf0e10cSrcweir             else
250cdf0e10cSrcweir                 m_xSearchCursor.previous();
251cdf0e10cSrcweir     }
252cdf0e10cSrcweir     catch(::com::sun::star::sdbc::SQLException  e)
253cdf0e10cSrcweir     {
254cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 0
255cdf0e10cSrcweir         String sDebugMessage;
256cdf0e10cSrcweir         sDebugMessage.AssignAscii("FmSearchEngine::MoveCursor : catched a DatabaseException (");
25724c56ab9SHerbert Dürr         sDebugMessage += e.SQLState.getStr();
258cdf0e10cSrcweir         sDebugMessage.AppendAscii(") !");
259cdf0e10cSrcweir         DBG_ERROR(ByteString(sDebugMessage, RTL_TEXTENCODING_ASCII_US).GetBuffer());
260cdf0e10cSrcweir #endif
261cdf0e10cSrcweir         bSuccess = sal_False;
262cdf0e10cSrcweir     }
263cdf0e10cSrcweir     catch(Exception  e)
264cdf0e10cSrcweir     {
265cdf0e10cSrcweir #if OSL_DEBUG_LEVEL > 0
266cdf0e10cSrcweir         UniString sDebugMessage;
267cdf0e10cSrcweir         sDebugMessage.AssignAscii("FmSearchEngine::MoveCursor : catched an Exception (");
26824c56ab9SHerbert Dürr         sDebugMessage += e.Message.getStr();
269cdf0e10cSrcweir         sDebugMessage.AppendAscii(") !");
270cdf0e10cSrcweir         DBG_ERROR(ByteString(sDebugMessage, RTL_TEXTENCODING_ASCII_US).GetBuffer());
271cdf0e10cSrcweir #endif
272cdf0e10cSrcweir         bSuccess = sal_False;
273cdf0e10cSrcweir     }
274cdf0e10cSrcweir     catch(...)
275cdf0e10cSrcweir     {
276cdf0e10cSrcweir         DBG_ERROR("FmSearchEngine::MoveCursor : catched an unknown Exception !");
277cdf0e10cSrcweir         bSuccess = sal_False;
278cdf0e10cSrcweir     }
279cdf0e10cSrcweir 
280cdf0e10cSrcweir     return bSuccess;
281cdf0e10cSrcweir }
282cdf0e10cSrcweir 
283cdf0e10cSrcweir //------------------------------------------------------------------------
MoveField(sal_Int32 & nPos,FieldCollectionIterator & iter,const FieldCollectionIterator & iterBegin,const FieldCollectionIterator & iterEnd)284cdf0e10cSrcweir sal_Bool FmSearchEngine::MoveField(sal_Int32& nPos, FieldCollectionIterator& iter, const FieldCollectionIterator& iterBegin, const FieldCollectionIterator& iterEnd)
285cdf0e10cSrcweir {
286cdf0e10cSrcweir     sal_Bool bSuccess(sal_True);
287cdf0e10cSrcweir     if (m_bForward)
288cdf0e10cSrcweir     {
289cdf0e10cSrcweir         ++iter;
290cdf0e10cSrcweir         ++nPos;
291cdf0e10cSrcweir         if (iter == iterEnd)
292cdf0e10cSrcweir         {
293cdf0e10cSrcweir             bSuccess = MoveCursor();
294cdf0e10cSrcweir             iter = iterBegin;
295cdf0e10cSrcweir             nPos = 0;
296cdf0e10cSrcweir         }
297cdf0e10cSrcweir     } else
298cdf0e10cSrcweir     {
299cdf0e10cSrcweir         if (iter == iterBegin)
300cdf0e10cSrcweir         {
301cdf0e10cSrcweir             bSuccess = MoveCursor();
302cdf0e10cSrcweir             iter = iterEnd;
303cdf0e10cSrcweir             nPos = iter-iterBegin;
304cdf0e10cSrcweir         }
305cdf0e10cSrcweir         --iter;
306cdf0e10cSrcweir         --nPos;
307cdf0e10cSrcweir     }
308cdf0e10cSrcweir     return bSuccess;
309cdf0e10cSrcweir }
310cdf0e10cSrcweir 
311cdf0e10cSrcweir //------------------------------------------------------------------------
BuildAndInsertFieldInfo(const Reference<::com::sun::star::container::XIndexAccess> & xAllFields,sal_Int32 nField)312cdf0e10cSrcweir void FmSearchEngine::BuildAndInsertFieldInfo(const Reference< ::com::sun::star::container::XIndexAccess > & xAllFields, sal_Int32 nField)
313cdf0e10cSrcweir {
314cdf0e10cSrcweir 	DBG_ASSERT( xAllFields.is() && ( nField >= 0 ) && ( nField < xAllFields->getCount() ),
315cdf0e10cSrcweir 		"FmSearchEngine::BuildAndInsertFieldInfo: invalid field descriptor!" );
316cdf0e10cSrcweir 
317cdf0e10cSrcweir 	// das Feld selber
318cdf0e10cSrcweir     Reference< XInterface > xCurrentField;
319cdf0e10cSrcweir     xAllFields->getByIndex(nField) >>= xCurrentField;
320cdf0e10cSrcweir 
321cdf0e10cSrcweir     // von dem weiss ich jetzt, dass es den DatabaseRecord-Service unterstuetzt (hoffe ich)
322cdf0e10cSrcweir     // fuer den FormatKey und den Typ brauche ich das PropertySet
323cdf0e10cSrcweir     Reference< ::com::sun::star::beans::XPropertySet >  xProperties(xCurrentField, UNO_QUERY);
324cdf0e10cSrcweir 
325cdf0e10cSrcweir     // die FieldInfo dazu aufbauen
326cdf0e10cSrcweir     FieldInfo fiCurrent;
327cdf0e10cSrcweir     fiCurrent.xContents = Reference< ::com::sun::star::sdb::XColumn > (xCurrentField, UNO_QUERY);
328cdf0e10cSrcweir     fiCurrent.nFormatKey = ::comphelper::getINT32(xProperties->getPropertyValue(FM_PROP_FORMATKEY));
329cdf0e10cSrcweir     fiCurrent.bDoubleHandling = sal_False;
330cdf0e10cSrcweir     if (m_xFormatSupplier.is())
331cdf0e10cSrcweir     {
332cdf0e10cSrcweir         Reference< ::com::sun::star::util::XNumberFormats >  xNumberFormats(m_xFormatSupplier->getNumberFormats());
333cdf0e10cSrcweir 
334cdf0e10cSrcweir         sal_Int16 nFormatType = ::comphelper::getNumberFormatType(xNumberFormats, fiCurrent.nFormatKey) & ~((sal_Int16)::com::sun::star::util::NumberFormat::DEFINED);
335cdf0e10cSrcweir         fiCurrent.bDoubleHandling = (nFormatType != ::com::sun::star::util::NumberFormat::TEXT);
336cdf0e10cSrcweir     }
337cdf0e10cSrcweir 
338cdf0e10cSrcweir     // und merken
339cdf0e10cSrcweir     m_arrUsedFields.insert(m_arrUsedFields.end(), fiCurrent);
340cdf0e10cSrcweir 
341cdf0e10cSrcweir }
342cdf0e10cSrcweir //------------------------------------------------------------------------
FormatField(const FieldInfo & rField)343cdf0e10cSrcweir ::rtl::OUString FmSearchEngine::FormatField(const FieldInfo& rField)
344cdf0e10cSrcweir {
345cdf0e10cSrcweir     DBG_ASSERT(!m_bUsingTextComponents, "FmSearchEngine::FormatField : im UsingTextComponents-Mode bitte FormatField(sal_Int32) benutzen !");
346cdf0e10cSrcweir 
347cdf0e10cSrcweir     if (!m_xFormatter.is())
348cdf0e10cSrcweir         return ::rtl::OUString();
349cdf0e10cSrcweir     // sonst werden Datumsflder zum Beispiel zu irgendeinem Default-Wert formatiert
350cdf0e10cSrcweir 
351cdf0e10cSrcweir     ::rtl::OUString sReturn;
352cdf0e10cSrcweir     try
353cdf0e10cSrcweir     {
354cdf0e10cSrcweir         if (rField.bDoubleHandling)
355cdf0e10cSrcweir         {
356cdf0e10cSrcweir             double fValue = rField.xContents->getDouble();
357cdf0e10cSrcweir             if (!rField.xContents->wasNull())
358cdf0e10cSrcweir                 sReturn = m_xFormatter->convertNumberToString(rField.nFormatKey, fValue);
359cdf0e10cSrcweir         }
360cdf0e10cSrcweir         else
361cdf0e10cSrcweir         {
362cdf0e10cSrcweir             ::rtl::OUString sValue = rField.xContents->getString();
363cdf0e10cSrcweir             if (!rField.xContents->wasNull())
364cdf0e10cSrcweir                 sReturn = m_xFormatter->formatString(rField.nFormatKey, sValue);
365cdf0e10cSrcweir         }
366cdf0e10cSrcweir     }
367cdf0e10cSrcweir     catch(...)
368cdf0e10cSrcweir     {
369cdf0e10cSrcweir     }
370cdf0e10cSrcweir 
371cdf0e10cSrcweir 
372cdf0e10cSrcweir     return sReturn;
373cdf0e10cSrcweir }
374cdf0e10cSrcweir 
375cdf0e10cSrcweir //------------------------------------------------------------------------
FormatField(sal_Int32 nWhich)376cdf0e10cSrcweir ::rtl::OUString FmSearchEngine::FormatField(sal_Int32 nWhich)
377cdf0e10cSrcweir {
378cdf0e10cSrcweir     if (m_bUsingTextComponents)
379cdf0e10cSrcweir     {
380cdf0e10cSrcweir         DBG_ASSERT((sal_uInt32)nWhich < m_aControlTexts.size(), "FmSearchEngine::FormatField(sal_Int32) : invalid position !");
381cdf0e10cSrcweir         DBG_ASSERT(m_aControlTexts[nWhich] != NULL, "FmSearchEngine::FormatField(sal_Int32) : invalid object in array !");
382cdf0e10cSrcweir         DBG_ASSERT(m_aControlTexts[nWhich]->getControl().is(), "FmSearchEngine::FormatField : invalid control !");
383cdf0e10cSrcweir 
384cdf0e10cSrcweir         if (m_nCurrentFieldIndex != -1)
385cdf0e10cSrcweir         {
386cdf0e10cSrcweir             DBG_ASSERT((nWhich == 0) || (nWhich == m_nCurrentFieldIndex), "FmSearchEngine::FormatField : Parameter nWhich ist ungueltig");
387cdf0e10cSrcweir             // analoge Situation wie unten
388cdf0e10cSrcweir             nWhich = m_nCurrentFieldIndex;
389cdf0e10cSrcweir         }
390cdf0e10cSrcweir 
391cdf0e10cSrcweir         DBG_ASSERT((nWhich >= 0) && ((sal_uInt32)nWhich < m_aControlTexts.size()),
392cdf0e10cSrcweir             "FmSearchEngine::FormatField : invalid argument nWhich !");
393cdf0e10cSrcweir         return m_aControlTexts[m_nCurrentFieldIndex == -1 ? nWhich : m_nCurrentFieldIndex]->getCurrentText();
394cdf0e10cSrcweir     }
395cdf0e10cSrcweir     else
396cdf0e10cSrcweir     {
397cdf0e10cSrcweir         if (m_nCurrentFieldIndex != -1)
398cdf0e10cSrcweir         {
399cdf0e10cSrcweir             DBG_ASSERT((nWhich == 0) || (nWhich == m_nCurrentFieldIndex), "FmSearchEngine::FormatField : Parameter nWhich ist ungueltig");
400cdf0e10cSrcweir             // ich bin im single-field-modus, da ist auch die richtige Feld-Nummer erlaubt, obwohl dann der richtige ::com::sun::star::sdbcx::Index
401cdf0e10cSrcweir             // fuer meinen Array-Zugriff natuerlich 0 ist
402cdf0e10cSrcweir             nWhich = 0;
403cdf0e10cSrcweir         }
404cdf0e10cSrcweir 
405cdf0e10cSrcweir         DBG_ASSERT((nWhich>=0) && (nWhich < (m_arrUsedFields.end() - m_arrUsedFields.begin())),
406cdf0e10cSrcweir             "FmSearchEngine::FormatField : Parameter nWhich ist ungueltig");
407cdf0e10cSrcweir         return FormatField(m_arrUsedFields[nWhich]);
408cdf0e10cSrcweir     }
409cdf0e10cSrcweir }
410cdf0e10cSrcweir 
411cdf0e10cSrcweir //------------------------------------------------------------------------
SearchSpecial(sal_Bool _bSearchForNull,sal_Int32 & nFieldPos,FieldCollectionIterator & iterFieldLoop,const FieldCollectionIterator & iterBegin,const FieldCollectionIterator & iterEnd)412cdf0e10cSrcweir FmSearchEngine::SEARCH_RESULT FmSearchEngine::SearchSpecial(sal_Bool _bSearchForNull, sal_Int32& nFieldPos,
413cdf0e10cSrcweir     FieldCollectionIterator& iterFieldLoop, const FieldCollectionIterator& iterBegin, const FieldCollectionIterator& iterEnd)
414cdf0e10cSrcweir {
415cdf0e10cSrcweir     // die Startposition merken
416cdf0e10cSrcweir     Any aStartMark;
417cdf0e10cSrcweir     try { aStartMark = m_xSearchCursor.getBookmark(); }
418cdf0e10cSrcweir     catch ( const Exception& ) { DBG_UNHANDLED_EXCEPTION(); return SR_ERROR; }
419cdf0e10cSrcweir     FieldCollectionIterator iterInitialField = iterFieldLoop;
420cdf0e10cSrcweir 
421cdf0e10cSrcweir     // --------------------------------------------------------------
422cdf0e10cSrcweir     sal_Bool bFound(sal_False);
423cdf0e10cSrcweir     sal_Bool bMovedAround(sal_False);
424cdf0e10cSrcweir     do
425cdf0e10cSrcweir     {
426cdf0e10cSrcweir         if (m_eMode == SM_ALLOWSCHEDULE) //CHINA001  if (m_eMode == FmSearchDialog::SM_ALLOWSCHEDULE)
427cdf0e10cSrcweir         {
428cdf0e10cSrcweir             Application::Reschedule();
429cdf0e10cSrcweir             Application::Reschedule();
430cdf0e10cSrcweir             // do 2 reschedules because of #70226# : some things done within this loop's body may cause an user event
431cdf0e10cSrcweir             // to be posted (deep within vcl), and these user events will be handled before any keyinput or paintings
432cdf0e10cSrcweir             // or anything like that. So within each loop we create one user event and handle one user event (and no
433cdf0e10cSrcweir             // paintings and these), so the office seems to be frozen while searching.
434cdf0e10cSrcweir             // FS - 70226 - 02.12.99
435cdf0e10cSrcweir         }
436cdf0e10cSrcweir 
437cdf0e10cSrcweir         // der aktuell zu vergleichende Inhalt
438cdf0e10cSrcweir         iterFieldLoop->xContents->getString();  // needed for wasNull
439cdf0e10cSrcweir         bFound = _bSearchForNull == iterFieldLoop->xContents->wasNull();
440cdf0e10cSrcweir         if (bFound)
441cdf0e10cSrcweir             break;
442cdf0e10cSrcweir 
443cdf0e10cSrcweir         // naechstes Feld (implizit naechster Datensatz, wenn noetig)
444cdf0e10cSrcweir         if (!MoveField(nFieldPos, iterFieldLoop, iterBegin, iterEnd))
445cdf0e10cSrcweir         {   // beim Bewegen auf das naechste Feld ging was schief ... weitermachen ist nicht drin, da das naechste Mal genau
446cdf0e10cSrcweir             // das selbe bestimmt wieder schief geht, also Abbruch
447cdf0e10cSrcweir             // vorher aber noch, damit das Weitersuchen an der aktuellen Position weitermacht :
448cdf0e10cSrcweir             try { m_aPreviousLocBookmark = m_xSearchCursor.getBookmark(); }
449cdf0e10cSrcweir             catch ( const Exception& ) { DBG_UNHANDLED_EXCEPTION(); }
450cdf0e10cSrcweir             m_iterPreviousLocField = iterFieldLoop;
451cdf0e10cSrcweir             // und wech
452cdf0e10cSrcweir             return SR_ERROR;
453cdf0e10cSrcweir         }
454cdf0e10cSrcweir 
455cdf0e10cSrcweir         Any aCurrentBookmark;
456cdf0e10cSrcweir         try { aCurrentBookmark = m_xSearchCursor.getBookmark(); }
457cdf0e10cSrcweir         catch ( const Exception& ) { DBG_UNHANDLED_EXCEPTION(); return SR_ERROR; }
458cdf0e10cSrcweir 
459cdf0e10cSrcweir         bMovedAround = EQUAL_BOOKMARKS(aStartMark, aCurrentBookmark) && (iterFieldLoop == iterInitialField);
460cdf0e10cSrcweir 
461cdf0e10cSrcweir         if (nFieldPos == 0)
462cdf0e10cSrcweir             // das heisst, ich habe mich auf einen neuen Datensatz bewegt
463cdf0e10cSrcweir             PropagateProgress(bMovedAround);
464cdf0e10cSrcweir                 // if we moved to the starting position we don't have to propagate an 'overflow' message
465cdf0e10cSrcweir                 // FS - 07.12.99 - 68530
466cdf0e10cSrcweir 
467cdf0e10cSrcweir         // abbrechen gefordert ?
468cdf0e10cSrcweir         if (CancelRequested())
469cdf0e10cSrcweir             return SR_CANCELED;
470cdf0e10cSrcweir 
471cdf0e10cSrcweir     } while (!bMovedAround);
472cdf0e10cSrcweir 
473cdf0e10cSrcweir     return bFound ? SR_FOUND : SR_NOTFOUND;
474cdf0e10cSrcweir }
475cdf0e10cSrcweir 
476cdf0e10cSrcweir //------------------------------------------------------------------------
SearchWildcard(const::rtl::OUString & strExpression,sal_Int32 & nFieldPos,FieldCollectionIterator & iterFieldLoop,const FieldCollectionIterator & iterBegin,const FieldCollectionIterator & iterEnd)477cdf0e10cSrcweir FmSearchEngine::SEARCH_RESULT FmSearchEngine::SearchWildcard(const ::rtl::OUString& strExpression, sal_Int32& nFieldPos,
478cdf0e10cSrcweir     FieldCollectionIterator& iterFieldLoop, const FieldCollectionIterator& iterBegin, const FieldCollectionIterator& iterEnd)
479cdf0e10cSrcweir {
480cdf0e10cSrcweir     // die Startposition merken
481cdf0e10cSrcweir     Any aStartMark;
482cdf0e10cSrcweir     try { aStartMark = m_xSearchCursor.getBookmark(); }
483cdf0e10cSrcweir     catch ( const Exception& ) { DBG_UNHANDLED_EXCEPTION(); return SR_ERROR; }
484cdf0e10cSrcweir     FieldCollectionIterator iterInitialField = iterFieldLoop;
485cdf0e10cSrcweir 
486cdf0e10cSrcweir     WildCard aSearchExpression(strExpression);
487cdf0e10cSrcweir 
488cdf0e10cSrcweir     // --------------------------------------------------------------
489cdf0e10cSrcweir     sal_Bool bFound(sal_False);
490cdf0e10cSrcweir     sal_Bool bMovedAround(sal_False);
491cdf0e10cSrcweir     do
492cdf0e10cSrcweir     {
493cdf0e10cSrcweir         if (m_eMode == SM_ALLOWSCHEDULE) //CHINA001  if (m_eMode == FmSearchDialog::SM_ALLOWSCHEDULE)
494cdf0e10cSrcweir         {
495cdf0e10cSrcweir             Application::Reschedule();
496cdf0e10cSrcweir             Application::Reschedule();
497cdf0e10cSrcweir             // do 2 reschedules because of #70226# : some things done within this loop's body may cause an user event
498cdf0e10cSrcweir             // to be posted (deep within vcl), and these user events will be handled before any keyinput or paintings
499cdf0e10cSrcweir             // or anything like that. So within each loop we create one user event and hanel one user event (and no
500cdf0e10cSrcweir             // paintings and these), so the office seems to be frozen while searching.
501cdf0e10cSrcweir             // FS - 70226 - 02.12.99
502cdf0e10cSrcweir         }
503cdf0e10cSrcweir 
504cdf0e10cSrcweir         // der aktuell zu vergleichende Inhalt
505cdf0e10cSrcweir         ::rtl::OUString sCurrentCheck;
506cdf0e10cSrcweir         if (m_bFormatter)
507cdf0e10cSrcweir             sCurrentCheck = FormatField(nFieldPos);
508cdf0e10cSrcweir         else
509cdf0e10cSrcweir             sCurrentCheck = iterFieldLoop->xContents->getString();
510cdf0e10cSrcweir 
511cdf0e10cSrcweir         if (!GetCaseSensitive())
512cdf0e10cSrcweir 			// norm the string
513cdf0e10cSrcweir 			m_aCharacterClassficator.toLower_rtl(sCurrentCheck);
514cdf0e10cSrcweir 
515cdf0e10cSrcweir         // jetzt ist der Test einfach ...
516cdf0e10cSrcweir         bFound = aSearchExpression.Matches(sCurrentCheck);
517cdf0e10cSrcweir 
518cdf0e10cSrcweir         if (bFound)
519cdf0e10cSrcweir             break;
520cdf0e10cSrcweir 
521cdf0e10cSrcweir         // naechstes Feld (implizit naechster Datensatz, wenn noetig)
522cdf0e10cSrcweir         if (!MoveField(nFieldPos, iterFieldLoop, iterBegin, iterEnd))
523cdf0e10cSrcweir         {   // beim Bewegen auf das naechste Feld ging was schief ... weitermachen ist nicht drin, da das naechste Mal genau
524cdf0e10cSrcweir             // das selbe bestimmt wieder schief geht, also Abbruch
525cdf0e10cSrcweir             // vorher aber noch, damit das Weitersuchen an der aktuellen Position weitermacht :
526cdf0e10cSrcweir             try { m_aPreviousLocBookmark = m_xSearchCursor.getBookmark(); }
527cdf0e10cSrcweir             catch ( const Exception& ) { DBG_UNHANDLED_EXCEPTION(); }
528cdf0e10cSrcweir             m_iterPreviousLocField = iterFieldLoop;
529cdf0e10cSrcweir             // und wech
530cdf0e10cSrcweir             return SR_ERROR;
531cdf0e10cSrcweir         }
532cdf0e10cSrcweir 
533cdf0e10cSrcweir         Any aCurrentBookmark;
534cdf0e10cSrcweir         try { aCurrentBookmark = m_xSearchCursor.getBookmark(); }
535cdf0e10cSrcweir         catch ( const Exception& ) { DBG_UNHANDLED_EXCEPTION(); return SR_ERROR; }
536cdf0e10cSrcweir 
537cdf0e10cSrcweir         bMovedAround = EQUAL_BOOKMARKS(aStartMark, aCurrentBookmark) && (iterFieldLoop == iterInitialField);
538cdf0e10cSrcweir 
539cdf0e10cSrcweir         if (nFieldPos == 0)
540cdf0e10cSrcweir             // das heisst, ich habe mich auf einen neuen Datensatz bewegt
541cdf0e10cSrcweir             PropagateProgress(bMovedAround);
542cdf0e10cSrcweir                 // if we moved to the starting position we don't have to propagate an 'overflow' message
543cdf0e10cSrcweir                 // FS - 07.12.99 - 68530
544cdf0e10cSrcweir 
545cdf0e10cSrcweir         // abbrechen gefordert ?
546cdf0e10cSrcweir         if (CancelRequested())
547cdf0e10cSrcweir             return SR_CANCELED;
548cdf0e10cSrcweir 
549cdf0e10cSrcweir     } while (!bMovedAround);
550cdf0e10cSrcweir 
551cdf0e10cSrcweir     return bFound ? SR_FOUND : SR_NOTFOUND;
552cdf0e10cSrcweir }
553cdf0e10cSrcweir 
554cdf0e10cSrcweir //------------------------------------------------------------------------
SearchRegularApprox(const::rtl::OUString & strExpression,sal_Int32 & nFieldPos,FieldCollectionIterator & iterFieldLoop,const FieldCollectionIterator & iterBegin,const FieldCollectionIterator & iterEnd)555cdf0e10cSrcweir FmSearchEngine::SEARCH_RESULT FmSearchEngine::SearchRegularApprox(const ::rtl::OUString& strExpression, sal_Int32& nFieldPos,
556cdf0e10cSrcweir     FieldCollectionIterator& iterFieldLoop, const FieldCollectionIterator& iterBegin, const FieldCollectionIterator& iterEnd)
557cdf0e10cSrcweir {
558cdf0e10cSrcweir     DBG_ASSERT(m_bLevenshtein || m_bRegular,
559cdf0e10cSrcweir         "FmSearchEngine::SearchRegularApprox : ungueltiger Suchmodus !");
560cdf0e10cSrcweir     DBG_ASSERT(!m_bLevenshtein || !m_bRegular,
561cdf0e10cSrcweir         "FmSearchEngine::SearchRegularApprox : kann nicht nach regulaeren Ausdruecken und nach Aehnlichkeiten gleichzeitig suchen !");
562cdf0e10cSrcweir 
563cdf0e10cSrcweir     // Startposition merken
564cdf0e10cSrcweir     Any aStartMark;
565cdf0e10cSrcweir     try { aStartMark = m_xSearchCursor.getBookmark(); }
566cdf0e10cSrcweir     catch ( const Exception& ) { DBG_UNHANDLED_EXCEPTION(); return SR_ERROR; }
567cdf0e10cSrcweir     FieldCollectionIterator iterInitialField = iterFieldLoop;
568cdf0e10cSrcweir 
569cdf0e10cSrcweir     // Parameter sammeln
570cdf0e10cSrcweir     SearchOptions aParam;
571cdf0e10cSrcweir     aParam.algorithmType = m_bRegular ? SearchAlgorithms_REGEXP : SearchAlgorithms_APPROXIMATE;
572cdf0e10cSrcweir     aParam.searchFlag = 0;
573cdf0e10cSrcweir     aParam.transliterateFlags = GetTransliterationFlags();
574cdf0e10cSrcweir 	if ( !GetTransliteration() )
575cdf0e10cSrcweir 	{	// if transliteration is not enabled, the only flags which matter are IGNORE_CASE and IGNORE_WIDTH
576cdf0e10cSrcweir 		aParam.transliterateFlags &= TransliterationModules_IGNORE_CASE | TransliterationModules_IGNORE_WIDTH;
577cdf0e10cSrcweir 	}
578cdf0e10cSrcweir     if (m_bLevenshtein)
579cdf0e10cSrcweir     {
580cdf0e10cSrcweir         if (m_bLevRelaxed)
581cdf0e10cSrcweir             aParam.searchFlag |= SearchFlags::LEV_RELAXED;
582cdf0e10cSrcweir         aParam.changedChars = m_nLevOther;
583cdf0e10cSrcweir         aParam.deletedChars = m_nLevShorter;
584cdf0e10cSrcweir         aParam.insertedChars = m_nLevLonger;
585cdf0e10cSrcweir     }
586cdf0e10cSrcweir     aParam.searchString = strExpression;
587cdf0e10cSrcweir 	aParam.Locale = SvtSysLocale().GetLocaleData().getLocale();
588cdf0e10cSrcweir     ::utl::TextSearch aLocalEngine(aParam);
589cdf0e10cSrcweir 
590cdf0e10cSrcweir     // --------------------------------------------------------------
591cdf0e10cSrcweir     bool bFound = false;
592cdf0e10cSrcweir     sal_Bool bMovedAround(sal_False);
593cdf0e10cSrcweir     do
594cdf0e10cSrcweir     {
595cdf0e10cSrcweir         if (m_eMode == SM_ALLOWSCHEDULE) //CHINA001   if (m_eMode == FmSearchDialog::SM_ALLOWSCHEDULE)
596cdf0e10cSrcweir         {
597cdf0e10cSrcweir             Application::Reschedule();
598cdf0e10cSrcweir             Application::Reschedule();
599cdf0e10cSrcweir             // do 2 reschedules because of #70226# : some things done within this loop's body may cause an user event
600cdf0e10cSrcweir             // to be posted (deep within vcl), and these user events will be handled before any keyinput or paintings
601cdf0e10cSrcweir             // or anything like that. So within each loop we create one user event and handle one user event (and no
602cdf0e10cSrcweir             // paintings and these), so the office seems to be frozen while searching.
603cdf0e10cSrcweir             // FS - 70226 - 02.12.99
604cdf0e10cSrcweir         }
605cdf0e10cSrcweir 
606cdf0e10cSrcweir         // der aktuell zu vergleichende Inhalt
607cdf0e10cSrcweir         ::rtl::OUString sCurrentCheck;
608cdf0e10cSrcweir         if (m_bFormatter)
609cdf0e10cSrcweir             sCurrentCheck = FormatField(nFieldPos);
610cdf0e10cSrcweir         else
611cdf0e10cSrcweir             sCurrentCheck = iterFieldLoop->xContents->getString();
612cdf0e10cSrcweir 
613cdf0e10cSrcweir         // (don't care about case here, this is done by the TextSearch object, 'cause we passed our case parameter to it)
614cdf0e10cSrcweir 
615cdf0e10cSrcweir         xub_StrLen nStart = 0, nEnd = (xub_StrLen)sCurrentCheck.getLength();
616cdf0e10cSrcweir         bFound = aLocalEngine.SearchFrwrd(sCurrentCheck, &nStart, &nEnd);
617cdf0e10cSrcweir             // das heisst hier 'forward' aber das bezieht sich nur auf die Suche innerhalb von sCurrentCheck, hat also mit
618cdf0e10cSrcweir             // der Richtung meines Datensatz-Durchwanderns nix zu tun (darum kuemmert sich MoveField)
619cdf0e10cSrcweir 
620cdf0e10cSrcweir         // checken, ob die Position stimmt
621cdf0e10cSrcweir         if (bFound)
622cdf0e10cSrcweir         {
623cdf0e10cSrcweir             switch (m_nPosition)
624cdf0e10cSrcweir             {
625cdf0e10cSrcweir                 case MATCHING_WHOLETEXT :
626cdf0e10cSrcweir                     if (nEnd != sCurrentCheck.getLength())
627cdf0e10cSrcweir                     {
628cdf0e10cSrcweir                         bFound = false;
629cdf0e10cSrcweir                         break;
630cdf0e10cSrcweir                     }
631cdf0e10cSrcweir                     // laeuft in den naechsten Case rein !
632cdf0e10cSrcweir                 case MATCHING_BEGINNING :
633cdf0e10cSrcweir                     if (nStart != 0)
634cdf0e10cSrcweir                         bFound = false;
635cdf0e10cSrcweir                     break;
636cdf0e10cSrcweir                 case MATCHING_END :
637cdf0e10cSrcweir                     if (nEnd != sCurrentCheck.getLength())
638cdf0e10cSrcweir                         bFound = false;
639cdf0e10cSrcweir                     break;
640cdf0e10cSrcweir             }
641cdf0e10cSrcweir         }
642cdf0e10cSrcweir 
643cdf0e10cSrcweir         if (bFound) // immer noch ?
644cdf0e10cSrcweir             break;
645cdf0e10cSrcweir 
646cdf0e10cSrcweir         // naechstes Feld (implizit naechster Datensatz, wenn noetig)
647cdf0e10cSrcweir         if (!MoveField(nFieldPos, iterFieldLoop, iterBegin, iterEnd))
648cdf0e10cSrcweir         {   // beim Bewegen auf das naechste Feld ging was schief ... weitermachen ist nicht drin, da das naechste Mal genau
649cdf0e10cSrcweir             // das selbe bestimmt wieder schief geht, also Abbruch (ohne Fehlermeldung, von der erwarte ich, dass sie im Move
650cdf0e10cSrcweir             // angezeigt wurde)
651cdf0e10cSrcweir             // vorher aber noch, damit das Weitersuchen an der aktuellen Position weitermacht :
652cdf0e10cSrcweir             try { m_aPreviousLocBookmark = m_xSearchCursor.getBookmark(); }
653cdf0e10cSrcweir             catch ( const Exception& ) { DBG_UNHANDLED_EXCEPTION(); }
654cdf0e10cSrcweir             m_iterPreviousLocField = iterFieldLoop;
655cdf0e10cSrcweir             // und wech
656cdf0e10cSrcweir             return SR_ERROR;
657cdf0e10cSrcweir         }
658cdf0e10cSrcweir 
659cdf0e10cSrcweir         Any aCurrentBookmark;
660cdf0e10cSrcweir         try { aCurrentBookmark = m_xSearchCursor.getBookmark(); }
661cdf0e10cSrcweir         catch ( const Exception& ) { DBG_UNHANDLED_EXCEPTION(); return SR_ERROR; }
662cdf0e10cSrcweir         bMovedAround = EQUAL_BOOKMARKS(aStartMark, aCurrentBookmark) && (iterFieldLoop == iterInitialField);
663cdf0e10cSrcweir 
664cdf0e10cSrcweir         if (nFieldPos == 0)
665cdf0e10cSrcweir             // das heisst, ich habe mich auf einen neuen Datensatz bewegt
666cdf0e10cSrcweir             PropagateProgress(bMovedAround);
667cdf0e10cSrcweir                 // if we moved to the starting position we don't have to propagate an 'overflow' message
668cdf0e10cSrcweir                 // FS - 07.12.99 - 68530
669cdf0e10cSrcweir 
670cdf0e10cSrcweir         // abbrechen gefordert ?
671cdf0e10cSrcweir         if (CancelRequested())
672cdf0e10cSrcweir             return SR_CANCELED;
673cdf0e10cSrcweir 
674cdf0e10cSrcweir     } while (!bMovedAround);
675cdf0e10cSrcweir 
676cdf0e10cSrcweir     return bFound ? SR_FOUND : SR_NOTFOUND;
677cdf0e10cSrcweir }
678cdf0e10cSrcweir 
679cdf0e10cSrcweir 
680cdf0e10cSrcweir DBG_NAME(FmSearchEngine);
681cdf0e10cSrcweir //------------------------------------------------------------------------
FmSearchEngine(const Reference<XMultiServiceFactory> & _rxORB,const Reference<XResultSet> & xCursor,const::rtl::OUString & sVisibleFields,const Reference<XNumberFormatsSupplier> & xFormatSupplier,FMSEARCH_MODE eMode)682cdf0e10cSrcweir FmSearchEngine::FmSearchEngine(const Reference< XMultiServiceFactory >& _rxORB,
683cdf0e10cSrcweir 			const Reference< XResultSet > & xCursor, const ::rtl::OUString& sVisibleFields,
684cdf0e10cSrcweir 			const Reference< XNumberFormatsSupplier > & xFormatSupplier, FMSEARCH_MODE eMode)//CHINA001 const Reference< XNumberFormatsSupplier > & xFormatSupplier, FmSearchDialog::SEARCH_MODE eMode)
685cdf0e10cSrcweir     :m_xSearchCursor(xCursor)
686cdf0e10cSrcweir     ,m_xFormatSupplier(xFormatSupplier)
687cdf0e10cSrcweir 	,m_aCharacterClassficator( _rxORB, SvtSysLocale().GetLocaleData().getLocale() )
688cdf0e10cSrcweir 	,m_aStringCompare( _rxORB )
689cdf0e10cSrcweir     ,m_nCurrentFieldIndex(-2)   // -1 hat schon eine Bedeutung, also nehme ich -2 fuer 'ungueltig'
690cdf0e10cSrcweir     ,m_bUsingTextComponents(sal_False)
691cdf0e10cSrcweir     ,m_eSearchForType(SEARCHFOR_STRING)
692cdf0e10cSrcweir     ,m_srResult(SR_FOUND)
693cdf0e10cSrcweir     ,m_bSearchingCurrently(sal_False)
694cdf0e10cSrcweir     ,m_bCancelAsynchRequest(sal_False)
695cdf0e10cSrcweir     ,m_eMode(eMode)
696cdf0e10cSrcweir     ,m_bFormatter(sal_False)
697cdf0e10cSrcweir     ,m_bForward(sal_False)
698cdf0e10cSrcweir     ,m_bWildcard(sal_False)
699cdf0e10cSrcweir     ,m_bRegular(sal_False)
700cdf0e10cSrcweir     ,m_bLevenshtein(sal_False)
701cdf0e10cSrcweir     ,m_bTransliteration(sal_False)
702cdf0e10cSrcweir     ,m_bLevRelaxed(sal_False)
703cdf0e10cSrcweir     ,m_nLevOther(0)
704cdf0e10cSrcweir     ,m_nLevShorter(0)
705cdf0e10cSrcweir     ,m_nLevLonger(0)
706cdf0e10cSrcweir     ,m_nPosition(MATCHING_ANYWHERE)
707cdf0e10cSrcweir     ,m_nTransliterationFlags(0)
708cdf0e10cSrcweir {
709cdf0e10cSrcweir     DBG_CTOR(FmSearchEngine,NULL);
710cdf0e10cSrcweir 
711cdf0e10cSrcweir     m_xFormatter = Reference< ::com::sun::star::util::XNumberFormatter > (::comphelper::getProcessServiceFactory()
712cdf0e10cSrcweir                     ->createInstance(FM_NUMBER_FORMATTER), UNO_QUERY);
713cdf0e10cSrcweir     if (m_xFormatter.is())
714cdf0e10cSrcweir         m_xFormatter->attachNumberFormatsSupplier(m_xFormatSupplier);
715cdf0e10cSrcweir 
716cdf0e10cSrcweir     Init(sVisibleFields);
717cdf0e10cSrcweir }
718cdf0e10cSrcweir 
719cdf0e10cSrcweir //------------------------------------------------------------------------
FmSearchEngine(const Reference<XMultiServiceFactory> & _rxORB,const Reference<XResultSet> & xCursor,const::rtl::OUString & sVisibleFields,const InterfaceArray & arrFields,FMSEARCH_MODE eMode)720cdf0e10cSrcweir FmSearchEngine::FmSearchEngine(const Reference< XMultiServiceFactory >& _rxORB,
721cdf0e10cSrcweir 		const Reference< XResultSet > & xCursor, const ::rtl::OUString& sVisibleFields,
722cdf0e10cSrcweir 		const InterfaceArray& arrFields, FMSEARCH_MODE eMode)//CHINA001 const InterfaceArray& arrFields, FmSearchDialog::SEARCH_MODE eMode)
723cdf0e10cSrcweir     :m_xSearchCursor(xCursor)
724cdf0e10cSrcweir 	,m_aCharacterClassficator( _rxORB, SvtSysLocale().GetLocaleData().getLocale() )
725cdf0e10cSrcweir 	,m_aStringCompare( _rxORB )
726cdf0e10cSrcweir     ,m_nCurrentFieldIndex(-2)   // -1 hat schon eine Bedeutung, also nehme ich -2 fuer 'ungueltig'
727cdf0e10cSrcweir     ,m_bUsingTextComponents(sal_True)
728cdf0e10cSrcweir     ,m_xOriginalIterator(xCursor)
729cdf0e10cSrcweir     ,m_xClonedIterator(m_xOriginalIterator, sal_True)
730cdf0e10cSrcweir     ,m_eSearchForType(SEARCHFOR_STRING)
731cdf0e10cSrcweir     ,m_srResult(SR_FOUND)
732cdf0e10cSrcweir     ,m_bSearchingCurrently(sal_False)
733cdf0e10cSrcweir     ,m_bCancelAsynchRequest(sal_False)
734cdf0e10cSrcweir     ,m_eMode(eMode)
735cdf0e10cSrcweir     ,m_bFormatter(sal_True)     // das muss konsistent sein mit m_xSearchCursor, der i.A. == m_xOriginalIterator ist
736cdf0e10cSrcweir     ,m_bForward(sal_False)
737cdf0e10cSrcweir     ,m_bWildcard(sal_False)
738cdf0e10cSrcweir     ,m_bRegular(sal_False)
739cdf0e10cSrcweir     ,m_bLevenshtein(sal_False)
740cdf0e10cSrcweir     ,m_bTransliteration(sal_False)
741cdf0e10cSrcweir     ,m_bLevRelaxed(sal_False)
742cdf0e10cSrcweir     ,m_nLevOther(0)
743cdf0e10cSrcweir     ,m_nLevShorter(0)
744cdf0e10cSrcweir     ,m_nLevLonger(0)
745cdf0e10cSrcweir     ,m_nPosition(MATCHING_ANYWHERE)
746cdf0e10cSrcweir     ,m_nTransliterationFlags(0)
747cdf0e10cSrcweir {
748cdf0e10cSrcweir     DBG_CTOR(FmSearchEngine,NULL);
749cdf0e10cSrcweir 
750cdf0e10cSrcweir     fillControlTexts(arrFields);
751cdf0e10cSrcweir     Init(sVisibleFields);
752cdf0e10cSrcweir }
753cdf0e10cSrcweir 
754cdf0e10cSrcweir //------------------------------------------------------------------------
~FmSearchEngine()755cdf0e10cSrcweir FmSearchEngine::~FmSearchEngine()
756cdf0e10cSrcweir {
757cdf0e10cSrcweir     clearControlTexts();
758cdf0e10cSrcweir 
759cdf0e10cSrcweir     DBG_DTOR(FmSearchEngine,NULL);
760cdf0e10cSrcweir }
761cdf0e10cSrcweir 
762cdf0e10cSrcweir //------------------------------------------------------------------------
SetIgnoreWidthCJK(sal_Bool bSet)763cdf0e10cSrcweir void FmSearchEngine::SetIgnoreWidthCJK(sal_Bool bSet)
764cdf0e10cSrcweir {
765cdf0e10cSrcweir     if (bSet)
766cdf0e10cSrcweir         m_nTransliterationFlags |= TransliterationModules_IGNORE_WIDTH;
767cdf0e10cSrcweir     else
768cdf0e10cSrcweir         m_nTransliterationFlags &= ~TransliterationModules_IGNORE_WIDTH;
769cdf0e10cSrcweir }
770cdf0e10cSrcweir 
771cdf0e10cSrcweir //------------------------------------------------------------------------
GetIgnoreWidthCJK() const772cdf0e10cSrcweir sal_Bool FmSearchEngine::GetIgnoreWidthCJK() const
773cdf0e10cSrcweir {
774cdf0e10cSrcweir     return 0 != (m_nTransliterationFlags & TransliterationModules_IGNORE_WIDTH);
775cdf0e10cSrcweir }
776cdf0e10cSrcweir 
777cdf0e10cSrcweir //------------------------------------------------------------------------
SetCaseSensitive(sal_Bool bSet)778cdf0e10cSrcweir void FmSearchEngine::SetCaseSensitive(sal_Bool bSet)
779cdf0e10cSrcweir {
780cdf0e10cSrcweir     if (bSet)
781cdf0e10cSrcweir         m_nTransliterationFlags &= ~TransliterationModules_IGNORE_CASE;
782cdf0e10cSrcweir     else
783cdf0e10cSrcweir         m_nTransliterationFlags |= TransliterationModules_IGNORE_CASE;
784cdf0e10cSrcweir }
785cdf0e10cSrcweir 
786cdf0e10cSrcweir //------------------------------------------------------------------------
GetCaseSensitive() const787cdf0e10cSrcweir sal_Bool FmSearchEngine::GetCaseSensitive() const
788cdf0e10cSrcweir {
789cdf0e10cSrcweir     return 0 == (m_nTransliterationFlags & TransliterationModules_IGNORE_CASE);
790cdf0e10cSrcweir }
791cdf0e10cSrcweir 
792cdf0e10cSrcweir //------------------------------------------------------------------------
clearControlTexts()793cdf0e10cSrcweir void FmSearchEngine::clearControlTexts()
794cdf0e10cSrcweir {
795cdf0e10cSrcweir     for (   ControlTextSuppliersIterator aIter = m_aControlTexts.begin();
796cdf0e10cSrcweir             aIter < m_aControlTexts.end();
797cdf0e10cSrcweir             ++aIter
798cdf0e10cSrcweir         )
799cdf0e10cSrcweir     {
800cdf0e10cSrcweir         delete *aIter;
801cdf0e10cSrcweir     }
802cdf0e10cSrcweir     m_aControlTexts.clear();
803cdf0e10cSrcweir }
804cdf0e10cSrcweir 
805cdf0e10cSrcweir //------------------------------------------------------------------------
fillControlTexts(const InterfaceArray & arrFields)806cdf0e10cSrcweir void FmSearchEngine::fillControlTexts(const InterfaceArray& arrFields)
807cdf0e10cSrcweir {
808cdf0e10cSrcweir     clearControlTexts();
809cdf0e10cSrcweir     Reference< XInterface >  xCurrent;
810cdf0e10cSrcweir     for (sal_uInt32 i=0; i<arrFields.size(); ++i)
811cdf0e10cSrcweir     {
812cdf0e10cSrcweir         xCurrent = arrFields.at(i);
813cdf0e10cSrcweir         DBG_ASSERT(xCurrent.is(), "FmSearchEngine::fillControlTexts : invalid field interface !");
814cdf0e10cSrcweir         // check which type of control this is
815cdf0e10cSrcweir         Reference< ::com::sun::star::awt::XTextComponent >  xAsText(xCurrent, UNO_QUERY);
816cdf0e10cSrcweir         if (xAsText.is())
817cdf0e10cSrcweir         {
818cdf0e10cSrcweir             m_aControlTexts.insert(m_aControlTexts.end(), new SimpleTextWrapper(xAsText));
819cdf0e10cSrcweir             continue;
820cdf0e10cSrcweir         }
821cdf0e10cSrcweir 
822cdf0e10cSrcweir         Reference< ::com::sun::star::awt::XListBox >  xAsListBox(xCurrent, UNO_QUERY);
823cdf0e10cSrcweir         if (xAsListBox.is())
824cdf0e10cSrcweir         {
825cdf0e10cSrcweir             m_aControlTexts.insert(m_aControlTexts.end(), new ListBoxWrapper(xAsListBox));
826cdf0e10cSrcweir             continue;
827cdf0e10cSrcweir         }
828cdf0e10cSrcweir 
829cdf0e10cSrcweir         Reference< ::com::sun::star::awt::XCheckBox >  xAsCheckBox(xCurrent, UNO_QUERY);
830cdf0e10cSrcweir         DBG_ASSERT(xAsCheckBox.is(), "FmSearchEngine::fillControlTexts : invalid field interface (no supported type) !");
831cdf0e10cSrcweir             // we don't have any more options ...
832cdf0e10cSrcweir         m_aControlTexts.insert(m_aControlTexts.end(), new CheckBoxWrapper(xAsCheckBox));
833cdf0e10cSrcweir     }
834cdf0e10cSrcweir }
835cdf0e10cSrcweir 
836cdf0e10cSrcweir //------------------------------------------------------------------------
Init(const::rtl::OUString & sVisibleFields)837cdf0e10cSrcweir void FmSearchEngine::Init(const ::rtl::OUString& sVisibleFields)
838cdf0e10cSrcweir {
839cdf0e10cSrcweir 	// analyze the fields
840cdf0e10cSrcweir 	// additionally, create the mapping: because the list of used columns can be shorter than the list
841cdf0e10cSrcweir 	// of columns of the cursor, we need a mapping: "used column numer n" -> "cursor column m"
842cdf0e10cSrcweir     m_arrFieldMapping.clear();
843cdf0e10cSrcweir 
844cdf0e10cSrcweir 	// important: The case of the columns does not need to be exact - for instance:
845cdf0e10cSrcweir 	// - a user created a form which works on a table, for which the driver returns a column name "COLUMN"
846cdf0e10cSrcweir 	// - the driver itself works case-insensitve with column names
847cdf0e10cSrcweir 	// - a control in the form is bound to "column" - not the different case
848cdf0e10cSrcweir 	// In such a scenario, the form and the field would work okay, but we here need to case for the different case
849cdf0e10cSrcweir 	// explicitly
850cdf0e10cSrcweir 	// 2003-01-09 - #i8755# - fs@openoffice.org
851cdf0e10cSrcweir 
852cdf0e10cSrcweir 	// so first of all, check if the database handles identifiers case sensitive
853cdf0e10cSrcweir 	Reference< XConnection > xConn;
854cdf0e10cSrcweir 	Reference< XDatabaseMetaData > xMeta;
855cdf0e10cSrcweir 	Reference< XPropertySet > xCursorProps( IFACECAST( m_xSearchCursor ), UNO_QUERY );
856cdf0e10cSrcweir 	if ( xCursorProps.is() )
857cdf0e10cSrcweir 	{
858cdf0e10cSrcweir 		try
859cdf0e10cSrcweir 		{
860cdf0e10cSrcweir 			xCursorProps->getPropertyValue( FM_PROP_ACTIVE_CONNECTION ) >>= xConn;
861cdf0e10cSrcweir 		}
862cdf0e10cSrcweir 		catch( Exception& ) { /* silent this - will be asserted below */ }
863cdf0e10cSrcweir 	}
864cdf0e10cSrcweir 	if ( xConn.is() )
865cdf0e10cSrcweir 		xMeta = xConn->getMetaData();
866cdf0e10cSrcweir 	OSL_ENSURE( xMeta.is(), "FmSearchEngine::Init: very strange cursor (could not derive connection meta data from it)!" );
867cdf0e10cSrcweir 
868cdf0e10cSrcweir 	sal_Bool bCaseSensitiveIdentifiers = sal_True;	// assume case sensivity
869cdf0e10cSrcweir 	if ( xMeta.is() )
870cdf0e10cSrcweir 		bCaseSensitiveIdentifiers = xMeta->supportsMixedCaseQuotedIdentifiers();
871cdf0e10cSrcweir 
872cdf0e10cSrcweir 	// now that we have this information, we need a collator which is able to case (in)sentively compare strings
873cdf0e10cSrcweir 	m_aStringCompare.loadDefaultCollator( SvtSysLocale().GetLocaleData().getLocale(),
874cdf0e10cSrcweir 		bCaseSensitiveIdentifiers ? 0 : ::com::sun::star::i18n::CollatorOptions::CollatorOptions_IGNORE_CASE );
875cdf0e10cSrcweir 
876cdf0e10cSrcweir     try
877cdf0e10cSrcweir     {
878cdf0e10cSrcweir         // der Cursor kann mir einen Record (als PropertySet) liefern, dieser unterstuetzt den DatabaseRecord-Service
879cdf0e10cSrcweir         Reference< ::com::sun::star::sdbcx::XColumnsSupplier >  xSupplyCols(IFACECAST(m_xSearchCursor), UNO_QUERY);
880cdf0e10cSrcweir         DBG_ASSERT(xSupplyCols.is(), "FmSearchEngine::Init : invalid cursor (no columns supplier) !");
881cdf0e10cSrcweir         Reference< ::com::sun::star::container::XNameAccess >       xAllFieldNames = xSupplyCols->getColumns();
882cdf0e10cSrcweir         Sequence< ::rtl::OUString > seqFieldNames = xAllFieldNames->getElementNames();
883cdf0e10cSrcweir         ::rtl::OUString*            pFieldNames = seqFieldNames.getArray();
884cdf0e10cSrcweir 
885cdf0e10cSrcweir 
886cdf0e10cSrcweir         ::rtl::OUString sCurrentField;
887cdf0e10cSrcweir         UniString sVis(sVisibleFields.getStr());
888cdf0e10cSrcweir         xub_StrLen nLen = sVis.GetTokenCount();
889cdf0e10cSrcweir         for (xub_StrLen i=0; i<nLen; ++i)
890cdf0e10cSrcweir         {
891cdf0e10cSrcweir             sCurrentField = sVis.GetToken(i);
892cdf0e10cSrcweir 
893cdf0e10cSrcweir             // in der Feld-Sammlung suchen
894cdf0e10cSrcweir             sal_Int32 nFoundIndex = -1;
895cdf0e10cSrcweir             for (sal_Int32 j=0; j<seqFieldNames.getLength(); ++j, ++pFieldNames)
896cdf0e10cSrcweir             {
897cdf0e10cSrcweir 				if ( 0 == m_aStringCompare.compareString( *pFieldNames, sCurrentField ) )
898cdf0e10cSrcweir                 {
899cdf0e10cSrcweir                     nFoundIndex = j;
900cdf0e10cSrcweir                     break;
901cdf0e10cSrcweir                 }
902cdf0e10cSrcweir             }
903cdf0e10cSrcweir             // set the field selection back to the first
904cdf0e10cSrcweir             pFieldNames = seqFieldNames.getArray();;
905cdf0e10cSrcweir             DBG_ASSERT(nFoundIndex != -1, "FmSearchEngine::Init : Invalid field name were given !");
906cdf0e10cSrcweir             m_arrFieldMapping.push_back(nFoundIndex);
907cdf0e10cSrcweir         }
908cdf0e10cSrcweir     }
909cdf0e10cSrcweir     catch(Exception&)
910cdf0e10cSrcweir     {
911*86e1cf34SPedro Giffuni         DBG_ERROR("Exception occurred!");
912cdf0e10cSrcweir     }
913cdf0e10cSrcweir 
914cdf0e10cSrcweir }
915cdf0e10cSrcweir 
916cdf0e10cSrcweir //------------------------------------------------------------------------
SetFormatterUsing(sal_Bool bSet)917cdf0e10cSrcweir void FmSearchEngine::SetFormatterUsing(sal_Bool bSet)
918cdf0e10cSrcweir {
919cdf0e10cSrcweir     if (m_bFormatter == bSet)
920cdf0e10cSrcweir         return;
921cdf0e10cSrcweir     m_bFormatter = bSet;
922cdf0e10cSrcweir 
923cdf0e10cSrcweir     if (m_bUsingTextComponents)
924cdf0e10cSrcweir     {
925cdf0e10cSrcweir         // ich benutzte keinen Formatter, sondern TextComponents -> der SearchIterator muss angepasst werden
926cdf0e10cSrcweir         try
927cdf0e10cSrcweir         {
928cdf0e10cSrcweir             if (m_bFormatter)
929cdf0e10cSrcweir             {
930cdf0e10cSrcweir                 DBG_ASSERT(m_xSearchCursor == m_xClonedIterator, "FmSearchEngine::SetFormatterUsing : inkonsistenter Zustand !");
931cdf0e10cSrcweir                 m_xSearchCursor = m_xOriginalIterator;
932cdf0e10cSrcweir                 m_xSearchCursor.moveToBookmark(m_xClonedIterator.getBookmark());
933cdf0e10cSrcweir                     // damit ich mit dem neuen Iterator wirklich dort weitermache, wo ich vorher aufgehoert habe
934cdf0e10cSrcweir             }
935cdf0e10cSrcweir             else
936cdf0e10cSrcweir             {
937cdf0e10cSrcweir                 DBG_ASSERT(m_xSearchCursor == m_xOriginalIterator, "FmSearchEngine::SetFormatterUsing : inkonsistenter Zustand !");
938cdf0e10cSrcweir                 m_xSearchCursor = m_xClonedIterator;
939cdf0e10cSrcweir                 m_xSearchCursor.moveToBookmark(m_xOriginalIterator.getBookmark());
940cdf0e10cSrcweir             }
941cdf0e10cSrcweir         }
942cdf0e10cSrcweir         catch( const Exception& )
943cdf0e10cSrcweir         {
944cdf0e10cSrcweir             DBG_UNHANDLED_EXCEPTION();
945cdf0e10cSrcweir         }
946cdf0e10cSrcweir 
947cdf0e10cSrcweir         // ich muss die Fields neu binden, da der Textaustausch eventuell ueber diese Fields erfolgt und sich der unterliegende Cursor
948cdf0e10cSrcweir         // geaendert hat
949cdf0e10cSrcweir         RebuildUsedFields(m_nCurrentFieldIndex, sal_True);
950cdf0e10cSrcweir     }
951cdf0e10cSrcweir     else
952cdf0e10cSrcweir         InvalidatePreviousLoc();
953cdf0e10cSrcweir }
954cdf0e10cSrcweir 
955cdf0e10cSrcweir //------------------------------------------------------------------------
PropagateProgress(sal_Bool _bDontPropagateOverflow)956cdf0e10cSrcweir void FmSearchEngine::PropagateProgress(sal_Bool _bDontPropagateOverflow)
957cdf0e10cSrcweir {
958cdf0e10cSrcweir     if (m_aProgressHandler.IsSet())
959cdf0e10cSrcweir     {
960cdf0e10cSrcweir         FmSearchProgress aProgress;
961cdf0e10cSrcweir         try
962cdf0e10cSrcweir         {
963cdf0e10cSrcweir             aProgress.aSearchState = FmSearchProgress::STATE_PROGRESS;
964cdf0e10cSrcweir             aProgress.nCurrentRecord = m_xSearchCursor.getRow() - 1;
965cdf0e10cSrcweir             if (m_bForward)
966cdf0e10cSrcweir                 aProgress.bOverflow = !_bDontPropagateOverflow && m_xSearchCursor.isFirst();
967cdf0e10cSrcweir             else
968cdf0e10cSrcweir                 aProgress.bOverflow = !_bDontPropagateOverflow && m_xSearchCursor.isLast();
969cdf0e10cSrcweir         }
970cdf0e10cSrcweir         catch( const Exception& )
971cdf0e10cSrcweir         {
972cdf0e10cSrcweir             DBG_UNHANDLED_EXCEPTION();
973cdf0e10cSrcweir         }
974cdf0e10cSrcweir 
975cdf0e10cSrcweir         m_aProgressHandler.Call(&aProgress);
976cdf0e10cSrcweir     }
977cdf0e10cSrcweir }
978cdf0e10cSrcweir 
979cdf0e10cSrcweir //------------------------------------------------------------------------
SearchNextImpl()980cdf0e10cSrcweir void FmSearchEngine::SearchNextImpl()
981cdf0e10cSrcweir {
982cdf0e10cSrcweir     DBG_ASSERT(!(m_bWildcard && m_bRegular) && !(m_bRegular && m_bLevenshtein) && !(m_bLevenshtein && m_bWildcard),
983cdf0e10cSrcweir         "FmSearchEngine::SearchNextImpl : Suchparameter schliessen sich gegenseitig aus !");
984cdf0e10cSrcweir 
985cdf0e10cSrcweir     DBG_ASSERT(m_xSearchCursor.is(), "FmSearchEngine::SearchNextImpl : habe ungueltigen Iterator !");
986cdf0e10cSrcweir 
987cdf0e10cSrcweir     // die Parameter der Suche
988cdf0e10cSrcweir     ::rtl::OUString strSearchExpression(m_strSearchExpression); // brauche ich non-const
989cdf0e10cSrcweir     if (!GetCaseSensitive())
990cdf0e10cSrcweir 		// norm the string
991cdf0e10cSrcweir 		m_aCharacterClassficator.toLower_rtl(strSearchExpression);
992cdf0e10cSrcweir 
993cdf0e10cSrcweir     if (!m_bRegular && !m_bLevenshtein)
994cdf0e10cSrcweir     {   // 'normale' Suche fuehre ich auf jeden Fall ueber WildCards durch, muss aber vorher je nach Modus den ::rtl::OUString anpassen
995cdf0e10cSrcweir 
996cdf0e10cSrcweir         if (!m_bWildcard)
997cdf0e10cSrcweir         {   // da natuerlich in allen anderen Faellen auch * und ? im Suchstring erlaubt sind, aber nicht als WildCards zaehlen
998cdf0e10cSrcweir             // sollen, muss ich normieren
999cdf0e10cSrcweir             UniString aTmp(strSearchExpression.getStr());
1000cdf0e10cSrcweir             static const UniString s_sStar = UniString::CreateFromAscii("\\*");
1001cdf0e10cSrcweir             static const UniString s_sQuotation = UniString::CreateFromAscii("\\?");
1002cdf0e10cSrcweir             aTmp.SearchAndReplaceAll('*', s_sStar);
1003cdf0e10cSrcweir             aTmp.SearchAndReplaceAll('?', s_sQuotation);
1004cdf0e10cSrcweir             strSearchExpression = aTmp;
1005cdf0e10cSrcweir 
1006cdf0e10cSrcweir             switch (m_nPosition)
1007cdf0e10cSrcweir             {
1008cdf0e10cSrcweir                 case MATCHING_ANYWHERE :
1009cdf0e10cSrcweir                     strSearchExpression = ::rtl::OUString::createFromAscii("*") + strSearchExpression
1010cdf0e10cSrcweir                     + ::rtl::OUString::createFromAscii("*");
1011cdf0e10cSrcweir                     break;
1012cdf0e10cSrcweir                 case MATCHING_BEGINNING :
1013cdf0e10cSrcweir                     strSearchExpression = strSearchExpression + ::rtl::OUString::createFromAscii("*");
1014cdf0e10cSrcweir                     break;
1015cdf0e10cSrcweir                 case MATCHING_END :
1016cdf0e10cSrcweir                     strSearchExpression = ::rtl::OUString::createFromAscii("*") + strSearchExpression;
1017cdf0e10cSrcweir                     break;
1018cdf0e10cSrcweir                 case MATCHING_WHOLETEXT :
1019cdf0e10cSrcweir                     break;
1020cdf0e10cSrcweir                 default :
1021cdf0e10cSrcweir                     DBG_ERROR("FmSearchEngine::SearchNextImpl() : die Methoden-Listbox duerfte nur 4 Eintraege enthalten ...");
1022cdf0e10cSrcweir             }
1023cdf0e10cSrcweir         }
1024cdf0e10cSrcweir     }
1025cdf0e10cSrcweir 
1026cdf0e10cSrcweir     // fuer Arbeit auf Feldliste
1027cdf0e10cSrcweir     FieldCollectionIterator iterBegin = m_arrUsedFields.begin();
1028cdf0e10cSrcweir     FieldCollectionIterator iterEnd = m_arrUsedFields.end();
1029cdf0e10cSrcweir     FieldCollectionIterator iterFieldCheck;
1030cdf0e10cSrcweir 
1031cdf0e10cSrcweir     sal_Int32 nFieldPos;
1032cdf0e10cSrcweir 
1033cdf0e10cSrcweir     if (HasPreviousLoc())
1034cdf0e10cSrcweir     {
1035cdf0e10cSrcweir         DBG_ASSERT(EQUAL_BOOKMARKS(m_aPreviousLocBookmark, m_xSearchCursor.getBookmark()),
1036cdf0e10cSrcweir             "FmSearchEngine::SearchNextImpl : ungueltige Position !");
1037cdf0e10cSrcweir         iterFieldCheck = m_iterPreviousLocField;
1038cdf0e10cSrcweir         // im Feld nach (oder vor) der letzten Fundstelle weitermachen
1039cdf0e10cSrcweir         nFieldPos = iterFieldCheck - iterBegin;
1040cdf0e10cSrcweir         MoveField(nFieldPos, iterFieldCheck, iterBegin, iterEnd);
1041cdf0e10cSrcweir     }
1042cdf0e10cSrcweir     else
1043cdf0e10cSrcweir     {
1044cdf0e10cSrcweir         if (m_bForward)
1045cdf0e10cSrcweir             iterFieldCheck = iterBegin;
1046cdf0e10cSrcweir         else
1047cdf0e10cSrcweir         {
1048cdf0e10cSrcweir             iterFieldCheck = iterEnd;
1049cdf0e10cSrcweir             --iterFieldCheck;
1050cdf0e10cSrcweir         }
1051cdf0e10cSrcweir         nFieldPos = iterFieldCheck - iterBegin;
1052cdf0e10cSrcweir     }
1053cdf0e10cSrcweir 
1054cdf0e10cSrcweir     PropagateProgress(sal_True);
1055cdf0e10cSrcweir     SEARCH_RESULT srResult;
1056cdf0e10cSrcweir     if (m_eSearchForType != SEARCHFOR_STRING)
1057cdf0e10cSrcweir         srResult = SearchSpecial(m_eSearchForType == SEARCHFOR_NULL, nFieldPos, iterFieldCheck, iterBegin, iterEnd);
1058cdf0e10cSrcweir     else if (!m_bRegular && !m_bLevenshtein)
1059cdf0e10cSrcweir         srResult = SearchWildcard(strSearchExpression, nFieldPos, iterFieldCheck, iterBegin, iterEnd);
1060cdf0e10cSrcweir     else
1061cdf0e10cSrcweir         srResult = SearchRegularApprox(strSearchExpression, nFieldPos, iterFieldCheck, iterBegin, iterEnd);
1062cdf0e10cSrcweir 
1063cdf0e10cSrcweir     m_srResult = srResult;
1064cdf0e10cSrcweir 
1065cdf0e10cSrcweir     if (SR_ERROR == m_srResult)
1066cdf0e10cSrcweir         return;
1067cdf0e10cSrcweir 
1068cdf0e10cSrcweir     // gefunden ?
1069cdf0e10cSrcweir     if (SR_FOUND == m_srResult)
1070cdf0e10cSrcweir     {
1071cdf0e10cSrcweir         // die Pos merken
1072cdf0e10cSrcweir         try { m_aPreviousLocBookmark = m_xSearchCursor.getBookmark(); }
1073cdf0e10cSrcweir         catch ( const Exception& ) { DBG_UNHANDLED_EXCEPTION(); }
1074cdf0e10cSrcweir         m_iterPreviousLocField = iterFieldCheck;
1075cdf0e10cSrcweir     }
1076cdf0e10cSrcweir     else
1077cdf0e10cSrcweir         // die "letzte Fundstelle" invalidieren
1078cdf0e10cSrcweir         InvalidatePreviousLoc();
1079cdf0e10cSrcweir }
1080cdf0e10cSrcweir 
1081cdf0e10cSrcweir //------------------------------------------------------------------------
1082cdf0e10cSrcweir IMPL_LINK(FmSearchEngine, OnSearchTerminated, FmSearchThread*, /*pThread*/)
1083cdf0e10cSrcweir {
1084cdf0e10cSrcweir     if (!m_aProgressHandler.IsSet())
1085cdf0e10cSrcweir         return 0L;
1086cdf0e10cSrcweir 
1087cdf0e10cSrcweir     FmSearchProgress aProgress;
1088cdf0e10cSrcweir     try
1089cdf0e10cSrcweir     {
1090cdf0e10cSrcweir         switch (m_srResult)
1091cdf0e10cSrcweir         {
1092cdf0e10cSrcweir             case SR_ERROR :
1093cdf0e10cSrcweir                 aProgress.aSearchState = FmSearchProgress::STATE_ERROR;
1094cdf0e10cSrcweir                 break;
1095cdf0e10cSrcweir             case SR_FOUND :
1096cdf0e10cSrcweir                 aProgress.aSearchState = FmSearchProgress::STATE_SUCCESSFULL;
1097cdf0e10cSrcweir                 aProgress.aBookmark = m_aPreviousLocBookmark;
1098cdf0e10cSrcweir                 aProgress.nFieldIndex = m_iterPreviousLocField - m_arrUsedFields.begin();
1099cdf0e10cSrcweir                 break;
1100cdf0e10cSrcweir             case SR_NOTFOUND :
1101cdf0e10cSrcweir                 aProgress.aSearchState = FmSearchProgress::STATE_NOTHINGFOUND;
1102cdf0e10cSrcweir                 aProgress.aBookmark = m_xSearchCursor.getBookmark();
1103cdf0e10cSrcweir                 break;
1104cdf0e10cSrcweir             case SR_CANCELED :
1105cdf0e10cSrcweir                 aProgress.aSearchState = FmSearchProgress::STATE_CANCELED;
1106cdf0e10cSrcweir                 aProgress.aBookmark = m_xSearchCursor.getBookmark();
1107cdf0e10cSrcweir                 break;
1108cdf0e10cSrcweir         }
1109cdf0e10cSrcweir         aProgress.nCurrentRecord = m_xSearchCursor.getRow() - 1;
1110cdf0e10cSrcweir     }
1111cdf0e10cSrcweir     catch( const Exception& )
1112cdf0e10cSrcweir     {
1113cdf0e10cSrcweir         DBG_UNHANDLED_EXCEPTION();
1114cdf0e10cSrcweir     }
1115cdf0e10cSrcweir 
1116cdf0e10cSrcweir     // per definitionem muss der Link Thread-sicher sein (das verlange ich einfach), so dass ich mich um so etwas hier nicht kuemmern muss
1117cdf0e10cSrcweir     m_aProgressHandler.Call(&aProgress);
1118cdf0e10cSrcweir 
1119cdf0e10cSrcweir     m_bSearchingCurrently = sal_False;
1120cdf0e10cSrcweir     return 0L;
1121cdf0e10cSrcweir }
1122cdf0e10cSrcweir 
1123cdf0e10cSrcweir //------------------------------------------------------------------------
IMPL_LINK(FmSearchEngine,OnNewRecordCount,void *,pCounterAsVoid)1124cdf0e10cSrcweir IMPL_LINK(FmSearchEngine, OnNewRecordCount, void*, pCounterAsVoid)
1125cdf0e10cSrcweir {
1126cdf0e10cSrcweir     if (!m_aProgressHandler.IsSet())
1127cdf0e10cSrcweir         return 0L;
1128cdf0e10cSrcweir 
1129cdf0e10cSrcweir     FmSearchProgress aProgress;
1130cdf0e10cSrcweir     aProgress.nCurrentRecord = (sal_uIntPtr)pCounterAsVoid;
1131cdf0e10cSrcweir     aProgress.aSearchState = FmSearchProgress::STATE_PROGRESS_COUNTING;
1132cdf0e10cSrcweir     m_aProgressHandler.Call(&aProgress);
1133cdf0e10cSrcweir 
1134cdf0e10cSrcweir     return 0L;
1135cdf0e10cSrcweir }
1136cdf0e10cSrcweir 
1137cdf0e10cSrcweir //------------------------------------------------------------------------
CancelRequested()1138cdf0e10cSrcweir sal_Bool FmSearchEngine::CancelRequested()
1139cdf0e10cSrcweir {
1140cdf0e10cSrcweir     m_aCancelAsynchAccess.acquire();
1141cdf0e10cSrcweir     sal_Bool bReturn = m_bCancelAsynchRequest;
1142cdf0e10cSrcweir     m_aCancelAsynchAccess.release();
1143cdf0e10cSrcweir     return bReturn;
1144cdf0e10cSrcweir }
1145cdf0e10cSrcweir 
1146cdf0e10cSrcweir //------------------------------------------------------------------------
CancelSearch()1147cdf0e10cSrcweir void FmSearchEngine::CancelSearch()
1148cdf0e10cSrcweir {
1149cdf0e10cSrcweir     m_aCancelAsynchAccess.acquire();
1150cdf0e10cSrcweir     m_bCancelAsynchRequest = sal_True;
1151cdf0e10cSrcweir     m_aCancelAsynchAccess.release();
1152cdf0e10cSrcweir }
1153cdf0e10cSrcweir 
1154cdf0e10cSrcweir //------------------------------------------------------------------------
SwitchToContext(const Reference<::com::sun::star::sdbc::XResultSet> & xCursor,const::rtl::OUString & sVisibleFields,const InterfaceArray & arrFields,sal_Int32 nFieldIndex)1155cdf0e10cSrcweir sal_Bool FmSearchEngine::SwitchToContext(const Reference< ::com::sun::star::sdbc::XResultSet > & xCursor, const ::rtl::OUString& sVisibleFields, const InterfaceArray& arrFields,
1156cdf0e10cSrcweir     sal_Int32 nFieldIndex)
1157cdf0e10cSrcweir {
1158cdf0e10cSrcweir     DBG_ASSERT(!m_bSearchingCurrently, "FmSearchEngine::SwitchToContext : please do not call while I'm searching !");
1159cdf0e10cSrcweir     if (m_bSearchingCurrently)
1160cdf0e10cSrcweir         return sal_False;
1161cdf0e10cSrcweir 
1162cdf0e10cSrcweir     m_xSearchCursor = xCursor;
1163cdf0e10cSrcweir     m_xOriginalIterator = xCursor;
1164cdf0e10cSrcweir     m_xClonedIterator = CursorWrapper(m_xOriginalIterator, sal_True);
1165cdf0e10cSrcweir     m_bUsingTextComponents = sal_True;
1166cdf0e10cSrcweir 
1167cdf0e10cSrcweir     fillControlTexts(arrFields);
1168cdf0e10cSrcweir 
1169cdf0e10cSrcweir     Init(sVisibleFields);
1170cdf0e10cSrcweir     RebuildUsedFields(nFieldIndex, sal_True);
1171cdf0e10cSrcweir 
1172cdf0e10cSrcweir     return sal_True;
1173cdf0e10cSrcweir }
1174cdf0e10cSrcweir 
1175cdf0e10cSrcweir //------------------------------------------------------------------------
ImplStartNextSearch()1176cdf0e10cSrcweir void FmSearchEngine::ImplStartNextSearch()
1177cdf0e10cSrcweir {
1178cdf0e10cSrcweir     m_bCancelAsynchRequest = sal_False;
1179cdf0e10cSrcweir     m_bSearchingCurrently = sal_True;
1180cdf0e10cSrcweir 
1181cdf0e10cSrcweir     if (m_eMode == SM_USETHREAD)//CHINA001 if (m_eMode == FmSearchDialog::SM_USETHREAD)
1182cdf0e10cSrcweir     {
1183cdf0e10cSrcweir         FmSearchThread* pSearcher = new FmSearchThread(this);
1184cdf0e10cSrcweir             // der loescht sich nach Beendigung selber ...
1185cdf0e10cSrcweir         pSearcher->setTerminationHandler(LINK(this, FmSearchEngine, OnSearchTerminated));
1186cdf0e10cSrcweir 
1187cdf0e10cSrcweir         pSearcher->createSuspended();
1188cdf0e10cSrcweir         pSearcher->setPriority(::vos::OThread::TPriority_Lowest);
1189cdf0e10cSrcweir         pSearcher->resume();
1190cdf0e10cSrcweir     }
1191cdf0e10cSrcweir     else
1192cdf0e10cSrcweir     {
1193cdf0e10cSrcweir         SearchNextImpl();
1194cdf0e10cSrcweir         LINK(this, FmSearchEngine, OnSearchTerminated).Call(NULL);
1195cdf0e10cSrcweir     }
1196cdf0e10cSrcweir }
1197cdf0e10cSrcweir 
1198cdf0e10cSrcweir //------------------------------------------------------------------------
SearchNext(const::rtl::OUString & strExpression)1199cdf0e10cSrcweir void FmSearchEngine::SearchNext(const ::rtl::OUString& strExpression)
1200cdf0e10cSrcweir {
1201cdf0e10cSrcweir     m_strSearchExpression = strExpression;
1202cdf0e10cSrcweir     m_eSearchForType = SEARCHFOR_STRING;
1203cdf0e10cSrcweir     ImplStartNextSearch();
1204cdf0e10cSrcweir }
1205cdf0e10cSrcweir 
1206cdf0e10cSrcweir //------------------------------------------------------------------------
SearchNextSpecial(sal_Bool _bSearchForNull)1207cdf0e10cSrcweir void FmSearchEngine::SearchNextSpecial(sal_Bool _bSearchForNull)
1208cdf0e10cSrcweir {
1209cdf0e10cSrcweir     m_eSearchForType = _bSearchForNull ? SEARCHFOR_NULL : SEARCHFOR_NOTNULL;
1210cdf0e10cSrcweir     ImplStartNextSearch();
1211cdf0e10cSrcweir }
1212cdf0e10cSrcweir 
1213cdf0e10cSrcweir //------------------------------------------------------------------------
StartOver(const::rtl::OUString & strExpression)1214cdf0e10cSrcweir void FmSearchEngine::StartOver(const ::rtl::OUString& strExpression)
1215cdf0e10cSrcweir {
1216cdf0e10cSrcweir     try
1217cdf0e10cSrcweir     {
1218cdf0e10cSrcweir         if (m_bForward)
1219cdf0e10cSrcweir             m_xSearchCursor.first();
1220cdf0e10cSrcweir         else
1221cdf0e10cSrcweir             m_xSearchCursor.last();
1222cdf0e10cSrcweir     }
1223cdf0e10cSrcweir     catch( const Exception& )
1224cdf0e10cSrcweir     {
1225cdf0e10cSrcweir         DBG_UNHANDLED_EXCEPTION();
1226cdf0e10cSrcweir         return;
1227cdf0e10cSrcweir     }
1228cdf0e10cSrcweir 
1229cdf0e10cSrcweir     InvalidatePreviousLoc();
1230cdf0e10cSrcweir     SearchNext(strExpression);
1231cdf0e10cSrcweir }
1232cdf0e10cSrcweir 
1233cdf0e10cSrcweir //------------------------------------------------------------------------
StartOverSpecial(sal_Bool _bSearchForNull)1234cdf0e10cSrcweir void FmSearchEngine::StartOverSpecial(sal_Bool _bSearchForNull)
1235cdf0e10cSrcweir {
1236cdf0e10cSrcweir     try
1237cdf0e10cSrcweir     {
1238cdf0e10cSrcweir         if (m_bForward)
1239cdf0e10cSrcweir             m_xSearchCursor.first();
1240cdf0e10cSrcweir         else
1241cdf0e10cSrcweir             m_xSearchCursor.last();
1242cdf0e10cSrcweir     }
1243cdf0e10cSrcweir     catch( const Exception& )
1244cdf0e10cSrcweir     {
1245cdf0e10cSrcweir         DBG_UNHANDLED_EXCEPTION();
1246cdf0e10cSrcweir         return;
1247cdf0e10cSrcweir     }
1248cdf0e10cSrcweir 
1249cdf0e10cSrcweir     InvalidatePreviousLoc();
1250cdf0e10cSrcweir     SearchNextSpecial(_bSearchForNull);
1251cdf0e10cSrcweir }
1252cdf0e10cSrcweir 
1253cdf0e10cSrcweir //------------------------------------------------------------------------
InvalidatePreviousLoc()1254cdf0e10cSrcweir void FmSearchEngine::InvalidatePreviousLoc()
1255cdf0e10cSrcweir {
1256cdf0e10cSrcweir     m_aPreviousLocBookmark.setValue(0,getVoidCppuType());
1257cdf0e10cSrcweir     m_iterPreviousLocField = m_arrUsedFields.end();
1258cdf0e10cSrcweir }
1259cdf0e10cSrcweir 
1260cdf0e10cSrcweir //------------------------------------------------------------------------
RebuildUsedFields(sal_Int32 nFieldIndex,sal_Bool bForce)1261cdf0e10cSrcweir void FmSearchEngine::RebuildUsedFields(sal_Int32 nFieldIndex, sal_Bool bForce)
1262cdf0e10cSrcweir {
1263cdf0e10cSrcweir     if (!bForce && (nFieldIndex == m_nCurrentFieldIndex))
1264cdf0e10cSrcweir         return;
1265cdf0e10cSrcweir     // (da ich keinen Wechsel des Iterators von aussen zulasse, heisst selber ::com::sun::star::sdbcx::Index auch immer selbe Spalte, also habe ich nix zu tun)
1266cdf0e10cSrcweir 
1267cdf0e10cSrcweir     DBG_ASSERT((nFieldIndex == -1) ||
1268cdf0e10cSrcweir                ((nFieldIndex >= 0) &&
1269cdf0e10cSrcweir                 (static_cast<size_t>(nFieldIndex) < m_arrFieldMapping.size())),
1270cdf0e10cSrcweir             "FmSearchEngine::RebuildUsedFields : nFieldIndex is invalid!");
1271cdf0e10cSrcweir     // alle Felder, die ich durchsuchen muss, einsammeln
1272cdf0e10cSrcweir     m_arrUsedFields.clear();
1273cdf0e10cSrcweir     if (nFieldIndex == -1)
1274cdf0e10cSrcweir     {
1275cdf0e10cSrcweir         Reference< ::com::sun::star::container::XIndexAccess >  xFields;
1276cdf0e10cSrcweir         for (size_t i=0; i<m_arrFieldMapping.size(); ++i)
1277cdf0e10cSrcweir         {
1278cdf0e10cSrcweir             Reference< ::com::sun::star::sdbcx::XColumnsSupplier >  xSupplyCols(IFACECAST(m_xSearchCursor), UNO_QUERY);
1279cdf0e10cSrcweir             DBG_ASSERT(xSupplyCols.is(), "FmSearchEngine::RebuildUsedFields : invalid cursor (no columns supplier) !");
1280cdf0e10cSrcweir             xFields = Reference< ::com::sun::star::container::XIndexAccess > (xSupplyCols->getColumns(), UNO_QUERY);
1281cdf0e10cSrcweir             BuildAndInsertFieldInfo(xFields, m_arrFieldMapping[i]);
1282cdf0e10cSrcweir         }
1283cdf0e10cSrcweir     }
1284cdf0e10cSrcweir     else
1285cdf0e10cSrcweir     {
1286cdf0e10cSrcweir         Reference< ::com::sun::star::container::XIndexAccess >  xFields;
1287cdf0e10cSrcweir         Reference< ::com::sun::star::sdbcx::XColumnsSupplier >  xSupplyCols(IFACECAST(m_xSearchCursor), UNO_QUERY);
1288cdf0e10cSrcweir         DBG_ASSERT(xSupplyCols.is(), "FmSearchEngine::RebuildUsedFields : invalid cursor (no columns supplier) !");
1289cdf0e10cSrcweir         xFields = Reference< ::com::sun::star::container::XIndexAccess > (xSupplyCols->getColumns(), UNO_QUERY);
1290cdf0e10cSrcweir         BuildAndInsertFieldInfo(xFields, m_arrFieldMapping[static_cast< size_t >(nFieldIndex)]);
1291cdf0e10cSrcweir     }
1292cdf0e10cSrcweir 
1293cdf0e10cSrcweir     m_nCurrentFieldIndex = nFieldIndex;
1294cdf0e10cSrcweir     // und natuerlich beginne ich die naechste Suche wieder jungfraeulich
1295cdf0e10cSrcweir     InvalidatePreviousLoc();
1296cdf0e10cSrcweir }
1297cdf0e10cSrcweir 
1298