1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include "filtnav.hxx"
23 #include "fmitems.hxx"
25 #include "svx/fmresids.hrc"
27 #include <com/sun/star/awt/XControlModel.hpp>
28 #include <com/sun/star/awt/XControl.hpp>
29 #include <com/sun/star/awt/XTextComponent.hpp>
30 #include <com/sun/star/form/runtime/XFormController.hpp>
31 #include <com/sun/star/lang/XUnoTunnel.hpp>
32 #include <com/sun/star/util/NumberFormatter.hpp>
33 #include <com/sun/star/beans/XFastPropertySet.hpp>
35 #include <comphelper/componentcontext.hxx>
36 #include <comphelper/processfactory.hxx>
37 #include <comphelper/property.hxx>
38 #include <comphelper/sequence.hxx>
39 #include <comphelper/string.hxx>
40 #include <comphelper/uno3.hxx>
41 #include <connectivity/dbtools.hxx>
42 #include <cppuhelper/implbase1.hxx>
43 #include <fmservs.hxx>
44 #include <fmshimp.hxx>
45 #include <rtl/logfile.hxx>
46 #include <sfx2/dispatch.hxx>
47 #include <sfx2/objitem.hxx>
48 #include <sfx2/objsh.hxx>
49 #include <sfx2/request.hxx>
50 #include <svx/dialmgr.hxx>
51 #include <svx/fmshell.hxx>
52 #include <svx/fmtools.hxx>
53 #include <svx/svxids.hrc>
54 #include <tools/shl.hxx>
55 #include <vcl/wrkwin.hxx>
56 #include <tools/diagnose_ex.h>
57 #include <svtools/svlbitm.hxx>
58 #include "svtools/treelistentry.hxx"
59 #include "svtools/viewdataentry.hxx"
63 #define DROP_ACTION_TIMER_INITIAL_TICKS 10
64 // solange dauert es, bis das Scrollen anspringt
65 #define DROP_ACTION_TIMER_SCROLL_TICKS 3
66 // in diesen Intervallen wird jeweils eine Zeile gescrollt
67 #define DROP_ACTION_TIMER_TICK_BASE 10
68 // das ist die Basis, mit der beide Angaben multipliziert werden (in ms)
70 using namespace ::svxform
;
71 using namespace ::connectivity::simple
;
72 using namespace ::connectivity
;
75 //........................................................................
78 //........................................................................
80 using ::com::sun::star::uno::Reference
;
81 using ::com::sun::star::lang::XMultiServiceFactory
;
82 using ::com::sun::star::awt::TextEvent
;
83 using ::com::sun::star::container::XIndexAccess
;
84 using ::com::sun::star::uno::UNO_QUERY
;
85 using ::com::sun::star::beans::XPropertySet
;
86 using ::com::sun::star::form::runtime::XFormController
;
87 using ::com::sun::star::form::runtime::XFilterController
;
88 using ::com::sun::star::form::runtime::XFilterControllerListener
;
89 using ::com::sun::star::form::runtime::FilterEvent
;
90 using ::com::sun::star::lang::EventObject
;
91 using ::com::sun::star::uno::RuntimeException
;
92 using ::com::sun::star::form::XForm
;
93 using ::com::sun::star::container::XChild
;
94 using ::com::sun::star::awt::XControl
;
95 using ::com::sun::star::sdbc::XConnection
;
96 using ::com::sun::star::util::XNumberFormatsSupplier
;
97 using ::com::sun::star::util::XNumberFormatter
;
98 using ::com::sun::star::util::XNumberFormatter2
;
99 using ::com::sun::star::util::NumberFormatter
;
100 using ::com::sun::star::sdbc::XRowSet
;
101 using ::com::sun::star::lang::Locale
;
102 using ::com::sun::star::sdb::SQLContext
;
103 using ::com::sun::star::uno::XInterface
;
104 using ::com::sun::star::uno::UNO_QUERY_THROW
;
105 using ::com::sun::star::uno::UNO_SET_THROW
;
106 using ::com::sun::star::uno::Exception
;
107 using ::com::sun::star::awt::XTextComponent
;
108 using ::com::sun::star::uno::Sequence
;
110 //========================================================================
111 OFilterItemExchange::OFilterItemExchange()
115 //------------------------------------------------------------------------
116 void OFilterItemExchange::AddSupportedFormats()
118 AddFormat(getFormatId());
121 //------------------------------------------------------------------------
122 sal_uInt32
OFilterItemExchange::getFormatId()
124 static sal_uInt32 s_nFormat
= (sal_uInt32
)-1;
125 if ((sal_uInt32
)-1 == s_nFormat
)
127 s_nFormat
= SotExchange::RegisterFormatName(OUString("application/x-openoffice;windows_formatname=\"form.FilterControlExchange\""));
128 DBG_ASSERT((sal_uInt32
)-1 != s_nFormat
, "OFilterExchangeHelper::getFormatId: bad exchange id!");
133 //------------------------------------------------------------------------
134 OLocalExchange
* OFilterExchangeHelper::createExchange() const
136 return new OFilterItemExchange
;
139 //========================================================================
140 TYPEINIT0(FmFilterData
);
141 Image
FmFilterData::GetImage() const
146 //========================================================================
147 TYPEINIT1(FmParentData
, FmFilterData
);
148 //------------------------------------------------------------------------
149 FmParentData::~FmParentData()
151 for (::std::vector
<FmFilterData
*>::const_iterator i
= m_aChildren
.begin();
152 i
!= m_aChildren
.end(); ++i
)
156 //========================================================================
157 TYPEINIT1(FmFormItem
, FmParentData
);
158 //------------------------------------------------------------------------
159 Image
FmFormItem::GetImage() const
165 ImageList
aNavigatorImages( SVX_RES( RID_SVXIMGLIST_FMEXPL
) );
166 aImage
= aNavigatorImages
.GetImage( RID_SVXIMG_FORM
);
171 //========================================================================
172 TYPEINIT1(FmFilterItems
, FmParentData
);
173 //------------------------------------------------------------------------
174 FmFilterItem
* FmFilterItems::Find( const ::sal_Int32 _nFilterComponentIndex
) const
176 for ( ::std::vector
< FmFilterData
* >::const_iterator i
= m_aChildren
.begin();
177 i
!= m_aChildren
.end();
181 FmFilterItem
* pCondition
= PTR_CAST( FmFilterItem
, *i
);
182 DBG_ASSERT( pCondition
, "FmFilterItems::Find: Wrong element in container!" );
183 if ( _nFilterComponentIndex
== pCondition
->GetComponentIndex() )
189 //------------------------------------------------------------------------
190 Image
FmFilterItems::GetImage() const
196 ImageList
aNavigatorImages( SVX_RES( RID_SVXIMGLIST_FMEXPL
) );
197 aImage
= aNavigatorImages
.GetImage( RID_SVXIMG_FILTER
);
202 //========================================================================
203 TYPEINIT1(FmFilterItem
, FmFilterData
);
204 //------------------------------------------------------------------------
205 FmFilterItem::FmFilterItem( FmFilterItems
* pParent
,
206 const OUString
& aFieldName
,
207 const OUString
& aText
,
208 const sal_Int32 _nComponentIndex
)
209 :FmFilterData(pParent
, aText
)
210 ,m_aFieldName(aFieldName
)
211 ,m_nComponentIndex( _nComponentIndex
)
215 //------------------------------------------------------------------------
216 Image
FmFilterItem::GetImage() const
222 ImageList
aNavigatorImages( SVX_RES( RID_SVXIMGLIST_FMEXPL
) );
223 aImage
= aNavigatorImages
.GetImage( RID_SVXIMG_FIELD
);
228 //========================================================================
229 // Hints for communicatition between model and view
230 //========================================================================
231 class FmFilterHint
: public SfxHint
233 FmFilterData
* m_pData
;
237 FmFilterHint(FmFilterData
* pData
):m_pData(pData
){}
238 FmFilterData
* GetData() const { return m_pData
; }
240 TYPEINIT1( FmFilterHint
, SfxHint
);
242 //========================================================================
243 class FmFilterInsertedHint
: public FmFilterHint
245 sal_uLong m_nPos
; // Position relative to the parent of the data
249 FmFilterInsertedHint(FmFilterData
* pData
, sal_uLong nRelPos
)
253 sal_uLong
GetPos() const { return m_nPos
; }
255 TYPEINIT1( FmFilterInsertedHint
, FmFilterHint
);
257 //========================================================================
258 class FmFilterRemovedHint
: public FmFilterHint
262 FmFilterRemovedHint(FmFilterData
* pData
)
263 :FmFilterHint(pData
){}
266 TYPEINIT1( FmFilterRemovedHint
, FmFilterHint
);
268 //========================================================================
269 class FmFilterTextChangedHint
: public FmFilterHint
273 FmFilterTextChangedHint(FmFilterData
* pData
)
274 :FmFilterHint(pData
){}
277 TYPEINIT1( FmFilterTextChangedHint
, FmFilterHint
);
279 //========================================================================
280 class FilterClearingHint
: public SfxHint
284 FilterClearingHint(){}
286 TYPEINIT1( FilterClearingHint
, SfxHint
);
288 //========================================================================
289 class FmFilterCurrentChangedHint
: public SfxHint
293 FmFilterCurrentChangedHint(){}
295 TYPEINIT1( FmFilterCurrentChangedHint
, SfxHint
);
297 //========================================================================
298 // class FmFilterAdapter, Listener an den FilterControls
299 //========================================================================
300 class FmFilterAdapter
: public ::cppu::WeakImplHelper1
< XFilterControllerListener
>
302 FmFilterModel
* m_pModel
;
303 Reference
< XIndexAccess
> m_xControllers
;
306 FmFilterAdapter(FmFilterModel
* pModel
, const Reference
< XIndexAccess
>& xControllers
);
309 virtual void SAL_CALL
disposing(const EventObject
& Source
) throw( RuntimeException
);
311 // XFilterControllerListener
312 virtual void SAL_CALL
predicateExpressionChanged( const FilterEvent
& _Event
) throw (RuntimeException
);
313 virtual void SAL_CALL
disjunctiveTermRemoved( const FilterEvent
& _Event
) throw (RuntimeException
);
314 virtual void SAL_CALL
disjunctiveTermAdded( const FilterEvent
& _Event
) throw (RuntimeException
);
317 void dispose() throw( RuntimeException
);
319 void AddOrRemoveListener( const Reference
< XIndexAccess
>& _rxControllers
, const bool _bAdd
);
321 void setText(sal_Int32 nPos
,
322 const FmFilterItem
* pFilterItem
,
323 const OUString
& rText
);
326 //------------------------------------------------------------------------
327 FmFilterAdapter::FmFilterAdapter(FmFilterModel
* pModel
, const Reference
< XIndexAccess
>& xControllers
)
329 ,m_xControllers( xControllers
)
331 AddOrRemoveListener( m_xControllers
, true );
334 //------------------------------------------------------------------------
335 void FmFilterAdapter::dispose() throw( RuntimeException
)
337 AddOrRemoveListener( m_xControllers
, false );
340 //------------------------------------------------------------------------
341 void FmFilterAdapter::AddOrRemoveListener( const Reference
< XIndexAccess
>& _rxControllers
, const bool _bAdd
)
343 for (sal_Int32 i
= 0, nLen
= _rxControllers
->getCount(); i
< nLen
; ++i
)
345 Reference
< XIndexAccess
> xElement( _rxControllers
->getByIndex(i
), UNO_QUERY
);
348 AddOrRemoveListener( xElement
, _bAdd
);
350 // handle this particular controller
351 Reference
< XFilterController
> xController( xElement
, UNO_QUERY
);
352 OSL_ENSURE( xController
.is(), "FmFilterAdapter::InsertElements: no XFilterController, cannot sync data!" );
353 if ( xController
.is() )
356 xController
->addFilterControllerListener( this );
358 xController
->removeFilterControllerListener( this );
363 //------------------------------------------------------------------------
364 void FmFilterAdapter::setText(sal_Int32 nRowPos
,
365 const FmFilterItem
* pFilterItem
,
366 const OUString
& rText
)
368 FmFormItem
* pFormItem
= PTR_CAST( FmFormItem
, pFilterItem
->GetParent()->GetParent() );
372 Reference
< XFilterController
> xController( pFormItem
->GetController(), UNO_QUERY_THROW
);
373 xController
->setPredicateExpression( pFilterItem
->GetComponentIndex(), nRowPos
, rText
);
375 catch( const Exception
& )
377 DBG_UNHANDLED_EXCEPTION();
383 //------------------------------------------------------------------------
384 void SAL_CALL
FmFilterAdapter::disposing(const EventObject
& /*e*/) throw( RuntimeException
)
388 //------------------------------------------------------------------------
391 OUString
lcl_getLabelName_nothrow( const Reference
< XControl
>& _rxControl
)
396 Reference
< XControl
> xControl( _rxControl
, UNO_SET_THROW
);
397 Reference
< XPropertySet
> xModel( xControl
->getModel(), UNO_QUERY_THROW
);
398 sLabelName
= getLabelName( xModel
);
400 catch( const Exception
& )
402 DBG_UNHANDLED_EXCEPTION();
407 Reference
< XPropertySet
> lcl_getBoundField_nothrow( const Reference
< XControl
>& _rxControl
)
409 Reference
< XPropertySet
> xField
;
412 Reference
< XControl
> xControl( _rxControl
, UNO_SET_THROW
);
413 Reference
< XPropertySet
> xModelProps( xControl
->getModel(), UNO_QUERY_THROW
);
414 xField
.set( xModelProps
->getPropertyValue( FM_PROP_BOUNDFIELD
), UNO_QUERY_THROW
);
416 catch( const Exception
& )
418 DBG_UNHANDLED_EXCEPTION();
424 // XFilterControllerListener
425 //------------------------------------------------------------------------
426 void FmFilterAdapter::predicateExpressionChanged( const FilterEvent
& _Event
) throw( RuntimeException
)
428 SolarMutexGuard aGuard
;
433 // the controller which sent the event
434 Reference
< XFormController
> xController( _Event
.Source
, UNO_QUERY_THROW
);
435 Reference
< XFilterController
> xFilterController( _Event
.Source
, UNO_QUERY_THROW
);
436 Reference
< XForm
> xForm( xController
->getModel(), UNO_QUERY_THROW
);
438 FmFormItem
* pFormItem
= m_pModel
->Find( m_pModel
->m_aChildren
, xForm
);
439 OSL_ENSURE( pFormItem
, "FmFilterAdapter::predicateExpressionChanged: don't know this form!" );
443 const sal_Int32
nActiveTerm( xFilterController
->getActiveTerm() );
445 FmFilterItems
* pFilter
= PTR_CAST( FmFilterItems
, pFormItem
->GetChildren()[ nActiveTerm
] );
446 FmFilterItem
* pFilterItem
= pFilter
->Find( _Event
.FilterComponent
);
449 if ( !_Event
.PredicateExpression
.isEmpty())
451 pFilterItem
->SetText( _Event
.PredicateExpression
);
452 // UI benachrichtigen
453 FmFilterTextChangedHint
aChangeHint(pFilterItem
);
454 m_pModel
->Broadcast( aChangeHint
);
458 // no text anymore so remove the condition
459 m_pModel
->Remove(pFilterItem
);
464 // searching the component by field name
465 OUString
aFieldName( lcl_getLabelName_nothrow( xFilterController
->getFilterComponent( _Event
.FilterComponent
) ) );
467 pFilterItem
= new FmFilterItem( pFilter
, aFieldName
, _Event
.PredicateExpression
, _Event
.FilterComponent
);
468 m_pModel
->Insert(pFilter
->GetChildren().end(), pFilterItem
);
471 // ensure there's one empty term in the filter, just in case the active term was previously empty
472 m_pModel
->EnsureEmptyFilterRows( *pFormItem
);
475 //------------------------------------------------------------------------
476 void SAL_CALL
FmFilterAdapter::disjunctiveTermRemoved( const FilterEvent
& _Event
) throw (RuntimeException
)
478 SolarMutexGuard aGuard
;
480 Reference
< XFormController
> xController( _Event
.Source
, UNO_QUERY_THROW
);
481 Reference
< XFilterController
> xFilterController( _Event
.Source
, UNO_QUERY_THROW
);
482 Reference
< XForm
> xForm( xController
->getModel(), UNO_QUERY_THROW
);
484 FmFormItem
* pFormItem
= m_pModel
->Find( m_pModel
->m_aChildren
, xForm
);
485 OSL_ENSURE( pFormItem
, "FmFilterAdapter::disjunctiveTermRemoved: don't know this form!" );
489 ::std::vector
< FmFilterData
* >& rTermItems
= pFormItem
->GetChildren();
490 const bool bValidIndex
= ( _Event
.DisjunctiveTerm
>= 0 ) && ( (size_t)_Event
.DisjunctiveTerm
< rTermItems
.size() );
491 OSL_ENSURE( bValidIndex
, "FmFilterAdapter::disjunctiveTermRemoved: invalid term index!" );
495 // if the first term was removed, then the to-be first term needs its text updated
496 if ( _Event
.DisjunctiveTerm
== 0 )
498 rTermItems
[1]->SetText( String( SVX_RES( RID_STR_FILTER_FILTER_FOR
) ) );
499 FmFilterTextChangedHint
aChangeHint( rTermItems
[1] );
500 m_pModel
->Broadcast( aChangeHint
);
503 // finally remove the entry from the model
504 m_pModel
->Remove( rTermItems
.begin() + _Event
.DisjunctiveTerm
);
506 // ensure there's one empty term in the filter, just in case the currently removed one was the last empty one
507 m_pModel
->EnsureEmptyFilterRows( *pFormItem
);
510 //------------------------------------------------------------------------
511 void SAL_CALL
FmFilterAdapter::disjunctiveTermAdded( const FilterEvent
& _Event
) throw (RuntimeException
)
513 SolarMutexGuard aGuard
;
515 Reference
< XFormController
> xController( _Event
.Source
, UNO_QUERY_THROW
);
516 Reference
< XFilterController
> xFilterController( _Event
.Source
, UNO_QUERY_THROW
);
517 Reference
< XForm
> xForm( xController
->getModel(), UNO_QUERY_THROW
);
519 FmFormItem
* pFormItem
= m_pModel
->Find( m_pModel
->m_aChildren
, xForm
);
520 OSL_ENSURE( pFormItem
, "FmFilterAdapter::disjunctiveTermAdded: don't know this form!" );
524 const sal_Int32 nInsertPos
= _Event
.DisjunctiveTerm
;
525 bool bValidIndex
= ( nInsertPos
>= 0 ) && ( (size_t)nInsertPos
<= pFormItem
->GetChildren().size() );
528 OSL_FAIL( "FmFilterAdapter::disjunctiveTermAdded: invalid index!" );
532 const ::std::vector
< FmFilterData
* >::iterator insertPos
= pFormItem
->GetChildren().begin() + nInsertPos
;
534 FmFilterItems
* pFilterItems
= new FmFilterItems( pFormItem
, String( SVX_RES( RID_STR_FILTER_FILTER_OR
) ) );
535 m_pModel
->Insert( insertPos
, pFilterItems
);
538 //========================================================================
539 // class FmFilterModel
540 //========================================================================
541 TYPEINIT1(FmFilterModel
, FmParentData
);
542 //------------------------------------------------------------------------
543 FmFilterModel::FmFilterModel()
544 :FmParentData(NULL
, OUString())
545 ,OSQLParserClient(comphelper::getProcessComponentContext())
547 ,m_pCurrentItems(NULL
)
551 //------------------------------------------------------------------------
552 FmFilterModel::~FmFilterModel()
557 //------------------------------------------------------------------------
558 void FmFilterModel::Clear()
561 FilterClearingHint aClearedHint
;
562 Broadcast( aClearedHint
);
567 m_pAdapter
->dispose();
568 m_pAdapter
->release();
572 m_pCurrentItems
= NULL
;
573 m_xController
= NULL
;
574 m_xControllers
= NULL
;
576 for (::std::vector
<FmFilterData
*>::const_iterator i
= m_aChildren
.begin();
577 i
!= m_aChildren
.end(); ++i
)
583 //------------------------------------------------------------------------
584 void FmFilterModel::Update(const Reference
< XIndexAccess
> & xControllers
, const Reference
< XFormController
> & xCurrent
)
586 if ( xCurrent
== m_xController
)
589 if (!xControllers
.is())
595 // there is only a new current controller
596 if ( m_xControllers
!= xControllers
)
600 m_xControllers
= xControllers
;
601 Update(m_xControllers
, this);
603 DBG_ASSERT(xCurrent
.is(), "FmFilterModel::Update(...) no current controller");
605 // Listening for TextChanges
606 m_pAdapter
= new FmFilterAdapter(this, xControllers
);
607 m_pAdapter
->acquire();
609 SetCurrentController(xCurrent
);
610 EnsureEmptyFilterRows( *this );
613 SetCurrentController(xCurrent
);
616 //------------------------------------------------------------------------
617 void FmFilterModel::Update(const Reference
< XIndexAccess
> & xControllers
, FmParentData
* pParent
)
621 sal_Int32 nCount
= xControllers
->getCount();
622 for ( sal_Int32 i
= 0; i
< nCount
; ++i
)
624 Reference
< XFormController
> xController( xControllers
->getByIndex(i
), UNO_QUERY_THROW
);
626 Reference
< XPropertySet
> xFormProperties( xController
->getModel(), UNO_QUERY_THROW
);
628 OSL_VERIFY( xFormProperties
->getPropertyValue( FM_PROP_NAME
) >>= aName
);
630 // Insert a new item for the form
631 FmFormItem
* pFormItem
= new FmFormItem( pParent
, xController
, aName
);
632 Insert( pParent
->GetChildren().end(), pFormItem
);
634 Reference
< XFilterController
> xFilterController( pFormItem
->GetFilterController(), UNO_SET_THROW
);
636 // insert the existing filters for the form
637 String
aTitle( SVX_RES( RID_STR_FILTER_FILTER_FOR
) );
639 Sequence
< Sequence
< OUString
> > aExpressions
= xFilterController
->getPredicateExpressions();
640 for ( const Sequence
< OUString
>* pConjunctionTerm
= aExpressions
.getConstArray();
641 pConjunctionTerm
!= aExpressions
.getConstArray() + aExpressions
.getLength();
645 // we always display one row, even if there's no term to be displayed
646 FmFilterItems
* pFilterItems
= new FmFilterItems( pFormItem
, aTitle
);
647 Insert( pFormItem
->GetChildren().end(), pFilterItems
);
649 const Sequence
< OUString
>& rDisjunction( *pConjunctionTerm
);
650 for ( const OUString
* pDisjunctiveTerm
= rDisjunction
.getConstArray();
651 pDisjunctiveTerm
!= rDisjunction
.getConstArray() + rDisjunction
.getLength();
655 if ( pDisjunctiveTerm
->isEmpty() )
656 // no condition for this particular component in this particular conjunction term
659 const sal_Int32 nComponentIndex
= pDisjunctiveTerm
- rDisjunction
.getConstArray();
661 // determine the display name of the control
662 const Reference
< XControl
> xFilterControl( xFilterController
->getFilterComponent( nComponentIndex
) );
663 const OUString
sDisplayName( lcl_getLabelName_nothrow( xFilterControl
) );
665 // insert a new entry
666 FmFilterItem
* pANDCondition
= new FmFilterItem( pFilterItems
, sDisplayName
, *pDisjunctiveTerm
, nComponentIndex
);
667 Insert( pFilterItems
->GetChildren().end(), pANDCondition
);
670 // title for the next conditions
671 aTitle
= SVX_RESSTR( RID_STR_FILTER_FILTER_OR
);
674 // now add dependent controllers
675 Reference
< XIndexAccess
> xControllerAsIndex( xController
, UNO_QUERY
);
676 Update( xControllerAsIndex
, pFormItem
);
679 catch( const Exception
& )
681 DBG_UNHANDLED_EXCEPTION();
685 //------------------------------------------------------------------------
686 FmFormItem
* FmFilterModel::Find(const ::std::vector
<FmFilterData
*>& rItems
, const Reference
< XFormController
> & xController
) const
688 for (::std::vector
<FmFilterData
*>::const_iterator i
= rItems
.begin();
689 i
!= rItems
.end(); ++i
)
691 FmFormItem
* pForm
= PTR_CAST(FmFormItem
,*i
);
694 if ( xController
== pForm
->GetController() )
698 pForm
= Find(pForm
->GetChildren(), xController
);
707 //------------------------------------------------------------------------
708 FmFormItem
* FmFilterModel::Find(const ::std::vector
<FmFilterData
*>& rItems
, const Reference
< XForm
>& xForm
) const
710 for (::std::vector
<FmFilterData
*>::const_iterator i
= rItems
.begin();
711 i
!= rItems
.end(); ++i
)
713 FmFormItem
* pForm
= PTR_CAST(FmFormItem
,*i
);
716 if (xForm
== pForm
->GetController()->getModel())
720 pForm
= Find(pForm
->GetChildren(), xForm
);
729 //------------------------------------------------------------------------
730 void FmFilterModel::SetCurrentController(const Reference
< XFormController
> & xCurrent
)
732 if ( xCurrent
== m_xController
)
735 m_xController
= xCurrent
;
737 FmFormItem
* pItem
= Find( m_aChildren
, xCurrent
);
743 Reference
< XFilterController
> xFilterController( m_xController
, UNO_QUERY_THROW
);
744 const sal_Int32
nActiveTerm( xFilterController
->getActiveTerm() );
745 if ( pItem
->GetChildren().size() > (size_t)nActiveTerm
)
747 SetCurrentItems( static_cast< FmFilterItems
* >( pItem
->GetChildren()[ nActiveTerm
] ) );
750 catch( const Exception
& )
752 DBG_UNHANDLED_EXCEPTION();
756 //------------------------------------------------------------------------
757 void FmFilterModel::AppendFilterItems( FmFormItem
& _rFormItem
)
759 // insert the condition behind the last filter items
760 ::std::vector
<FmFilterData
*>::reverse_iterator iter
;
761 for ( iter
= _rFormItem
.GetChildren().rbegin();
762 iter
!= _rFormItem
.GetChildren().rend();
766 if ((*iter
)->ISA(FmFilterItems
))
770 sal_Int32 nInsertPos
= iter
.base() - _rFormItem
.GetChildren().begin();
771 // delegate this to the FilterController, it will notify us, which will let us update our model
774 Reference
< XFilterController
> xFilterController( _rFormItem
.GetFilterController(), UNO_SET_THROW
);
775 if ( nInsertPos
>= xFilterController
->getDisjunctiveTerms() )
776 xFilterController
->appendEmptyDisjunctiveTerm();
778 catch( const Exception
& )
780 DBG_UNHANDLED_EXCEPTION();
784 //------------------------------------------------------------------------
785 void FmFilterModel::Insert(const ::std::vector
<FmFilterData
*>::iterator
& rPos
, FmFilterData
* pData
)
787 ::std::vector
<FmFilterData
*>& rItems
= pData
->GetParent()->GetChildren();
788 sal_uLong nPos
= rPos
== rItems
.end() ? LIST_APPEND
: rPos
- rItems
.begin();
789 rItems
.insert(rPos
, pData
);
791 // UI benachrichtigen
792 FmFilterInsertedHint
aInsertedHint(pData
, nPos
);
793 Broadcast( aInsertedHint
);
796 //------------------------------------------------------------------------
797 void FmFilterModel::Remove(FmFilterData
* pData
)
799 FmParentData
* pParent
= pData
->GetParent();
800 ::std::vector
<FmFilterData
*>& rItems
= pParent
->GetChildren();
802 // erase the item from the model
803 ::std::vector
<FmFilterData
*>::iterator i
= ::std::find(rItems
.begin(), rItems
.end(), pData
);
804 DBG_ASSERT(i
!= rItems
.end(), "FmFilterModel::Remove(): unknown Item");
805 // position within the parent
806 sal_Int32 nPos
= i
- rItems
.begin();
807 if (pData
->ISA(FmFilterItems
))
809 FmFormItem
* pFormItem
= (FmFormItem
*)pParent
;
813 Reference
< XFilterController
> xFilterController( pFormItem
->GetFilterController(), UNO_SET_THROW
);
815 bool bEmptyLastTerm
= ( ( nPos
== 0 ) && xFilterController
->getDisjunctiveTerms() == 1 );
816 if ( bEmptyLastTerm
)
818 // remove all children (by setting an empty predicate expression)
819 ::std::vector
< FmFilterData
* >& rChildren
= ((FmFilterItems
*)pData
)->GetChildren();
820 while ( !rChildren
.empty() )
822 ::std::vector
< FmFilterData
* >::iterator removePos
= rChildren
.end() - 1;
823 FmFilterItem
* pFilterItem
= PTR_CAST( FmFilterItem
, *removePos
);
824 m_pAdapter
->setText( nPos
, pFilterItem
, OUString() );
830 xFilterController
->removeDisjunctiveTerm( nPos
);
833 catch( const Exception
& )
835 DBG_UNHANDLED_EXCEPTION();
838 else // FormItems can not be deleted
840 FmFilterItem
* pFilterItem
= PTR_CAST(FmFilterItem
, pData
);
842 // if its the last condition remove the parent
843 if (rItems
.size() == 1)
844 Remove(pFilterItem
->GetParent());
847 // find the position of the father within his father
848 ::std::vector
<FmFilterData
*>& rParentParentItems
= pData
->GetParent()->GetParent()->GetChildren();
849 ::std::vector
<FmFilterData
*>::iterator j
= ::std::find(rParentParentItems
.begin(), rParentParentItems
.end(), pFilterItem
->GetParent());
850 DBG_ASSERT(j
!= rParentParentItems
.end(), "FmFilterModel::Remove(): unknown Item");
851 sal_Int32 nParentPos
= j
- rParentParentItems
.begin();
853 // EmptyText removes the filter
854 m_pAdapter
->setText(nParentPos
, pFilterItem
, OUString());
860 //------------------------------------------------------------------------
861 void FmFilterModel::Remove( const ::std::vector
<FmFilterData
*>::iterator
& rPos
)
863 // remove from parent's child list
864 FmFilterData
* pData
= *rPos
;
865 pData
->GetParent()->GetChildren().erase( rPos
);
867 // notify the view, this will remove the actual SvTreeListEntry
868 FmFilterRemovedHint
aRemoveHint( pData
);
869 Broadcast( aRemoveHint
);
874 //------------------------------------------------------------------------
875 sal_Bool
FmFilterModel::ValidateText(FmFilterItem
* pItem
, OUString
& rText
, OUString
& rErrorMsg
) const
877 FmFormItem
* pFormItem
= PTR_CAST( FmFormItem
, pItem
->GetParent()->GetParent() );
880 Reference
< XFormController
> xFormController( pFormItem
->GetController() );
881 // obtain the connection of the form belonging to the controller
882 OStaticDataAccessTools aStaticTools
;
883 Reference
< XRowSet
> xRowSet( xFormController
->getModel(), UNO_QUERY_THROW
);
884 Reference
< XConnection
> xConnection( aStaticTools
.getRowSetConnection( xRowSet
) );
886 // obtain a number formatter for this connection
887 // TODO: shouldn't this be cached?
888 Reference
< XNumberFormatsSupplier
> xFormatSupplier
= aStaticTools
.getNumberFormats( xConnection
, sal_True
);
889 Reference
< XNumberFormatter
> xFormatter( NumberFormatter::create( comphelper::getProcessComponentContext() ), UNO_QUERY_THROW
);
890 xFormatter
->attachNumberFormatsSupplier( xFormatSupplier
);
892 // get the field (database column) which the item is responsible for
893 Reference
< XFilterController
> xFilterController( xFormController
, UNO_QUERY_THROW
);
894 Reference
< XPropertySet
> xField( lcl_getBoundField_nothrow( xFilterController
->getFilterComponent( pItem
->GetComponentIndex() ) ), UNO_SET_THROW
);
896 // parse the given text as filter predicate
897 OUString aErr
, aTxt( rText
);
898 ::rtl::Reference
< ISQLParseNode
> xParseNode
= predicateTree( aErr
, aTxt
, xFormatter
, xField
);
901 if ( xParseNode
.is() )
903 OUString aPreparedText
;
904 Locale aAppLocale
= Application::GetSettings().GetUILanguageTag().getLocale();
905 xParseNode
->parseNodeToPredicateStr(
906 aPreparedText
, xConnection
, xFormatter
, xField
, OUString(), aAppLocale
, '.', getParseContext() );
907 rText
= aPreparedText
;
911 catch( const Exception
& )
913 DBG_UNHANDLED_EXCEPTION();
919 //------------------------------------------------------------------------
920 void FmFilterModel::Append(FmFilterItems
* pItems
, FmFilterItem
* pFilterItem
)
922 Insert(pItems
->GetChildren().end(), pFilterItem
);
925 //------------------------------------------------------------------------
926 void FmFilterModel::SetTextForItem(FmFilterItem
* pItem
, const OUString
& rText
)
928 ::std::vector
<FmFilterData
*>& rItems
= pItem
->GetParent()->GetParent()->GetChildren();
929 ::std::vector
<FmFilterData
*>::iterator i
= ::std::find(rItems
.begin(), rItems
.end(), pItem
->GetParent());
930 sal_Int32 nParentPos
= i
- rItems
.begin();
932 m_pAdapter
->setText(nParentPos
, pItem
, rText
);
939 pItem
->SetText(rText
);
940 FmFilterTextChangedHint
aChangeHint(pItem
);
941 Broadcast( aChangeHint
);
945 //------------------------------------------------------------------------
946 void FmFilterModel::SetCurrentItems(FmFilterItems
* pCurrent
)
948 if (m_pCurrentItems
== pCurrent
)
951 // search for the condition
954 FmFormItem
* pFormItem
= (FmFormItem
*)pCurrent
->GetParent();
955 ::std::vector
<FmFilterData
*>& rItems
= pFormItem
->GetChildren();
956 ::std::vector
<FmFilterData
*>::const_iterator i
= ::std::find(rItems
.begin(), rItems
.end(), pCurrent
);
958 if (i
!= rItems
.end())
960 // determine the filter position
961 sal_Int32 nPos
= i
- rItems
.begin();
964 Reference
< XFilterController
> xFilterController( pFormItem
->GetFilterController(), UNO_SET_THROW
);
965 xFilterController
->setActiveTerm( nPos
);
967 catch( const Exception
& )
969 DBG_UNHANDLED_EXCEPTION();
972 if ( m_xController
!= pFormItem
->GetController() )
973 // calls SetCurrentItems again
974 SetCurrentController( pFormItem
->GetController() );
976 m_pCurrentItems
= pCurrent
;
979 m_pCurrentItems
= NULL
;
982 m_pCurrentItems
= NULL
;
985 // UI benachrichtigen
986 FmFilterCurrentChangedHint aHint
;
990 //------------------------------------------------------------------------
991 void FmFilterModel::EnsureEmptyFilterRows( FmParentData
& _rItem
)
993 // checks whether for each form there's one free level for input
994 ::std::vector
< FmFilterData
* >& rChildren
= _rItem
.GetChildren();
995 sal_Bool bAppendLevel
= _rItem
.ISA( FmFormItem
);
997 for ( ::std::vector
<FmFilterData
*>::iterator i
= rChildren
.begin();
998 i
!= rChildren
.end();
1002 FmFilterItems
* pItems
= PTR_CAST(FmFilterItems
, *i
);
1003 if ( pItems
&& pItems
->GetChildren().empty() )
1005 bAppendLevel
= sal_False
;
1009 FmFormItem
* pFormItem
= PTR_CAST(FmFormItem
, *i
);
1012 EnsureEmptyFilterRows( *pFormItem
);
1019 FmFormItem
* pFormItem
= PTR_CAST( FmFormItem
, &_rItem
);
1020 OSL_ENSURE( pFormItem
, "FmFilterModel::EnsureEmptyFilterRows: no FmFormItem, but a FmFilterItems child?" );
1022 AppendFilterItems( *pFormItem
);
1026 //========================================================================
1027 // class FmFilterItemsString
1028 //========================================================================
1029 class FmFilterItemsString
: public SvLBoxString
1032 FmFilterItemsString( SvTreeListEntry
* pEntry
, sal_uInt16 nFlags
, const XubString
& rStr
)
1033 :SvLBoxString(pEntry
,nFlags
,rStr
){}
1035 virtual void Paint(const Point
& rPos
, SvTreeListBox
& rDev
, const SvViewDataEntry
* pView
, const SvTreeListEntry
* pEntry
);
1036 virtual void InitViewData( SvTreeListBox
* pView
,SvTreeListEntry
* pEntry
, SvViewDataItem
* pViewData
);
1039 const int nxDBmp
= 12;
1040 //------------------------------------------------------------------------
1041 void FmFilterItemsString::Paint(
1042 const Point
& rPos
, SvTreeListBox
& rDev
, const SvViewDataEntry
* /*pView*/, const SvTreeListEntry
* pEntry
)
1044 FmFilterItems
* pRow
= (FmFilterItems
*)pEntry
->GetUserData();
1045 FmFormItem
* pForm
= (FmFormItem
*)pRow
->GetParent();
1047 // current filter is significant painted
1048 const bool bIsCurrentFilter
= pForm
->GetChildren()[ pForm
->GetFilterController()->getActiveTerm() ] == pRow
;
1049 if ( bIsCurrentFilter
)
1051 rDev
.Push( PUSH_LINECOLOR
);
1053 rDev
.SetLineColor( rDev
.GetTextColor() );
1055 Rectangle
aRect( rPos
, GetSize( &rDev
, pEntry
) );
1056 Point
aFirst( rPos
.X(), aRect
.Bottom() - 6 );
1057 Point
aSecond(aFirst
.X() + 2, aFirst
.Y() + 3 );
1059 rDev
.DrawLine( aFirst
, aSecond
);
1066 rDev
.DrawLine( aFirst
, aSecond
);
1071 rDev
.DrawText( Point(rPos
.X() + nxDBmp
, rPos
.Y()), GetText() );
1074 //------------------------------------------------------------------------
1075 void FmFilterItemsString::InitViewData( SvTreeListBox
* pView
,SvTreeListEntry
* pEntry
, SvViewDataItem
* pViewData
)
1078 pViewData
= pView
->GetViewDataItem( pEntry
, this );
1080 Size
aSize(pView
->GetTextWidth(GetText()), pView
->GetTextHeight());
1081 aSize
.Width() += nxDBmp
;
1082 pViewData
->maSize
= aSize
;
1085 //========================================================================
1086 // class FmFilterString
1087 //========================================================================
1088 class FmFilterString
: public SvLBoxString
1093 FmFilterString( SvTreeListEntry
* pEntry
, sal_uInt16 nFlags
, const XubString
& rStr
, const OUString
& aName
)
1094 :SvLBoxString(pEntry
,nFlags
,rStr
)
1100 virtual void Paint(const Point
& rPos
, SvTreeListBox
& rDev
, const SvViewDataEntry
* pView
, const SvTreeListEntry
* pEntry
);
1101 virtual void InitViewData( SvTreeListBox
* pView
,SvTreeListEntry
* pEntry
, SvViewDataItem
* pViewData
);
1106 //------------------------------------------------------------------------
1107 void FmFilterString::InitViewData( SvTreeListBox
* pView
,SvTreeListEntry
* pEntry
, SvViewDataItem
* pViewData
)
1110 pViewData
= pView
->GetViewDataItem( pEntry
, this );
1112 Font
aOldFont( pView
->GetFont());
1113 Font
aFont( aOldFont
);
1114 aFont
.SetWeight(WEIGHT_BOLD
);
1115 pView
->Control::SetFont( aFont
);
1117 Size
aSize(pView
->GetTextWidth(m_aName
), pView
->GetTextHeight());
1118 pView
->Control::SetFont( aOldFont
);
1119 aSize
.Width() += pView
->GetTextWidth(GetText()) + nxD
;
1120 pViewData
->maSize
= aSize
;
1123 //------------------------------------------------------------------------
1124 void FmFilterString::Paint(
1125 const Point
& rPos
, SvTreeListBox
& rDev
, const SvViewDataEntry
* /*pView*/, const SvTreeListEntry
* /*pEntry*/)
1127 Font
aOldFont( rDev
.GetFont());
1128 Font
aFont( aOldFont
);
1129 aFont
.SetWeight(WEIGHT_BOLD
);
1130 rDev
.SetFont( aFont
);
1133 rDev
.DrawText( aPos
, m_aName
);
1135 // position for the second text
1136 aPos
.X() += rDev
.GetTextWidth(m_aName
) + nxD
;
1137 rDev
.SetFont( aOldFont
);
1138 rDev
.DrawText( aPos
, GetText() );
1141 //========================================================================
1142 // class FmFilterNavigator
1143 //========================================================================
1144 FmFilterNavigator::FmFilterNavigator( Window
* pParent
)
1145 :SvTreeListBox( pParent
, WB_HASBUTTONS
|WB_HASLINES
|WB_BORDER
|WB_HASBUTTONSATROOT
)
1147 ,m_pEditingCurrently( NULL
)
1148 ,m_aControlExchange( this )
1149 ,m_aTimerCounter( 0 )
1150 ,m_aDropActionType( DA_SCROLLUP
)
1152 SetHelpId( HID_FILTER_NAVIGATOR
);
1155 ImageList
aNavigatorImages( SVX_RES( RID_SVXIMGLIST_FMEXPL
) );
1157 aNavigatorImages
.GetImage( RID_SVXIMG_COLLAPSEDNODE
),
1158 aNavigatorImages
.GetImage( RID_SVXIMG_EXPANDEDNODE
)
1162 m_pModel
= new FmFilterModel();
1163 StartListening( *m_pModel
);
1165 EnableInplaceEditing( sal_True
);
1166 SetSelectionMode(MULTIPLE_SELECTION
);
1168 SetDragDropMode(0xFFFF);
1170 m_aDropActionTimer
.SetTimeoutHdl(LINK(this, FmFilterNavigator
, OnDropActionTimer
));
1173 //------------------------------------------------------------------------
1174 FmFilterNavigator::~FmFilterNavigator()
1176 EndListening( *m_pModel
);
1180 //------------------------------------------------------------------------
1181 void FmFilterNavigator::UpdateContent(const Reference
< XIndexAccess
> & xControllers
, const Reference
< XFormController
> & xCurrent
)
1183 if (xCurrent
== m_pModel
->GetCurrentController())
1186 m_pModel
->Update(xControllers
, xCurrent
);
1188 // expand the filters for the current controller
1189 SvTreeListEntry
* pEntry
= FindEntry(m_pModel
->GetCurrentForm());
1190 if (pEntry
&& !IsExpanded(pEntry
))
1192 SelectAll(sal_False
);
1194 if (!IsExpanded(pEntry
))
1197 pEntry
= FindEntry(m_pModel
->GetCurrentItems());
1200 if (!IsExpanded(pEntry
))
1202 Select(pEntry
, sal_True
);
1207 //------------------------------------------------------------------------
1208 sal_Bool
FmFilterNavigator::EditingEntry( SvTreeListEntry
* pEntry
, Selection
& rSelection
)
1210 m_pEditingCurrently
= pEntry
;
1211 if (!SvTreeListBox::EditingEntry( pEntry
, rSelection
))
1214 return pEntry
&& ((FmFilterData
*)pEntry
->GetUserData())->ISA(FmFilterItem
);
1217 //------------------------------------------------------------------------
1218 sal_Bool
FmFilterNavigator::EditedEntry( SvTreeListEntry
* pEntry
, const OUString
& rNewText
)
1220 DBG_ASSERT(pEntry
== m_pEditingCurrently
, "FmFilterNavigator::EditedEntry: suspicious entry!");
1221 m_pEditingCurrently
= NULL
;
1223 if (EditingCanceled())
1226 DBG_ASSERT(((FmFilterData
*)pEntry
->GetUserData())->ISA(FmFilterItem
),
1227 "FmFilterNavigator::EditedEntry() wrong entry");
1229 OUString
aText(comphelper::string::strip(rNewText
, ' '));
1230 if (aText
.isEmpty())
1232 // deleting the entry asynchron
1234 PostUserEvent(nEvent
, LINK(this, FmFilterNavigator
, OnRemove
), pEntry
);
1240 if (m_pModel
->ValidateText((FmFilterItem
*)pEntry
->GetUserData(), aText
, aErrorMsg
))
1243 // this will set the text at the FmFilterItem, as well as update any filter controls
1244 // which are connected to this particular entry
1245 m_pModel
->SetTextForItem( static_cast< FmFilterItem
* >( pEntry
->GetUserData() ), aText
);
1247 SetCursor( pEntry
, sal_True
);
1248 SetEntryText( pEntry
, aText
);
1252 // display the error and return sal_False
1254 aError
.Message
= String(SVX_RES(RID_STR_SYNTAXERROR
));
1255 aError
.Details
= aErrorMsg
;
1256 displayException(aError
, this);
1264 //------------------------------------------------------------------------
1265 IMPL_LINK( FmFilterNavigator
, OnRemove
, SvTreeListEntry
*, pEntry
)
1267 // now remove the entry
1268 m_pModel
->Remove((FmFilterData
*) pEntry
->GetUserData());
1272 //------------------------------------------------------------------------
1273 IMPL_LINK_NOARG(FmFilterNavigator
, OnDropActionTimer
)
1275 if (--m_aTimerCounter
> 0)
1278 switch (m_aDropActionType
)
1281 ScrollOutputArea(1);
1282 m_aTimerCounter
= DROP_ACTION_TIMER_SCROLL_TICKS
;
1284 case DA_SCROLLDOWN
:
1285 ScrollOutputArea(-1);
1286 m_aTimerCounter
= DROP_ACTION_TIMER_SCROLL_TICKS
;
1290 SvTreeListEntry
* pToExpand
= GetEntry(m_aTimerTriggered
);
1291 if (pToExpand
&& (GetChildCount(pToExpand
) > 0) && !IsExpanded(pToExpand
))
1292 // tja, eigentlich muesste ich noch testen, ob die Node nicht schon expandiert ist, aber ich
1293 // habe dazu weder in den Basisklassen noch im Model eine Methode gefunden ...
1294 // aber ich denke, die BK sollte es auch so vertragen
1297 // nach dem Expand habe ich im Gegensatz zum Scrollen natuerlich nix mehr zu tun
1298 m_aDropActionTimer
.Stop();
1306 //------------------------------------------------------------------------
1307 sal_Int8
FmFilterNavigator::AcceptDrop( const AcceptDropEvent
& rEvt
)
1309 Point aDropPos
= rEvt
.maPosPixel
;
1311 // kuemmern wir uns erst mal um moeglich DropActions (Scrollen und Aufklappen)
1314 if (m_aDropActionTimer
.IsActive())
1315 m_aDropActionTimer
.Stop();
1319 sal_Bool bNeedTrigger
= sal_False
;
1320 // auf dem ersten Eintrag ?
1321 if ((aDropPos
.Y() >= 0) && (aDropPos
.Y() < GetEntryHeight()))
1323 m_aDropActionType
= DA_SCROLLUP
;
1324 bNeedTrigger
= sal_True
;
1328 // auf dem letzten (bzw. in dem Bereich, den ein Eintrag einnehmen wuerde, wenn er unten genau buendig
1329 // abschliessen wuerde) ?
1330 if ((aDropPos
.Y() < GetSizePixel().Height()) && (aDropPos
.Y() >= GetSizePixel().Height() - GetEntryHeight()))
1332 m_aDropActionType
= DA_SCROLLDOWN
;
1333 bNeedTrigger
= sal_True
;
1336 { // is it an entry with children, and not yet expanded?
1337 SvTreeListEntry
* pDropppedOn
= GetEntry(aDropPos
);
1338 if (pDropppedOn
&& (GetChildCount(pDropppedOn
) > 0) && !IsExpanded(pDropppedOn
))
1341 m_aDropActionType
= DA_EXPANDNODE
;
1342 bNeedTrigger
= sal_True
;
1346 if (bNeedTrigger
&& (m_aTimerTriggered
!= aDropPos
))
1348 // neu anfangen zu zaehlen
1349 m_aTimerCounter
= DROP_ACTION_TIMER_INITIAL_TICKS
;
1350 // die Pos merken, da ich auch QueryDrops bekomme, wenn sich die Maus gar nicht bewegt hat
1351 m_aTimerTriggered
= aDropPos
;
1352 // und den Timer los
1353 if (!m_aDropActionTimer
.IsActive()) // gibt es den Timer schon ?
1355 m_aDropActionTimer
.SetTimeout(DROP_ACTION_TIMER_TICK_BASE
);
1356 m_aDropActionTimer
.Start();
1359 else if (!bNeedTrigger
)
1360 m_aDropActionTimer
.Stop();
1364 // Hat das Object das richtige Format?
1365 if (!m_aControlExchange
.isDragSource())
1366 return DND_ACTION_NONE
;
1368 if (!m_aControlExchange
->hasFormat(GetDataFlavorExVector()))
1369 return DND_ACTION_NONE
;
1371 // do we conain the formitem?
1372 if (!FindEntry(m_aControlExchange
->getFormItem()))
1373 return DND_ACTION_NONE
;
1375 SvTreeListEntry
* pDropTarget
= GetEntry(aDropPos
);
1377 return DND_ACTION_NONE
;
1379 FmFilterData
* pData
= (FmFilterData
*)pDropTarget
->GetUserData();
1380 FmFormItem
* pForm
= NULL
;
1381 if (pData
->ISA(FmFilterItem
))
1383 pForm
= PTR_CAST(FmFormItem
,pData
->GetParent()->GetParent());
1384 if (pForm
!= m_aControlExchange
->getFormItem())
1385 return DND_ACTION_NONE
;
1387 else if (pData
->ISA(FmFilterItems
))
1389 pForm
= PTR_CAST(FmFormItem
,pData
->GetParent());
1390 if (pForm
!= m_aControlExchange
->getFormItem())
1391 return DND_ACTION_NONE
;
1394 return DND_ACTION_NONE
;
1396 return rEvt
.mnAction
;
1398 // -----------------------------------------------------------------------------
1401 FmFilterItems
* getTargetItems(SvTreeListEntry
* _pTarget
)
1403 FmFilterData
* pData
= static_cast<FmFilterData
*>(_pTarget
->GetUserData());
1404 FmFilterItems
* pTargetItems
= pData
->ISA(FmFilterItems
)
1406 PTR_CAST(FmFilterItems
,pData
)
1408 PTR_CAST(FmFilterItems
,pData
->GetParent());
1409 return pTargetItems
;
1412 //------------------------------------------------------------------------
1413 sal_Int8
FmFilterNavigator::ExecuteDrop( const ExecuteDropEvent
& rEvt
)
1415 // ware schlecht, wenn nach dem Droppen noch gescrollt wird ...
1416 if (m_aDropActionTimer
.IsActive())
1417 m_aDropActionTimer
.Stop();
1419 // Format-Ueberpruefung
1420 if (!m_aControlExchange
.isDragSource())
1421 return DND_ACTION_NONE
;
1423 // das Ziel des Drop sowie einige Daten darueber
1424 Point aDropPos
= rEvt
.maPosPixel
;
1425 SvTreeListEntry
* pDropTarget
= GetEntry( aDropPos
);
1427 return DND_ACTION_NONE
;
1429 // search the container where to add the items
1430 FmFilterItems
* pTargetItems
= getTargetItems(pDropTarget
);
1431 SelectAll(sal_False
);
1432 SvTreeListEntry
* pEntry
= FindEntry(pTargetItems
);
1433 Select(pEntry
, sal_True
);
1434 SetCurEntry(pEntry
);
1436 insertFilterItem(m_aControlExchange
->getDraggedEntries(),pTargetItems
,DND_ACTION_COPY
== rEvt
.mnAction
);
1441 //------------------------------------------------------------------------
1442 void FmFilterNavigator::InitEntry(SvTreeListEntry
* pEntry
,
1443 const OUString
& rStr
,
1446 SvLBoxButtonKind eButtonKind
)
1448 SvTreeListBox::InitEntry( pEntry
, rStr
, rImg1
, rImg2
, eButtonKind
);
1449 SvLBoxString
* pString
= NULL
;
1451 if (((FmFilterData
*)pEntry
->GetUserData())->ISA(FmFilterItem
))
1452 pString
= new FmFilterString(pEntry
, 0, rStr
, ((FmFilterItem
*)pEntry
->GetUserData())->GetFieldName());
1453 else if (((FmFilterData
*)pEntry
->GetUserData())->ISA(FmFilterItems
))
1454 pString
= new FmFilterItemsString(pEntry
, 0, rStr
);
1457 pEntry
->ReplaceItem( pString
, 1 );
1460 //------------------------------------------------------------------------
1461 sal_Bool
FmFilterNavigator::Select( SvTreeListEntry
* pEntry
, sal_Bool bSelect
)
1463 if (bSelect
== IsSelected(pEntry
)) // das passiert manchmal, ich glaube, die Basisklasse geht zu sehr auf Nummer sicher ;)
1466 if (SvTreeListBox::Select(pEntry
, bSelect
))
1470 FmFormItem
* pFormItem
= NULL
;
1471 if (((FmFilterData
*)pEntry
->GetUserData())->ISA(FmFilterItem
))
1472 pFormItem
= (FmFormItem
*)((FmFilterItem
*)pEntry
->GetUserData())->GetParent()->GetParent();
1473 else if (((FmFilterData
*)pEntry
->GetUserData())->ISA(FmFilterItems
))
1474 pFormItem
= (FmFormItem
*)((FmFilterItem
*)pEntry
->GetUserData())->GetParent()->GetParent();
1475 else if (((FmFilterData
*)pEntry
->GetUserData())->ISA(FmFormItem
))
1476 pFormItem
= (FmFormItem
*)pEntry
->GetUserData();
1480 // will the controller be exchanged?
1481 if (((FmFilterData
*)pEntry
->GetUserData())->ISA(FmFilterItem
))
1482 m_pModel
->SetCurrentItems((FmFilterItems
*)((FmFilterItem
*)pEntry
->GetUserData())->GetParent());
1483 else if (((FmFilterData
*)pEntry
->GetUserData())->ISA(FmFilterItems
))
1484 m_pModel
->SetCurrentItems((FmFilterItems
*)pEntry
->GetUserData());
1485 else if (((FmFilterData
*)pEntry
->GetUserData())->ISA(FmFormItem
))
1486 m_pModel
->SetCurrentController(((FmFormItem
*)pEntry
->GetUserData())->GetController());
1495 //------------------------------------------------------------------------
1496 void FmFilterNavigator::Notify( SfxBroadcaster
& /*rBC*/, const SfxHint
& rHint
)
1498 if (rHint
.ISA(FmFilterInsertedHint
))
1500 FmFilterInsertedHint
* pHint
= (FmFilterInsertedHint
*)&rHint
;
1501 Insert(pHint
->GetData(), pHint
->GetPos());
1503 else if( rHint
.ISA(FilterClearingHint
) )
1505 SvTreeListBox::Clear();
1507 else if( rHint
.ISA(FmFilterRemovedHint
) )
1509 FmFilterRemovedHint
* pHint
= (FmFilterRemovedHint
*)&rHint
;
1510 Remove(pHint
->GetData());
1512 else if( rHint
.ISA(FmFilterTextChangedHint
) )
1514 FmFilterTextChangedHint
* pHint
= (FmFilterTextChangedHint
*)&rHint
;
1515 SvTreeListEntry
* pEntry
= FindEntry(pHint
->GetData());
1517 SetEntryText( pEntry
, pHint
->GetData()->GetText());
1519 else if( rHint
.ISA(FmFilterCurrentChangedHint
) )
1521 // invalidate the entries
1522 for (SvTreeListEntry
* pEntry
= First(); pEntry
!= NULL
;
1523 pEntry
= Next(pEntry
))
1524 GetModel()->InvalidateEntry( pEntry
);
1528 //------------------------------------------------------------------------
1529 SvTreeListEntry
* FmFilterNavigator::FindEntry(const FmFilterData
* pItem
) const
1531 SvTreeListEntry
* pEntry
= NULL
;
1534 for (pEntry
= First(); pEntry
!= NULL
; pEntry
= Next( pEntry
))
1536 FmFilterData
* pEntryItem
= (FmFilterData
*)pEntry
->GetUserData();
1537 if (pEntryItem
== pItem
)
1544 //------------------------------------------------------------------------
1545 void FmFilterNavigator::Insert(FmFilterData
* pItem
, sal_uLong nPos
)
1547 const FmParentData
* pParent
= pItem
->GetParent() ? pItem
->GetParent() : GetFilterModel();
1550 SvTreeListEntry
* pParentEntry
= FindEntry( pParent
);
1551 InsertEntry( pItem
->GetText(), pItem
->GetImage(), pItem
->GetImage(), pParentEntry
, sal_False
, nPos
, pItem
);
1553 Expand( pParentEntry
);
1556 //------------------------------------------------------------------------
1557 void FmFilterNavigator::Remove(FmFilterData
* pItem
)
1559 // der Entry zu den Daten
1560 SvTreeListEntry
* pEntry
= FindEntry(pItem
);
1562 if (pEntry
== m_pEditingCurrently
)
1564 EndEditing(sal_True
);
1567 GetModel()->Remove( pEntry
);
1569 // -----------------------------------------------------------------------------
1570 FmFormItem
* FmFilterNavigator::getSelectedFilterItems(::std::vector
<FmFilterItem
*>& _rItemList
)
1572 // be sure that the data is only used within only one form!
1573 FmFormItem
* pFirstItem
= NULL
;
1575 sal_Bool bHandled
= sal_True
;
1576 sal_Bool bFoundSomething
= sal_False
;
1577 for (SvTreeListEntry
* pEntry
= FirstSelected();
1578 bHandled
&& pEntry
!= NULL
;
1579 pEntry
= NextSelected(pEntry
))
1581 FmFilterItem
* pFilter
= PTR_CAST(FmFilterItem
, (FmFilterData
*)pEntry
->GetUserData());
1584 FmFormItem
* pForm
= PTR_CAST(FmFormItem
,pFilter
->GetParent()->GetParent());
1586 bHandled
= sal_False
;
1587 else if (!pFirstItem
)
1589 else if (pFirstItem
!= pForm
)
1590 bHandled
= sal_False
;
1594 _rItemList
.push_back(pFilter
);
1595 bFoundSomething
= sal_True
;
1599 if ( !bHandled
|| !bFoundSomething
)
1603 // -----------------------------------------------------------------------------
1604 void FmFilterNavigator::insertFilterItem(const ::std::vector
<FmFilterItem
*>& _rFilterList
,FmFilterItems
* _pTargetItems
,sal_Bool _bCopy
)
1606 ::std::vector
<FmFilterItem
*>::const_iterator aEnd
= _rFilterList
.end();
1607 for ( ::std::vector
< FmFilterItem
* >::const_iterator i
= _rFilterList
.begin();
1612 FmFilterItem
* pLookupItem( *i
);
1613 if ( pLookupItem
->GetParent() == _pTargetItems
)
1616 FmFilterItem
* pFilterItem
= _pTargetItems
->Find( pLookupItem
->GetComponentIndex() );
1617 String aText
= pLookupItem
->GetText();
1620 pFilterItem
= new FmFilterItem( _pTargetItems
, pLookupItem
->GetFieldName(), aText
, pLookupItem
->GetComponentIndex() );
1621 m_pModel
->Append( _pTargetItems
, pFilterItem
);
1625 m_pModel
->Remove( pLookupItem
);
1627 // now set the text for the new dragged item
1628 m_pModel
->SetTextForItem( pFilterItem
, aText
);
1631 m_pModel
->EnsureEmptyFilterRows( *_pTargetItems
->GetParent() );
1634 //------------------------------------------------------------------------------
1635 void FmFilterNavigator::StartDrag( sal_Int8
/*_nAction*/, const Point
& /*_rPosPixel*/ )
1639 // be sure that the data is only used within a only one form!
1640 m_aControlExchange
.prepareDrag();
1642 ::std::vector
<FmFilterItem
*> aItemList
;
1643 if ( FmFormItem
* pFirstItem
= getSelectedFilterItems(aItemList
) )
1645 m_aControlExchange
->setDraggedEntries(aItemList
);
1646 m_aControlExchange
->setFormItem(pFirstItem
);
1647 m_aControlExchange
.startDrag( DND_ACTION_COPYMOVE
);
1651 //------------------------------------------------------------------------------
1652 void FmFilterNavigator::Command( const CommandEvent
& rEvt
)
1654 sal_Bool bHandled
= sal_False
;
1655 switch (rEvt
.GetCommand())
1657 case COMMAND_CONTEXTMENU
:
1659 // die Stelle, an der geklickt wurde
1661 SvTreeListEntry
* pClicked
= NULL
;
1662 if (rEvt
.IsMouseEvent())
1664 aWhere
= rEvt
.GetMousePosPixel();
1665 pClicked
= GetEntry(aWhere
);
1666 if (pClicked
== NULL
)
1669 if (!IsSelected(pClicked
))
1671 SelectAll(sal_False
);
1672 Select(pClicked
, sal_True
);
1673 SetCurEntry(pClicked
);
1678 pClicked
= GetCurEntry();
1681 aWhere
= GetEntryPosition( pClicked
);
1684 ::std::vector
<FmFilterData
*> aSelectList
;
1685 for (SvTreeListEntry
* pEntry
= FirstSelected();
1687 pEntry
= NextSelected(pEntry
))
1689 // don't delete forms
1690 FmFormItem
* pForm
= PTR_CAST(FmFormItem
, (FmFilterData
*)pEntry
->GetUserData());
1692 aSelectList
.push_back((FmFilterData
*)pEntry
->GetUserData());
1694 if (aSelectList
.size() == 1)
1696 // don't delete the only empty row of a form
1697 FmFilterItems
* pFilterItems
= PTR_CAST(FmFilterItems
, aSelectList
[0]);
1698 if (pFilterItems
&& pFilterItems
->GetChildren().empty()
1699 && pFilterItems
->GetParent()->GetChildren().size() == 1)
1700 aSelectList
.clear();
1703 PopupMenu
aContextMenu(SVX_RES(RID_FM_FILTER_MENU
));
1705 // every condition could be deleted except the first one if its the only one
1706 aContextMenu
.EnableItem( SID_FM_DELETE
, !aSelectList
.empty() );
1709 sal_Bool bEdit
= PTR_CAST(FmFilterItem
, (FmFilterData
*)pClicked
->GetUserData()) != NULL
&&
1710 IsSelected(pClicked
) && GetSelectionCount() == 1;
1712 aContextMenu
.EnableItem( SID_FM_FILTER_EDIT
,
1714 aContextMenu
.EnableItem( SID_FM_FILTER_IS_NULL
,
1716 aContextMenu
.EnableItem( SID_FM_FILTER_IS_NOT_NULL
,
1719 aContextMenu
.RemoveDisabledEntries(sal_True
, sal_True
);
1720 sal_uInt16 nSlotId
= aContextMenu
.Execute( this, aWhere
);
1723 case SID_FM_FILTER_EDIT
:
1725 EditEntry( pClicked
);
1727 case SID_FM_FILTER_IS_NULL
:
1728 case SID_FM_FILTER_IS_NOT_NULL
:
1732 if (nSlotId
== SID_FM_FILTER_IS_NULL
)
1735 aText
= "IS NOT NULL";
1737 m_pModel
->ValidateText((FmFilterItem
*)pClicked
->GetUserData(),
1739 m_pModel
->SetTextForItem((FmFilterItem
*)pClicked
->GetUserData(), aText
);
1746 bHandled
= sal_True
;
1751 SvTreeListBox::Command( rEvt
);
1753 // -----------------------------------------------------------------------------
1754 SvTreeListEntry
* FmFilterNavigator::getNextEntry(SvTreeListEntry
* _pStartWith
)
1756 SvTreeListEntry
* pEntry
= _pStartWith
? _pStartWith
: LastSelected();
1757 pEntry
= Next(pEntry
);
1758 // we need the next filter entry
1759 while( pEntry
&& GetChildCount( pEntry
) == 0 && pEntry
!= Last() )
1760 pEntry
= Next(pEntry
);
1763 // -----------------------------------------------------------------------------
1764 SvTreeListEntry
* FmFilterNavigator::getPrevEntry(SvTreeListEntry
* _pStartWith
)
1766 SvTreeListEntry
* pEntry
= _pStartWith
? _pStartWith
: FirstSelected();
1767 pEntry
= Prev(pEntry
);
1768 // check if the previous entry is a filter, if so get the next prev
1769 if ( pEntry
&& GetChildCount( pEntry
) != 0 )
1771 pEntry
= Prev(pEntry
);
1772 // if the entry is still no leaf return
1773 if ( pEntry
&& GetChildCount( pEntry
) != 0 )
1778 //------------------------------------------------------------------------
1779 void FmFilterNavigator::KeyInput(const KeyEvent
& rKEvt
)
1781 const KeyCode
& rKeyCode
= rKEvt
.GetKeyCode();
1783 switch ( rKeyCode
.GetCode() )
1788 if ( !rKeyCode
.IsMod1() || !rKeyCode
.IsMod2() || rKeyCode
.IsShift() )
1791 ::std::vector
<FmFilterItem
*> aItemList
;
1792 if ( !getSelectedFilterItems( aItemList
) )
1795 ::std::mem_fun1_t
<SvTreeListEntry
*,FmFilterNavigator
,SvTreeListEntry
*> getter
= ::std::mem_fun(&FmFilterNavigator::getNextEntry
);
1796 if ( rKeyCode
.GetCode() == KEY_UP
)
1797 getter
= ::std::mem_fun(&FmFilterNavigator::getPrevEntry
);
1799 SvTreeListEntry
* pTarget
= getter( this, NULL
);
1803 FmFilterItems
* pTargetItems
= getTargetItems( pTarget
);
1804 if ( !pTargetItems
)
1807 ::std::vector
<FmFilterItem
*>::const_iterator aEnd
= aItemList
.end();
1808 sal_Bool bNextTargetItem
= sal_True
;
1809 while ( bNextTargetItem
)
1811 ::std::vector
<FmFilterItem
*>::const_iterator i
= aItemList
.begin();
1812 for (; i
!= aEnd
; ++i
)
1814 if ( (*i
)->GetParent() == pTargetItems
)
1816 pTarget
= getter(this,pTarget
);
1819 pTargetItems
= getTargetItems( pTarget
);
1824 FmFilterItem
* pFilterItem
= pTargetItems
->Find( (*i
)->GetComponentIndex() );
1825 // we found the text component so jump above
1828 pTarget
= getter( this, pTarget
);
1832 pTargetItems
= getTargetItems( pTarget
);
1837 bNextTargetItem
= i
!= aEnd
&& pTargetItems
;
1842 insertFilterItem( aItemList
, pTargetItems
);
1850 if ( rKeyCode
.GetModifier() )
1853 if ( !IsSelected( First() ) || GetEntryCount() > 1 )
1859 SvTreeListBox::KeyInput(rKEvt
);
1862 //------------------------------------------------------------------------------
1863 void FmFilterNavigator::DeleteSelection()
1865 // to avoid the deletion of an entry twice (e.g. deletion of a parent and afterward
1866 // the deletion of it's child, i have to shrink the selecton list
1867 ::std::vector
<SvTreeListEntry
*> aEntryList
;
1868 for (SvTreeListEntry
* pEntry
= FirstSelected();
1870 pEntry
= NextSelected(pEntry
))
1872 FmFilterItem
* pFilterItem
= PTR_CAST(FmFilterItem
, (FmFilterData
*)pEntry
->GetUserData());
1873 if (pFilterItem
&& IsSelected(GetParent(pEntry
)))
1876 FmFormItem
* pForm
= PTR_CAST(FmFormItem
, (FmFilterData
*)pEntry
->GetUserData());
1878 aEntryList
.push_back(pEntry
);
1881 // Remove the selection
1882 SelectAll(sal_False
);
1884 for (::std::vector
<SvTreeListEntry
*>::reverse_iterator i
= aEntryList
.rbegin();
1885 // link problems with operator ==
1886 i
.base() != aEntryList
.rend().base(); ++i
)
1888 m_pModel
->Remove((FmFilterData
*)(*i
)->GetUserData());
1891 // -----------------------------------------------------------------------------
1893 //========================================================================
1894 // class FmFilterNavigatorWin
1895 //========================================================================
1896 FmFilterNavigatorWin::FmFilterNavigatorWin( SfxBindings
* _pBindings
, SfxChildWindow
* _pMgr
,
1898 :SfxDockingWindow( _pBindings
, _pMgr
, _pParent
, WinBits(WB_STDMODELESS
|WB_SIZEABLE
|WB_ROLLABLE
|WB_3DLOOK
|WB_DOCKABLE
) )
1899 ,SfxControllerItem( SID_FM_FILTER_NAVIGATOR_CONTROL
, *_pBindings
)
1901 SetHelpId( HID_FILTER_NAVIGATOR_WIN
);
1903 m_pNavigator
= new FmFilterNavigator( this );
1904 m_pNavigator
->Show();
1905 SetText( SVX_RES(RID_STR_FILTER_NAVIGATOR
) );
1906 SfxDockingWindow::SetFloatingSize( Size(200,200) );
1909 //------------------------------------------------------------------------
1910 FmFilterNavigatorWin::~FmFilterNavigatorWin()
1912 delete m_pNavigator
;
1915 //-----------------------------------------------------------------------
1916 void FmFilterNavigatorWin::UpdateContent(FmFormShell
* pFormShell
)
1919 m_pNavigator
->UpdateContent( NULL
, NULL
);
1922 Reference
< XFormController
> xController(pFormShell
->GetImpl()->getActiveInternalController());
1923 Reference
< XIndexAccess
> xContainer
;
1924 if (xController
.is())
1926 Reference
< XChild
> xChild(xController
, UNO_QUERY
);
1927 for (Reference
< XInterface
> xParent(xChild
->getParent());
1929 xParent
= xChild
.is() ? xChild
->getParent() : Reference
< XInterface
> ())
1931 xContainer
= Reference
< XIndexAccess
> (xParent
, UNO_QUERY
);
1932 xChild
= Reference
< XChild
> (xParent
, UNO_QUERY
);
1935 m_pNavigator
->UpdateContent(xContainer
, xController
);
1939 //-----------------------------------------------------------------------
1940 void FmFilterNavigatorWin::StateChanged( sal_uInt16 nSID
, SfxItemState eState
, const SfxPoolItem
* pState
)
1942 if( !pState
|| SID_FM_FILTER_NAVIGATOR_CONTROL
!= nSID
)
1945 if( eState
>= SFX_ITEM_AVAILABLE
)
1947 FmFormShell
* pShell
= PTR_CAST( FmFormShell
,((SfxObjectItem
*)pState
)->GetShell() );
1948 UpdateContent( pShell
);
1951 UpdateContent( NULL
);
1954 //-----------------------------------------------------------------------
1955 sal_Bool
FmFilterNavigatorWin::Close()
1957 if ( m_pNavigator
&& m_pNavigator
->IsEditingActive() )
1958 m_pNavigator
->EndEditing();
1960 if ( m_pNavigator
&& m_pNavigator
->IsEditingActive() )
1961 // the EndEditing was vetoed (perhaps of an syntax error or such)
1964 UpdateContent( NULL
);
1965 return SfxDockingWindow::Close();
1968 //-----------------------------------------------------------------------
1969 void FmFilterNavigatorWin::FillInfo( SfxChildWinInfo
& rInfo
) const
1971 SfxDockingWindow::FillInfo( rInfo
);
1972 rInfo
.bVisible
= sal_False
;
1975 //-----------------------------------------------------------------------
1976 Size
FmFilterNavigatorWin::CalcDockingSize( SfxChildAlignment eAlign
)
1978 if ( ( eAlign
== SFX_ALIGN_TOP
) || ( eAlign
== SFX_ALIGN_BOTTOM
) )
1981 return SfxDockingWindow::CalcDockingSize( eAlign
);
1984 //-----------------------------------------------------------------------
1985 SfxChildAlignment
FmFilterNavigatorWin::CheckAlignment( SfxChildAlignment eActAlign
, SfxChildAlignment eAlign
)
1989 case SFX_ALIGN_LEFT
:
1990 case SFX_ALIGN_RIGHT
:
1991 case SFX_ALIGN_NOALIGNMENT
:
2000 //------------------------------------------------------------------------
2001 void FmFilterNavigatorWin::Resize()
2003 SfxDockingWindow::Resize();
2005 Size aLogOutputSize
= PixelToLogic( GetOutputSizePixel(), MAP_APPFONT
);
2006 Size aLogExplSize
= aLogOutputSize
;
2007 aLogExplSize
.Width() -= 6;
2008 aLogExplSize
.Height() -= 6;
2010 Point aExplPos
= LogicToPixel( Point(3,3), MAP_APPFONT
);
2011 Size aExplSize
= LogicToPixel( aLogExplSize
, MAP_APPFONT
);
2013 m_pNavigator
->SetPosSizePixel( aExplPos
, aExplSize
);
2015 // -----------------------------------------------------------------------------
2016 void FmFilterNavigatorWin::GetFocus()
2020 m_pNavigator
->GrabFocus();
2022 // -----------------------------------------------------------------------------
2025 //========================================================================
2026 // class FmFilterNavigatorWinMgr
2027 //========================================================================
2028 SFX_IMPL_DOCKINGWINDOW( FmFilterNavigatorWinMgr
, SID_FM_FILTER_NAVIGATOR
)
2030 //-----------------------------------------------------------------------
2031 FmFilterNavigatorWinMgr::FmFilterNavigatorWinMgr( Window
*_pParent
, sal_uInt16 _nId
,
2032 SfxBindings
*_pBindings
, SfxChildWinInfo
* _pInfo
)
2033 :SfxChildWindow( _pParent
, _nId
)
2035 pWindow
= new FmFilterNavigatorWin( _pBindings
, this, _pParent
);
2036 eChildAlignment
= SFX_ALIGN_NOALIGNMENT
;
2037 ((SfxDockingWindow
*)pWindow
)->Initialize( _pInfo
);
2040 //........................................................................
2041 } // namespace svxform
2042 //........................................................................
2044 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */