bump product version to 4.1.6.2
[LibreOffice.git] / svx / source / form / filtnav.cxx
blob8b665eb9a508a6178ec022475508e10a5a0a42eb
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include "filtnav.hxx"
21 #include "fmexch.hxx"
22 #include "fmhelp.hrc"
23 #include "fmitems.hxx"
24 #include "fmprop.hrc"
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"
61 #include <functional>
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 //........................................................................
76 namespace svxform
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!");
130 return s_nFormat;
133 //------------------------------------------------------------------------
134 OLocalExchange* OFilterExchangeHelper::createExchange() const
136 return new OFilterItemExchange;
139 //========================================================================
140 TYPEINIT0(FmFilterData);
141 Image FmFilterData::GetImage() const
143 return Image();
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)
153 delete (*i);
156 //========================================================================
157 TYPEINIT1(FmFormItem, FmParentData);
158 //------------------------------------------------------------------------
159 Image FmFormItem::GetImage() const
161 static Image aImage;
163 if (!aImage)
165 ImageList aNavigatorImages( SVX_RES( RID_SVXIMGLIST_FMEXPL ) );
166 aImage = aNavigatorImages.GetImage( RID_SVXIMG_FORM );
168 return aImage;
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() )
184 return pCondition;
186 return NULL;
189 //------------------------------------------------------------------------
190 Image FmFilterItems::GetImage() const
192 static Image aImage;
194 if (!aImage)
196 ImageList aNavigatorImages( SVX_RES( RID_SVXIMGLIST_FMEXPL ) );
197 aImage = aNavigatorImages.GetImage( RID_SVXIMG_FILTER );
199 return aImage;
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
218 static Image aImage;
220 if (!aImage)
222 ImageList aNavigatorImages( SVX_RES( RID_SVXIMGLIST_FMEXPL ) );
223 aImage = aNavigatorImages.GetImage( RID_SVXIMG_FIELD );
225 return aImage;
228 //========================================================================
229 // Hints for communicatition between model and view
230 //========================================================================
231 class FmFilterHint : public SfxHint
233 FmFilterData* m_pData;
235 public:
236 TYPEINFO();
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
247 public:
248 TYPEINFO();
249 FmFilterInsertedHint(FmFilterData* pData, sal_uLong nRelPos)
250 :FmFilterHint(pData)
251 ,m_nPos(nRelPos){}
253 sal_uLong GetPos() const { return m_nPos; }
255 TYPEINIT1( FmFilterInsertedHint, FmFilterHint );
257 //========================================================================
258 class FmFilterRemovedHint : public FmFilterHint
260 public:
261 TYPEINFO();
262 FmFilterRemovedHint(FmFilterData* pData)
263 :FmFilterHint(pData){}
266 TYPEINIT1( FmFilterRemovedHint, FmFilterHint );
268 //========================================================================
269 class FmFilterTextChangedHint : public FmFilterHint
271 public:
272 TYPEINFO();
273 FmFilterTextChangedHint(FmFilterData* pData)
274 :FmFilterHint(pData){}
277 TYPEINIT1( FmFilterTextChangedHint, FmFilterHint );
279 //========================================================================
280 class FilterClearingHint : public SfxHint
282 public:
283 TYPEINFO();
284 FilterClearingHint(){}
286 TYPEINIT1( FilterClearingHint, SfxHint );
288 //========================================================================
289 class FmFilterCurrentChangedHint : public SfxHint
291 public:
292 TYPEINFO();
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;
305 public:
306 FmFilterAdapter(FmFilterModel* pModel, const Reference< XIndexAccess >& xControllers);
308 // XEventListener
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);
316 // helpers
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)
328 :m_pModel( pModel )
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 );
347 // step down
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() )
355 if ( _bAdd )
356 xController->addFilterControllerListener( this );
357 else
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();
382 // XEventListener
383 //------------------------------------------------------------------------
384 void SAL_CALL FmFilterAdapter::disposing(const EventObject& /*e*/) throw( RuntimeException )
388 //------------------------------------------------------------------------
389 namespace
391 OUString lcl_getLabelName_nothrow( const Reference< XControl >& _rxControl )
393 OUString sLabelName;
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();
404 return sLabelName;
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();
420 return xField;
424 // XFilterControllerListener
425 //------------------------------------------------------------------------
426 void FmFilterAdapter::predicateExpressionChanged( const FilterEvent& _Event ) throw( RuntimeException )
428 SolarMutexGuard aGuard;
430 if ( !m_pModel )
431 return;
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!" );
440 if ( !pFormItem )
441 return;
443 const sal_Int32 nActiveTerm( xFilterController->getActiveTerm() );
445 FmFilterItems* pFilter = PTR_CAST( FmFilterItems, pFormItem->GetChildren()[ nActiveTerm ] );
446 FmFilterItem* pFilterItem = pFilter->Find( _Event.FilterComponent );
447 if ( pFilterItem )
449 if ( !_Event.PredicateExpression.isEmpty())
451 pFilterItem->SetText( _Event.PredicateExpression );
452 // UI benachrichtigen
453 FmFilterTextChangedHint aChangeHint(pFilterItem);
454 m_pModel->Broadcast( aChangeHint );
456 else
458 // no text anymore so remove the condition
459 m_pModel->Remove(pFilterItem);
462 else
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!" );
486 if ( !pFormItem )
487 return;
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!" );
492 if ( !bValidIndex )
493 return;
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!" );
521 if ( !pFormItem )
522 return;
524 const sal_Int32 nInsertPos = _Event.DisjunctiveTerm;
525 bool bValidIndex = ( nInsertPos >= 0 ) && ( (size_t)nInsertPos <= pFormItem->GetChildren().size() );
526 if ( !bValidIndex )
528 OSL_FAIL( "FmFilterAdapter::disjunctiveTermAdded: invalid index!" );
529 return;
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())
546 ,m_pAdapter(NULL)
547 ,m_pCurrentItems(NULL)
551 //------------------------------------------------------------------------
552 FmFilterModel::~FmFilterModel()
554 Clear();
557 //------------------------------------------------------------------------
558 void FmFilterModel::Clear()
560 // notify
561 FilterClearingHint aClearedHint;
562 Broadcast( aClearedHint );
564 // loose endings
565 if (m_pAdapter)
567 m_pAdapter->dispose();
568 m_pAdapter->release();
569 m_pAdapter= NULL;
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)
578 delete (*i);
580 m_aChildren.clear();
583 //------------------------------------------------------------------------
584 void FmFilterModel::Update(const Reference< XIndexAccess > & xControllers, const Reference< XFormController > & xCurrent)
586 if ( xCurrent == m_xController )
587 return;
589 if (!xControllers.is())
591 Clear();
592 return;
595 // there is only a new current controller
596 if ( m_xControllers != xControllers )
598 Clear();
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 );
612 else
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 );
627 OUString aName;
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();
642 ++pConjunctionTerm
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();
652 ++pDisjunctiveTerm
655 if ( pDisjunctiveTerm->isEmpty() )
656 // no condition for this particular component in this particular conjunction term
657 continue;
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);
692 if (pForm)
694 if ( xController == pForm->GetController() )
695 return pForm;
696 else
698 pForm = Find(pForm->GetChildren(), xController);
699 if (pForm)
700 return pForm;
704 return NULL;
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);
714 if (pForm)
716 if (xForm == pForm->GetController()->getModel())
717 return pForm;
718 else
720 pForm = Find(pForm->GetChildren(), xForm);
721 if (pForm)
722 return pForm;
726 return NULL;
729 //------------------------------------------------------------------------
730 void FmFilterModel::SetCurrentController(const Reference< XFormController > & xCurrent)
732 if ( xCurrent == m_xController )
733 return;
735 m_xController = xCurrent;
737 FmFormItem* pItem = Find( m_aChildren, xCurrent );
738 if ( !pItem )
739 return;
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();
763 ++iter
766 if ((*iter)->ISA(FmFilterItems))
767 break;
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() );
825 Remove( removePos );
828 else
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());
845 else
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());
855 Remove( i );
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 );
871 delete pData;
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 );
899 rErrorMsg = aErr;
900 rText = aTxt;
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;
908 return sal_True;
911 catch( const Exception& )
913 DBG_UNHANDLED_EXCEPTION();
916 return sal_False;
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);
934 if (rText.isEmpty())
935 Remove(pItem);
936 else
938 // Change the text
939 pItem->SetText(rText);
940 FmFilterTextChangedHint aChangeHint(pItem);
941 Broadcast( aChangeHint );
945 //------------------------------------------------------------------------
946 void FmFilterModel::SetCurrentItems(FmFilterItems* pCurrent)
948 if (m_pCurrentItems == pCurrent)
949 return;
951 // search for the condition
952 if (pCurrent)
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() );
975 else
976 m_pCurrentItems = pCurrent;
978 else
979 m_pCurrentItems = NULL;
981 else
982 m_pCurrentItems = NULL;
985 // UI benachrichtigen
986 FmFilterCurrentChangedHint aHint;
987 Broadcast( 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;
1006 break;
1009 FmFormItem* pFormItem = PTR_CAST(FmFormItem, *i);
1010 if (pFormItem)
1012 EnsureEmptyFilterRows( *pFormItem );
1013 continue;
1017 if ( bAppendLevel )
1019 FmFormItem* pFormItem = PTR_CAST( FmFormItem, &_rItem );
1020 OSL_ENSURE( pFormItem, "FmFilterModel::EnsureEmptyFilterRows: no FmFormItem, but a FmFilterItems child?" );
1021 if ( pFormItem )
1022 AppendFilterItems( *pFormItem );
1026 //========================================================================
1027 // class FmFilterItemsString
1028 //========================================================================
1029 class FmFilterItemsString : public SvLBoxString
1031 public:
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 );
1061 aFirst = aSecond;
1062 aFirst.X() += 1;
1063 aSecond.X() += 6;
1064 aSecond.Y() -= 5;
1066 rDev.DrawLine( aFirst, aSecond );
1068 rDev.Pop();
1071 rDev.DrawText( Point(rPos.X() + nxDBmp, rPos.Y()), GetText() );
1074 //------------------------------------------------------------------------
1075 void FmFilterItemsString::InitViewData( SvTreeListBox* pView,SvTreeListEntry* pEntry, SvViewDataItem* pViewData)
1077 if( !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
1090 OUString m_aName;
1092 public:
1093 FmFilterString( SvTreeListEntry* pEntry, sal_uInt16 nFlags, const XubString& rStr, const OUString& aName)
1094 :SvLBoxString(pEntry,nFlags,rStr)
1095 ,m_aName(aName)
1097 m_aName += ": ";
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);
1104 const int nxD = 4;
1106 //------------------------------------------------------------------------
1107 void FmFilterString::InitViewData( SvTreeListBox* pView,SvTreeListEntry* pEntry, SvViewDataItem* pViewData)
1109 if( !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 );
1132 Point aPos(rPos);
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 )
1146 ,m_pModel( NULL )
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 ) );
1156 SetNodeBitmaps(
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 );
1177 delete m_pModel;
1180 //------------------------------------------------------------------------
1181 void FmFilterNavigator::UpdateContent(const Reference< XIndexAccess > & xControllers, const Reference< XFormController > & xCurrent)
1183 if (xCurrent == m_pModel->GetCurrentController())
1184 return;
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))
1195 Expand(pEntry);
1197 pEntry = FindEntry(m_pModel->GetCurrentItems());
1198 if (pEntry)
1200 if (!IsExpanded(pEntry))
1201 Expand(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 ))
1212 return sal_False;
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())
1224 return sal_True;
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
1233 sal_uLong nEvent;
1234 PostUserEvent(nEvent, LINK(this, FmFilterNavigator, OnRemove), pEntry);
1236 else
1238 OUString aErrorMsg;
1240 if (m_pModel->ValidateText((FmFilterItem*)pEntry->GetUserData(), aText, aErrorMsg))
1242 GrabFocus();
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 );
1250 else
1252 // display the error and return sal_False
1253 SQLContext aError;
1254 aError.Message = String(SVX_RES(RID_STR_SYNTAXERROR));
1255 aError.Details = aErrorMsg;
1256 displayException(aError, this);
1258 return sal_False;
1261 return sal_True;
1264 //------------------------------------------------------------------------
1265 IMPL_LINK( FmFilterNavigator, OnRemove, SvTreeListEntry*, pEntry )
1267 // now remove the entry
1268 m_pModel->Remove((FmFilterData*) pEntry->GetUserData());
1269 return 0L;
1272 //------------------------------------------------------------------------
1273 IMPL_LINK_NOARG(FmFilterNavigator, OnDropActionTimer)
1275 if (--m_aTimerCounter > 0)
1276 return 0L;
1278 switch (m_aDropActionType)
1280 case DA_SCROLLUP :
1281 ScrollOutputArea(1);
1282 m_aTimerCounter = DROP_ACTION_TIMER_SCROLL_TICKS;
1283 break;
1284 case DA_SCROLLDOWN :
1285 ScrollOutputArea(-1);
1286 m_aTimerCounter = DROP_ACTION_TIMER_SCROLL_TICKS;
1287 break;
1288 case DA_EXPANDNODE:
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
1295 Expand(pToExpand);
1297 // nach dem Expand habe ich im Gegensatz zum Scrollen natuerlich nix mehr zu tun
1298 m_aDropActionTimer.Stop();
1300 break;
1302 return 0L;
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)
1312 if (rEvt.mbLeaving)
1314 if (m_aDropActionTimer.IsActive())
1315 m_aDropActionTimer.Stop();
1317 else
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;
1326 else
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;
1335 else
1336 { // is it an entry with children, and not yet expanded?
1337 SvTreeListEntry* pDropppedOn = GetEntry(aDropPos);
1338 if (pDropppedOn && (GetChildCount(pDropppedOn) > 0) && !IsExpanded(pDropppedOn))
1340 // -> aufklappen
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);
1376 if (!pDropTarget)
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;
1393 else
1394 return DND_ACTION_NONE;
1396 return rEvt.mnAction;
1398 // -----------------------------------------------------------------------------
1399 namespace
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 );
1426 if (!pDropTarget)
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);
1438 return sal_True;
1441 //------------------------------------------------------------------------
1442 void FmFilterNavigator::InitEntry(SvTreeListEntry* pEntry,
1443 const OUString& rStr,
1444 const Image& rImg1,
1445 const Image& rImg2,
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 );
1456 if (pString)
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 ;)
1464 return sal_True;
1466 if (SvTreeListBox::Select(pEntry, bSelect))
1468 if (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();
1478 if (pFormItem)
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());
1489 return sal_True;
1491 else
1492 return sal_False;
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());
1516 if (pEntry)
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;
1532 if (pItem)
1534 for (pEntry = First(); pEntry != NULL; pEntry = Next( pEntry ))
1536 FmFilterData* pEntryItem = (FmFilterData*)pEntry->GetUserData();
1537 if (pEntryItem == pItem)
1538 break;
1541 return pEntry;
1544 //------------------------------------------------------------------------
1545 void FmFilterNavigator::Insert(FmFilterData* pItem, sal_uLong nPos)
1547 const FmParentData* pParent = pItem->GetParent() ? pItem->GetParent() : GetFilterModel();
1549 // insert the item
1550 SvTreeListEntry* pParentEntry = FindEntry( pParent );
1551 InsertEntry( pItem->GetText(), pItem->GetImage(), pItem->GetImage(), pParentEntry, sal_False, nPos, pItem );
1552 if ( pParentEntry )
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)
1563 // cancel editing
1564 EndEditing(sal_True);
1566 if (pEntry)
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());
1582 if (pFilter)
1584 FmFormItem* pForm = PTR_CAST(FmFormItem,pFilter->GetParent()->GetParent());
1585 if (!pForm)
1586 bHandled = sal_False;
1587 else if (!pFirstItem)
1588 pFirstItem = pForm;
1589 else if (pFirstItem != pForm)
1590 bHandled = sal_False;
1592 if (bHandled)
1594 _rItemList.push_back(pFilter);
1595 bFoundSomething = sal_True;
1599 if ( !bHandled || !bFoundSomething )
1600 pFirstItem = NULL;
1601 return pFirstItem;
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();
1608 i != aEnd;
1612 FmFilterItem* pLookupItem( *i );
1613 if ( pLookupItem->GetParent() == _pTargetItems )
1614 continue;
1616 FmFilterItem* pFilterItem = _pTargetItems->Find( pLookupItem->GetComponentIndex() );
1617 String aText = pLookupItem->GetText();
1618 if ( !pFilterItem )
1620 pFilterItem = new FmFilterItem( _pTargetItems, pLookupItem->GetFieldName(), aText, pLookupItem->GetComponentIndex() );
1621 m_pModel->Append( _pTargetItems, pFilterItem );
1624 if ( !_bCopy )
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*/ )
1637 EndSelection();
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
1660 Point aWhere;
1661 SvTreeListEntry* pClicked = NULL;
1662 if (rEvt.IsMouseEvent())
1664 aWhere = rEvt.GetMousePosPixel();
1665 pClicked = GetEntry(aWhere);
1666 if (pClicked == NULL)
1667 break;
1669 if (!IsSelected(pClicked))
1671 SelectAll(sal_False);
1672 Select(pClicked, sal_True);
1673 SetCurEntry(pClicked);
1676 else
1678 pClicked = GetCurEntry();
1679 if (!pClicked)
1680 break;
1681 aWhere = GetEntryPosition( pClicked );
1684 ::std::vector<FmFilterData*> aSelectList;
1685 for (SvTreeListEntry* pEntry = FirstSelected();
1686 pEntry != NULL;
1687 pEntry = NextSelected(pEntry))
1689 // don't delete forms
1690 FmFormItem* pForm = PTR_CAST(FmFormItem, (FmFilterData*)pEntry->GetUserData());
1691 if (!pForm)
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,
1713 bEdit );
1714 aContextMenu.EnableItem( SID_FM_FILTER_IS_NULL,
1715 bEdit );
1716 aContextMenu.EnableItem( SID_FM_FILTER_IS_NOT_NULL,
1717 bEdit );
1719 aContextMenu.RemoveDisabledEntries(sal_True, sal_True);
1720 sal_uInt16 nSlotId = aContextMenu.Execute( this, aWhere );
1721 switch( nSlotId )
1723 case SID_FM_FILTER_EDIT:
1725 EditEntry( pClicked );
1726 } break;
1727 case SID_FM_FILTER_IS_NULL:
1728 case SID_FM_FILTER_IS_NOT_NULL:
1730 OUString aErrorMsg;
1731 OUString aText;
1732 if (nSlotId == SID_FM_FILTER_IS_NULL)
1733 aText = "IS NULL";
1734 else
1735 aText = "IS NOT NULL";
1737 m_pModel->ValidateText((FmFilterItem*)pClicked->GetUserData(),
1738 aText, aErrorMsg);
1739 m_pModel->SetTextForItem((FmFilterItem*)pClicked->GetUserData(), aText);
1740 } break;
1741 case SID_FM_DELETE:
1743 DeleteSelection();
1744 } break;
1746 bHandled = sal_True;
1747 } break;
1750 if (!bHandled)
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);
1761 return 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 )
1774 pEntry = NULL;
1776 return pEntry;
1778 //------------------------------------------------------------------------
1779 void FmFilterNavigator::KeyInput(const KeyEvent& rKEvt)
1781 const KeyCode& rKeyCode = rKEvt.GetKeyCode();
1783 switch ( rKeyCode.GetCode() )
1785 case KEY_UP:
1786 case KEY_DOWN:
1788 if ( !rKeyCode.IsMod1() || !rKeyCode.IsMod2() || rKeyCode.IsShift() )
1789 break;
1791 ::std::vector<FmFilterItem*> aItemList;
1792 if ( !getSelectedFilterItems( aItemList ) )
1793 break;
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 );
1800 if ( !pTarget )
1801 break;
1803 FmFilterItems* pTargetItems = getTargetItems( pTarget );
1804 if ( !pTargetItems )
1805 break;
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);
1817 if ( !pTarget )
1818 return;
1819 pTargetItems = getTargetItems( pTarget );
1820 break;
1822 else
1824 FmFilterItem* pFilterItem = pTargetItems->Find( (*i)->GetComponentIndex() );
1825 // we found the text component so jump above
1826 if ( pFilterItem )
1828 pTarget = getter( this, pTarget );
1829 if ( !pTarget )
1830 return;
1832 pTargetItems = getTargetItems( pTarget );
1833 break;
1837 bNextTargetItem = i != aEnd && pTargetItems;
1840 if ( pTargetItems )
1842 insertFilterItem( aItemList, pTargetItems );
1843 return;
1846 break;
1848 case KEY_DELETE:
1850 if ( rKeyCode.GetModifier() )
1851 break;
1853 if ( !IsSelected( First() ) || GetEntryCount() > 1 )
1854 DeleteSelection();
1855 return;
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();
1869 pEntry != NULL;
1870 pEntry = NextSelected(pEntry))
1872 FmFilterItem* pFilterItem = PTR_CAST(FmFilterItem, (FmFilterData*)pEntry->GetUserData());
1873 if (pFilterItem && IsSelected(GetParent(pEntry)))
1874 continue;
1876 FmFormItem* pForm = PTR_CAST(FmFormItem, (FmFilterData*)pEntry->GetUserData());
1877 if (!pForm)
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,
1897 Window* _pParent )
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)
1918 if (!pFormShell)
1919 m_pNavigator->UpdateContent( NULL, NULL );
1920 else
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());
1928 xParent.is();
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 )
1943 return;
1945 if( eState >= SFX_ITEM_AVAILABLE )
1947 FmFormShell* pShell = PTR_CAST( FmFormShell,((SfxObjectItem*)pState)->GetShell() );
1948 UpdateContent( pShell );
1950 else
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)
1962 return sal_False;
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 ) )
1979 return Size();
1981 return SfxDockingWindow::CalcDockingSize( eAlign );
1984 //-----------------------------------------------------------------------
1985 SfxChildAlignment FmFilterNavigatorWin::CheckAlignment( SfxChildAlignment eActAlign, SfxChildAlignment eAlign )
1987 switch (eAlign)
1989 case SFX_ALIGN_LEFT:
1990 case SFX_ALIGN_RIGHT:
1991 case SFX_ALIGN_NOALIGNMENT:
1992 return (eAlign);
1993 default:
1994 break;
1997 return (eActAlign);
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()
2018 // oj #97405#
2019 if ( m_pNavigator )
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: */