LCOV - code coverage report
Current view: top level - svx/source/form - fmsrcimp.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 0 526 0.0 %
Date: 2012-08-25 Functions: 0 52 0.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 850 0.0 %

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

Generated by: LCOV version 1.10