bump product version to 4.2.0.1
[LibreOffice.git] / include / svx / fmsrcimp.hxx
blobb1f26b684e73590bf802322fc7a21b11f59446f6
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #ifndef INCLUDED_SVX_FMSRCIMP_HXX
21 #define INCLUDED_SVX_FMSRCIMP_HXX
23 #include <svx/fmtools.hxx>
24 #include <svx/svxdllapi.h>
26 #include <com/sun/star/awt/XCheckBox.hpp>
27 #include <com/sun/star/awt/XListBox.hpp>
28 #include <com/sun/star/awt/XTextComponent.hpp>
29 #include <com/sun/star/util/XNumberFormatsSupplier.hpp>
30 #include <com/sun/star/util/XNumberFormatter.hpp>
32 #include <comphelper/stl_types.hxx>
33 #include <cppuhelper/implbase1.hxx>
34 #include <osl/mutex.hxx>
35 #include <unotools/charclass.hxx>
36 #include <unotools/collatorwrapper.hxx>
37 #include <osl/thread.hxx>
39 #include <deque>
41 /**
42 * class FmSearchThread
44 class FmSearchEngine;
45 class FmSearchThread : public ::osl::Thread
47 FmSearchEngine* m_pEngine;
48 Link m_aTerminationHdl;
50 virtual void SAL_CALL run();
51 virtual void SAL_CALL onTerminated();
53 public:
54 FmSearchThread(FmSearchEngine* pEngine) : m_pEngine(pEngine) { }
55 void setTerminationHandler(Link aHdl) { m_aTerminationHdl = aHdl; }
58 /**
59 * struct FmSearchProgress - the owner of SearchEngine receives this structure for status updates
60 * (at the end of the search)
62 struct FmSearchProgress
64 enum STATE { STATE_PROGRESS, STATE_PROGRESS_COUNTING, STATE_CANCELED, STATE_SUCCESSFULL, STATE_NOTHINGFOUND, STATE_ERROR };
65 // (move to new record; progress during counting of records; cancelled; record found; nothing found;
66 // any non-processable error)
67 STATE aSearchState;
69 // current record - always valid (e.g. of interest for continuing search in case of cancellation)
70 sal_uInt32 nCurrentRecord;
71 // Overflow - only valid in case of STATE_PROGRESS
72 sal_Bool bOverflow;
74 // the position of the search cursor - valid in case of STATE_SUCCESSFULL, STATE_CANCELED and STATE_NOTHING_FOUND
75 ::com::sun::star::uno::Any aBookmark;
76 // the field, in which the text was found - valid in case of STATE_SUCCESSFULL
77 sal_Int32 nFieldIndex;
80 /**
81 * class FmRecordCountListener - utility class for FmSearchEngine, listens at a certain cursor and provides
82 * the differences in RecordCount
84 class FmRecordCountListener : public ::cppu::WeakImplHelper1< ::com::sun::star::beans::XPropertyChangeListener>
86 // attribute
87 Link m_lnkWhoWantsToKnow;
88 ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySet > m_xListening;
90 // attribute access
91 public:
92 Link SetPropChangeHandler(const Link& lnk);
94 // methods
95 public:
96 FmRecordCountListener(const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XResultSet >& dbcCursor);
97 // the set has to support the sdb::ResultSet service
98 virtual ~FmRecordCountListener();
100 // DECLARE_UNO3_AGG_DEFAULTS(FmPropertyListener, UsrObject);
101 // virtual sal_Bool queryInterface(::com::sun::star::uno::Uik aUik, ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& rOut);
103 // ::com::sun::star::lang::XEventListener
104 virtual void SAL_CALL disposing(const ::com::sun::star::lang::EventObject& Source) throw(::com::sun::star::uno::RuntimeException);
106 // ::com::sun::star::beans::XPropertyChangeListener
107 virtual void SAL_CALL propertyChange(const ::com::sun::star::beans::PropertyChangeEvent& evt) throw(::com::sun::star::uno::RuntimeException);
109 void DisConnect();
111 private:
112 void NotifyCurrentCount();
117 * class FmSearchEngine - Impl class for FmSearchDialog
119 namespace svxform {
120 // We have three possible control types we may search in, determined by the supported interfaces : ::com::sun::star::awt::XTextComponent,
121 // ::com::sun::star::awt::XListBox, ::com::sun::star::awt::XCheckBox.
122 // While searching we don't want to do this distinction for every control in every round. So we need some helpers.
123 class ControlTextWrapper
125 // attributes
126 ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > m_xControl;
127 // attribute access
128 public:
129 ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > getControl() const{ return m_xControl; }
130 public:
131 ControlTextWrapper(const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface >& _xControl) { m_xControl = _xControl; }
132 virtual ~ControlTextWrapper() { }
134 virtual OUString getCurrentText() const = 0;
136 class SimpleTextWrapper : public ControlTextWrapper
138 ::com::sun::star::uno::Reference< ::com::sun::star::awt::XTextComponent > m_xText;
139 public:
140 SimpleTextWrapper(const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XTextComponent >& _xText);
141 virtual OUString getCurrentText() const;
143 class ListBoxWrapper : public ControlTextWrapper
145 ::com::sun::star::uno::Reference< ::com::sun::star::awt::XListBox > m_xBox;
146 public:
147 ListBoxWrapper(const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XListBox >& _xBox);
148 virtual OUString getCurrentText() const;
150 class CheckBoxWrapper : public ControlTextWrapper
152 ::com::sun::star::uno::Reference< ::com::sun::star::awt::XCheckBox > m_xBox;
153 public:
154 CheckBoxWrapper(const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XCheckBox >& _xBox);
155 virtual OUString getCurrentText() const;
159 enum FMSEARCH_MODE { SM_BRUTE, SM_ALLOWSCHEDULE, SM_USETHREAD };
161 DECLARE_STL_VECTOR( ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface>, InterfaceArray);
163 class SVX_DLLPUBLIC FmSearchEngine
165 friend class FmSearchThread;
167 enum SEARCH_RESULT { SR_FOUND, SR_NOTFOUND, SR_ERROR, SR_CANCELED };
168 enum SEARCHFOR_TYPE { SEARCHFOR_STRING, SEARCHFOR_NULL, SEARCHFOR_NOTNULL };
170 CursorWrapper m_xSearchCursor;
171 std::deque<sal_Int32> m_arrFieldMapping;
172 // Since the iterator could have more columns, as managed here (in this field listbox),
173 // a mapping of this ::com::sun::star::form keys on the indices of the respective columns is kept in the iterator
175 // the formatter
176 ::com::sun::star::uno::Reference< ::com::sun::star::util::XNumberFormatsSupplier > m_xFormatSupplier;
177 ::com::sun::star::uno::Reference< ::com::sun::star::util::XNumberFormatter > m_xFormatter;
179 CharClass m_aCharacterClassficator;
180 CollatorWrapper m_aStringCompare;
182 // the collection of all interesting fields (or their ::com::sun::star::data::XDatabaseVariant interfaces and FormatKeys)
183 struct FieldInfo
185 ::com::sun::star::uno::Reference< ::com::sun::star::sdb::XColumn > xContents;
186 sal_uInt32 nFormatKey;
187 sal_Bool bDoubleHandling;
190 DECLARE_STL_VECTOR(FieldInfo, FieldCollection);
191 FieldCollection m_arrUsedFields;
192 sal_Int32 m_nCurrentFieldIndex; // the last parameter of RebuildUsedFields, it allows checks in FormatField
194 DECLARE_STL_VECTOR(svxform::ControlTextWrapper*, ControlTextSuppliers);
195 ControlTextSuppliers m_aControlTexts;
197 sal_Bool m_bUsingTextComponents;
198 CursorWrapper m_xOriginalIterator;
199 CursorWrapper m_xClonedIterator;
201 // Data for the decision in which field a "Found" is accepted
202 ::com::sun::star::uno::Any m_aPreviousLocBookmark; // position of the last finding
203 FieldCollectionIterator m_iterPreviousLocField; // field of the last finding
205 // Communication with the thread that does the actual searching
206 OUString m_strSearchExpression; // forward direction
207 SEARCHFOR_TYPE m_eSearchForType; // ditto
208 SEARCH_RESULT m_srResult; // backward direction
210 // The link we broadcast the progress and the result to
211 Link m_aProgressHandler;
212 sal_Bool m_bSearchingCurrently : 1; // is an (asynchronous) search running?
213 sal_Bool m_bCancelAsynchRequest : 1; // should be cancelled?
214 ::osl::Mutex m_aCancelAsynchAccess; // access to_bCancelAsynchRequest (technically only
215 // relevant for m_eMode == SM_USETHREAD)
216 FMSEARCH_MODE m_eMode; // current mode
218 // parameters for the search
219 sal_Bool m_bFormatter : 1; // use field formatting
220 sal_Bool m_bForward : 1; // direction
221 sal_Bool m_bWildcard : 1; // wildcard search
222 sal_Bool m_bRegular : 1; // regular expression
223 sal_Bool m_bLevenshtein : 1; // Levenshtein search
224 sal_Bool m_bTransliteration : 1; // Levenshtein search
226 sal_Bool m_bLevRelaxed : 1; // parameters for Levenshtein search
227 sal_uInt16 m_nLevOther;
228 sal_uInt16 m_nLevShorter;
229 sal_uInt16 m_nLevLonger;
231 sal_uInt16 m_nPosition; // if not regular or levenshtein, then one of the MATCHING_... values
233 sal_Int32 m_nTransliterationFlags;
235 // -------------
236 // member access
237 private:
238 SVX_DLLPRIVATE sal_Bool CancelRequested(); // provides a through m_aCancelAsynchAccess backed interpretation of m_bCancelAsynchRequest
240 public:
241 void SetCaseSensitive(sal_Bool bSet);
242 sal_Bool GetCaseSensitive() const;
244 void SetFormatterUsing(sal_Bool bSet); // this is somewhat more extensive, so no inline ... here
245 sal_Bool GetFormatterUsing() const { return m_bFormatter; }
247 void SetDirection(sal_Bool bForward) { m_bForward = bForward; }
248 sal_Bool GetDirection() const { return m_bForward; }
250 void SetWildcard(sal_Bool bSet) { m_bWildcard = bSet; }
251 sal_Bool GetWildcard() const { return m_bWildcard; }
253 void SetRegular(sal_Bool bSet) { m_bRegular = bSet; }
254 sal_Bool GetRegular() const { return m_bRegular; }
256 void SetLevenshtein(sal_Bool bSet) { m_bLevenshtein = bSet; }
257 sal_Bool GetLevenshtein() const { return m_bLevenshtein; }
259 void SetIgnoreWidthCJK(sal_Bool bSet);
260 sal_Bool GetIgnoreWidthCJK() const;
262 void SetTransliteration(sal_Bool bSet) { m_bTransliteration = bSet; }
263 sal_Bool GetTransliteration() const { return m_bTransliteration; }
265 void SetLevRelaxed(sal_Bool bSet) { m_bLevRelaxed = bSet; }
266 sal_Bool GetLevRelaxed() const { return m_bLevRelaxed; }
267 void SetLevOther(sal_uInt16 nHowMuch) { m_nLevOther = nHowMuch; }
268 sal_uInt16 GetLevOther() const { return m_nLevOther; }
269 void SetLevShorter(sal_uInt16 nHowMuch) { m_nLevShorter = nHowMuch; }
270 sal_uInt16 GetLevShorter() const { return m_nLevShorter; }
271 void SetLevLonger(sal_uInt16 nHowMuch) { m_nLevLonger = nHowMuch; }
272 sal_uInt16 GetLevLonger() const { return m_nLevLonger; }
273 // all Lev. values will only be considered in case of m_bLevenshtein==sal_True
275 void SetTransliterationFlags(sal_Int32 _nFlags) { m_nTransliterationFlags = _nFlags; }
276 sal_Int32 GetTransliterationFlags() const { return m_nTransliterationFlags; }
278 void SetPosition(sal_uInt16 nValue) { m_nPosition = nValue; }
279 sal_uInt16 GetPosition() const { return m_nPosition; }
280 // position will be ignored in case of m_bWildCard==sal_True
282 FMSEARCH_MODE GetSearchMode() const { return m_eMode; }
284 public:
285 /** two constructs, both analogical to FmSearchDialog, therefore look this up for explanations ....
286 xCursor has to implement ::com::sun::star::data::DatabaseCursor service each time.
287 If eMode == SM_USETHREAD, a ProgressHandler should be set, because in this case the result forwarding will be done
288 by this handler.
289 If eMode != SM_USETHREAD, SearchNext and StarOver won't return, until the search has finished (independently of its
290 success), only then the result can be requested. If additionally the ProgressHandler is set, it will be called for
291 every record as well as at the end of the search.
293 FmSearchEngine(
294 const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >& _rxContext,
295 const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XResultSet >& xCursor,
296 const OUString& strVisibleFields,
297 const ::com::sun::star::uno::Reference< ::com::sun::star::util::XNumberFormatsSupplier >& xFormat,
298 FMSEARCH_MODE eMode);
299 FmSearchEngine(
300 const ::com::sun::star::uno::Reference< ::com::sun::star::uno::XComponentContext >& _rxContext,
301 const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XResultSet >& xCursor,
302 const OUString& strVisibleFields,
303 const InterfaceArray& arrFields,
304 FMSEARCH_MODE eMode);
306 virtual ~FmSearchEngine();
308 /** the link will be called on every record and after the completion of the search, the parameter is a pointer to
309 a FmSearchProgress structure
310 the handler should be in any case thread-safe
312 void SetProgressHandler(Link aHdl) { m_aProgressHandler = aHdl; }
314 /// search for the next appearance (for nDirection values check DIRECTION_*-defines)
315 void SearchNext(const OUString& strExpression);
316 /// analogous, search for "NULL" (_bSearchForNull==sal_True) or "not NULL"
317 void SearchNextSpecial(sal_Bool _bSearchForNull);
318 /// search for the next appearance, dependent on nDirection from the start or end
319 void StartOver(const OUString& strExpression);
320 /// analogous, search for "NULL" (_bSearchForNull==sal_True) or "not NULL"
321 void StartOverSpecial(sal_Bool _bSearchForNull);
322 /// invalidate previous search reference
323 void InvalidatePreviousLoc();
325 /** rebuilds m_arrUsedFields (nFieldIndex==-1 means all fields, otherwise it specifies the field index)
326 if bForce is not set, nothing will happen in case of nFieldIndex == m_nCurrentFieldIndex
327 (calls InvalidatePreviousLoc)
329 void RebuildUsedFields(sal_Int32 nFieldIndex, sal_Bool bForce = sal_False);
330 OUString FormatField(sal_Int32 nWhich);
332 /// returns directly; once it was really aborted, ProgressHandler is called with STATE_CANCELED
333 void CancelSearch();
335 /** only valid, if not an (asynchronous) search is running, the next search will then be executed
336 on top of the new iterator with the new parameter
338 sal_Bool SwitchToContext(const ::com::sun::star::uno::Reference< ::com::sun::star::sdbc::XResultSet >& xCursor, const OUString& strVisibleFields, const InterfaceArray& arrFields,
339 sal_Int32 nFieldIndex);
341 protected:
342 void Init(const OUString& strVisibleFields);
344 void SearchNextImpl();
345 // this Impl method is running in SearchThread
347 // start a thread-search (or call SearchNextImpl directly, depending on the search mode)
348 void ImplStartNextSearch();
350 private:
351 SVX_DLLPRIVATE void clearControlTexts();
352 SVX_DLLPRIVATE void fillControlTexts(const InterfaceArray& arrFields);
354 // three methods implementing a complete search loop (null/not null, wildcard, SearchText)
355 // (they all have some code in common, but with this solution we have do do a distinction only once per search (before
356 // starting the loop), not in every loop step
357 SVX_DLLPRIVATE SEARCH_RESULT SearchSpecial(sal_Bool _bSearchForNull, sal_Int32& nFieldPos, FieldCollectionIterator& iterFieldLoop,
358 const FieldCollectionIterator& iterBegin, const FieldCollectionIterator& iterEnd);
359 SVX_DLLPRIVATE SEARCH_RESULT SearchWildcard(const OUString& strExpression, sal_Int32& nFieldPos, FieldCollectionIterator& iterFieldLoop,
360 const FieldCollectionIterator& iterBegin, const FieldCollectionIterator& iterEnd);
361 SVX_DLLPRIVATE SEARCH_RESULT SearchRegularApprox(const OUString& strExpression, sal_Int32& nFieldPos, FieldCollectionIterator& iterFieldLoop,
362 const FieldCollectionIterator& iterBegin, const FieldCollectionIterator& iterEnd);
364 SVX_DLLPRIVATE void PropagateProgress(sal_Bool _bDontPropagateOverflow);
365 // call the ProgressHandler with STATE_PROGRESS and the current position of the search iterator
367 // helpers, that are needed several times
368 SVX_DLLPRIVATE sal_Bool MoveCursor();
369 // moves m_xSearchIterator with respect to direction/overflow cursor
370 SVX_DLLPRIVATE sal_Bool MoveField(sal_Int32& nPos, FieldCollectionIterator& iter, const FieldCollectionIterator& iterBegin, const FieldCollectionIterator& iterEnd);
371 // moves the iterator with respect to the direction/overflow iterator/overflow cursor
372 SVX_DLLPRIVATE void BuildAndInsertFieldInfo(const ::com::sun::star::uno::Reference< ::com::sun::star::container::XIndexAccess >& xAllFields, sal_Int32 nField);
373 // builds a FieldInfo in relation to field number nField (in xAllFields) and adds it to m_arrUsedFields
374 // xAllFields needs to support the DatabaseRecord service
375 SVX_DLLPRIVATE OUString FormatField(const FieldInfo& rField);
376 // formats the field with the NumberFormatter
378 SVX_DLLPRIVATE sal_Bool HasPreviousLoc() { return m_aPreviousLocBookmark.hasValue(); }
380 DECL_LINK(OnSearchTerminated, FmSearchThread*);
381 // is used by SearchThread, after the return from this handler the thread removes itself
382 DECL_LINK(OnNewRecordCount, void*);
385 #endif // INCLUDED_SVX_FMSRCIMP_HXX
387 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */