xref: /aoo41x/main/svx/source/form/filtnav.cxx (revision f6e50924)
1*f6e50924SAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3*f6e50924SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*f6e50924SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*f6e50924SAndrew Rist  * distributed with this work for additional information
6*f6e50924SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*f6e50924SAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*f6e50924SAndrew Rist  * "License"); you may not use this file except in compliance
9*f6e50924SAndrew Rist  * with the License.  You may obtain a copy of the License at
10*f6e50924SAndrew Rist  *
11*f6e50924SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12*f6e50924SAndrew Rist  *
13*f6e50924SAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*f6e50924SAndrew Rist  * software distributed under the License is distributed on an
15*f6e50924SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*f6e50924SAndrew Rist  * KIND, either express or implied.  See the License for the
17*f6e50924SAndrew Rist  * specific language governing permissions and limitations
18*f6e50924SAndrew Rist  * under the License.
19*f6e50924SAndrew Rist  *
20*f6e50924SAndrew Rist  *************************************************************/
21*f6e50924SAndrew Rist 
22*f6e50924SAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_svx.hxx"
26cdf0e10cSrcweir 
27cdf0e10cSrcweir 
28cdf0e10cSrcweir #include "filtnav.hxx"
29cdf0e10cSrcweir #include "fmexch.hxx"
30cdf0e10cSrcweir #include "fmhelp.hrc"
31cdf0e10cSrcweir #include "fmitems.hxx"
32cdf0e10cSrcweir #include "fmprop.hrc"
33cdf0e10cSrcweir #include "svx/fmresids.hrc"
34cdf0e10cSrcweir #include "gridcell.hxx"
35cdf0e10cSrcweir 
36cdf0e10cSrcweir /** === begin UNO includes === **/
37cdf0e10cSrcweir #include <com/sun/star/form/runtime/XFormController.hpp>
38cdf0e10cSrcweir #include <com/sun/star/lang/XUnoTunnel.hpp>
39cdf0e10cSrcweir #include <com/sun/star/util/XNumberFormatter.hpp>
40cdf0e10cSrcweir /** === end UNO includes === **/
41cdf0e10cSrcweir 
42cdf0e10cSrcweir #include <comphelper/processfactory.hxx>
43cdf0e10cSrcweir #include <svx/fmtools.hxx>
44cdf0e10cSrcweir #include <comphelper/property.hxx>
45cdf0e10cSrcweir #include <comphelper/sequence.hxx>
46cdf0e10cSrcweir #include <comphelper/uno3.hxx>
47cdf0e10cSrcweir #include <connectivity/dbtools.hxx>
48cdf0e10cSrcweir #include <cppuhelper/implbase1.hxx>
49cdf0e10cSrcweir #include <fmservs.hxx>
50cdf0e10cSrcweir #include <fmshimp.hxx>
51cdf0e10cSrcweir #include <rtl/logfile.hxx>
52cdf0e10cSrcweir #include <sfx2/dispatch.hxx>
53cdf0e10cSrcweir #include <sfx2/objitem.hxx>
54cdf0e10cSrcweir #include <sfx2/objsh.hxx>
55cdf0e10cSrcweir #include <sfx2/request.hxx>
56cdf0e10cSrcweir #include <svx/dialmgr.hxx>
57cdf0e10cSrcweir #include <svx/fmshell.hxx>
58cdf0e10cSrcweir #include <svx/svxids.hrc>
59cdf0e10cSrcweir #include <tools/shl.hxx>
60cdf0e10cSrcweir #include <vcl/wrkwin.hxx>
61cdf0e10cSrcweir 
62cdf0e10cSrcweir #include <functional>
63cdf0e10cSrcweir 
64cdf0e10cSrcweir #define SYNC_DELAY						200
65cdf0e10cSrcweir #define DROP_ACTION_TIMER_INITIAL_TICKS 	10
66cdf0e10cSrcweir 	// solange dauert es, bis das Scrollen anspringt
67cdf0e10cSrcweir #define DROP_ACTION_TIMER_SCROLL_TICKS		3
68cdf0e10cSrcweir 	// in diesen Intervallen wird jeweils eine Zeile gescrollt
69cdf0e10cSrcweir #define DROP_ACTION_TIMER_TICK_BASE 		10
70cdf0e10cSrcweir 	// das ist die Basis, mit der beide Angaben multipliziert werden (in ms)
71cdf0e10cSrcweir 
72cdf0e10cSrcweir using namespace ::svxform;
73cdf0e10cSrcweir using namespace ::connectivity::simple;
74cdf0e10cSrcweir using namespace ::connectivity;
75cdf0e10cSrcweir 
76cdf0e10cSrcweir 
77cdf0e10cSrcweir //........................................................................
78cdf0e10cSrcweir namespace svxform
79cdf0e10cSrcweir {
80cdf0e10cSrcweir //........................................................................
81cdf0e10cSrcweir 
82cdf0e10cSrcweir     /** === begin UNO using === **/
83cdf0e10cSrcweir     using ::com::sun::star::uno::Reference;
84cdf0e10cSrcweir     using ::com::sun::star::lang::XMultiServiceFactory;
85cdf0e10cSrcweir     using ::com::sun::star::awt::TextEvent;
86cdf0e10cSrcweir     using ::com::sun::star::container::XIndexAccess;
87cdf0e10cSrcweir     using ::com::sun::star::uno::UNO_QUERY;
88cdf0e10cSrcweir     using ::com::sun::star::beans::XPropertySet;
89cdf0e10cSrcweir     using ::com::sun::star::form::runtime::XFormController;
90cdf0e10cSrcweir     using ::com::sun::star::form::runtime::XFilterController;
91cdf0e10cSrcweir     using ::com::sun::star::form::runtime::XFilterControllerListener;
92cdf0e10cSrcweir     using ::com::sun::star::form::runtime::FilterEvent;
93cdf0e10cSrcweir     using ::com::sun::star::lang::EventObject;
94cdf0e10cSrcweir     using ::com::sun::star::uno::RuntimeException;
95cdf0e10cSrcweir     using ::com::sun::star::form::XForm;
96cdf0e10cSrcweir     using ::com::sun::star::container::XChild;
97cdf0e10cSrcweir     using ::com::sun::star::awt::XControl;
98cdf0e10cSrcweir     using ::com::sun::star::sdbc::XConnection;
99cdf0e10cSrcweir     using ::com::sun::star::util::XNumberFormatsSupplier;
100cdf0e10cSrcweir     using ::com::sun::star::beans::XPropertySet;
101cdf0e10cSrcweir     using ::com::sun::star::util::XNumberFormatter;
102cdf0e10cSrcweir     using ::com::sun::star::sdbc::XRowSet;
103cdf0e10cSrcweir     using ::com::sun::star::lang::Locale;
104cdf0e10cSrcweir     using ::com::sun::star::sdb::SQLContext;
105cdf0e10cSrcweir     using ::com::sun::star::uno::XInterface;
106cdf0e10cSrcweir     using ::com::sun::star::uno::UNO_QUERY_THROW;
107cdf0e10cSrcweir     using ::com::sun::star::uno::UNO_SET_THROW;
108cdf0e10cSrcweir     using ::com::sun::star::uno::Exception;
109cdf0e10cSrcweir     using ::com::sun::star::awt::XTextComponent;
110cdf0e10cSrcweir     using ::com::sun::star::uno::Sequence;
111cdf0e10cSrcweir     /** === end UNO using === **/
112cdf0e10cSrcweir 
113cdf0e10cSrcweir //========================================================================
114cdf0e10cSrcweir OFilterItemExchange::OFilterItemExchange()
115cdf0e10cSrcweir {
116cdf0e10cSrcweir }
117cdf0e10cSrcweir 
118cdf0e10cSrcweir //------------------------------------------------------------------------
119cdf0e10cSrcweir void OFilterItemExchange::AddSupportedFormats()
120cdf0e10cSrcweir {
121cdf0e10cSrcweir 	AddFormat(getFormatId());
122cdf0e10cSrcweir }
123cdf0e10cSrcweir 
124cdf0e10cSrcweir //------------------------------------------------------------------------
125cdf0e10cSrcweir sal_uInt32 OFilterItemExchange::getFormatId()
126cdf0e10cSrcweir {
127cdf0e10cSrcweir 	static sal_uInt32 s_nFormat = (sal_uInt32)-1;
128cdf0e10cSrcweir 	if ((sal_uInt32)-1 == s_nFormat)
129cdf0e10cSrcweir 	{
130cdf0e10cSrcweir 		s_nFormat = SotExchange::RegisterFormatName(String::CreateFromAscii("application/x-openoffice;windows_formatname=\"form.FilterControlExchange\""));
131cdf0e10cSrcweir 		DBG_ASSERT((sal_uInt32)-1 != s_nFormat, "OFilterExchangeHelper::getFormatId: bad exchange id!");
132cdf0e10cSrcweir 	}
133cdf0e10cSrcweir 	return s_nFormat;
134cdf0e10cSrcweir }
135cdf0e10cSrcweir 
136cdf0e10cSrcweir //------------------------------------------------------------------------
137cdf0e10cSrcweir OLocalExchange* OFilterExchangeHelper::createExchange() const
138cdf0e10cSrcweir {
139cdf0e10cSrcweir 	return new OFilterItemExchange;
140cdf0e10cSrcweir }
141cdf0e10cSrcweir 
142cdf0e10cSrcweir //========================================================================
143cdf0e10cSrcweir TYPEINIT0(FmFilterData);
144cdf0e10cSrcweir Image FmFilterData::GetImage( BmpColorMode /*_eMode*/ ) const
145cdf0e10cSrcweir {
146cdf0e10cSrcweir 	return Image();
147cdf0e10cSrcweir }
148cdf0e10cSrcweir 
149cdf0e10cSrcweir //========================================================================
150cdf0e10cSrcweir TYPEINIT1(FmParentData, FmFilterData);
151cdf0e10cSrcweir //------------------------------------------------------------------------
152cdf0e10cSrcweir FmParentData::~FmParentData()
153cdf0e10cSrcweir {
154cdf0e10cSrcweir 	for (::std::vector<FmFilterData*>::const_iterator i = m_aChildren.begin();
155cdf0e10cSrcweir 		 i != m_aChildren.end(); i++)
156cdf0e10cSrcweir 		delete (*i);
157cdf0e10cSrcweir }
158cdf0e10cSrcweir 
159cdf0e10cSrcweir //========================================================================
160cdf0e10cSrcweir TYPEINIT1(FmFormItem, FmParentData);
161cdf0e10cSrcweir //------------------------------------------------------------------------
162cdf0e10cSrcweir Image FmFormItem::GetImage( BmpColorMode _eMode ) const
163cdf0e10cSrcweir {
164cdf0e10cSrcweir 	static Image aImage;
165cdf0e10cSrcweir 	static Image aImage_HC;
166cdf0e10cSrcweir 
167cdf0e10cSrcweir 	if (!aImage)
168cdf0e10cSrcweir 	{
169cdf0e10cSrcweir 		ImageList aNavigatorImages( SVX_RES( RID_SVXIMGLIST_FMEXPL ) );
170cdf0e10cSrcweir 		ImageList aNavigatorImages_HC( SVX_RES( RID_SVXIMGLIST_FMEXPL_HC ) );
171cdf0e10cSrcweir 
172cdf0e10cSrcweir 		aImage = aNavigatorImages.GetImage( RID_SVXIMG_FORM );
173cdf0e10cSrcweir 		aImage_HC = aNavigatorImages_HC.GetImage( RID_SVXIMG_FORM );
174cdf0e10cSrcweir 	}
175cdf0e10cSrcweir 	return ( BMP_COLOR_HIGHCONTRAST == _eMode ) ? aImage_HC : aImage;
176cdf0e10cSrcweir }
177cdf0e10cSrcweir 
178cdf0e10cSrcweir //========================================================================
179cdf0e10cSrcweir TYPEINIT1(FmFilterItems, FmParentData);
180cdf0e10cSrcweir //------------------------------------------------------------------------
181cdf0e10cSrcweir FmFilterItem* FmFilterItems::Find( const ::sal_Int32 _nFilterComponentIndex ) const
182cdf0e10cSrcweir {
183cdf0e10cSrcweir 	for (   ::std::vector< FmFilterData* >::const_iterator i = m_aChildren.begin();
184cdf0e10cSrcweir 		    i != m_aChildren.end();
185cdf0e10cSrcweir             ++i
186cdf0e10cSrcweir         )
187cdf0e10cSrcweir 	{
188cdf0e10cSrcweir 		FmFilterItem* pCondition = PTR_CAST( FmFilterItem, *i );
189cdf0e10cSrcweir         DBG_ASSERT( pCondition, "FmFilterItems::Find: Wrong element in container!" );
190cdf0e10cSrcweir 		if ( _nFilterComponentIndex == pCondition->GetComponentIndex() )
191cdf0e10cSrcweir 			return pCondition;
192cdf0e10cSrcweir 	}
193cdf0e10cSrcweir 	return NULL;
194cdf0e10cSrcweir }
195cdf0e10cSrcweir 
196cdf0e10cSrcweir //------------------------------------------------------------------------
197cdf0e10cSrcweir Image FmFilterItems::GetImage( BmpColorMode _eMode ) const
198cdf0e10cSrcweir {
199cdf0e10cSrcweir 	static Image aImage;
200cdf0e10cSrcweir 	static Image aImage_HC;
201cdf0e10cSrcweir 
202cdf0e10cSrcweir 	if (!aImage)
203cdf0e10cSrcweir 	{
204cdf0e10cSrcweir 		ImageList aNavigatorImages( SVX_RES( RID_SVXIMGLIST_FMEXPL ) );
205cdf0e10cSrcweir 		ImageList aNavigatorImages_HC( SVX_RES( RID_SVXIMGLIST_FMEXPL_HC ) );
206cdf0e10cSrcweir 
207cdf0e10cSrcweir 		aImage = aNavigatorImages.GetImage( RID_SVXIMG_FILTER );
208cdf0e10cSrcweir 		aImage_HC = aNavigatorImages_HC.GetImage( RID_SVXIMG_FILTER );
209cdf0e10cSrcweir 	}
210cdf0e10cSrcweir 	return ( BMP_COLOR_HIGHCONTRAST == _eMode ) ? aImage_HC : aImage;
211cdf0e10cSrcweir }
212cdf0e10cSrcweir 
213cdf0e10cSrcweir //========================================================================
214cdf0e10cSrcweir TYPEINIT1(FmFilterItem, FmFilterData);
215cdf0e10cSrcweir //------------------------------------------------------------------------
216cdf0e10cSrcweir FmFilterItem::FmFilterItem( const Reference< XMultiServiceFactory >& _rxFactory,
217cdf0e10cSrcweir 						    FmFilterItems* pParent,
218cdf0e10cSrcweir 					        const ::rtl::OUString& aFieldName,
219cdf0e10cSrcweir 					        const ::rtl::OUString& aText,
220cdf0e10cSrcweir 					        const sal_Int32 _nComponentIndex )
221cdf0e10cSrcweir 		  :FmFilterData(_rxFactory,pParent, aText)
222cdf0e10cSrcweir 		  ,m_aFieldName(aFieldName)
223cdf0e10cSrcweir 		  ,m_nComponentIndex( _nComponentIndex )
224cdf0e10cSrcweir {
225cdf0e10cSrcweir }
226cdf0e10cSrcweir 
227cdf0e10cSrcweir //------------------------------------------------------------------------
228cdf0e10cSrcweir Image FmFilterItem::GetImage( BmpColorMode _eMode ) const
229cdf0e10cSrcweir {
230cdf0e10cSrcweir 	static Image aImage;
231cdf0e10cSrcweir 	static Image aImage_HC;
232cdf0e10cSrcweir 
233cdf0e10cSrcweir 	if (!aImage)
234cdf0e10cSrcweir 	{
235cdf0e10cSrcweir 		ImageList aNavigatorImages( SVX_RES( RID_SVXIMGLIST_FMEXPL ) );
236cdf0e10cSrcweir 		ImageList aNavigatorImages_HC( SVX_RES( RID_SVXIMGLIST_FMEXPL_HC ) );
237cdf0e10cSrcweir 
238cdf0e10cSrcweir 		aImage = aNavigatorImages.GetImage( RID_SVXIMG_FIELD );
239cdf0e10cSrcweir 		aImage_HC = aNavigatorImages_HC.GetImage( RID_SVXIMG_FIELD );
240cdf0e10cSrcweir 	}
241cdf0e10cSrcweir 	return ( BMP_COLOR_HIGHCONTRAST == _eMode ) ? aImage_HC : aImage;
242cdf0e10cSrcweir }
243cdf0e10cSrcweir 
244cdf0e10cSrcweir //========================================================================
245cdf0e10cSrcweir // Hints for communicatition between model and view
246cdf0e10cSrcweir //========================================================================
247cdf0e10cSrcweir class FmFilterHint : public SfxHint
248cdf0e10cSrcweir {
249cdf0e10cSrcweir 	FmFilterData*	m_pData;
250cdf0e10cSrcweir 
251cdf0e10cSrcweir public:
252cdf0e10cSrcweir 	TYPEINFO();
253cdf0e10cSrcweir 	FmFilterHint(FmFilterData* pData):m_pData(pData){}
254cdf0e10cSrcweir 	FmFilterData* GetData() const { return m_pData; }
255cdf0e10cSrcweir };
256cdf0e10cSrcweir TYPEINIT1( FmFilterHint, SfxHint );
257cdf0e10cSrcweir 
258cdf0e10cSrcweir //========================================================================
259cdf0e10cSrcweir class FmFilterInsertedHint : public FmFilterHint
260cdf0e10cSrcweir {
261cdf0e10cSrcweir 	sal_Int32 m_nPos;	// Position relative to the parent of the data
262cdf0e10cSrcweir 
263cdf0e10cSrcweir public:
264cdf0e10cSrcweir 	TYPEINFO();
265cdf0e10cSrcweir 	FmFilterInsertedHint(FmFilterData* pData, sal_Int32 nRelPos)
266cdf0e10cSrcweir 		:FmFilterHint(pData)
267cdf0e10cSrcweir 		,m_nPos(nRelPos){}
268cdf0e10cSrcweir 
269cdf0e10cSrcweir 	sal_Int32 GetPos() const { return m_nPos; }
270cdf0e10cSrcweir };
271cdf0e10cSrcweir TYPEINIT1( FmFilterInsertedHint, FmFilterHint );
272cdf0e10cSrcweir 
273cdf0e10cSrcweir //========================================================================
274cdf0e10cSrcweir class FmFilterRemovedHint : public FmFilterHint
275cdf0e10cSrcweir {
276cdf0e10cSrcweir public:
277cdf0e10cSrcweir 	TYPEINFO();
278cdf0e10cSrcweir 	FmFilterRemovedHint(FmFilterData* pData)
279cdf0e10cSrcweir 		:FmFilterHint(pData){}
280cdf0e10cSrcweir 
281cdf0e10cSrcweir };
282cdf0e10cSrcweir TYPEINIT1( FmFilterRemovedHint, FmFilterHint );
283cdf0e10cSrcweir 
284cdf0e10cSrcweir //========================================================================
285cdf0e10cSrcweir class FmFilterTextChangedHint : public FmFilterHint
286cdf0e10cSrcweir {
287cdf0e10cSrcweir public:
288cdf0e10cSrcweir 	TYPEINFO();
289cdf0e10cSrcweir 	FmFilterTextChangedHint(FmFilterData* pData)
290cdf0e10cSrcweir 		:FmFilterHint(pData){}
291cdf0e10cSrcweir 
292cdf0e10cSrcweir };
293cdf0e10cSrcweir TYPEINIT1( FmFilterTextChangedHint, FmFilterHint );
294cdf0e10cSrcweir 
295cdf0e10cSrcweir //========================================================================
296cdf0e10cSrcweir class FilterClearingHint : public SfxHint
297cdf0e10cSrcweir {
298cdf0e10cSrcweir public:
299cdf0e10cSrcweir 	TYPEINFO();
300cdf0e10cSrcweir 	FilterClearingHint(){}
301cdf0e10cSrcweir };
302cdf0e10cSrcweir TYPEINIT1( FilterClearingHint, SfxHint );
303cdf0e10cSrcweir 
304cdf0e10cSrcweir //========================================================================
305cdf0e10cSrcweir class FmFilterCurrentChangedHint : public SfxHint
306cdf0e10cSrcweir {
307cdf0e10cSrcweir public:
308cdf0e10cSrcweir 	TYPEINFO();
309cdf0e10cSrcweir 	FmFilterCurrentChangedHint(){}
310cdf0e10cSrcweir };
311cdf0e10cSrcweir TYPEINIT1( FmFilterCurrentChangedHint, SfxHint );
312cdf0e10cSrcweir 
313cdf0e10cSrcweir //========================================================================
314cdf0e10cSrcweir // class FmFilterAdapter, Listener an den FilterControls
315cdf0e10cSrcweir //========================================================================
316cdf0e10cSrcweir class FmFilterAdapter : public ::cppu::WeakImplHelper1< XFilterControllerListener >
317cdf0e10cSrcweir {
318cdf0e10cSrcweir 	FmFilterModel*			    m_pModel;
319cdf0e10cSrcweir     Reference< XIndexAccess >   m_xControllers;
320cdf0e10cSrcweir 
321cdf0e10cSrcweir public:
322cdf0e10cSrcweir 	FmFilterAdapter(FmFilterModel* pModel, const Reference< XIndexAccess >& xControllers);
323cdf0e10cSrcweir 
324cdf0e10cSrcweir // XEventListener
325cdf0e10cSrcweir 	virtual void SAL_CALL disposing(const EventObject& Source) throw( RuntimeException );
326cdf0e10cSrcweir 
327cdf0e10cSrcweir // XFilterControllerListener
328cdf0e10cSrcweir     virtual void SAL_CALL predicateExpressionChanged( const FilterEvent& _Event ) throw (RuntimeException);
329cdf0e10cSrcweir     virtual void SAL_CALL disjunctiveTermRemoved( const FilterEvent& _Event ) throw (RuntimeException);
330cdf0e10cSrcweir     virtual void SAL_CALL disjunctiveTermAdded( const FilterEvent& _Event ) throw (RuntimeException);
331cdf0e10cSrcweir 
332cdf0e10cSrcweir // helpers
333cdf0e10cSrcweir 	void dispose() throw( RuntimeException );
334cdf0e10cSrcweir 
335cdf0e10cSrcweir 	void AddOrRemoveListener( const Reference< XIndexAccess >& _rxControllers, const bool _bAdd );
336cdf0e10cSrcweir 
337cdf0e10cSrcweir 	void setText(sal_Int32 nPos,
338cdf0e10cSrcweir 		const FmFilterItem* pFilterItem,
339cdf0e10cSrcweir 		const ::rtl::OUString& rText);
340cdf0e10cSrcweir };
341cdf0e10cSrcweir 
342cdf0e10cSrcweir //------------------------------------------------------------------------
343cdf0e10cSrcweir FmFilterAdapter::FmFilterAdapter(FmFilterModel* pModel, const Reference< XIndexAccess >& xControllers)
344cdf0e10cSrcweir     :m_pModel( pModel )
345cdf0e10cSrcweir     ,m_xControllers( xControllers )
346cdf0e10cSrcweir {
347cdf0e10cSrcweir     AddOrRemoveListener( m_xControllers, true );
348cdf0e10cSrcweir }
349cdf0e10cSrcweir 
350cdf0e10cSrcweir //------------------------------------------------------------------------
351cdf0e10cSrcweir void FmFilterAdapter::dispose() throw( RuntimeException )
352cdf0e10cSrcweir {
353cdf0e10cSrcweir     AddOrRemoveListener( m_xControllers, false );
354cdf0e10cSrcweir }
355cdf0e10cSrcweir 
356cdf0e10cSrcweir //------------------------------------------------------------------------
357cdf0e10cSrcweir void FmFilterAdapter::AddOrRemoveListener( const Reference< XIndexAccess >& _rxControllers, const bool _bAdd )
358cdf0e10cSrcweir {
359cdf0e10cSrcweir 	for (sal_Int32 i = 0, nLen = _rxControllers->getCount(); i < nLen; ++i)
360cdf0e10cSrcweir 	{
361cdf0e10cSrcweir 		Reference< XIndexAccess > xElement( _rxControllers->getByIndex(i), UNO_QUERY );
362cdf0e10cSrcweir 
363cdf0e10cSrcweir 		// step down
364cdf0e10cSrcweir 		AddOrRemoveListener( xElement, _bAdd );
365cdf0e10cSrcweir 
366cdf0e10cSrcweir         // handle this particular controller
367cdf0e10cSrcweir         Reference< XFilterController > xController( xElement, UNO_QUERY );
368cdf0e10cSrcweir         OSL_ENSURE( xController.is(), "FmFilterAdapter::InsertElements: no XFilterController, cannot sync data!" );
369cdf0e10cSrcweir         if ( xController.is() )
370cdf0e10cSrcweir         {
371cdf0e10cSrcweir             if ( _bAdd )
372cdf0e10cSrcweir                 xController->addFilterControllerListener( this );
373cdf0e10cSrcweir             else
374cdf0e10cSrcweir                 xController->removeFilterControllerListener( this );
375cdf0e10cSrcweir         }
376cdf0e10cSrcweir 	}
377cdf0e10cSrcweir }
378cdf0e10cSrcweir 
379cdf0e10cSrcweir //------------------------------------------------------------------------
380cdf0e10cSrcweir void FmFilterAdapter::setText(sal_Int32 nRowPos,
381cdf0e10cSrcweir 							  const FmFilterItem* pFilterItem,
382cdf0e10cSrcweir 							  const ::rtl::OUString& rText)
383cdf0e10cSrcweir {
384cdf0e10cSrcweir 	FmFormItem* pFormItem = PTR_CAST( FmFormItem, pFilterItem->GetParent()->GetParent() );
385cdf0e10cSrcweir 
386cdf0e10cSrcweir     try
387cdf0e10cSrcweir     {
388cdf0e10cSrcweir         Reference< XFilterController > xController( pFormItem->GetController(), UNO_QUERY_THROW );
389cdf0e10cSrcweir         xController->setPredicateExpression( pFilterItem->GetComponentIndex(), nRowPos, rText );
390cdf0e10cSrcweir     }
391cdf0e10cSrcweir     catch( const Exception& )
392cdf0e10cSrcweir     {
393cdf0e10cSrcweir     	DBG_UNHANDLED_EXCEPTION();
394cdf0e10cSrcweir     }
395cdf0e10cSrcweir }
396cdf0e10cSrcweir 
397cdf0e10cSrcweir 
398cdf0e10cSrcweir // XEventListener
399cdf0e10cSrcweir //------------------------------------------------------------------------
400cdf0e10cSrcweir void SAL_CALL FmFilterAdapter::disposing(const EventObject& /*e*/) throw( RuntimeException )
401cdf0e10cSrcweir {
402cdf0e10cSrcweir }
403cdf0e10cSrcweir 
404cdf0e10cSrcweir //------------------------------------------------------------------------
405cdf0e10cSrcweir namespace
406cdf0e10cSrcweir {
407cdf0e10cSrcweir     ::rtl::OUString lcl_getLabelName_nothrow( const Reference< XControl >& _rxControl )
408cdf0e10cSrcweir     {
409cdf0e10cSrcweir         ::rtl::OUString sLabelName;
410cdf0e10cSrcweir         try
411cdf0e10cSrcweir         {
412cdf0e10cSrcweir             Reference< XControl > xControl( _rxControl, UNO_SET_THROW );
413cdf0e10cSrcweir             Reference< XPropertySet > xModel( xControl->getModel(), UNO_QUERY_THROW );
414cdf0e10cSrcweir             sLabelName = getLabelName( xModel );
415cdf0e10cSrcweir         }
416cdf0e10cSrcweir         catch( const Exception& )
417cdf0e10cSrcweir         {
418cdf0e10cSrcweir         	DBG_UNHANDLED_EXCEPTION();
419cdf0e10cSrcweir         }
420cdf0e10cSrcweir         return sLabelName;
421cdf0e10cSrcweir     }
422cdf0e10cSrcweir 
423cdf0e10cSrcweir     Reference< XPropertySet > lcl_getBoundField_nothrow( const Reference< XControl >& _rxControl )
424cdf0e10cSrcweir     {
425cdf0e10cSrcweir         Reference< XPropertySet > xField;
426cdf0e10cSrcweir         try
427cdf0e10cSrcweir         {
428cdf0e10cSrcweir             Reference< XControl > xControl( _rxControl, UNO_SET_THROW );
429cdf0e10cSrcweir             Reference< XPropertySet > xModelProps( xControl->getModel(), UNO_QUERY_THROW );
430cdf0e10cSrcweir             xField.set( xModelProps->getPropertyValue( FM_PROP_BOUNDFIELD ), UNO_QUERY_THROW );
431cdf0e10cSrcweir         }
432cdf0e10cSrcweir         catch( const Exception& )
433cdf0e10cSrcweir         {
434cdf0e10cSrcweir         	DBG_UNHANDLED_EXCEPTION();
435cdf0e10cSrcweir         }
436cdf0e10cSrcweir         return xField;
437cdf0e10cSrcweir     }
438cdf0e10cSrcweir }
439cdf0e10cSrcweir 
440cdf0e10cSrcweir // XFilterControllerListener
441cdf0e10cSrcweir //------------------------------------------------------------------------
442cdf0e10cSrcweir void FmFilterAdapter::predicateExpressionChanged( const FilterEvent& _Event ) throw( RuntimeException )
443cdf0e10cSrcweir {
444cdf0e10cSrcweir     ::vos::OGuard aGuard( Application::GetSolarMutex() );
445cdf0e10cSrcweir 
446cdf0e10cSrcweir     if ( !m_pModel )
447cdf0e10cSrcweir         return;
448cdf0e10cSrcweir 
449cdf0e10cSrcweir     // the controller which sent the event
450cdf0e10cSrcweir     Reference< XFormController > xController( _Event.Source, UNO_QUERY_THROW );
451cdf0e10cSrcweir     Reference< XFilterController > xFilterController( _Event.Source, UNO_QUERY_THROW );
452cdf0e10cSrcweir     Reference< XForm > xForm( xController->getModel(), UNO_QUERY_THROW );
453cdf0e10cSrcweir 
454cdf0e10cSrcweir     FmFormItem* pFormItem = m_pModel->Find( m_pModel->m_aChildren, xForm );
455cdf0e10cSrcweir     OSL_ENSURE( pFormItem, "FmFilterAdapter::predicateExpressionChanged: don't know this form!" );
456cdf0e10cSrcweir     if ( !pFormItem )
457cdf0e10cSrcweir         return;
458cdf0e10cSrcweir 
459cdf0e10cSrcweir     const sal_Int32 nActiveTerm( xFilterController->getActiveTerm() );
460cdf0e10cSrcweir 
461cdf0e10cSrcweir 	FmFilterItems* pFilter = PTR_CAST( FmFilterItems, pFormItem->GetChildren()[ nActiveTerm ] );
462cdf0e10cSrcweir 	FmFilterItem* pFilterItem = pFilter->Find( _Event.FilterComponent );
463cdf0e10cSrcweir 	if ( pFilterItem )
464cdf0e10cSrcweir 	{
465cdf0e10cSrcweir 		if ( _Event.PredicateExpression.getLength())
466cdf0e10cSrcweir 		{
467cdf0e10cSrcweir 			pFilterItem->SetText( _Event.PredicateExpression );
468cdf0e10cSrcweir 			// UI benachrichtigen
469cdf0e10cSrcweir 			FmFilterTextChangedHint aChangeHint(pFilterItem);
470cdf0e10cSrcweir 			m_pModel->Broadcast( aChangeHint );
471cdf0e10cSrcweir 		}
472cdf0e10cSrcweir 		else
473cdf0e10cSrcweir 		{
474cdf0e10cSrcweir 			// no text anymore so remove the condition
475cdf0e10cSrcweir 			m_pModel->Remove(pFilterItem);
476cdf0e10cSrcweir 		}
477cdf0e10cSrcweir 	}
478cdf0e10cSrcweir 	else
479cdf0e10cSrcweir 	{
480cdf0e10cSrcweir 		// searching the component by field name
481cdf0e10cSrcweir 		::rtl::OUString aFieldName( lcl_getLabelName_nothrow( xFilterController->getFilterComponent( _Event.FilterComponent ) ) );
482cdf0e10cSrcweir 
483cdf0e10cSrcweir 		pFilterItem = new FmFilterItem( m_pModel->getORB(), pFilter, aFieldName, _Event.PredicateExpression, _Event.FilterComponent );
484cdf0e10cSrcweir 		m_pModel->Insert(pFilter->GetChildren().end(), pFilterItem);
485cdf0e10cSrcweir 	}
486cdf0e10cSrcweir 
487cdf0e10cSrcweir     // ensure there's one empty term in the filter, just in case the active term was previously empty
488cdf0e10cSrcweir     m_pModel->EnsureEmptyFilterRows( *pFormItem );
489cdf0e10cSrcweir }
490cdf0e10cSrcweir 
491cdf0e10cSrcweir //------------------------------------------------------------------------
492cdf0e10cSrcweir void SAL_CALL FmFilterAdapter::disjunctiveTermRemoved( const FilterEvent& _Event ) throw (RuntimeException)
493cdf0e10cSrcweir {
494cdf0e10cSrcweir     ::vos::OGuard aGuard( Application::GetSolarMutex() );
495cdf0e10cSrcweir 
496cdf0e10cSrcweir     Reference< XFormController > xController( _Event.Source, UNO_QUERY_THROW );
497cdf0e10cSrcweir     Reference< XFilterController > xFilterController( _Event.Source, UNO_QUERY_THROW );
498cdf0e10cSrcweir     Reference< XForm > xForm( xController->getModel(), UNO_QUERY_THROW );
499cdf0e10cSrcweir 
500cdf0e10cSrcweir     FmFormItem* pFormItem = m_pModel->Find( m_pModel->m_aChildren, xForm );
501cdf0e10cSrcweir     OSL_ENSURE( pFormItem, "FmFilterAdapter::disjunctiveTermRemoved: don't know this form!" );
502cdf0e10cSrcweir     if ( !pFormItem )
503cdf0e10cSrcweir         return;
504cdf0e10cSrcweir 
505cdf0e10cSrcweir 	::std::vector< FmFilterData* >& rTermItems = pFormItem->GetChildren();
506cdf0e10cSrcweir     const bool bValidIndex = ( _Event.DisjunctiveTerm >= 0 ) && ( (size_t)_Event.DisjunctiveTerm < rTermItems.size() );
507cdf0e10cSrcweir     OSL_ENSURE( bValidIndex, "FmFilterAdapter::disjunctiveTermRemoved: invalid term index!" );
508cdf0e10cSrcweir     if ( !bValidIndex )
509cdf0e10cSrcweir         return;
510cdf0e10cSrcweir 
511cdf0e10cSrcweir     // if the first term was removed, then the to-be first term needs its text updated
512cdf0e10cSrcweir     if ( _Event.DisjunctiveTerm == 0 )
513cdf0e10cSrcweir     {
514cdf0e10cSrcweir         rTermItems[1]->SetText( String( SVX_RES( RID_STR_FILTER_FILTER_FOR ) ) );
515cdf0e10cSrcweir         FmFilterTextChangedHint aChangeHint( rTermItems[1] );
516cdf0e10cSrcweir         m_pModel->Broadcast( aChangeHint );
517cdf0e10cSrcweir     }
518cdf0e10cSrcweir 
519cdf0e10cSrcweir     // finally remove the entry from the model
520cdf0e10cSrcweir     m_pModel->Remove( rTermItems.begin() + _Event.DisjunctiveTerm );
521cdf0e10cSrcweir 
522cdf0e10cSrcweir     // ensure there's one empty term in the filter, just in case the currently removed one was the last empty one
523cdf0e10cSrcweir     m_pModel->EnsureEmptyFilterRows( *pFormItem );
524cdf0e10cSrcweir }
525cdf0e10cSrcweir 
526cdf0e10cSrcweir //------------------------------------------------------------------------
527cdf0e10cSrcweir void SAL_CALL FmFilterAdapter::disjunctiveTermAdded( const FilterEvent& _Event ) throw (RuntimeException)
528cdf0e10cSrcweir {
529cdf0e10cSrcweir     ::vos::OGuard aGuard( Application::GetSolarMutex() );
530cdf0e10cSrcweir 
531cdf0e10cSrcweir     Reference< XFormController > xController( _Event.Source, UNO_QUERY_THROW );
532cdf0e10cSrcweir     Reference< XFilterController > xFilterController( _Event.Source, UNO_QUERY_THROW );
533cdf0e10cSrcweir     Reference< XForm > xForm( xController->getModel(), UNO_QUERY_THROW );
534cdf0e10cSrcweir 
535cdf0e10cSrcweir     FmFormItem* pFormItem = m_pModel->Find( m_pModel->m_aChildren, xForm );
536cdf0e10cSrcweir     OSL_ENSURE( pFormItem, "FmFilterAdapter::disjunctiveTermAdded: don't know this form!" );
537cdf0e10cSrcweir     if ( !pFormItem )
538cdf0e10cSrcweir         return;
539cdf0e10cSrcweir 
540cdf0e10cSrcweir     const sal_Int32 nInsertPos = _Event.DisjunctiveTerm;
541cdf0e10cSrcweir     bool bValidIndex = ( nInsertPos >= 0 ) && ( (size_t)nInsertPos <= pFormItem->GetChildren().size() );
542cdf0e10cSrcweir     if ( !bValidIndex )
543cdf0e10cSrcweir     {
544cdf0e10cSrcweir         OSL_ENSURE( false, "FmFilterAdapter::disjunctiveTermAdded: invalid index!" );
545cdf0e10cSrcweir         return;
546cdf0e10cSrcweir     }
547cdf0e10cSrcweir 
548cdf0e10cSrcweir     const ::std::vector< FmFilterData* >::iterator insertPos = pFormItem->GetChildren().begin() + nInsertPos;
549cdf0e10cSrcweir 
550cdf0e10cSrcweir     FmFilterItems* pFilterItems = new FmFilterItems( m_pModel->getORB(), pFormItem, String( SVX_RES( RID_STR_FILTER_FILTER_OR ) ) );
551cdf0e10cSrcweir     m_pModel->Insert( insertPos, pFilterItems );
552cdf0e10cSrcweir }
553cdf0e10cSrcweir 
554cdf0e10cSrcweir //========================================================================
555cdf0e10cSrcweir // class FmFilterModel
556cdf0e10cSrcweir //========================================================================
557cdf0e10cSrcweir TYPEINIT1(FmFilterModel, FmParentData);
558cdf0e10cSrcweir //------------------------------------------------------------------------
559cdf0e10cSrcweir FmFilterModel::FmFilterModel(const Reference< XMultiServiceFactory >& _rxFactory)
560cdf0e10cSrcweir 			  :FmParentData(_rxFactory,NULL, ::rtl::OUString())
561cdf0e10cSrcweir 			  ,OSQLParserClient(_rxFactory)
562cdf0e10cSrcweir 			  ,m_xORB(_rxFactory)
563cdf0e10cSrcweir 			  ,m_pAdapter(NULL)
564cdf0e10cSrcweir 			  ,m_pCurrentItems(NULL)
565cdf0e10cSrcweir {
566cdf0e10cSrcweir }
567cdf0e10cSrcweir 
568cdf0e10cSrcweir //------------------------------------------------------------------------
569cdf0e10cSrcweir FmFilterModel::~FmFilterModel()
570cdf0e10cSrcweir {
571cdf0e10cSrcweir 	Clear();
572cdf0e10cSrcweir }
573cdf0e10cSrcweir 
574cdf0e10cSrcweir //------------------------------------------------------------------------
575cdf0e10cSrcweir void FmFilterModel::Clear()
576cdf0e10cSrcweir {
577cdf0e10cSrcweir 	// notify
578cdf0e10cSrcweir 	FilterClearingHint aClearedHint;
579cdf0e10cSrcweir 	Broadcast( aClearedHint );
580cdf0e10cSrcweir 
581cdf0e10cSrcweir 	// loose endings
582cdf0e10cSrcweir 	if (m_pAdapter)
583cdf0e10cSrcweir 	{
584cdf0e10cSrcweir 		m_pAdapter->dispose();
585cdf0e10cSrcweir 		m_pAdapter->release();
586cdf0e10cSrcweir 		m_pAdapter= NULL;
587cdf0e10cSrcweir 	}
588cdf0e10cSrcweir 
589cdf0e10cSrcweir 	m_pCurrentItems  = NULL;
590cdf0e10cSrcweir 	m_xController	 = NULL;
591cdf0e10cSrcweir 	m_xControllers	 = NULL;
592cdf0e10cSrcweir 
593cdf0e10cSrcweir 	for (::std::vector<FmFilterData*>::const_iterator i = m_aChildren.begin();
594cdf0e10cSrcweir 		 i != m_aChildren.end(); i++)
595cdf0e10cSrcweir 		delete (*i);
596cdf0e10cSrcweir 
597cdf0e10cSrcweir 	m_aChildren.clear();
598cdf0e10cSrcweir }
599cdf0e10cSrcweir 
600cdf0e10cSrcweir //------------------------------------------------------------------------
601cdf0e10cSrcweir void FmFilterModel::Update(const Reference< XIndexAccess > & xControllers, const Reference< XFormController > & xCurrent)
602cdf0e10cSrcweir {
603cdf0e10cSrcweir 	if ( xCurrent == m_xController )
604cdf0e10cSrcweir 		return;
605cdf0e10cSrcweir 
606cdf0e10cSrcweir 	if (!xControllers.is())
607cdf0e10cSrcweir 	{
608cdf0e10cSrcweir 		Clear();
609cdf0e10cSrcweir 		return;
610cdf0e10cSrcweir 	}
611cdf0e10cSrcweir 
612cdf0e10cSrcweir 	// there is only a new current controller
613cdf0e10cSrcweir 	if ( m_xControllers != xControllers )
614cdf0e10cSrcweir 	{
615cdf0e10cSrcweir 		Clear();
616cdf0e10cSrcweir 
617cdf0e10cSrcweir 		m_xControllers = xControllers;
618cdf0e10cSrcweir 		Update(m_xControllers, this);
619cdf0e10cSrcweir 
620cdf0e10cSrcweir 		DBG_ASSERT(xCurrent.is(), "FmFilterModel::Update(...) no current controller");
621cdf0e10cSrcweir 
622cdf0e10cSrcweir 		// Listening for TextChanges
623cdf0e10cSrcweir 		m_pAdapter = new FmFilterAdapter(this, xControllers);
624cdf0e10cSrcweir 		m_pAdapter->acquire();
625cdf0e10cSrcweir 
626cdf0e10cSrcweir 		SetCurrentController(xCurrent);
627cdf0e10cSrcweir 		EnsureEmptyFilterRows( *this );
628cdf0e10cSrcweir 	}
629cdf0e10cSrcweir 	else
630cdf0e10cSrcweir 		SetCurrentController(xCurrent);
631cdf0e10cSrcweir }
632cdf0e10cSrcweir 
633cdf0e10cSrcweir //------------------------------------------------------------------------
634cdf0e10cSrcweir void FmFilterModel::Update(const Reference< XIndexAccess > & xControllers, FmParentData* pParent)
635cdf0e10cSrcweir {
636cdf0e10cSrcweir     try
637cdf0e10cSrcweir     {
638cdf0e10cSrcweir         sal_Int32 nCount = xControllers->getCount();
639cdf0e10cSrcweir         for ( sal_Int32 i = 0; i < nCount; ++i )
640cdf0e10cSrcweir         {
641cdf0e10cSrcweir             Reference< XFormController > xController( xControllers->getByIndex(i), UNO_QUERY_THROW );
642cdf0e10cSrcweir 
643cdf0e10cSrcweir             Reference< XPropertySet > xFormProperties( xController->getModel(), UNO_QUERY_THROW );
644cdf0e10cSrcweir             ::rtl::OUString aName;
645cdf0e10cSrcweir             OSL_VERIFY( xFormProperties->getPropertyValue( FM_PROP_NAME ) >>= aName );
646cdf0e10cSrcweir 
647cdf0e10cSrcweir             // Insert a new item for the form
648cdf0e10cSrcweir             FmFormItem* pFormItem = new FmFormItem( m_xORB, pParent, xController, aName );
649cdf0e10cSrcweir             Insert( pParent->GetChildren().end(), pFormItem );
650cdf0e10cSrcweir 
651cdf0e10cSrcweir             Reference< XFilterController > xFilterController( pFormItem->GetFilterController(), UNO_SET_THROW );
652cdf0e10cSrcweir 
653cdf0e10cSrcweir             // insert the existing filters for the form
654cdf0e10cSrcweir             String aTitle( SVX_RES( RID_STR_FILTER_FILTER_FOR ) );
655cdf0e10cSrcweir 
656cdf0e10cSrcweir             Sequence< Sequence< ::rtl::OUString > > aExpressions = xFilterController->getPredicateExpressions();
657cdf0e10cSrcweir             for (   const Sequence< ::rtl::OUString >* pConjunctionTerm = aExpressions.getConstArray();
658cdf0e10cSrcweir                     pConjunctionTerm != aExpressions.getConstArray() + aExpressions.getLength();
659cdf0e10cSrcweir                     ++pConjunctionTerm
660cdf0e10cSrcweir                 )
661cdf0e10cSrcweir             {
662cdf0e10cSrcweir                 // we always display one row, even if there's no term to be displayed
663cdf0e10cSrcweir                 FmFilterItems* pFilterItems = new FmFilterItems( m_xORB, pFormItem, aTitle );
664cdf0e10cSrcweir                 Insert( pFormItem->GetChildren().end(), pFilterItems );
665cdf0e10cSrcweir 
666cdf0e10cSrcweir                 const Sequence< ::rtl::OUString >& rDisjunction( *pConjunctionTerm );
667cdf0e10cSrcweir                 for (   const ::rtl::OUString* pDisjunctiveTerm = rDisjunction.getConstArray();
668cdf0e10cSrcweir                         pDisjunctiveTerm != rDisjunction.getConstArray() + rDisjunction.getLength();
669cdf0e10cSrcweir                         ++pDisjunctiveTerm
670cdf0e10cSrcweir                     )
671cdf0e10cSrcweir                 {
672cdf0e10cSrcweir                     if ( pDisjunctiveTerm->getLength() == 0 )
673cdf0e10cSrcweir                         // no condition for this particular component in this particular conjunction term
674cdf0e10cSrcweir                         continue;
675cdf0e10cSrcweir 
676cdf0e10cSrcweir                     const sal_Int32 nComponentIndex = pDisjunctiveTerm - rDisjunction.getConstArray();
677cdf0e10cSrcweir 
678cdf0e10cSrcweir                     // determine the display name of the control
679cdf0e10cSrcweir                     const Reference< XControl > xFilterControl( xFilterController->getFilterComponent( nComponentIndex ) );
680cdf0e10cSrcweir                     const ::rtl::OUString sDisplayName( lcl_getLabelName_nothrow( xFilterControl ) );
681cdf0e10cSrcweir 
682cdf0e10cSrcweir                     // insert a new entry
683cdf0e10cSrcweir                     FmFilterItem* pANDCondition = new FmFilterItem( m_xORB, pFilterItems, sDisplayName, *pDisjunctiveTerm, nComponentIndex );
684cdf0e10cSrcweir                     Insert( pFilterItems->GetChildren().end(), pANDCondition );
685cdf0e10cSrcweir                 }
686cdf0e10cSrcweir 
687cdf0e10cSrcweir                 // title for the next conditions
688cdf0e10cSrcweir                 aTitle = SVX_RES( RID_STR_FILTER_FILTER_OR );
689cdf0e10cSrcweir             }
690cdf0e10cSrcweir 
691cdf0e10cSrcweir             // now add dependent controllers
692cdf0e10cSrcweir             Reference< XIndexAccess > xControllerAsIndex( xController, UNO_QUERY );
693cdf0e10cSrcweir             Update( xControllerAsIndex, pFormItem );
694cdf0e10cSrcweir         }
695cdf0e10cSrcweir     }
696cdf0e10cSrcweir     catch( const Exception& )
697cdf0e10cSrcweir     {
698cdf0e10cSrcweir     	DBG_UNHANDLED_EXCEPTION();
699cdf0e10cSrcweir     }
700cdf0e10cSrcweir }
701cdf0e10cSrcweir 
702cdf0e10cSrcweir //------------------------------------------------------------------------
703cdf0e10cSrcweir FmFormItem* FmFilterModel::Find(const ::std::vector<FmFilterData*>& rItems, const Reference< XFormController > & xController) const
704cdf0e10cSrcweir {
705cdf0e10cSrcweir 	for (::std::vector<FmFilterData*>::const_iterator i = rItems.begin();
706cdf0e10cSrcweir 		 i != rItems.end(); i++)
707cdf0e10cSrcweir 	{
708cdf0e10cSrcweir 		FmFormItem* pForm = PTR_CAST(FmFormItem,*i);
709cdf0e10cSrcweir 		if (pForm)
710cdf0e10cSrcweir 		{
711cdf0e10cSrcweir 			if ( xController == pForm->GetController() )
712cdf0e10cSrcweir 				return pForm;
713cdf0e10cSrcweir 			else
714cdf0e10cSrcweir 			{
715cdf0e10cSrcweir 				pForm = Find(pForm->GetChildren(), xController);
716cdf0e10cSrcweir 				if (pForm)
717cdf0e10cSrcweir 					return pForm;
718cdf0e10cSrcweir 			}
719cdf0e10cSrcweir 		}
720cdf0e10cSrcweir 	}
721cdf0e10cSrcweir 	return NULL;
722cdf0e10cSrcweir }
723cdf0e10cSrcweir 
724cdf0e10cSrcweir //------------------------------------------------------------------------
725cdf0e10cSrcweir FmFormItem* FmFilterModel::Find(const ::std::vector<FmFilterData*>& rItems, const Reference< XForm >& xForm) const
726cdf0e10cSrcweir {
727cdf0e10cSrcweir 	for (::std::vector<FmFilterData*>::const_iterator i = rItems.begin();
728cdf0e10cSrcweir 		 i != rItems.end(); i++)
729cdf0e10cSrcweir 	{
730cdf0e10cSrcweir 		FmFormItem* pForm = PTR_CAST(FmFormItem,*i);
731cdf0e10cSrcweir 		if (pForm)
732cdf0e10cSrcweir 		{
733cdf0e10cSrcweir 			if (xForm == pForm->GetController()->getModel())
734cdf0e10cSrcweir 				return pForm;
735cdf0e10cSrcweir 			else
736cdf0e10cSrcweir 			{
737cdf0e10cSrcweir 				pForm = Find(pForm->GetChildren(), xForm);
738cdf0e10cSrcweir 				if (pForm)
739cdf0e10cSrcweir 					return pForm;
740cdf0e10cSrcweir 			}
741cdf0e10cSrcweir 		}
742cdf0e10cSrcweir 	}
743cdf0e10cSrcweir 	return NULL;
744cdf0e10cSrcweir }
745cdf0e10cSrcweir 
746cdf0e10cSrcweir //------------------------------------------------------------------------
747cdf0e10cSrcweir void FmFilterModel::SetCurrentController(const Reference< XFormController > & xCurrent)
748cdf0e10cSrcweir {
749cdf0e10cSrcweir 	if ( xCurrent == m_xController )
750cdf0e10cSrcweir 		return;
751cdf0e10cSrcweir 
752cdf0e10cSrcweir 	m_xController = xCurrent;
753cdf0e10cSrcweir 
754cdf0e10cSrcweir     FmFormItem* pItem = Find( m_aChildren, xCurrent );
755cdf0e10cSrcweir     if ( !pItem )
756cdf0e10cSrcweir         return;
757cdf0e10cSrcweir 
758cdf0e10cSrcweir     try
759cdf0e10cSrcweir     {
760cdf0e10cSrcweir         Reference< XFilterController > xFilterController( m_xController, UNO_QUERY_THROW );
761cdf0e10cSrcweir         const sal_Int32 nActiveTerm( xFilterController->getActiveTerm() );
762cdf0e10cSrcweir 	    if ( pItem->GetChildren().size() > (size_t)nActiveTerm )
763cdf0e10cSrcweir         {
764cdf0e10cSrcweir 		    SetCurrentItems( static_cast< FmFilterItems* >( pItem->GetChildren()[ nActiveTerm ] ) );
765cdf0e10cSrcweir         }
766cdf0e10cSrcweir     }
767cdf0e10cSrcweir     catch( const Exception& )
768cdf0e10cSrcweir     {
769cdf0e10cSrcweir     	DBG_UNHANDLED_EXCEPTION();
770cdf0e10cSrcweir     }
771cdf0e10cSrcweir }
772cdf0e10cSrcweir 
773cdf0e10cSrcweir //------------------------------------------------------------------------
774cdf0e10cSrcweir void FmFilterModel::AppendFilterItems( FmFormItem& _rFormItem )
775cdf0e10cSrcweir {
776cdf0e10cSrcweir 	// insert the condition behind the last filter items
777cdf0e10cSrcweir 	::std::vector<FmFilterData*>::reverse_iterator iter;
778cdf0e10cSrcweir     for (   iter = _rFormItem.GetChildren().rbegin();
779cdf0e10cSrcweir 		    iter != _rFormItem.GetChildren().rend();
780cdf0e10cSrcweir             ++iter
781cdf0e10cSrcweir         )
782cdf0e10cSrcweir 	{
783cdf0e10cSrcweir 		if ((*iter)->ISA(FmFilterItems))
784cdf0e10cSrcweir 			break;
785cdf0e10cSrcweir 	}
786cdf0e10cSrcweir 
787cdf0e10cSrcweir     sal_Int32 nInsertPos = iter.base() - _rFormItem.GetChildren().begin();
788cdf0e10cSrcweir 	// delegate this to the FilterController, it will notify us, which will let us update our model
789cdf0e10cSrcweir     try
790cdf0e10cSrcweir     {
791cdf0e10cSrcweir         Reference< XFilterController > xFilterController( _rFormItem.GetFilterController(), UNO_SET_THROW );
792cdf0e10cSrcweir         if ( nInsertPos >= xFilterController->getDisjunctiveTerms() )
793cdf0e10cSrcweir             xFilterController->appendEmptyDisjunctiveTerm();
794cdf0e10cSrcweir     }
795cdf0e10cSrcweir     catch( const Exception& )
796cdf0e10cSrcweir     {
797cdf0e10cSrcweir     	DBG_UNHANDLED_EXCEPTION();
798cdf0e10cSrcweir     }
799cdf0e10cSrcweir }
800cdf0e10cSrcweir 
801cdf0e10cSrcweir //------------------------------------------------------------------------
802cdf0e10cSrcweir void FmFilterModel::Insert(const ::std::vector<FmFilterData*>::iterator& rPos, FmFilterData* pData)
803cdf0e10cSrcweir {
804cdf0e10cSrcweir 	::std::vector<FmFilterData*>& rItems = pData->GetParent()->GetChildren();
805cdf0e10cSrcweir 	sal_Int32 nPos = rPos == rItems.end() ? LIST_APPEND : rPos - rItems.begin();
806cdf0e10cSrcweir 	rItems.insert(rPos, pData);
807cdf0e10cSrcweir 
808cdf0e10cSrcweir 	// UI benachrichtigen
809cdf0e10cSrcweir 	FmFilterInsertedHint aInsertedHint(pData, nPos);
810cdf0e10cSrcweir 	Broadcast( aInsertedHint );
811cdf0e10cSrcweir }
812cdf0e10cSrcweir 
813cdf0e10cSrcweir //------------------------------------------------------------------------
814cdf0e10cSrcweir void FmFilterModel::Remove(FmFilterData* pData)
815cdf0e10cSrcweir {
816cdf0e10cSrcweir 	FmParentData* pParent = pData->GetParent();
817cdf0e10cSrcweir 	::std::vector<FmFilterData*>& rItems = pParent->GetChildren();
818cdf0e10cSrcweir 
819cdf0e10cSrcweir 	// erase the item from the model
820cdf0e10cSrcweir 	::std::vector<FmFilterData*>::iterator i = ::std::find(rItems.begin(), rItems.end(), pData);
821cdf0e10cSrcweir 	DBG_ASSERT(i != rItems.end(), "FmFilterModel::Remove(): unknown Item");
822cdf0e10cSrcweir 	// position within the parent
823cdf0e10cSrcweir 	sal_Int32 nPos = i - rItems.begin();
824cdf0e10cSrcweir 	if (pData->ISA(FmFilterItems))
825cdf0e10cSrcweir 	{
826cdf0e10cSrcweir 		FmFormItem* pFormItem = (FmFormItem*)pParent;
827cdf0e10cSrcweir 
828cdf0e10cSrcweir         try
829cdf0e10cSrcweir         {
830cdf0e10cSrcweir             Reference< XFilterController > xFilterController( pFormItem->GetFilterController(), UNO_SET_THROW );
831cdf0e10cSrcweir 
832cdf0e10cSrcweir             bool bEmptyLastTerm = ( ( nPos == 0 ) && xFilterController->getDisjunctiveTerms() == 1 );
833cdf0e10cSrcweir             if ( bEmptyLastTerm )
834cdf0e10cSrcweir             {
835cdf0e10cSrcweir 			    // remove all children (by setting an empty predicate expression)
836cdf0e10cSrcweir 			    ::std::vector< FmFilterData* >& rChildren = ((FmFilterItems*)pData)->GetChildren();
837cdf0e10cSrcweir 			    while ( !rChildren.empty() )
838cdf0e10cSrcweir 			    {
839cdf0e10cSrcweir                     ::std::vector< FmFilterData* >::iterator removePos = rChildren.end() - 1;
840cdf0e10cSrcweir 				    FmFilterItem* pFilterItem = PTR_CAST( FmFilterItem, *removePos );
841cdf0e10cSrcweir 				    m_pAdapter->setText( nPos, pFilterItem, ::rtl::OUString() );
842cdf0e10cSrcweir 				    Remove( removePos );
843cdf0e10cSrcweir                 }
844cdf0e10cSrcweir             }
845cdf0e10cSrcweir             else
846cdf0e10cSrcweir             {
847cdf0e10cSrcweir                 xFilterController->removeDisjunctiveTerm( nPos );
848cdf0e10cSrcweir             }
849cdf0e10cSrcweir         }
850cdf0e10cSrcweir         catch( const Exception& )
851cdf0e10cSrcweir         {
852cdf0e10cSrcweir     	    DBG_UNHANDLED_EXCEPTION();
853cdf0e10cSrcweir         }
854cdf0e10cSrcweir 	}
855cdf0e10cSrcweir 	else // FormItems can not be deleted
856cdf0e10cSrcweir 	{
857cdf0e10cSrcweir 		FmFilterItem* pFilterItem = PTR_CAST(FmFilterItem, pData);
858cdf0e10cSrcweir 
859cdf0e10cSrcweir 		// if its the last condition remove the parent
860cdf0e10cSrcweir 		if (rItems.size() == 1)
861cdf0e10cSrcweir 			Remove(pFilterItem->GetParent());
862cdf0e10cSrcweir 		else
863cdf0e10cSrcweir 		{
864cdf0e10cSrcweir 			// find the position of the father within his father
865cdf0e10cSrcweir 			::std::vector<FmFilterData*>& rParentParentItems = pData->GetParent()->GetParent()->GetChildren();
866cdf0e10cSrcweir 			::std::vector<FmFilterData*>::iterator j = ::std::find(rParentParentItems.begin(), rParentParentItems.end(), pFilterItem->GetParent());
867cdf0e10cSrcweir 			DBG_ASSERT(j != rParentParentItems.end(), "FmFilterModel::Remove(): unknown Item");
868cdf0e10cSrcweir 			sal_Int32 nParentPos = j - rParentParentItems.begin();
869cdf0e10cSrcweir 
870cdf0e10cSrcweir 			// EmptyText removes the filter
871cdf0e10cSrcweir 			m_pAdapter->setText(nParentPos, pFilterItem, ::rtl::OUString());
872cdf0e10cSrcweir 			Remove( i );
873cdf0e10cSrcweir 		}
874cdf0e10cSrcweir 	}
875cdf0e10cSrcweir }
876cdf0e10cSrcweir 
877cdf0e10cSrcweir //------------------------------------------------------------------------
878cdf0e10cSrcweir void FmFilterModel::Remove( const ::std::vector<FmFilterData*>::iterator& rPos )
879cdf0e10cSrcweir {
880cdf0e10cSrcweir     // remove from parent's child list
881cdf0e10cSrcweir     FmFilterData* pData = *rPos;
882cdf0e10cSrcweir     pData->GetParent()->GetChildren().erase( rPos );
883cdf0e10cSrcweir 
884cdf0e10cSrcweir 	// notify the view, this will remove the actual SvLBoxEntry
885cdf0e10cSrcweir 	FmFilterRemovedHint aRemoveHint( pData );
886cdf0e10cSrcweir 	Broadcast( aRemoveHint );
887cdf0e10cSrcweir 
888cdf0e10cSrcweir 	delete pData;
889cdf0e10cSrcweir }
890cdf0e10cSrcweir 
891cdf0e10cSrcweir //------------------------------------------------------------------------
892cdf0e10cSrcweir sal_Bool FmFilterModel::ValidateText(FmFilterItem* pItem, UniString& rText, UniString& rErrorMsg) const
893cdf0e10cSrcweir {
894cdf0e10cSrcweir 	FmFormItem* pFormItem = PTR_CAST( FmFormItem, pItem->GetParent()->GetParent() );
895cdf0e10cSrcweir     try
896cdf0e10cSrcweir     {
897cdf0e10cSrcweir         Reference< XFormController > xFormController( pFormItem->GetController() );
898cdf0e10cSrcweir         // obtain the connection of the form belonging to the controller
899cdf0e10cSrcweir         OStaticDataAccessTools aStaticTools;
900cdf0e10cSrcweir         Reference< XRowSet > xRowSet( xFormController->getModel(), UNO_QUERY_THROW );
901cdf0e10cSrcweir         Reference< XConnection > xConnection( aStaticTools.getRowSetConnection( xRowSet ) );
902cdf0e10cSrcweir 
903cdf0e10cSrcweir         // obtain a number formatter for this connection
904cdf0e10cSrcweir         // TODO: shouldn't this be cached?
905cdf0e10cSrcweir         Reference< XNumberFormatsSupplier > xFormatSupplier = aStaticTools.getNumberFormats( xConnection, sal_True );
906cdf0e10cSrcweir         Reference< XNumberFormatter > xFormatter( m_xORB->createInstance( FM_NUMBER_FORMATTER ), UNO_QUERY );
907cdf0e10cSrcweir         xFormatter->attachNumberFormatsSupplier( xFormatSupplier );
908cdf0e10cSrcweir 
909cdf0e10cSrcweir         // get the field (database column) which the item is responsible for
910cdf0e10cSrcweir         Reference< XFilterController > xFilterController( xFormController, UNO_QUERY_THROW );
911cdf0e10cSrcweir         Reference< XPropertySet > xField( lcl_getBoundField_nothrow( xFilterController->getFilterComponent( pItem->GetComponentIndex() ) ), UNO_SET_THROW );
912cdf0e10cSrcweir 
913cdf0e10cSrcweir         // parse the given text as filter predicate
914cdf0e10cSrcweir         ::rtl::OUString aErr, aTxt( rText );
915cdf0e10cSrcweir         ::rtl::Reference< ISQLParseNode > xParseNode = predicateTree( aErr, aTxt, xFormatter, xField );
916cdf0e10cSrcweir         rErrorMsg = aErr;
917cdf0e10cSrcweir         rText = aTxt;
918cdf0e10cSrcweir         if ( xParseNode.is() )
919cdf0e10cSrcweir         {
920cdf0e10cSrcweir 	        ::rtl::OUString aPreparedText;
921cdf0e10cSrcweir 	        Locale aAppLocale = Application::GetSettings().GetUILocale();
922cdf0e10cSrcweir 	        xParseNode->parseNodeToPredicateStr(
923cdf0e10cSrcweir                 aPreparedText, xConnection, xFormatter, xField, aAppLocale, '.', getParseContext() );
924cdf0e10cSrcweir 	        rText = aPreparedText;
925cdf0e10cSrcweir 	        return sal_True;
926cdf0e10cSrcweir         }
927cdf0e10cSrcweir     }
928cdf0e10cSrcweir     catch( const Exception& )
929cdf0e10cSrcweir     {
930cdf0e10cSrcweir     	DBG_UNHANDLED_EXCEPTION();
931cdf0e10cSrcweir     }
932cdf0e10cSrcweir 
933cdf0e10cSrcweir     return sal_False;
934cdf0e10cSrcweir }
935cdf0e10cSrcweir 
936cdf0e10cSrcweir //------------------------------------------------------------------------
937cdf0e10cSrcweir void FmFilterModel::Append(FmFilterItems* pItems, FmFilterItem* pFilterItem)
938cdf0e10cSrcweir {
939cdf0e10cSrcweir 	Insert(pItems->GetChildren().end(), pFilterItem);
940cdf0e10cSrcweir }
941cdf0e10cSrcweir 
942cdf0e10cSrcweir //------------------------------------------------------------------------
943cdf0e10cSrcweir void FmFilterModel::SetTextForItem(FmFilterItem* pItem, const ::rtl::OUString& rText)
944cdf0e10cSrcweir {
945cdf0e10cSrcweir 	::std::vector<FmFilterData*>& rItems = pItem->GetParent()->GetParent()->GetChildren();
946cdf0e10cSrcweir 	::std::vector<FmFilterData*>::iterator i = ::std::find(rItems.begin(), rItems.end(), pItem->GetParent());
947cdf0e10cSrcweir 	sal_Int32 nParentPos = i - rItems.begin();
948cdf0e10cSrcweir 
949cdf0e10cSrcweir 	m_pAdapter->setText(nParentPos, pItem, rText);
950cdf0e10cSrcweir 
951cdf0e10cSrcweir 	if (!rText)
952cdf0e10cSrcweir 		Remove(pItem);
953cdf0e10cSrcweir 	else
954cdf0e10cSrcweir 	{
955cdf0e10cSrcweir 		// Change the text
956cdf0e10cSrcweir 		pItem->SetText(rText);
957cdf0e10cSrcweir 		FmFilterTextChangedHint aChangeHint(pItem);
958cdf0e10cSrcweir 		Broadcast( aChangeHint );
959cdf0e10cSrcweir 	}
960cdf0e10cSrcweir }
961cdf0e10cSrcweir 
962cdf0e10cSrcweir //------------------------------------------------------------------------
963cdf0e10cSrcweir void FmFilterModel::SetCurrentItems(FmFilterItems* pCurrent)
964cdf0e10cSrcweir {
965cdf0e10cSrcweir 	if (m_pCurrentItems == pCurrent)
966cdf0e10cSrcweir 		return;
967cdf0e10cSrcweir 
968cdf0e10cSrcweir 	// search for the condition
969cdf0e10cSrcweir 	if (pCurrent)
970cdf0e10cSrcweir 	{
971cdf0e10cSrcweir 		FmFormItem* pFormItem = (FmFormItem*)pCurrent->GetParent();
972cdf0e10cSrcweir 		::std::vector<FmFilterData*>& rItems = pFormItem->GetChildren();
973cdf0e10cSrcweir 		::std::vector<FmFilterData*>::const_iterator i = ::std::find(rItems.begin(), rItems.end(), pCurrent);
974cdf0e10cSrcweir 
975cdf0e10cSrcweir 		if (i != rItems.end())
976cdf0e10cSrcweir 		{
977cdf0e10cSrcweir 			// determine the filter position
978cdf0e10cSrcweir 			sal_Int32 nPos = i - rItems.begin();
979cdf0e10cSrcweir             try
980cdf0e10cSrcweir             {
981cdf0e10cSrcweir                 Reference< XFilterController > xFilterController( pFormItem->GetFilterController(), UNO_SET_THROW );
982cdf0e10cSrcweir 			    xFilterController->setActiveTerm( nPos );
983cdf0e10cSrcweir             }
984cdf0e10cSrcweir             catch( const Exception& )
985cdf0e10cSrcweir             {
986cdf0e10cSrcweir             	DBG_UNHANDLED_EXCEPTION();
987cdf0e10cSrcweir             }
988cdf0e10cSrcweir 
989cdf0e10cSrcweir 			if ( m_xController != pFormItem->GetController() )
990cdf0e10cSrcweir 				// calls SetCurrentItems again
991cdf0e10cSrcweir 				SetCurrentController( pFormItem->GetController() );
992cdf0e10cSrcweir 			else
993cdf0e10cSrcweir 				m_pCurrentItems = pCurrent;
994cdf0e10cSrcweir 		}
995cdf0e10cSrcweir 		else
996cdf0e10cSrcweir 			m_pCurrentItems = NULL;
997cdf0e10cSrcweir 	}
998cdf0e10cSrcweir 	else
999cdf0e10cSrcweir 		m_pCurrentItems = NULL;
1000cdf0e10cSrcweir 
1001cdf0e10cSrcweir 
1002cdf0e10cSrcweir 	// UI benachrichtigen
1003cdf0e10cSrcweir 	FmFilterCurrentChangedHint aHint;
1004cdf0e10cSrcweir 	Broadcast( aHint );
1005cdf0e10cSrcweir }
1006cdf0e10cSrcweir 
1007cdf0e10cSrcweir //------------------------------------------------------------------------
1008cdf0e10cSrcweir void FmFilterModel::EnsureEmptyFilterRows( FmParentData& _rItem )
1009cdf0e10cSrcweir {
1010cdf0e10cSrcweir 	// checks whether for each form there's one free level for input
1011cdf0e10cSrcweir 	::std::vector< FmFilterData* >& rChildren = _rItem.GetChildren();
1012cdf0e10cSrcweir 	sal_Bool bAppendLevel = _rItem.ISA( FmFormItem );
1013cdf0e10cSrcweir 
1014cdf0e10cSrcweir 	for (   ::std::vector<FmFilterData*>::iterator i = rChildren.begin();
1015cdf0e10cSrcweir 		    i != rChildren.end();
1016cdf0e10cSrcweir             ++i
1017cdf0e10cSrcweir         )
1018cdf0e10cSrcweir 	{
1019cdf0e10cSrcweir 		FmFilterItems* pItems = PTR_CAST(FmFilterItems, *i);
1020cdf0e10cSrcweir 		if ( pItems && pItems->GetChildren().empty() )
1021cdf0e10cSrcweir 		{
1022cdf0e10cSrcweir 			bAppendLevel = sal_False;
1023cdf0e10cSrcweir 			break;
1024cdf0e10cSrcweir 		}
1025cdf0e10cSrcweir 
1026cdf0e10cSrcweir 		FmFormItem* pFormItem = PTR_CAST(FmFormItem, *i);
1027cdf0e10cSrcweir 		if (pFormItem)
1028cdf0e10cSrcweir 		{
1029cdf0e10cSrcweir 			EnsureEmptyFilterRows( *pFormItem );
1030cdf0e10cSrcweir 			continue;
1031cdf0e10cSrcweir 		}
1032cdf0e10cSrcweir 	}
1033cdf0e10cSrcweir 
1034cdf0e10cSrcweir 	if ( bAppendLevel )
1035cdf0e10cSrcweir     {
1036cdf0e10cSrcweir         FmFormItem* pFormItem = PTR_CAST( FmFormItem, &_rItem );
1037cdf0e10cSrcweir         OSL_ENSURE( pFormItem, "FmFilterModel::EnsureEmptyFilterRows: no FmFormItem, but a FmFilterItems child?" );
1038cdf0e10cSrcweir         if ( pFormItem )
1039cdf0e10cSrcweir 		    AppendFilterItems( *pFormItem );
1040cdf0e10cSrcweir     }
1041cdf0e10cSrcweir }
1042cdf0e10cSrcweir 
1043cdf0e10cSrcweir //========================================================================
1044cdf0e10cSrcweir // class FmFilterItemsString
1045cdf0e10cSrcweir //========================================================================
1046cdf0e10cSrcweir class FmFilterItemsString : public SvLBoxString
1047cdf0e10cSrcweir {
1048cdf0e10cSrcweir public:
1049cdf0e10cSrcweir 	FmFilterItemsString( SvLBoxEntry* pEntry, sal_uInt16 nFlags,	const XubString& rStr )
1050cdf0e10cSrcweir 		:SvLBoxString(pEntry,nFlags,rStr){}
1051cdf0e10cSrcweir 
1052cdf0e10cSrcweir 	virtual void Paint(const Point& rPos, SvLBox& rDev, sal_uInt16 nFlags, SvLBoxEntry* pEntry);
1053cdf0e10cSrcweir 	virtual void InitViewData( SvLBox* pView,SvLBoxEntry* pEntry, SvViewDataItem* pViewData);
1054cdf0e10cSrcweir };
1055cdf0e10cSrcweir 
1056cdf0e10cSrcweir const int nxDBmp = 12;
1057cdf0e10cSrcweir //------------------------------------------------------------------------
1058cdf0e10cSrcweir void FmFilterItemsString::Paint(const Point& rPos, SvLBox& rDev, sal_uInt16 /*nFlags*/, SvLBoxEntry* pEntry )
1059cdf0e10cSrcweir {
1060cdf0e10cSrcweir 	FmFilterItems* pRow = (FmFilterItems*)pEntry->GetUserData();
1061cdf0e10cSrcweir 	FmFormItem* pForm = (FmFormItem*)pRow->GetParent();
1062cdf0e10cSrcweir 
1063cdf0e10cSrcweir     // current filter is significant painted
1064cdf0e10cSrcweir     const bool bIsCurrentFilter = pForm->GetChildren()[ pForm->GetFilterController()->getActiveTerm() ] == pRow;
1065cdf0e10cSrcweir 	if ( bIsCurrentFilter )
1066cdf0e10cSrcweir     {
1067cdf0e10cSrcweir         rDev.Push( PUSH_LINECOLOR );
1068cdf0e10cSrcweir 
1069cdf0e10cSrcweir 		rDev.SetLineColor( rDev.GetTextColor() );
1070cdf0e10cSrcweir 
1071cdf0e10cSrcweir 		Rectangle aRect( rPos, GetSize( &rDev, pEntry ) );
1072cdf0e10cSrcweir 		Point aFirst( rPos.X(), aRect.Bottom() - 6 );
1073cdf0e10cSrcweir 		Point aSecond(aFirst .X() + 2, aFirst.Y() + 3 );
1074cdf0e10cSrcweir 
1075cdf0e10cSrcweir 		rDev.DrawLine( aFirst, aSecond );
1076cdf0e10cSrcweir 
1077cdf0e10cSrcweir 		aFirst = aSecond;
1078cdf0e10cSrcweir 		aFirst.X() += 1;
1079cdf0e10cSrcweir 		aSecond.X() += 6;
1080cdf0e10cSrcweir 		aSecond.Y() -= 5;
1081cdf0e10cSrcweir 
1082cdf0e10cSrcweir 		rDev.DrawLine( aFirst, aSecond );
1083cdf0e10cSrcweir 
1084cdf0e10cSrcweir         rDev.Pop();
1085cdf0e10cSrcweir 	}
1086cdf0e10cSrcweir 
1087cdf0e10cSrcweir 	rDev.DrawText( Point(rPos.X() + nxDBmp, rPos.Y()), GetText() );
1088cdf0e10cSrcweir }
1089cdf0e10cSrcweir 
1090cdf0e10cSrcweir //------------------------------------------------------------------------
1091cdf0e10cSrcweir void FmFilterItemsString::InitViewData( SvLBox* pView,SvLBoxEntry* pEntry, SvViewDataItem* pViewData)
1092cdf0e10cSrcweir {
1093cdf0e10cSrcweir 	if( !pViewData )
1094cdf0e10cSrcweir 		pViewData = pView->GetViewDataItem( pEntry, this );
1095cdf0e10cSrcweir 
1096cdf0e10cSrcweir 	Size aSize(pView->GetTextWidth(GetText()), pView->GetTextHeight());
1097cdf0e10cSrcweir 	aSize.Width() += nxDBmp;
1098cdf0e10cSrcweir 	pViewData->aSize = aSize;
1099cdf0e10cSrcweir }
1100cdf0e10cSrcweir 
1101cdf0e10cSrcweir //========================================================================
1102cdf0e10cSrcweir // class FmFilterString
1103cdf0e10cSrcweir //========================================================================
1104cdf0e10cSrcweir class FmFilterString : public SvLBoxString
1105cdf0e10cSrcweir {
1106cdf0e10cSrcweir 	UniString m_aName;
1107cdf0e10cSrcweir 
1108cdf0e10cSrcweir public:
1109cdf0e10cSrcweir 	FmFilterString( SvLBoxEntry* pEntry, sal_uInt16 nFlags, const XubString& rStr, const UniString& aName)
1110cdf0e10cSrcweir 		:SvLBoxString(pEntry,nFlags,rStr)
1111cdf0e10cSrcweir 		,m_aName(aName)
1112cdf0e10cSrcweir 	{
1113cdf0e10cSrcweir 		m_aName.AppendAscii(": ");
1114cdf0e10cSrcweir 	}
1115cdf0e10cSrcweir 
1116cdf0e10cSrcweir 	virtual void Paint(const Point& rPos, SvLBox& rDev, sal_uInt16 nFlags, SvLBoxEntry* pEntry);
1117cdf0e10cSrcweir 	virtual void InitViewData( SvLBox* pView,SvLBoxEntry* pEntry, SvViewDataItem* pViewData);
1118cdf0e10cSrcweir };
1119cdf0e10cSrcweir 
1120cdf0e10cSrcweir const int nxD = 4;
1121cdf0e10cSrcweir 
1122cdf0e10cSrcweir //------------------------------------------------------------------------
1123cdf0e10cSrcweir void FmFilterString::InitViewData( SvLBox* pView,SvLBoxEntry* pEntry, SvViewDataItem* pViewData)
1124cdf0e10cSrcweir {
1125cdf0e10cSrcweir 	if( !pViewData )
1126cdf0e10cSrcweir 		pViewData = pView->GetViewDataItem( pEntry, this );
1127cdf0e10cSrcweir 
1128cdf0e10cSrcweir 	Font aOldFont( pView->GetFont());
1129cdf0e10cSrcweir 	Font aFont( aOldFont );
1130cdf0e10cSrcweir 	aFont.SetWeight(WEIGHT_BOLD);
1131cdf0e10cSrcweir 	pView->SetFont( aFont );
1132cdf0e10cSrcweir 
1133cdf0e10cSrcweir 	Size aSize(pView->GetTextWidth(m_aName), pView->GetTextHeight());
1134cdf0e10cSrcweir 	pView->SetFont( aOldFont );
1135cdf0e10cSrcweir 	aSize.Width() += pView->GetTextWidth(GetText()) + nxD;
1136cdf0e10cSrcweir 	pViewData->aSize = aSize;
1137cdf0e10cSrcweir }
1138cdf0e10cSrcweir 
1139cdf0e10cSrcweir //------------------------------------------------------------------------
1140cdf0e10cSrcweir void FmFilterString::Paint(const Point& rPos, SvLBox& rDev, sal_uInt16 /*nFlags*/, SvLBoxEntry* /*pEntry*/ )
1141cdf0e10cSrcweir {
1142cdf0e10cSrcweir 	Font aOldFont( rDev.GetFont());
1143cdf0e10cSrcweir 	Font aFont( aOldFont );
1144cdf0e10cSrcweir 	aFont.SetWeight(WEIGHT_BOLD);
1145cdf0e10cSrcweir 	rDev.SetFont( aFont );
1146cdf0e10cSrcweir 
1147cdf0e10cSrcweir 	Point aPos(rPos);
1148cdf0e10cSrcweir 	rDev.DrawText( aPos, m_aName );
1149cdf0e10cSrcweir 
1150cdf0e10cSrcweir 	// position for the second text
1151cdf0e10cSrcweir 	aPos.X() += rDev.GetTextWidth(m_aName) + nxD;
1152cdf0e10cSrcweir 	rDev.SetFont( aOldFont );
1153cdf0e10cSrcweir 	rDev.DrawText( aPos, GetText() );
1154cdf0e10cSrcweir }
1155cdf0e10cSrcweir 
1156cdf0e10cSrcweir //========================================================================
1157cdf0e10cSrcweir // class FmFilterNavigator
1158cdf0e10cSrcweir //========================================================================
1159cdf0e10cSrcweir FmFilterNavigator::FmFilterNavigator( Window* pParent )
1160cdf0e10cSrcweir 				  :SvTreeListBox( pParent, WB_HASBUTTONS|WB_HASLINES|WB_BORDER|WB_HASBUTTONSATROOT )
1161cdf0e10cSrcweir                   ,m_pModel( NULL )
1162cdf0e10cSrcweir 				  ,m_pEditingCurrently( NULL )
1163cdf0e10cSrcweir 				  ,m_aControlExchange( this )
1164cdf0e10cSrcweir                   ,m_aTimerCounter( 0 )
1165cdf0e10cSrcweir                   ,m_aDropActionType( DA_SCROLLUP )
1166cdf0e10cSrcweir {
1167cdf0e10cSrcweir 	SetHelpId( HID_FILTER_NAVIGATOR );
1168cdf0e10cSrcweir 
1169cdf0e10cSrcweir 	{
1170cdf0e10cSrcweir 		{
1171cdf0e10cSrcweir 			ImageList aNavigatorImages( SVX_RES( RID_SVXIMGLIST_FMEXPL ) );
1172cdf0e10cSrcweir 			SetNodeBitmaps(
1173cdf0e10cSrcweir 				aNavigatorImages.GetImage( RID_SVXIMG_COLLAPSEDNODE ),
1174cdf0e10cSrcweir 				aNavigatorImages.GetImage( RID_SVXIMG_EXPANDEDNODE ),
1175cdf0e10cSrcweir 				BMP_COLOR_NORMAL
1176cdf0e10cSrcweir 			);
1177cdf0e10cSrcweir 		}
1178cdf0e10cSrcweir 		{
1179cdf0e10cSrcweir 			ImageList aNavigatorImages( SVX_RES( RID_SVXIMGLIST_FMEXPL_HC ) );
1180cdf0e10cSrcweir 			SetNodeBitmaps(
1181cdf0e10cSrcweir 				aNavigatorImages.GetImage( RID_SVXIMG_COLLAPSEDNODE ),
1182cdf0e10cSrcweir 				aNavigatorImages.GetImage( RID_SVXIMG_EXPANDEDNODE ),
1183cdf0e10cSrcweir 				BMP_COLOR_HIGHCONTRAST
1184cdf0e10cSrcweir 			);
1185cdf0e10cSrcweir 		}
1186cdf0e10cSrcweir 	}
1187cdf0e10cSrcweir 
1188cdf0e10cSrcweir 	m_pModel = new FmFilterModel(comphelper::getProcessServiceFactory());
1189cdf0e10cSrcweir 	StartListening( *m_pModel );
1190cdf0e10cSrcweir 
1191cdf0e10cSrcweir 	EnableInplaceEditing( sal_True );
1192cdf0e10cSrcweir 	SetSelectionMode(MULTIPLE_SELECTION);
1193cdf0e10cSrcweir 
1194cdf0e10cSrcweir 	SetDragDropMode(0xFFFF);
1195cdf0e10cSrcweir 
1196cdf0e10cSrcweir 	m_aDropActionTimer.SetTimeoutHdl(LINK(this, FmFilterNavigator, OnDropActionTimer));
1197cdf0e10cSrcweir }
1198cdf0e10cSrcweir 
1199cdf0e10cSrcweir //------------------------------------------------------------------------
1200cdf0e10cSrcweir FmFilterNavigator::~FmFilterNavigator()
1201cdf0e10cSrcweir {
1202cdf0e10cSrcweir 	EndListening( *m_pModel );
1203cdf0e10cSrcweir 	delete m_pModel;
1204cdf0e10cSrcweir }
1205cdf0e10cSrcweir 
1206cdf0e10cSrcweir //------------------------------------------------------------------------
1207cdf0e10cSrcweir void FmFilterNavigator::Clear()
1208cdf0e10cSrcweir {
1209cdf0e10cSrcweir 	m_pModel->Clear();
1210cdf0e10cSrcweir }
1211cdf0e10cSrcweir 
1212cdf0e10cSrcweir //------------------------------------------------------------------------
1213cdf0e10cSrcweir void FmFilterNavigator::UpdateContent(const Reference< XIndexAccess > & xControllers, const Reference< XFormController > & xCurrent)
1214cdf0e10cSrcweir {
1215cdf0e10cSrcweir 	if (xCurrent == m_pModel->GetCurrentController())
1216cdf0e10cSrcweir 		return;
1217cdf0e10cSrcweir 
1218cdf0e10cSrcweir 	m_pModel->Update(xControllers, xCurrent);
1219cdf0e10cSrcweir 
1220cdf0e10cSrcweir 	// expand the filters for the current controller
1221cdf0e10cSrcweir 	SvLBoxEntry* pEntry = FindEntry(m_pModel->GetCurrentForm());
1222cdf0e10cSrcweir 	if (pEntry && !IsExpanded(pEntry))
1223cdf0e10cSrcweir 	{
1224cdf0e10cSrcweir 		SelectAll(sal_False);
1225cdf0e10cSrcweir 
1226cdf0e10cSrcweir 		if (!IsExpanded(pEntry))
1227cdf0e10cSrcweir 			Expand(pEntry);
1228cdf0e10cSrcweir 
1229cdf0e10cSrcweir 		pEntry = FindEntry(m_pModel->GetCurrentItems());
1230cdf0e10cSrcweir 		if (pEntry)
1231cdf0e10cSrcweir 		{
1232cdf0e10cSrcweir 			if (!IsExpanded(pEntry))
1233cdf0e10cSrcweir 				Expand(pEntry);
1234cdf0e10cSrcweir 			Select(pEntry, sal_True);
1235cdf0e10cSrcweir 		}
1236cdf0e10cSrcweir 	}
1237cdf0e10cSrcweir }
1238cdf0e10cSrcweir 
1239cdf0e10cSrcweir //------------------------------------------------------------------------
1240cdf0e10cSrcweir sal_Bool FmFilterNavigator::EditingEntry( SvLBoxEntry* pEntry, Selection& rSelection )
1241cdf0e10cSrcweir {
1242cdf0e10cSrcweir 	m_pEditingCurrently = pEntry;
1243cdf0e10cSrcweir 	if (!SvTreeListBox::EditingEntry( pEntry, rSelection ))
1244cdf0e10cSrcweir 		return sal_False;
1245cdf0e10cSrcweir 
1246cdf0e10cSrcweir 	return pEntry && ((FmFilterData*)pEntry->GetUserData())->ISA(FmFilterItem);
1247cdf0e10cSrcweir }
1248cdf0e10cSrcweir 
1249cdf0e10cSrcweir //------------------------------------------------------------------------
1250cdf0e10cSrcweir sal_Bool FmFilterNavigator::EditedEntry( SvLBoxEntry* pEntry, const XubString& rNewText )
1251cdf0e10cSrcweir {
1252cdf0e10cSrcweir 	DBG_ASSERT(pEntry == m_pEditingCurrently, "FmFilterNavigator::EditedEntry: suspicious entry!");
1253cdf0e10cSrcweir 	m_pEditingCurrently = NULL;
1254cdf0e10cSrcweir 
1255cdf0e10cSrcweir 	if (EditingCanceled())
1256cdf0e10cSrcweir 		return sal_True;
1257cdf0e10cSrcweir 
1258cdf0e10cSrcweir 	DBG_ASSERT(((FmFilterData*)pEntry->GetUserData())->ISA(FmFilterItem),
1259cdf0e10cSrcweir 					"FmFilterNavigator::EditedEntry() wrong entry");
1260cdf0e10cSrcweir 
1261cdf0e10cSrcweir 	UniString aText(rNewText);
1262cdf0e10cSrcweir 	aText.EraseTrailingChars();
1263cdf0e10cSrcweir 	aText.EraseLeadingChars();
1264cdf0e10cSrcweir 	if (aText.Len() == 0)
1265cdf0e10cSrcweir 	{
1266cdf0e10cSrcweir 		// deleting the entry asynchron
1267cdf0e10cSrcweir 		sal_uLong nEvent;
1268cdf0e10cSrcweir 		PostUserEvent(nEvent, LINK(this, FmFilterNavigator, OnRemove), pEntry);
1269cdf0e10cSrcweir 	}
1270cdf0e10cSrcweir 	else
1271cdf0e10cSrcweir 	{
1272cdf0e10cSrcweir 		UniString aErrorMsg;
1273cdf0e10cSrcweir 
1274cdf0e10cSrcweir 		if (m_pModel->ValidateText((FmFilterItem*)pEntry->GetUserData(), aText, aErrorMsg))
1275cdf0e10cSrcweir 		{
1276cdf0e10cSrcweir 			GrabFocus();
1277cdf0e10cSrcweir 			// this will set the text at the FmFilterItem, as well as update any filter controls
1278cdf0e10cSrcweir 			// which are connected to this particular entry
1279cdf0e10cSrcweir 			m_pModel->SetTextForItem( static_cast< FmFilterItem* >( pEntry->GetUserData() ), aText );
1280cdf0e10cSrcweir 
1281cdf0e10cSrcweir 			SetCursor( pEntry, sal_True );
1282cdf0e10cSrcweir 			SetEntryText( pEntry, aText );
1283cdf0e10cSrcweir 		}
1284cdf0e10cSrcweir 		else
1285cdf0e10cSrcweir 		{
1286cdf0e10cSrcweir 			// display the error and return sal_False
1287cdf0e10cSrcweir 			SQLContext aError;
1288cdf0e10cSrcweir 			aError.Message = String(SVX_RES(RID_STR_SYNTAXERROR));
1289cdf0e10cSrcweir 			aError.Details = aErrorMsg;
1290cdf0e10cSrcweir 			displayException(aError, this);
1291cdf0e10cSrcweir 
1292cdf0e10cSrcweir 			return sal_False;
1293cdf0e10cSrcweir 		}
1294cdf0e10cSrcweir 	}
1295cdf0e10cSrcweir 	return sal_True;
1296cdf0e10cSrcweir }
1297cdf0e10cSrcweir 
1298cdf0e10cSrcweir //------------------------------------------------------------------------
1299cdf0e10cSrcweir IMPL_LINK( FmFilterNavigator, OnRemove, SvLBoxEntry*, pEntry )
1300cdf0e10cSrcweir {
1301cdf0e10cSrcweir 	// now remove the entry
1302cdf0e10cSrcweir 	m_pModel->Remove((FmFilterData*) pEntry->GetUserData());
1303cdf0e10cSrcweir 	return 0L;
1304cdf0e10cSrcweir }
1305cdf0e10cSrcweir 
1306cdf0e10cSrcweir //------------------------------------------------------------------------
1307cdf0e10cSrcweir IMPL_LINK( FmFilterNavigator, OnDropActionTimer, void*, EMPTYARG )
1308cdf0e10cSrcweir {
1309cdf0e10cSrcweir 	if (--m_aTimerCounter > 0)
1310cdf0e10cSrcweir 		return 0L;
1311cdf0e10cSrcweir 
1312cdf0e10cSrcweir 	switch (m_aDropActionType)
1313cdf0e10cSrcweir 	{
1314cdf0e10cSrcweir 		case DA_SCROLLUP :
1315cdf0e10cSrcweir 			ScrollOutputArea(1);
1316cdf0e10cSrcweir 	        m_aTimerCounter = DROP_ACTION_TIMER_SCROLL_TICKS;
1317cdf0e10cSrcweir 			break;
1318cdf0e10cSrcweir 		case DA_SCROLLDOWN :
1319cdf0e10cSrcweir 			ScrollOutputArea(-1);
1320cdf0e10cSrcweir 	        m_aTimerCounter = DROP_ACTION_TIMER_SCROLL_TICKS;
1321cdf0e10cSrcweir 			break;
1322cdf0e10cSrcweir         case DA_EXPANDNODE:
1323cdf0e10cSrcweir 	    {
1324cdf0e10cSrcweir 		    SvLBoxEntry* pToExpand = GetEntry(m_aTimerTriggered);
1325cdf0e10cSrcweir 		    if (pToExpand && (GetChildCount(pToExpand) > 0) &&	!IsExpanded(pToExpand))
1326cdf0e10cSrcweir 			    // tja, eigentlich muesste ich noch testen, ob die Node nicht schon expandiert ist, aber ich
1327cdf0e10cSrcweir 			    // habe dazu weder in den Basisklassen noch im Model eine Methode gefunden ...
1328cdf0e10cSrcweir 			    // aber ich denke, die BK sollte es auch so vertragen
1329cdf0e10cSrcweir 			    Expand(pToExpand);
1330cdf0e10cSrcweir 
1331cdf0e10cSrcweir 		    // nach dem Expand habe ich im Gegensatz zum Scrollen natuerlich nix mehr zu tun
1332cdf0e10cSrcweir 		    m_aDropActionTimer.Stop();
1333cdf0e10cSrcweir 	    }
1334cdf0e10cSrcweir         break;
1335cdf0e10cSrcweir 	}
1336cdf0e10cSrcweir 	return 0L;
1337cdf0e10cSrcweir }
1338cdf0e10cSrcweir 
1339cdf0e10cSrcweir 
1340cdf0e10cSrcweir //------------------------------------------------------------------------
1341cdf0e10cSrcweir sal_Int8 FmFilterNavigator::AcceptDrop( const AcceptDropEvent& rEvt )
1342cdf0e10cSrcweir {
1343cdf0e10cSrcweir 	Point aDropPos = rEvt.maPosPixel;
1344cdf0e10cSrcweir 
1345cdf0e10cSrcweir 	// kuemmern wir uns erst mal um moeglich DropActions (Scrollen und Aufklappen)
1346cdf0e10cSrcweir 	if (rEvt.mbLeaving)
1347cdf0e10cSrcweir 	{
1348cdf0e10cSrcweir 		if (m_aDropActionTimer.IsActive())
1349cdf0e10cSrcweir 			m_aDropActionTimer.Stop();
1350cdf0e10cSrcweir 	}
1351cdf0e10cSrcweir 	else
1352cdf0e10cSrcweir 	{
1353cdf0e10cSrcweir 		sal_Bool bNeedTrigger = sal_False;
1354cdf0e10cSrcweir 		// auf dem ersten Eintrag ?
1355cdf0e10cSrcweir 		if ((aDropPos.Y() >= 0) && (aDropPos.Y() < GetEntryHeight()))
1356cdf0e10cSrcweir 		{
1357cdf0e10cSrcweir 			m_aDropActionType = DA_SCROLLUP;
1358cdf0e10cSrcweir 			bNeedTrigger = sal_True;
1359cdf0e10cSrcweir 		}
1360cdf0e10cSrcweir 		else
1361cdf0e10cSrcweir 		{
1362cdf0e10cSrcweir 			// auf dem letzten (bzw. in dem Bereich, den ein Eintrag einnehmen wuerde, wenn er unten genau buendig
1363cdf0e10cSrcweir 			// abschliessen wuerde) ?
1364cdf0e10cSrcweir 			if ((aDropPos.Y() < GetSizePixel().Height()) && (aDropPos.Y() >= GetSizePixel().Height() - GetEntryHeight()))
1365cdf0e10cSrcweir 			{
1366cdf0e10cSrcweir 				m_aDropActionType = DA_SCROLLDOWN;
1367cdf0e10cSrcweir 				bNeedTrigger = sal_True;
1368cdf0e10cSrcweir 			}
1369cdf0e10cSrcweir 			else
1370cdf0e10cSrcweir 			{	// is it an entry whith children, and not yet expanded?
1371cdf0e10cSrcweir 				SvLBoxEntry* pDropppedOn = GetEntry(aDropPos);
1372cdf0e10cSrcweir 				if (pDropppedOn && (GetChildCount(pDropppedOn) > 0) && !IsExpanded(pDropppedOn))
1373cdf0e10cSrcweir 				{
1374cdf0e10cSrcweir 					// -> aufklappen
1375cdf0e10cSrcweir 					m_aDropActionType = DA_EXPANDNODE;
1376cdf0e10cSrcweir 					bNeedTrigger = sal_True;
1377cdf0e10cSrcweir 				}
1378cdf0e10cSrcweir 			}
1379cdf0e10cSrcweir 		}
1380cdf0e10cSrcweir 		if (bNeedTrigger && (m_aTimerTriggered != aDropPos))
1381cdf0e10cSrcweir 		{
1382cdf0e10cSrcweir 			// neu anfangen zu zaehlen
1383cdf0e10cSrcweir 			m_aTimerCounter = DROP_ACTION_TIMER_INITIAL_TICKS;
1384cdf0e10cSrcweir 			// die Pos merken, da ich auch QueryDrops bekomme, wenn sich die Maus gar nicht bewegt hat
1385cdf0e10cSrcweir 			m_aTimerTriggered = aDropPos;
1386cdf0e10cSrcweir 			// und den Timer los
1387cdf0e10cSrcweir 			if (!m_aDropActionTimer.IsActive()) // gibt es den Timer schon ?
1388cdf0e10cSrcweir 			{
1389cdf0e10cSrcweir 				m_aDropActionTimer.SetTimeout(DROP_ACTION_TIMER_TICK_BASE);
1390cdf0e10cSrcweir 				m_aDropActionTimer.Start();
1391cdf0e10cSrcweir 			}
1392cdf0e10cSrcweir 		}
1393cdf0e10cSrcweir 		else if (!bNeedTrigger)
1394cdf0e10cSrcweir 			m_aDropActionTimer.Stop();
1395cdf0e10cSrcweir 	}
1396cdf0e10cSrcweir 
1397cdf0e10cSrcweir 
1398cdf0e10cSrcweir 	// Hat das Object das richtige Format?
1399cdf0e10cSrcweir 	if (!m_aControlExchange.isDragSource())
1400cdf0e10cSrcweir 		return DND_ACTION_NONE;
1401cdf0e10cSrcweir 
1402cdf0e10cSrcweir 	if (!m_aControlExchange->hasFormat(GetDataFlavorExVector()))
1403cdf0e10cSrcweir 		return DND_ACTION_NONE;
1404cdf0e10cSrcweir 
1405cdf0e10cSrcweir 	// do we conain the formitem?
1406cdf0e10cSrcweir 	if (!FindEntry(m_aControlExchange->getFormItem()))
1407cdf0e10cSrcweir 		return DND_ACTION_NONE;
1408cdf0e10cSrcweir 
1409cdf0e10cSrcweir 	SvLBoxEntry* pDropTarget = GetEntry(aDropPos);
1410cdf0e10cSrcweir 	if (!pDropTarget)
1411cdf0e10cSrcweir 		return DND_ACTION_NONE;
1412cdf0e10cSrcweir 
1413cdf0e10cSrcweir 	FmFilterData* pData = (FmFilterData*)pDropTarget->GetUserData();
1414cdf0e10cSrcweir 	FmFormItem* pForm = NULL;
1415cdf0e10cSrcweir 	if (pData->ISA(FmFilterItem))
1416cdf0e10cSrcweir 	{
1417cdf0e10cSrcweir 		pForm = PTR_CAST(FmFormItem,pData->GetParent()->GetParent());
1418cdf0e10cSrcweir 		if (pForm != m_aControlExchange->getFormItem())
1419cdf0e10cSrcweir 			return DND_ACTION_NONE;
1420cdf0e10cSrcweir 	}
1421cdf0e10cSrcweir 	else if (pData->ISA(FmFilterItems))
1422cdf0e10cSrcweir 	{
1423cdf0e10cSrcweir 		pForm = PTR_CAST(FmFormItem,pData->GetParent());
1424cdf0e10cSrcweir 		if (pForm != m_aControlExchange->getFormItem())
1425cdf0e10cSrcweir 			return DND_ACTION_NONE;
1426cdf0e10cSrcweir 	}
1427cdf0e10cSrcweir 	else
1428cdf0e10cSrcweir 		return DND_ACTION_NONE;
1429cdf0e10cSrcweir 
1430cdf0e10cSrcweir 	return rEvt.mnAction;
1431cdf0e10cSrcweir }
1432cdf0e10cSrcweir // -----------------------------------------------------------------------------
1433cdf0e10cSrcweir namespace
1434cdf0e10cSrcweir {
1435cdf0e10cSrcweir 	FmFilterItems* getTargetItems(SvLBoxEntry* _pTarget)
1436cdf0e10cSrcweir 	{
1437cdf0e10cSrcweir 		FmFilterData*	pData = static_cast<FmFilterData*>(_pTarget->GetUserData());
1438cdf0e10cSrcweir 		FmFilterItems*	pTargetItems = pData->ISA(FmFilterItems)
1439cdf0e10cSrcweir 										?
1440cdf0e10cSrcweir 										PTR_CAST(FmFilterItems,pData)
1441cdf0e10cSrcweir 										:
1442cdf0e10cSrcweir 									PTR_CAST(FmFilterItems,pData->GetParent());
1443cdf0e10cSrcweir 		return pTargetItems;
1444cdf0e10cSrcweir 	}
1445cdf0e10cSrcweir }
1446cdf0e10cSrcweir //------------------------------------------------------------------------
1447cdf0e10cSrcweir sal_Int8 FmFilterNavigator::ExecuteDrop( const ExecuteDropEvent& rEvt )
1448cdf0e10cSrcweir {
1449cdf0e10cSrcweir 	// ware schlecht, wenn nach dem Droppen noch gescrollt wird ...
1450cdf0e10cSrcweir 	if (m_aDropActionTimer.IsActive())
1451cdf0e10cSrcweir 		m_aDropActionTimer.Stop();
1452cdf0e10cSrcweir 
1453cdf0e10cSrcweir 	// Format-Ueberpruefung
1454cdf0e10cSrcweir 	if (!m_aControlExchange.isDragSource())
1455cdf0e10cSrcweir 		return DND_ACTION_NONE;
1456cdf0e10cSrcweir 
1457cdf0e10cSrcweir 	// das Ziel des Drop sowie einige Daten darueber
1458cdf0e10cSrcweir 	Point aDropPos = rEvt.maPosPixel;
1459cdf0e10cSrcweir 	SvLBoxEntry* pDropTarget = GetEntry( aDropPos );
1460cdf0e10cSrcweir 	if (!pDropTarget)
1461cdf0e10cSrcweir 		return DND_ACTION_NONE;
1462cdf0e10cSrcweir 
1463cdf0e10cSrcweir 	// search the container where to add the items
1464cdf0e10cSrcweir 	FmFilterItems*	pTargetItems = getTargetItems(pDropTarget);
1465cdf0e10cSrcweir 	SelectAll(sal_False);
1466cdf0e10cSrcweir 	SvLBoxEntry* pEntry = FindEntry(pTargetItems);
1467cdf0e10cSrcweir 	Select(pEntry, sal_True);
1468cdf0e10cSrcweir 	SetCurEntry(pEntry);
1469cdf0e10cSrcweir 
1470cdf0e10cSrcweir 	insertFilterItem(m_aControlExchange->getDraggedEntries(),pTargetItems,DND_ACTION_COPY == rEvt.mnAction);
1471cdf0e10cSrcweir 
1472cdf0e10cSrcweir 	return sal_True;
1473cdf0e10cSrcweir }
1474cdf0e10cSrcweir 
1475cdf0e10cSrcweir //------------------------------------------------------------------------
1476cdf0e10cSrcweir void FmFilterNavigator::InitEntry(SvLBoxEntry* pEntry,
1477cdf0e10cSrcweir 								  const XubString& rStr,
1478cdf0e10cSrcweir 								  const Image& rImg1,
1479cdf0e10cSrcweir 								  const Image& rImg2,
1480cdf0e10cSrcweir                                                                   SvLBoxButtonKind eButtonKind)
1481cdf0e10cSrcweir {
1482cdf0e10cSrcweir 	SvTreeListBox::InitEntry( pEntry, rStr, rImg1, rImg2, eButtonKind );
1483cdf0e10cSrcweir 	SvLBoxString* pString = NULL;
1484cdf0e10cSrcweir 
1485cdf0e10cSrcweir 	if (((FmFilterData*)pEntry->GetUserData())->ISA(FmFilterItem))
1486cdf0e10cSrcweir 		pString = new FmFilterString(pEntry, 0, rStr, ((FmFilterItem*)pEntry->GetUserData())->GetFieldName());
1487cdf0e10cSrcweir 	else if (((FmFilterData*)pEntry->GetUserData())->ISA(FmFilterItems))
1488cdf0e10cSrcweir 		pString = new FmFilterItemsString(pEntry, 0, rStr );
1489cdf0e10cSrcweir 
1490cdf0e10cSrcweir 	if (pString)
1491cdf0e10cSrcweir 		pEntry->ReplaceItem( pString, 1 );
1492cdf0e10cSrcweir }
1493cdf0e10cSrcweir 
1494cdf0e10cSrcweir //------------------------------------------------------------------------
1495cdf0e10cSrcweir sal_Bool FmFilterNavigator::Select( SvLBoxEntry* pEntry, sal_Bool bSelect )
1496cdf0e10cSrcweir {
1497cdf0e10cSrcweir 	if (bSelect == IsSelected(pEntry))	// das passiert manchmal, ich glaube, die Basisklasse geht zu sehr auf Nummer sicher ;)
1498cdf0e10cSrcweir 		return sal_True;
1499cdf0e10cSrcweir 
1500cdf0e10cSrcweir 	if (SvTreeListBox::Select(pEntry, bSelect))
1501cdf0e10cSrcweir 	{
1502cdf0e10cSrcweir 		if (bSelect)
1503cdf0e10cSrcweir 		{
1504cdf0e10cSrcweir 			FmFormItem* pFormItem = NULL;
1505cdf0e10cSrcweir 			if (((FmFilterData*)pEntry->GetUserData())->ISA(FmFilterItem))
1506cdf0e10cSrcweir 				pFormItem = (FmFormItem*)((FmFilterItem*)pEntry->GetUserData())->GetParent()->GetParent();
1507cdf0e10cSrcweir 			else if (((FmFilterData*)pEntry->GetUserData())->ISA(FmFilterItems))
1508cdf0e10cSrcweir 				pFormItem = (FmFormItem*)((FmFilterItem*)pEntry->GetUserData())->GetParent()->GetParent();
1509cdf0e10cSrcweir 			else if (((FmFilterData*)pEntry->GetUserData())->ISA(FmFormItem))
1510cdf0e10cSrcweir 				pFormItem = (FmFormItem*)pEntry->GetUserData();
1511cdf0e10cSrcweir 
1512cdf0e10cSrcweir 			if (pFormItem)
1513cdf0e10cSrcweir 			{
1514cdf0e10cSrcweir 				// will the controller be exchanged?
1515cdf0e10cSrcweir 				if (((FmFilterData*)pEntry->GetUserData())->ISA(FmFilterItem))
1516cdf0e10cSrcweir 					m_pModel->SetCurrentItems((FmFilterItems*)((FmFilterItem*)pEntry->GetUserData())->GetParent());
1517cdf0e10cSrcweir 				else if (((FmFilterData*)pEntry->GetUserData())->ISA(FmFilterItems))
1518cdf0e10cSrcweir 					m_pModel->SetCurrentItems((FmFilterItems*)pEntry->GetUserData());
1519cdf0e10cSrcweir 				else if (((FmFilterData*)pEntry->GetUserData())->ISA(FmFormItem))
1520cdf0e10cSrcweir 					m_pModel->SetCurrentController(((FmFormItem*)pEntry->GetUserData())->GetController());
1521cdf0e10cSrcweir 			}
1522cdf0e10cSrcweir 		}
1523cdf0e10cSrcweir 		return sal_True;
1524cdf0e10cSrcweir 	}
1525cdf0e10cSrcweir 	else
1526cdf0e10cSrcweir 		return sal_False;
1527cdf0e10cSrcweir }
1528cdf0e10cSrcweir 
1529cdf0e10cSrcweir //------------------------------------------------------------------------
1530cdf0e10cSrcweir void FmFilterNavigator::Notify( SfxBroadcaster& /*rBC*/, const SfxHint& rHint )
1531cdf0e10cSrcweir {
1532cdf0e10cSrcweir 	if (rHint.ISA(FmFilterInsertedHint))
1533cdf0e10cSrcweir 	{
1534cdf0e10cSrcweir 		FmFilterInsertedHint* pHint = (FmFilterInsertedHint*)&rHint;
1535cdf0e10cSrcweir 		Insert(pHint->GetData(), pHint->GetPos());
1536cdf0e10cSrcweir 	}
1537cdf0e10cSrcweir 	else if( rHint.ISA(FilterClearingHint) )
1538cdf0e10cSrcweir 	{
1539cdf0e10cSrcweir 		SvTreeListBox::Clear();
1540cdf0e10cSrcweir 	}
1541cdf0e10cSrcweir 	else if( rHint.ISA(FmFilterRemovedHint) )
1542cdf0e10cSrcweir 	{
1543cdf0e10cSrcweir 		FmFilterRemovedHint* pHint = (FmFilterRemovedHint*)&rHint;
1544cdf0e10cSrcweir 		Remove(pHint->GetData());
1545cdf0e10cSrcweir 	}
1546cdf0e10cSrcweir 	else if( rHint.ISA(FmFilterTextChangedHint) )
1547cdf0e10cSrcweir 	{
1548cdf0e10cSrcweir 		FmFilterTextChangedHint* pHint = (FmFilterTextChangedHint*)&rHint;
1549cdf0e10cSrcweir 		SvLBoxEntry* pEntry = FindEntry(pHint->GetData());
1550cdf0e10cSrcweir 		if (pEntry)
1551cdf0e10cSrcweir 			SetEntryText( pEntry, pHint->GetData()->GetText());
1552cdf0e10cSrcweir 	}
1553cdf0e10cSrcweir 	else if( rHint.ISA(FmFilterCurrentChangedHint) )
1554cdf0e10cSrcweir 	{
1555cdf0e10cSrcweir 		// invalidate the entries
1556cdf0e10cSrcweir 		for (SvLBoxEntry* pEntry = First(); pEntry != NULL;
1557cdf0e10cSrcweir 			 pEntry = Next(pEntry))
1558cdf0e10cSrcweir 			GetModel()->InvalidateEntry( pEntry );
1559cdf0e10cSrcweir 	}
1560cdf0e10cSrcweir }
1561cdf0e10cSrcweir 
1562cdf0e10cSrcweir //------------------------------------------------------------------------
1563cdf0e10cSrcweir SvLBoxEntry* FmFilterNavigator::FindEntry(const FmFilterData* pItem) const
1564cdf0e10cSrcweir {
1565cdf0e10cSrcweir 	SvLBoxEntry* pEntry = NULL;
1566cdf0e10cSrcweir 	if (pItem)
1567cdf0e10cSrcweir 	{
1568cdf0e10cSrcweir 		for (pEntry = First(); pEntry != NULL; pEntry = Next( pEntry ))
1569cdf0e10cSrcweir 		{
1570cdf0e10cSrcweir 			FmFilterData* pEntryItem = (FmFilterData*)pEntry->GetUserData();
1571cdf0e10cSrcweir 			if (pEntryItem == pItem)
1572cdf0e10cSrcweir 				break;
1573cdf0e10cSrcweir 		}
1574cdf0e10cSrcweir 	}
1575cdf0e10cSrcweir 	return pEntry;
1576cdf0e10cSrcweir }
1577cdf0e10cSrcweir 
1578cdf0e10cSrcweir //------------------------------------------------------------------------
1579cdf0e10cSrcweir void FmFilterNavigator::Insert(FmFilterData* pItem, sal_Int32 nPos)
1580cdf0e10cSrcweir {
1581cdf0e10cSrcweir 	const FmParentData* pParent = pItem->GetParent() ? pItem->GetParent() : GetFilterModel();
1582cdf0e10cSrcweir 
1583cdf0e10cSrcweir 	// insert the item
1584cdf0e10cSrcweir 	SvLBoxEntry* pParentEntry = FindEntry( pParent );
1585cdf0e10cSrcweir 	SvLBoxEntry* pNewEntry = InsertEntry(pItem->GetText(), pItem->GetImage(), pItem->GetImage(), pParentEntry, sal_False, nPos, pItem );
1586cdf0e10cSrcweir 	if ( pNewEntry )
1587cdf0e10cSrcweir 	{
1588cdf0e10cSrcweir 		SetExpandedEntryBmp( pNewEntry, pItem->GetImage( BMP_COLOR_HIGHCONTRAST ), BMP_COLOR_HIGHCONTRAST );
1589cdf0e10cSrcweir 		SetCollapsedEntryBmp( pNewEntry, pItem->GetImage( BMP_COLOR_HIGHCONTRAST ), BMP_COLOR_HIGHCONTRAST );
1590cdf0e10cSrcweir 	}
1591cdf0e10cSrcweir     if ( pParentEntry )
1592cdf0e10cSrcweir         Expand( pParentEntry );
1593cdf0e10cSrcweir }
1594cdf0e10cSrcweir 
1595cdf0e10cSrcweir //------------------------------------------------------------------------
1596cdf0e10cSrcweir void FmFilterNavigator::Remove(FmFilterData* pItem)
1597cdf0e10cSrcweir {
1598cdf0e10cSrcweir 	// der Entry zu den Daten
1599cdf0e10cSrcweir 	SvLBoxEntry* pEntry = FindEntry(pItem);
1600cdf0e10cSrcweir 
1601cdf0e10cSrcweir 	if (pEntry == m_pEditingCurrently)
1602cdf0e10cSrcweir 		// cancel editing
1603cdf0e10cSrcweir 		EndEditing(sal_True);
1604cdf0e10cSrcweir 
1605cdf0e10cSrcweir 	if (pEntry)
1606cdf0e10cSrcweir 		GetModel()->Remove( pEntry );
1607cdf0e10cSrcweir }
1608cdf0e10cSrcweir // -----------------------------------------------------------------------------
1609cdf0e10cSrcweir FmFormItem* FmFilterNavigator::getSelectedFilterItems(::std::vector<FmFilterItem*>& _rItemList)
1610cdf0e10cSrcweir {
1611cdf0e10cSrcweir 	// be sure that the data is only used within only one form!
1612cdf0e10cSrcweir 	FmFormItem* pFirstItem = NULL;
1613cdf0e10cSrcweir 
1614cdf0e10cSrcweir 	sal_Bool bHandled = sal_True;
1615cdf0e10cSrcweir 	sal_Bool bFoundSomething = sal_False;
1616cdf0e10cSrcweir 	for (SvLBoxEntry* pEntry = FirstSelected();
1617cdf0e10cSrcweir 		 bHandled && pEntry != NULL;
1618cdf0e10cSrcweir 		 pEntry = NextSelected(pEntry))
1619cdf0e10cSrcweir 	{
1620cdf0e10cSrcweir 		FmFilterItem* pFilter = PTR_CAST(FmFilterItem, (FmFilterData*)pEntry->GetUserData());
1621cdf0e10cSrcweir 		if (pFilter)
1622cdf0e10cSrcweir 		{
1623cdf0e10cSrcweir 			FmFormItem* pForm = PTR_CAST(FmFormItem,pFilter->GetParent()->GetParent());
1624cdf0e10cSrcweir 			if (!pForm)
1625cdf0e10cSrcweir 				bHandled = sal_False;
1626cdf0e10cSrcweir 			else if (!pFirstItem)
1627cdf0e10cSrcweir 				pFirstItem = pForm;
1628cdf0e10cSrcweir 			else if (pFirstItem != pForm)
1629cdf0e10cSrcweir 				bHandled = sal_False;
1630cdf0e10cSrcweir 
1631cdf0e10cSrcweir 			if (bHandled)
1632cdf0e10cSrcweir 			{
1633cdf0e10cSrcweir 				_rItemList.push_back(pFilter);
1634cdf0e10cSrcweir 				bFoundSomething = sal_True;
1635cdf0e10cSrcweir 			}
1636cdf0e10cSrcweir 		}
1637cdf0e10cSrcweir 	}
1638cdf0e10cSrcweir 	if ( !bHandled || !bFoundSomething )
1639cdf0e10cSrcweir 		pFirstItem = NULL;
1640cdf0e10cSrcweir 	return pFirstItem;
1641cdf0e10cSrcweir }
1642cdf0e10cSrcweir // -----------------------------------------------------------------------------
1643cdf0e10cSrcweir void FmFilterNavigator::insertFilterItem(const ::std::vector<FmFilterItem*>& _rFilterList,FmFilterItems* _pTargetItems,sal_Bool _bCopy)
1644cdf0e10cSrcweir {
1645cdf0e10cSrcweir 	::std::vector<FmFilterItem*>::const_iterator aEnd = _rFilterList.end();
1646cdf0e10cSrcweir 	for (   ::std::vector< FmFilterItem* >::const_iterator i = _rFilterList.begin();
1647cdf0e10cSrcweir             i != aEnd;
1648cdf0e10cSrcweir             ++i
1649cdf0e10cSrcweir         )
1650cdf0e10cSrcweir 	{
1651cdf0e10cSrcweir         FmFilterItem* pLookupItem( *i );
1652cdf0e10cSrcweir 		if ( pLookupItem->GetParent() == _pTargetItems )
1653cdf0e10cSrcweir 			continue;
1654cdf0e10cSrcweir 
1655cdf0e10cSrcweir 		FmFilterItem* pFilterItem = _pTargetItems->Find( pLookupItem->GetComponentIndex() );
1656cdf0e10cSrcweir 		String aText = pLookupItem->GetText();
1657cdf0e10cSrcweir 		if ( !pFilterItem )
1658cdf0e10cSrcweir 		{
1659cdf0e10cSrcweir 			pFilterItem = new FmFilterItem( m_pModel->getORB(), _pTargetItems, pLookupItem->GetFieldName(), aText, pLookupItem->GetComponentIndex() );
1660cdf0e10cSrcweir 			m_pModel->Append( _pTargetItems, pFilterItem );
1661cdf0e10cSrcweir 		}
1662cdf0e10cSrcweir 
1663cdf0e10cSrcweir 		if ( !_bCopy )
1664cdf0e10cSrcweir 			m_pModel->Remove( pLookupItem );
1665cdf0e10cSrcweir 
1666cdf0e10cSrcweir 		// now set the text for the new dragged item
1667cdf0e10cSrcweir 		m_pModel->SetTextForItem( pFilterItem, aText );
1668cdf0e10cSrcweir 	}
1669cdf0e10cSrcweir 
1670cdf0e10cSrcweir 	m_pModel->EnsureEmptyFilterRows( *_pTargetItems->GetParent() );
1671cdf0e10cSrcweir }
1672cdf0e10cSrcweir 
1673cdf0e10cSrcweir //------------------------------------------------------------------------------
1674cdf0e10cSrcweir void FmFilterNavigator::StartDrag( sal_Int8 /*_nAction*/, const Point& /*_rPosPixel*/ )
1675cdf0e10cSrcweir {
1676cdf0e10cSrcweir 	EndSelection();
1677cdf0e10cSrcweir 
1678cdf0e10cSrcweir 	// be sure that the data is only used within a only one form!
1679cdf0e10cSrcweir 	m_aControlExchange.prepareDrag();
1680cdf0e10cSrcweir 
1681cdf0e10cSrcweir 	::std::vector<FmFilterItem*> aItemList;
1682cdf0e10cSrcweir 	if ( FmFormItem* pFirstItem = getSelectedFilterItems(aItemList) )
1683cdf0e10cSrcweir 	{
1684cdf0e10cSrcweir 		m_aControlExchange->setDraggedEntries(aItemList);
1685cdf0e10cSrcweir 		m_aControlExchange->setFormItem(pFirstItem);
1686cdf0e10cSrcweir 		m_aControlExchange.startDrag( DND_ACTION_COPYMOVE );
1687cdf0e10cSrcweir 	}
1688cdf0e10cSrcweir }
1689cdf0e10cSrcweir 
1690cdf0e10cSrcweir //------------------------------------------------------------------------------
1691cdf0e10cSrcweir void FmFilterNavigator::Command( const CommandEvent& rEvt )
1692cdf0e10cSrcweir {
1693cdf0e10cSrcweir 	sal_Bool bHandled = sal_False;
1694cdf0e10cSrcweir 	switch (rEvt.GetCommand())
1695cdf0e10cSrcweir 	{
1696cdf0e10cSrcweir 		case COMMAND_CONTEXTMENU:
1697cdf0e10cSrcweir 		{
1698cdf0e10cSrcweir 			// die Stelle, an der geklickt wurde
1699cdf0e10cSrcweir 			Point aWhere;
1700cdf0e10cSrcweir 			SvLBoxEntry* pClicked = NULL;
1701cdf0e10cSrcweir 			if (rEvt.IsMouseEvent())
1702cdf0e10cSrcweir 			{
1703cdf0e10cSrcweir 				aWhere = rEvt.GetMousePosPixel();
1704cdf0e10cSrcweir 				pClicked = GetEntry(aWhere);
1705cdf0e10cSrcweir 				if (pClicked == NULL)
1706cdf0e10cSrcweir 					break;
1707cdf0e10cSrcweir 
1708cdf0e10cSrcweir 				if (!IsSelected(pClicked))
1709cdf0e10cSrcweir 				{
1710cdf0e10cSrcweir 					SelectAll(sal_False);
1711cdf0e10cSrcweir 					Select(pClicked, sal_True);
1712cdf0e10cSrcweir 					SetCurEntry(pClicked);
1713cdf0e10cSrcweir 				}
1714cdf0e10cSrcweir 			}
1715cdf0e10cSrcweir 			else
1716cdf0e10cSrcweir 			{
1717cdf0e10cSrcweir 				pClicked = GetCurEntry();
1718cdf0e10cSrcweir 				if (!pClicked)
1719cdf0e10cSrcweir 					break;
1720cdf0e10cSrcweir 				aWhere = GetEntryPosition( pClicked );
1721cdf0e10cSrcweir 			}
1722cdf0e10cSrcweir 
1723cdf0e10cSrcweir 			::std::vector<FmFilterData*> aSelectList;
1724cdf0e10cSrcweir 			for (SvLBoxEntry* pEntry = FirstSelected();
1725cdf0e10cSrcweir 				 pEntry != NULL;
1726cdf0e10cSrcweir 				 pEntry = NextSelected(pEntry))
1727cdf0e10cSrcweir 			{
1728cdf0e10cSrcweir 				// don't delete forms
1729cdf0e10cSrcweir 				FmFormItem* pForm = PTR_CAST(FmFormItem, (FmFilterData*)pEntry->GetUserData());
1730cdf0e10cSrcweir 				if (!pForm)
1731cdf0e10cSrcweir 					aSelectList.push_back((FmFilterData*)pEntry->GetUserData());
1732cdf0e10cSrcweir 			}
1733cdf0e10cSrcweir 			if (aSelectList.size() == 1)
1734cdf0e10cSrcweir 			{
1735cdf0e10cSrcweir 				// don't delete the only empty row of a form
1736cdf0e10cSrcweir 				FmFilterItems* pFilterItems = PTR_CAST(FmFilterItems, aSelectList[0]);
1737cdf0e10cSrcweir 				if (pFilterItems && pFilterItems->GetChildren().empty()
1738cdf0e10cSrcweir 					&& pFilterItems->GetParent()->GetChildren().size() == 1)
1739cdf0e10cSrcweir 					aSelectList.clear();
1740cdf0e10cSrcweir 			}
1741cdf0e10cSrcweir 
1742cdf0e10cSrcweir 			PopupMenu aContextMenu(SVX_RES(RID_FM_FILTER_MENU));
1743cdf0e10cSrcweir 
1744cdf0e10cSrcweir 			// every condition could be deleted except the first one if its the only one
1745cdf0e10cSrcweir 			aContextMenu.EnableItem( SID_FM_DELETE, !aSelectList.empty() );
1746cdf0e10cSrcweir 
1747cdf0e10cSrcweir 			//
1748cdf0e10cSrcweir 			sal_Bool bEdit = PTR_CAST(FmFilterItem, (FmFilterData*)pClicked->GetUserData()) != NULL &&
1749cdf0e10cSrcweir 				IsSelected(pClicked) && GetSelectionCount() == 1;
1750cdf0e10cSrcweir 
1751cdf0e10cSrcweir 			aContextMenu.EnableItem( SID_FM_FILTER_EDIT,
1752cdf0e10cSrcweir 				bEdit );
1753cdf0e10cSrcweir 			aContextMenu.EnableItem( SID_FM_FILTER_IS_NULL,
1754cdf0e10cSrcweir 				bEdit );
1755cdf0e10cSrcweir 			aContextMenu.EnableItem( SID_FM_FILTER_IS_NOT_NULL,
1756cdf0e10cSrcweir 				bEdit );
1757cdf0e10cSrcweir 
1758cdf0e10cSrcweir 			aContextMenu.RemoveDisabledEntries(sal_True, sal_True);
1759cdf0e10cSrcweir 			sal_uInt16 nSlotId = aContextMenu.Execute( this, aWhere );
1760cdf0e10cSrcweir 			switch( nSlotId )
1761cdf0e10cSrcweir 			{
1762cdf0e10cSrcweir 				case SID_FM_FILTER_EDIT:
1763cdf0e10cSrcweir 				{
1764cdf0e10cSrcweir 					EditEntry( pClicked );
1765cdf0e10cSrcweir 				}	break;
1766cdf0e10cSrcweir 				case SID_FM_FILTER_IS_NULL:
1767cdf0e10cSrcweir 				case SID_FM_FILTER_IS_NOT_NULL:
1768cdf0e10cSrcweir 				{
1769cdf0e10cSrcweir 					UniString aErrorMsg;
1770cdf0e10cSrcweir 					UniString aText;
1771cdf0e10cSrcweir 					if (nSlotId == SID_FM_FILTER_IS_NULL)
1772cdf0e10cSrcweir 						aText.AssignAscii("IS NULL");
1773cdf0e10cSrcweir 					else
1774cdf0e10cSrcweir 						aText.AssignAscii("IS NOT NULL");
1775cdf0e10cSrcweir 
1776cdf0e10cSrcweir 					m_pModel->ValidateText((FmFilterItem*)pClicked->GetUserData(),
1777cdf0e10cSrcweir 											aText, aErrorMsg);
1778cdf0e10cSrcweir 					m_pModel->SetTextForItem((FmFilterItem*)pClicked->GetUserData(), aText);
1779cdf0e10cSrcweir 				}	break;
1780cdf0e10cSrcweir 				case SID_FM_DELETE:
1781cdf0e10cSrcweir 				{
1782cdf0e10cSrcweir 					DeleteSelection();
1783cdf0e10cSrcweir 				}	break;
1784cdf0e10cSrcweir 			}
1785cdf0e10cSrcweir 			bHandled = sal_True;
1786cdf0e10cSrcweir 		} break;
1787cdf0e10cSrcweir 	}
1788cdf0e10cSrcweir 
1789cdf0e10cSrcweir 	if (!bHandled)
1790cdf0e10cSrcweir 		SvTreeListBox::Command( rEvt );
1791cdf0e10cSrcweir }
1792cdf0e10cSrcweir // -----------------------------------------------------------------------------
1793cdf0e10cSrcweir SvLBoxEntry* FmFilterNavigator::getNextEntry(SvLBoxEntry* _pStartWith)
1794cdf0e10cSrcweir {
1795cdf0e10cSrcweir 	SvLBoxEntry* pEntry = _pStartWith ? _pStartWith : LastSelected();
1796cdf0e10cSrcweir 	pEntry = Next(pEntry);
1797cdf0e10cSrcweir 	// we need the next filter entry
1798cdf0e10cSrcweir 	while( pEntry && GetChildCount( pEntry ) == 0 && pEntry != Last() )
1799cdf0e10cSrcweir 		pEntry = Next(pEntry);
1800cdf0e10cSrcweir 	return pEntry;
1801cdf0e10cSrcweir }
1802cdf0e10cSrcweir // -----------------------------------------------------------------------------
1803cdf0e10cSrcweir SvLBoxEntry* FmFilterNavigator::getPrevEntry(SvLBoxEntry* _pStartWith)
1804cdf0e10cSrcweir {
1805cdf0e10cSrcweir 	SvLBoxEntry* pEntry = _pStartWith ? _pStartWith : FirstSelected();
1806cdf0e10cSrcweir 	pEntry = Prev(pEntry);
1807cdf0e10cSrcweir 	// check if the previous entry is a filter, if so get the next prev
1808cdf0e10cSrcweir 	if ( pEntry && GetChildCount( pEntry ) != 0 )
1809cdf0e10cSrcweir 	{
1810cdf0e10cSrcweir 		pEntry = Prev(pEntry);
1811cdf0e10cSrcweir 		// if the entry is still no leaf return
1812cdf0e10cSrcweir 		if ( pEntry && GetChildCount( pEntry ) != 0 )
1813cdf0e10cSrcweir 			pEntry = NULL;
1814cdf0e10cSrcweir 	}
1815cdf0e10cSrcweir 	return pEntry;
1816cdf0e10cSrcweir }
1817cdf0e10cSrcweir //------------------------------------------------------------------------
1818cdf0e10cSrcweir void FmFilterNavigator::KeyInput(const KeyEvent& rKEvt)
1819cdf0e10cSrcweir {
1820cdf0e10cSrcweir 	const KeyCode&  rKeyCode = rKEvt.GetKeyCode();
1821cdf0e10cSrcweir 
1822cdf0e10cSrcweir     switch ( rKeyCode.GetCode() )
1823cdf0e10cSrcweir     {
1824cdf0e10cSrcweir     case KEY_UP:
1825cdf0e10cSrcweir     case KEY_DOWN:
1826cdf0e10cSrcweir     {
1827cdf0e10cSrcweir         if ( !rKeyCode.IsMod1() || !rKeyCode.IsMod2() || rKeyCode.IsShift() )
1828cdf0e10cSrcweir             break;
1829cdf0e10cSrcweir 
1830cdf0e10cSrcweir         ::std::vector<FmFilterItem*> aItemList;
1831cdf0e10cSrcweir 		if ( !getSelectedFilterItems( aItemList ) )
1832cdf0e10cSrcweir             break;
1833cdf0e10cSrcweir 
1834cdf0e10cSrcweir 		::std::mem_fun1_t<SvLBoxEntry*,FmFilterNavigator,SvLBoxEntry*> getter = ::std::mem_fun(&FmFilterNavigator::getNextEntry);
1835cdf0e10cSrcweir 		if ( rKeyCode.GetCode() == KEY_UP )
1836cdf0e10cSrcweir 			getter = ::std::mem_fun(&FmFilterNavigator::getPrevEntry);
1837cdf0e10cSrcweir 
1838cdf0e10cSrcweir 		SvLBoxEntry* pTarget = getter( this, NULL );
1839cdf0e10cSrcweir 		if ( !pTarget )
1840cdf0e10cSrcweir             break;
1841cdf0e10cSrcweir 
1842cdf0e10cSrcweir         FmFilterItems* pTargetItems = getTargetItems( pTarget );
1843cdf0e10cSrcweir 		if ( !pTargetItems )
1844cdf0e10cSrcweir             break;
1845cdf0e10cSrcweir 
1846cdf0e10cSrcweir         ::std::vector<FmFilterItem*>::const_iterator aEnd = aItemList.end();
1847cdf0e10cSrcweir 		sal_Bool bNextTargetItem = sal_True;
1848cdf0e10cSrcweir 		while ( bNextTargetItem )
1849cdf0e10cSrcweir 		{
1850cdf0e10cSrcweir 			::std::vector<FmFilterItem*>::const_iterator i = aItemList.begin();
1851cdf0e10cSrcweir 			for (; i != aEnd; ++i)
1852cdf0e10cSrcweir 			{
1853cdf0e10cSrcweir 				if ( (*i)->GetParent() == pTargetItems )
1854cdf0e10cSrcweir 				{
1855cdf0e10cSrcweir 					pTarget = getter(this,pTarget);
1856cdf0e10cSrcweir 					if ( !pTarget )
1857cdf0e10cSrcweir 						return;
1858cdf0e10cSrcweir 					pTargetItems = getTargetItems( pTarget );
1859cdf0e10cSrcweir 					break;
1860cdf0e10cSrcweir 				}
1861cdf0e10cSrcweir 				else
1862cdf0e10cSrcweir 				{
1863cdf0e10cSrcweir 					FmFilterItem* pFilterItem = pTargetItems->Find( (*i)->GetComponentIndex() );
1864cdf0e10cSrcweir 					// we found the text component so jump above
1865cdf0e10cSrcweir 					if ( pFilterItem )
1866cdf0e10cSrcweir 					{
1867cdf0e10cSrcweir 						pTarget = getter( this, pTarget );
1868cdf0e10cSrcweir 						if ( !pTarget )
1869cdf0e10cSrcweir 							return;
1870cdf0e10cSrcweir 
1871cdf0e10cSrcweir                         pTargetItems = getTargetItems( pTarget );
1872cdf0e10cSrcweir 						break;
1873cdf0e10cSrcweir 					}
1874cdf0e10cSrcweir 				}
1875cdf0e10cSrcweir 			}
1876cdf0e10cSrcweir 			bNextTargetItem = i != aEnd && pTargetItems;
1877cdf0e10cSrcweir 		}
1878cdf0e10cSrcweir 
1879cdf0e10cSrcweir 		if ( pTargetItems )
1880cdf0e10cSrcweir 		{
1881cdf0e10cSrcweir 			insertFilterItem( aItemList, pTargetItems );
1882cdf0e10cSrcweir 			return;
1883cdf0e10cSrcweir 		}
1884cdf0e10cSrcweir     }
1885cdf0e10cSrcweir     break;
1886cdf0e10cSrcweir 
1887cdf0e10cSrcweir     case KEY_DELETE:
1888cdf0e10cSrcweir     {
1889cdf0e10cSrcweir         if ( rKeyCode.GetModifier() )
1890cdf0e10cSrcweir             break;
1891cdf0e10cSrcweir 
1892cdf0e10cSrcweir         if ( !IsSelected( First() ) || GetEntryCount() > 1 )
1893cdf0e10cSrcweir 			DeleteSelection();
1894cdf0e10cSrcweir 		return;
1895cdf0e10cSrcweir     }
1896cdf0e10cSrcweir     }
1897cdf0e10cSrcweir 
1898cdf0e10cSrcweir     SvTreeListBox::KeyInput(rKEvt);
1899cdf0e10cSrcweir }
1900cdf0e10cSrcweir 
1901cdf0e10cSrcweir //------------------------------------------------------------------------------
1902cdf0e10cSrcweir void FmFilterNavigator::DeleteSelection()
1903cdf0e10cSrcweir {
1904cdf0e10cSrcweir 	// to avoid the deletion of an entry twice (e.g. deletion of a parent and afterward
1905cdf0e10cSrcweir 	// the deletion of it's child, i have to shrink the selecton list
1906cdf0e10cSrcweir 	::std::vector<SvLBoxEntry*> aEntryList;
1907cdf0e10cSrcweir 	for (SvLBoxEntry* pEntry = FirstSelected();
1908cdf0e10cSrcweir 		 pEntry != NULL;
1909cdf0e10cSrcweir 		 pEntry = NextSelected(pEntry))
1910cdf0e10cSrcweir 	{
1911cdf0e10cSrcweir 		FmFilterItem* pFilterItem = PTR_CAST(FmFilterItem, (FmFilterData*)pEntry->GetUserData());
1912cdf0e10cSrcweir 		if (pFilterItem && IsSelected(GetParent(pEntry)))
1913cdf0e10cSrcweir 			continue;
1914cdf0e10cSrcweir 
1915cdf0e10cSrcweir 		FmFormItem* pForm = PTR_CAST(FmFormItem, (FmFilterData*)pEntry->GetUserData());
1916cdf0e10cSrcweir 		if (!pForm)
1917cdf0e10cSrcweir 			aEntryList.push_back(pEntry);
1918cdf0e10cSrcweir 	}
1919cdf0e10cSrcweir 
1920cdf0e10cSrcweir 	// Remove the selection
1921cdf0e10cSrcweir 	SelectAll(sal_False);
1922cdf0e10cSrcweir 
1923cdf0e10cSrcweir 	for (::std::vector<SvLBoxEntry*>::reverse_iterator i = aEntryList.rbegin();
1924cdf0e10cSrcweir 		// link problems with operator ==
1925cdf0e10cSrcweir 		i.base() != aEntryList.rend().base(); i++)
1926cdf0e10cSrcweir 	{
1927cdf0e10cSrcweir 		m_pModel->Remove((FmFilterData*)(*i)->GetUserData());
1928cdf0e10cSrcweir 	}
1929cdf0e10cSrcweir }
1930cdf0e10cSrcweir // -----------------------------------------------------------------------------
1931cdf0e10cSrcweir 
1932cdf0e10cSrcweir //========================================================================
1933cdf0e10cSrcweir // class FmFilterNavigatorWin
1934cdf0e10cSrcweir //========================================================================
1935cdf0e10cSrcweir FmFilterNavigatorWin::FmFilterNavigatorWin( SfxBindings* _pBindings, SfxChildWindow* _pMgr,
1936cdf0e10cSrcweir 							  Window* _pParent )
1937cdf0e10cSrcweir 					 :SfxDockingWindow( _pBindings, _pMgr, _pParent, WinBits(WB_STDMODELESS|WB_SIZEABLE|WB_ROLLABLE|WB_3DLOOK|WB_DOCKABLE) )
1938cdf0e10cSrcweir 					 ,SfxControllerItem( SID_FM_FILTER_NAVIGATOR_CONTROL, *_pBindings )
1939cdf0e10cSrcweir {
1940cdf0e10cSrcweir 	SetHelpId( HID_FILTER_NAVIGATOR_WIN );
1941cdf0e10cSrcweir 
1942cdf0e10cSrcweir 	m_pNavigator = new FmFilterNavigator( this );
1943cdf0e10cSrcweir 	m_pNavigator->Show();
1944cdf0e10cSrcweir 	SetText( SVX_RES(RID_STR_FILTER_NAVIGATOR) );
1945cdf0e10cSrcweir 	SfxDockingWindow::SetFloatingSize( Size(200,200) );
1946cdf0e10cSrcweir }
1947cdf0e10cSrcweir 
1948cdf0e10cSrcweir //------------------------------------------------------------------------
1949cdf0e10cSrcweir FmFilterNavigatorWin::~FmFilterNavigatorWin()
1950cdf0e10cSrcweir {
1951cdf0e10cSrcweir 	delete m_pNavigator;
1952cdf0e10cSrcweir }
1953cdf0e10cSrcweir 
1954cdf0e10cSrcweir //-----------------------------------------------------------------------
1955cdf0e10cSrcweir void FmFilterNavigatorWin::UpdateContent(FmFormShell* pFormShell)
1956cdf0e10cSrcweir {
1957cdf0e10cSrcweir 	if (!pFormShell)
1958cdf0e10cSrcweir 		m_pNavigator->UpdateContent( NULL, NULL );
1959cdf0e10cSrcweir 	else
1960cdf0e10cSrcweir 	{
1961cdf0e10cSrcweir 		Reference< XFormController >  xController(pFormShell->GetImpl()->getActiveInternalController());
1962cdf0e10cSrcweir 		Reference< XIndexAccess >	xContainer;
1963cdf0e10cSrcweir 		if (xController.is())
1964cdf0e10cSrcweir 		{
1965cdf0e10cSrcweir 			Reference< XChild >  xChild(xController, UNO_QUERY);
1966cdf0e10cSrcweir 			for (Reference< XInterface >  xParent(xChild->getParent());
1967cdf0e10cSrcweir 				 xParent.is();
1968cdf0e10cSrcweir 				 xParent = xChild.is() ? xChild->getParent() : Reference< XInterface > ())
1969cdf0e10cSrcweir 			{
1970cdf0e10cSrcweir 				xContainer = Reference< XIndexAccess > (xParent, UNO_QUERY);
1971cdf0e10cSrcweir 				xChild = Reference< XChild > (xParent, UNO_QUERY);
1972cdf0e10cSrcweir 			}
1973cdf0e10cSrcweir 		}
1974cdf0e10cSrcweir 		m_pNavigator->UpdateContent(xContainer, xController);
1975cdf0e10cSrcweir 	}
1976cdf0e10cSrcweir }
1977cdf0e10cSrcweir 
1978cdf0e10cSrcweir //-----------------------------------------------------------------------
1979cdf0e10cSrcweir void FmFilterNavigatorWin::StateChanged( sal_uInt16 nSID, SfxItemState eState, const SfxPoolItem* pState )
1980cdf0e10cSrcweir {
1981cdf0e10cSrcweir 	if( !pState  || SID_FM_FILTER_NAVIGATOR_CONTROL != nSID )
1982cdf0e10cSrcweir 		return;
1983cdf0e10cSrcweir 
1984cdf0e10cSrcweir 	if( eState >= SFX_ITEM_AVAILABLE )
1985cdf0e10cSrcweir 	{
1986cdf0e10cSrcweir 		FmFormShell* pShell = PTR_CAST( FmFormShell,((SfxObjectItem*)pState)->GetShell() );
1987cdf0e10cSrcweir 		UpdateContent( pShell );
1988cdf0e10cSrcweir 	}
1989cdf0e10cSrcweir 	else
1990cdf0e10cSrcweir 		UpdateContent( NULL );
1991cdf0e10cSrcweir }
1992cdf0e10cSrcweir 
1993cdf0e10cSrcweir //-----------------------------------------------------------------------
1994cdf0e10cSrcweir sal_Bool FmFilterNavigatorWin::Close()
1995cdf0e10cSrcweir {
1996cdf0e10cSrcweir 	if ( m_pNavigator && m_pNavigator->IsEditingActive() )
1997cdf0e10cSrcweir 		m_pNavigator->EndEditing();
1998cdf0e10cSrcweir 
1999cdf0e10cSrcweir 	if ( m_pNavigator && m_pNavigator->IsEditingActive() )
2000cdf0e10cSrcweir 		// the EndEditing was vetoed (perhaps of an syntax error or such)
2001cdf0e10cSrcweir 		return sal_False;
2002cdf0e10cSrcweir 
2003cdf0e10cSrcweir 	UpdateContent( NULL );
2004cdf0e10cSrcweir 	return SfxDockingWindow::Close();
2005cdf0e10cSrcweir }
2006cdf0e10cSrcweir 
2007cdf0e10cSrcweir //-----------------------------------------------------------------------
2008cdf0e10cSrcweir void FmFilterNavigatorWin::FillInfo( SfxChildWinInfo& rInfo ) const
2009cdf0e10cSrcweir {
2010cdf0e10cSrcweir 	SfxDockingWindow::FillInfo( rInfo );
2011cdf0e10cSrcweir 	rInfo.bVisible = sal_False;
2012cdf0e10cSrcweir }
2013cdf0e10cSrcweir 
2014cdf0e10cSrcweir //-----------------------------------------------------------------------
2015cdf0e10cSrcweir Size FmFilterNavigatorWin::CalcDockingSize( SfxChildAlignment eAlign )
2016cdf0e10cSrcweir {
2017cdf0e10cSrcweir 	if ( ( eAlign == SFX_ALIGN_TOP ) || ( eAlign == SFX_ALIGN_BOTTOM ) )
2018cdf0e10cSrcweir 		return Size();
2019cdf0e10cSrcweir 
2020cdf0e10cSrcweir     return SfxDockingWindow::CalcDockingSize( eAlign );
2021cdf0e10cSrcweir }
2022cdf0e10cSrcweir 
2023cdf0e10cSrcweir //-----------------------------------------------------------------------
2024cdf0e10cSrcweir SfxChildAlignment FmFilterNavigatorWin::CheckAlignment( SfxChildAlignment eActAlign, SfxChildAlignment eAlign )
2025cdf0e10cSrcweir {
2026cdf0e10cSrcweir 	switch (eAlign)
2027cdf0e10cSrcweir 	{
2028cdf0e10cSrcweir 		case SFX_ALIGN_LEFT:
2029cdf0e10cSrcweir 		case SFX_ALIGN_RIGHT:
2030cdf0e10cSrcweir 		case SFX_ALIGN_NOALIGNMENT:
2031cdf0e10cSrcweir 			return (eAlign);
2032cdf0e10cSrcweir         default:
2033cdf0e10cSrcweir             break;
2034cdf0e10cSrcweir 	}
2035cdf0e10cSrcweir 
2036cdf0e10cSrcweir 	return (eActAlign);
2037cdf0e10cSrcweir }
2038cdf0e10cSrcweir 
2039cdf0e10cSrcweir //------------------------------------------------------------------------
2040cdf0e10cSrcweir void FmFilterNavigatorWin::Resize()
2041cdf0e10cSrcweir {
2042cdf0e10cSrcweir 	SfxDockingWindow::Resize();
2043cdf0e10cSrcweir 
2044cdf0e10cSrcweir 	Size aLogOutputSize = PixelToLogic( GetOutputSizePixel(), MAP_APPFONT );
2045cdf0e10cSrcweir 	Size aLogExplSize = aLogOutputSize;
2046cdf0e10cSrcweir 	aLogExplSize.Width() -= 6;
2047cdf0e10cSrcweir 	aLogExplSize.Height() -= 6;
2048cdf0e10cSrcweir 
2049cdf0e10cSrcweir 	Point aExplPos = LogicToPixel( Point(3,3), MAP_APPFONT );
2050cdf0e10cSrcweir 	Size aExplSize = LogicToPixel( aLogExplSize, MAP_APPFONT );
2051cdf0e10cSrcweir 
2052cdf0e10cSrcweir 	m_pNavigator->SetPosSizePixel( aExplPos, aExplSize );
2053cdf0e10cSrcweir }
2054cdf0e10cSrcweir // -----------------------------------------------------------------------------
2055cdf0e10cSrcweir void FmFilterNavigatorWin::GetFocus()
2056cdf0e10cSrcweir {
2057cdf0e10cSrcweir 	// oj #97405#
2058cdf0e10cSrcweir 	if ( m_pNavigator )
2059cdf0e10cSrcweir 		m_pNavigator->GrabFocus();
2060cdf0e10cSrcweir }
2061cdf0e10cSrcweir // -----------------------------------------------------------------------------
2062cdf0e10cSrcweir 
2063cdf0e10cSrcweir 
2064cdf0e10cSrcweir //========================================================================
2065cdf0e10cSrcweir // class FmFilterNavigatorWinMgr
2066cdf0e10cSrcweir //========================================================================
2067cdf0e10cSrcweir SFX_IMPL_DOCKINGWINDOW( FmFilterNavigatorWinMgr, SID_FM_FILTER_NAVIGATOR )
2068cdf0e10cSrcweir 
2069cdf0e10cSrcweir //-----------------------------------------------------------------------
2070cdf0e10cSrcweir FmFilterNavigatorWinMgr::FmFilterNavigatorWinMgr( Window *_pParent, sal_uInt16 _nId,
2071cdf0e10cSrcweir 									SfxBindings *_pBindings, SfxChildWinInfo* _pInfo )
2072cdf0e10cSrcweir 				 :SfxChildWindow( _pParent, _nId )
2073cdf0e10cSrcweir {
2074cdf0e10cSrcweir 	pWindow = new FmFilterNavigatorWin( _pBindings, this, _pParent );
2075cdf0e10cSrcweir 	eChildAlignment = SFX_ALIGN_NOALIGNMENT;
2076cdf0e10cSrcweir 	((SfxDockingWindow*)pWindow)->Initialize( _pInfo );
2077cdf0e10cSrcweir }
2078cdf0e10cSrcweir 
2079cdf0e10cSrcweir //........................................................................
2080cdf0e10cSrcweir }	// namespace svxform
2081cdf0e10cSrcweir //........................................................................
2082