Version 3.6.0.4, tag libreoffice-3.6.0.4
[LibreOffice.git] / svx / source / form / filtnav.cxx
blob94ac4fd09133663e275edca233d8a580a2c2109f
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * Copyright 2000, 2010 Oracle and/or its affiliates.
8 * OpenOffice.org - a multi-platform office productivity suite
10 * This file is part of OpenOffice.org.
12 * OpenOffice.org is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU Lesser General Public License version 3
14 * only, as published by the Free Software Foundation.
16 * OpenOffice.org is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License version 3 for more details
20 * (a copy is included in the LICENSE file that accompanied this code).
22 * You should have received a copy of the GNU Lesser General Public License
23 * version 3 along with OpenOffice.org. If not, see
24 * <http://www.openoffice.org/license.html>
25 * for a copy of the LGPLv3 License.
27 ************************************************************************/
31 #include "filtnav.hxx"
32 #include "fmexch.hxx"
33 #include "fmhelp.hrc"
34 #include "fmitems.hxx"
35 #include "fmprop.hrc"
36 #include "svx/fmresids.hrc"
38 /** === begin UNO includes === **/
39 #include <com/sun/star/awt/XControlModel.hpp>
40 #include <com/sun/star/awt/XControl.hpp>
41 #include <com/sun/star/awt/XTextComponent.hpp>
42 #include <com/sun/star/form/runtime/XFormController.hpp>
43 #include <com/sun/star/lang/XUnoTunnel.hpp>
44 #include <com/sun/star/util/XNumberFormatter.hpp>
45 #include <com/sun/star/beans/XFastPropertySet.hpp>
46 /** === end UNO includes === **/
48 #include <comphelper/processfactory.hxx>
49 #include <svx/fmtools.hxx>
50 #include <comphelper/property.hxx>
51 #include <comphelper/sequence.hxx>
52 #include <comphelper/uno3.hxx>
53 #include <connectivity/dbtools.hxx>
54 #include <cppuhelper/implbase1.hxx>
55 #include <fmservs.hxx>
56 #include <fmshimp.hxx>
57 #include <rtl/logfile.hxx>
58 #include <sfx2/dispatch.hxx>
59 #include <sfx2/objitem.hxx>
60 #include <sfx2/objsh.hxx>
61 #include <sfx2/request.hxx>
62 #include <svx/dialmgr.hxx>
63 #include <svx/fmshell.hxx>
64 #include <svx/svxids.hrc>
65 #include <tools/shl.hxx>
66 #include <vcl/wrkwin.hxx>
67 #include <tools/diagnose_ex.h>
69 #include <functional>
71 #define DROP_ACTION_TIMER_INITIAL_TICKS 10
72 // solange dauert es, bis das Scrollen anspringt
73 #define DROP_ACTION_TIMER_SCROLL_TICKS 3
74 // in diesen Intervallen wird jeweils eine Zeile gescrollt
75 #define DROP_ACTION_TIMER_TICK_BASE 10
76 // das ist die Basis, mit der beide Angaben multipliziert werden (in ms)
78 using namespace ::svxform;
79 using namespace ::connectivity::simple;
80 using namespace ::connectivity;
83 //........................................................................
84 namespace svxform
86 //........................................................................
88 /** === begin UNO using === **/
89 using ::com::sun::star::uno::Reference;
90 using ::com::sun::star::lang::XMultiServiceFactory;
91 using ::com::sun::star::awt::TextEvent;
92 using ::com::sun::star::container::XIndexAccess;
93 using ::com::sun::star::uno::UNO_QUERY;
94 using ::com::sun::star::beans::XPropertySet;
95 using ::com::sun::star::form::runtime::XFormController;
96 using ::com::sun::star::form::runtime::XFilterController;
97 using ::com::sun::star::form::runtime::XFilterControllerListener;
98 using ::com::sun::star::form::runtime::FilterEvent;
99 using ::com::sun::star::lang::EventObject;
100 using ::com::sun::star::uno::RuntimeException;
101 using ::com::sun::star::form::XForm;
102 using ::com::sun::star::container::XChild;
103 using ::com::sun::star::awt::XControl;
104 using ::com::sun::star::sdbc::XConnection;
105 using ::com::sun::star::util::XNumberFormatsSupplier;
106 using ::com::sun::star::beans::XPropertySet;
107 using ::com::sun::star::util::XNumberFormatter;
108 using ::com::sun::star::sdbc::XRowSet;
109 using ::com::sun::star::lang::Locale;
110 using ::com::sun::star::sdb::SQLContext;
111 using ::com::sun::star::uno::XInterface;
112 using ::com::sun::star::uno::UNO_QUERY_THROW;
113 using ::com::sun::star::uno::UNO_SET_THROW;
114 using ::com::sun::star::uno::Exception;
115 using ::com::sun::star::awt::XTextComponent;
116 using ::com::sun::star::uno::Sequence;
117 /** === end UNO using === **/
119 //========================================================================
120 OFilterItemExchange::OFilterItemExchange()
124 //------------------------------------------------------------------------
125 void OFilterItemExchange::AddSupportedFormats()
127 AddFormat(getFormatId());
130 //------------------------------------------------------------------------
131 sal_uInt32 OFilterItemExchange::getFormatId()
133 static sal_uInt32 s_nFormat = (sal_uInt32)-1;
134 if ((sal_uInt32)-1 == s_nFormat)
136 s_nFormat = SotExchange::RegisterFormatName(String::CreateFromAscii("application/x-openoffice;windows_formatname=\"form.FilterControlExchange\""));
137 DBG_ASSERT((sal_uInt32)-1 != s_nFormat, "OFilterExchangeHelper::getFormatId: bad exchange id!");
139 return s_nFormat;
142 //------------------------------------------------------------------------
143 OLocalExchange* OFilterExchangeHelper::createExchange() const
145 return new OFilterItemExchange;
148 //========================================================================
149 TYPEINIT0(FmFilterData);
150 Image FmFilterData::GetImage() const
152 return Image();
155 //========================================================================
156 TYPEINIT1(FmParentData, FmFilterData);
157 //------------------------------------------------------------------------
158 FmParentData::~FmParentData()
160 for (::std::vector<FmFilterData*>::const_iterator i = m_aChildren.begin();
161 i != m_aChildren.end(); ++i)
162 delete (*i);
165 //========================================================================
166 TYPEINIT1(FmFormItem, FmParentData);
167 //------------------------------------------------------------------------
168 Image FmFormItem::GetImage() const
170 static Image aImage;
172 if (!aImage)
174 ImageList aNavigatorImages( SVX_RES( RID_SVXIMGLIST_FMEXPL ) );
175 aImage = aNavigatorImages.GetImage( RID_SVXIMG_FORM );
177 return aImage;
180 //========================================================================
181 TYPEINIT1(FmFilterItems, FmParentData);
182 //------------------------------------------------------------------------
183 FmFilterItem* FmFilterItems::Find( const ::sal_Int32 _nFilterComponentIndex ) const
185 for ( ::std::vector< FmFilterData* >::const_iterator i = m_aChildren.begin();
186 i != m_aChildren.end();
190 FmFilterItem* pCondition = PTR_CAST( FmFilterItem, *i );
191 DBG_ASSERT( pCondition, "FmFilterItems::Find: Wrong element in container!" );
192 if ( _nFilterComponentIndex == pCondition->GetComponentIndex() )
193 return pCondition;
195 return NULL;
198 //------------------------------------------------------------------------
199 Image FmFilterItems::GetImage() const
201 static Image aImage;
203 if (!aImage)
205 ImageList aNavigatorImages( SVX_RES( RID_SVXIMGLIST_FMEXPL ) );
206 aImage = aNavigatorImages.GetImage( RID_SVXIMG_FILTER );
208 return aImage;
211 //========================================================================
212 TYPEINIT1(FmFilterItem, FmFilterData);
213 //------------------------------------------------------------------------
214 FmFilterItem::FmFilterItem( const Reference< XMultiServiceFactory >& _rxFactory,
215 FmFilterItems* pParent,
216 const ::rtl::OUString& aFieldName,
217 const ::rtl::OUString& aText,
218 const sal_Int32 _nComponentIndex )
219 :FmFilterData(_rxFactory,pParent, aText)
220 ,m_aFieldName(aFieldName)
221 ,m_nComponentIndex( _nComponentIndex )
225 //------------------------------------------------------------------------
226 Image FmFilterItem::GetImage() const
228 static Image aImage;
230 if (!aImage)
232 ImageList aNavigatorImages( SVX_RES( RID_SVXIMGLIST_FMEXPL ) );
233 aImage = aNavigatorImages.GetImage( RID_SVXIMG_FIELD );
235 return aImage;
238 //========================================================================
239 // Hints for communicatition between model and view
240 //========================================================================
241 class FmFilterHint : public SfxHint
243 FmFilterData* m_pData;
245 public:
246 TYPEINFO();
247 FmFilterHint(FmFilterData* pData):m_pData(pData){}
248 FmFilterData* GetData() const { return m_pData; }
250 TYPEINIT1( FmFilterHint, SfxHint );
252 //========================================================================
253 class FmFilterInsertedHint : public FmFilterHint
255 sal_Int32 m_nPos; // Position relative to the parent of the data
257 public:
258 TYPEINFO();
259 FmFilterInsertedHint(FmFilterData* pData, sal_Int32 nRelPos)
260 :FmFilterHint(pData)
261 ,m_nPos(nRelPos){}
263 sal_Int32 GetPos() const { return m_nPos; }
265 TYPEINIT1( FmFilterInsertedHint, FmFilterHint );
267 //========================================================================
268 class FmFilterRemovedHint : public FmFilterHint
270 public:
271 TYPEINFO();
272 FmFilterRemovedHint(FmFilterData* pData)
273 :FmFilterHint(pData){}
276 TYPEINIT1( FmFilterRemovedHint, FmFilterHint );
278 //========================================================================
279 class FmFilterTextChangedHint : public FmFilterHint
281 public:
282 TYPEINFO();
283 FmFilterTextChangedHint(FmFilterData* pData)
284 :FmFilterHint(pData){}
287 TYPEINIT1( FmFilterTextChangedHint, FmFilterHint );
289 //========================================================================
290 class FilterClearingHint : public SfxHint
292 public:
293 TYPEINFO();
294 FilterClearingHint(){}
296 TYPEINIT1( FilterClearingHint, SfxHint );
298 //========================================================================
299 class FmFilterCurrentChangedHint : public SfxHint
301 public:
302 TYPEINFO();
303 FmFilterCurrentChangedHint(){}
305 TYPEINIT1( FmFilterCurrentChangedHint, SfxHint );
307 //========================================================================
308 // class FmFilterAdapter, Listener an den FilterControls
309 //========================================================================
310 class FmFilterAdapter : public ::cppu::WeakImplHelper1< XFilterControllerListener >
312 FmFilterModel* m_pModel;
313 Reference< XIndexAccess > m_xControllers;
315 public:
316 FmFilterAdapter(FmFilterModel* pModel, const Reference< XIndexAccess >& xControllers);
318 // XEventListener
319 virtual void SAL_CALL disposing(const EventObject& Source) throw( RuntimeException );
321 // XFilterControllerListener
322 virtual void SAL_CALL predicateExpressionChanged( const FilterEvent& _Event ) throw (RuntimeException);
323 virtual void SAL_CALL disjunctiveTermRemoved( const FilterEvent& _Event ) throw (RuntimeException);
324 virtual void SAL_CALL disjunctiveTermAdded( const FilterEvent& _Event ) throw (RuntimeException);
326 // helpers
327 void dispose() throw( RuntimeException );
329 void AddOrRemoveListener( const Reference< XIndexAccess >& _rxControllers, const bool _bAdd );
331 void setText(sal_Int32 nPos,
332 const FmFilterItem* pFilterItem,
333 const ::rtl::OUString& rText);
336 //------------------------------------------------------------------------
337 FmFilterAdapter::FmFilterAdapter(FmFilterModel* pModel, const Reference< XIndexAccess >& xControllers)
338 :m_pModel( pModel )
339 ,m_xControllers( xControllers )
341 AddOrRemoveListener( m_xControllers, true );
344 //------------------------------------------------------------------------
345 void FmFilterAdapter::dispose() throw( RuntimeException )
347 AddOrRemoveListener( m_xControllers, false );
350 //------------------------------------------------------------------------
351 void FmFilterAdapter::AddOrRemoveListener( const Reference< XIndexAccess >& _rxControllers, const bool _bAdd )
353 for (sal_Int32 i = 0, nLen = _rxControllers->getCount(); i < nLen; ++i)
355 Reference< XIndexAccess > xElement( _rxControllers->getByIndex(i), UNO_QUERY );
357 // step down
358 AddOrRemoveListener( xElement, _bAdd );
360 // handle this particular controller
361 Reference< XFilterController > xController( xElement, UNO_QUERY );
362 OSL_ENSURE( xController.is(), "FmFilterAdapter::InsertElements: no XFilterController, cannot sync data!" );
363 if ( xController.is() )
365 if ( _bAdd )
366 xController->addFilterControllerListener( this );
367 else
368 xController->removeFilterControllerListener( this );
373 //------------------------------------------------------------------------
374 void FmFilterAdapter::setText(sal_Int32 nRowPos,
375 const FmFilterItem* pFilterItem,
376 const ::rtl::OUString& rText)
378 FmFormItem* pFormItem = PTR_CAST( FmFormItem, pFilterItem->GetParent()->GetParent() );
382 Reference< XFilterController > xController( pFormItem->GetController(), UNO_QUERY_THROW );
383 xController->setPredicateExpression( pFilterItem->GetComponentIndex(), nRowPos, rText );
385 catch( const Exception& )
387 DBG_UNHANDLED_EXCEPTION();
392 // XEventListener
393 //------------------------------------------------------------------------
394 void SAL_CALL FmFilterAdapter::disposing(const EventObject& /*e*/) throw( RuntimeException )
398 //------------------------------------------------------------------------
399 namespace
401 ::rtl::OUString lcl_getLabelName_nothrow( const Reference< XControl >& _rxControl )
403 ::rtl::OUString sLabelName;
406 Reference< XControl > xControl( _rxControl, UNO_SET_THROW );
407 Reference< XPropertySet > xModel( xControl->getModel(), UNO_QUERY_THROW );
408 sLabelName = getLabelName( xModel );
410 catch( const Exception& )
412 DBG_UNHANDLED_EXCEPTION();
414 return sLabelName;
417 Reference< XPropertySet > lcl_getBoundField_nothrow( const Reference< XControl >& _rxControl )
419 Reference< XPropertySet > xField;
422 Reference< XControl > xControl( _rxControl, UNO_SET_THROW );
423 Reference< XPropertySet > xModelProps( xControl->getModel(), UNO_QUERY_THROW );
424 xField.set( xModelProps->getPropertyValue( FM_PROP_BOUNDFIELD ), UNO_QUERY_THROW );
426 catch( const Exception& )
428 DBG_UNHANDLED_EXCEPTION();
430 return xField;
434 // XFilterControllerListener
435 //------------------------------------------------------------------------
436 void FmFilterAdapter::predicateExpressionChanged( const FilterEvent& _Event ) throw( RuntimeException )
438 SolarMutexGuard aGuard;
440 if ( !m_pModel )
441 return;
443 // the controller which sent the event
444 Reference< XFormController > xController( _Event.Source, UNO_QUERY_THROW );
445 Reference< XFilterController > xFilterController( _Event.Source, UNO_QUERY_THROW );
446 Reference< XForm > xForm( xController->getModel(), UNO_QUERY_THROW );
448 FmFormItem* pFormItem = m_pModel->Find( m_pModel->m_aChildren, xForm );
449 OSL_ENSURE( pFormItem, "FmFilterAdapter::predicateExpressionChanged: don't know this form!" );
450 if ( !pFormItem )
451 return;
453 const sal_Int32 nActiveTerm( xFilterController->getActiveTerm() );
455 FmFilterItems* pFilter = PTR_CAST( FmFilterItems, pFormItem->GetChildren()[ nActiveTerm ] );
456 FmFilterItem* pFilterItem = pFilter->Find( _Event.FilterComponent );
457 if ( pFilterItem )
459 if ( !_Event.PredicateExpression.isEmpty())
461 pFilterItem->SetText( _Event.PredicateExpression );
462 // UI benachrichtigen
463 FmFilterTextChangedHint aChangeHint(pFilterItem);
464 m_pModel->Broadcast( aChangeHint );
466 else
468 // no text anymore so remove the condition
469 m_pModel->Remove(pFilterItem);
472 else
474 // searching the component by field name
475 ::rtl::OUString aFieldName( lcl_getLabelName_nothrow( xFilterController->getFilterComponent( _Event.FilterComponent ) ) );
477 pFilterItem = new FmFilterItem( m_pModel->getORB(), pFilter, aFieldName, _Event.PredicateExpression, _Event.FilterComponent );
478 m_pModel->Insert(pFilter->GetChildren().end(), pFilterItem);
481 // ensure there's one empty term in the filter, just in case the active term was previously empty
482 m_pModel->EnsureEmptyFilterRows( *pFormItem );
485 //------------------------------------------------------------------------
486 void SAL_CALL FmFilterAdapter::disjunctiveTermRemoved( const FilterEvent& _Event ) throw (RuntimeException)
488 SolarMutexGuard aGuard;
490 Reference< XFormController > xController( _Event.Source, UNO_QUERY_THROW );
491 Reference< XFilterController > xFilterController( _Event.Source, UNO_QUERY_THROW );
492 Reference< XForm > xForm( xController->getModel(), UNO_QUERY_THROW );
494 FmFormItem* pFormItem = m_pModel->Find( m_pModel->m_aChildren, xForm );
495 OSL_ENSURE( pFormItem, "FmFilterAdapter::disjunctiveTermRemoved: don't know this form!" );
496 if ( !pFormItem )
497 return;
499 ::std::vector< FmFilterData* >& rTermItems = pFormItem->GetChildren();
500 const bool bValidIndex = ( _Event.DisjunctiveTerm >= 0 ) && ( (size_t)_Event.DisjunctiveTerm < rTermItems.size() );
501 OSL_ENSURE( bValidIndex, "FmFilterAdapter::disjunctiveTermRemoved: invalid term index!" );
502 if ( !bValidIndex )
503 return;
505 // if the first term was removed, then the to-be first term needs its text updated
506 if ( _Event.DisjunctiveTerm == 0 )
508 rTermItems[1]->SetText( String( SVX_RES( RID_STR_FILTER_FILTER_FOR ) ) );
509 FmFilterTextChangedHint aChangeHint( rTermItems[1] );
510 m_pModel->Broadcast( aChangeHint );
513 // finally remove the entry from the model
514 m_pModel->Remove( rTermItems.begin() + _Event.DisjunctiveTerm );
516 // ensure there's one empty term in the filter, just in case the currently removed one was the last empty one
517 m_pModel->EnsureEmptyFilterRows( *pFormItem );
520 //------------------------------------------------------------------------
521 void SAL_CALL FmFilterAdapter::disjunctiveTermAdded( const FilterEvent& _Event ) throw (RuntimeException)
523 SolarMutexGuard aGuard;
525 Reference< XFormController > xController( _Event.Source, UNO_QUERY_THROW );
526 Reference< XFilterController > xFilterController( _Event.Source, UNO_QUERY_THROW );
527 Reference< XForm > xForm( xController->getModel(), UNO_QUERY_THROW );
529 FmFormItem* pFormItem = m_pModel->Find( m_pModel->m_aChildren, xForm );
530 OSL_ENSURE( pFormItem, "FmFilterAdapter::disjunctiveTermAdded: don't know this form!" );
531 if ( !pFormItem )
532 return;
534 const sal_Int32 nInsertPos = _Event.DisjunctiveTerm;
535 bool bValidIndex = ( nInsertPos >= 0 ) && ( (size_t)nInsertPos <= pFormItem->GetChildren().size() );
536 if ( !bValidIndex )
538 OSL_FAIL( "FmFilterAdapter::disjunctiveTermAdded: invalid index!" );
539 return;
542 const ::std::vector< FmFilterData* >::iterator insertPos = pFormItem->GetChildren().begin() + nInsertPos;
544 FmFilterItems* pFilterItems = new FmFilterItems( m_pModel->getORB(), pFormItem, String( SVX_RES( RID_STR_FILTER_FILTER_OR ) ) );
545 m_pModel->Insert( insertPos, pFilterItems );
548 //========================================================================
549 // class FmFilterModel
550 //========================================================================
551 TYPEINIT1(FmFilterModel, FmParentData);
552 //------------------------------------------------------------------------
553 FmFilterModel::FmFilterModel(const Reference< XMultiServiceFactory >& _rxFactory)
554 :FmParentData(_rxFactory,NULL, ::rtl::OUString())
555 ,OSQLParserClient(_rxFactory)
556 ,m_xORB(_rxFactory)
557 ,m_pAdapter(NULL)
558 ,m_pCurrentItems(NULL)
562 //------------------------------------------------------------------------
563 FmFilterModel::~FmFilterModel()
565 Clear();
568 //------------------------------------------------------------------------
569 void FmFilterModel::Clear()
571 // notify
572 FilterClearingHint aClearedHint;
573 Broadcast( aClearedHint );
575 // loose endings
576 if (m_pAdapter)
578 m_pAdapter->dispose();
579 m_pAdapter->release();
580 m_pAdapter= NULL;
583 m_pCurrentItems = NULL;
584 m_xController = NULL;
585 m_xControllers = NULL;
587 for (::std::vector<FmFilterData*>::const_iterator i = m_aChildren.begin();
588 i != m_aChildren.end(); ++i)
589 delete (*i);
591 m_aChildren.clear();
594 //------------------------------------------------------------------------
595 void FmFilterModel::Update(const Reference< XIndexAccess > & xControllers, const Reference< XFormController > & xCurrent)
597 if ( xCurrent == m_xController )
598 return;
600 if (!xControllers.is())
602 Clear();
603 return;
606 // there is only a new current controller
607 if ( m_xControllers != xControllers )
609 Clear();
611 m_xControllers = xControllers;
612 Update(m_xControllers, this);
614 DBG_ASSERT(xCurrent.is(), "FmFilterModel::Update(...) no current controller");
616 // Listening for TextChanges
617 m_pAdapter = new FmFilterAdapter(this, xControllers);
618 m_pAdapter->acquire();
620 SetCurrentController(xCurrent);
621 EnsureEmptyFilterRows( *this );
623 else
624 SetCurrentController(xCurrent);
627 //------------------------------------------------------------------------
628 void FmFilterModel::Update(const Reference< XIndexAccess > & xControllers, FmParentData* pParent)
632 sal_Int32 nCount = xControllers->getCount();
633 for ( sal_Int32 i = 0; i < nCount; ++i )
635 Reference< XFormController > xController( xControllers->getByIndex(i), UNO_QUERY_THROW );
637 Reference< XPropertySet > xFormProperties( xController->getModel(), UNO_QUERY_THROW );
638 ::rtl::OUString aName;
639 OSL_VERIFY( xFormProperties->getPropertyValue( FM_PROP_NAME ) >>= aName );
641 // Insert a new item for the form
642 FmFormItem* pFormItem = new FmFormItem( m_xORB, pParent, xController, aName );
643 Insert( pParent->GetChildren().end(), pFormItem );
645 Reference< XFilterController > xFilterController( pFormItem->GetFilterController(), UNO_SET_THROW );
647 // insert the existing filters for the form
648 String aTitle( SVX_RES( RID_STR_FILTER_FILTER_FOR ) );
650 Sequence< Sequence< ::rtl::OUString > > aExpressions = xFilterController->getPredicateExpressions();
651 for ( const Sequence< ::rtl::OUString >* pConjunctionTerm = aExpressions.getConstArray();
652 pConjunctionTerm != aExpressions.getConstArray() + aExpressions.getLength();
653 ++pConjunctionTerm
656 // we always display one row, even if there's no term to be displayed
657 FmFilterItems* pFilterItems = new FmFilterItems( m_xORB, pFormItem, aTitle );
658 Insert( pFormItem->GetChildren().end(), pFilterItems );
660 const Sequence< ::rtl::OUString >& rDisjunction( *pConjunctionTerm );
661 for ( const ::rtl::OUString* pDisjunctiveTerm = rDisjunction.getConstArray();
662 pDisjunctiveTerm != rDisjunction.getConstArray() + rDisjunction.getLength();
663 ++pDisjunctiveTerm
666 if ( pDisjunctiveTerm->isEmpty() )
667 // no condition for this particular component in this particular conjunction term
668 continue;
670 const sal_Int32 nComponentIndex = pDisjunctiveTerm - rDisjunction.getConstArray();
672 // determine the display name of the control
673 const Reference< XControl > xFilterControl( xFilterController->getFilterComponent( nComponentIndex ) );
674 const ::rtl::OUString sDisplayName( lcl_getLabelName_nothrow( xFilterControl ) );
676 // insert a new entry
677 FmFilterItem* pANDCondition = new FmFilterItem( m_xORB, pFilterItems, sDisplayName, *pDisjunctiveTerm, nComponentIndex );
678 Insert( pFilterItems->GetChildren().end(), pANDCondition );
681 // title for the next conditions
682 aTitle = SVX_RESSTR( RID_STR_FILTER_FILTER_OR );
685 // now add dependent controllers
686 Reference< XIndexAccess > xControllerAsIndex( xController, UNO_QUERY );
687 Update( xControllerAsIndex, pFormItem );
690 catch( const Exception& )
692 DBG_UNHANDLED_EXCEPTION();
696 //------------------------------------------------------------------------
697 FmFormItem* FmFilterModel::Find(const ::std::vector<FmFilterData*>& rItems, const Reference< XFormController > & xController) const
699 for (::std::vector<FmFilterData*>::const_iterator i = rItems.begin();
700 i != rItems.end(); ++i)
702 FmFormItem* pForm = PTR_CAST(FmFormItem,*i);
703 if (pForm)
705 if ( xController == pForm->GetController() )
706 return pForm;
707 else
709 pForm = Find(pForm->GetChildren(), xController);
710 if (pForm)
711 return pForm;
715 return NULL;
718 //------------------------------------------------------------------------
719 FmFormItem* FmFilterModel::Find(const ::std::vector<FmFilterData*>& rItems, const Reference< XForm >& xForm) const
721 for (::std::vector<FmFilterData*>::const_iterator i = rItems.begin();
722 i != rItems.end(); ++i)
724 FmFormItem* pForm = PTR_CAST(FmFormItem,*i);
725 if (pForm)
727 if (xForm == pForm->GetController()->getModel())
728 return pForm;
729 else
731 pForm = Find(pForm->GetChildren(), xForm);
732 if (pForm)
733 return pForm;
737 return NULL;
740 //------------------------------------------------------------------------
741 void FmFilterModel::SetCurrentController(const Reference< XFormController > & xCurrent)
743 if ( xCurrent == m_xController )
744 return;
746 m_xController = xCurrent;
748 FmFormItem* pItem = Find( m_aChildren, xCurrent );
749 if ( !pItem )
750 return;
754 Reference< XFilterController > xFilterController( m_xController, UNO_QUERY_THROW );
755 const sal_Int32 nActiveTerm( xFilterController->getActiveTerm() );
756 if ( pItem->GetChildren().size() > (size_t)nActiveTerm )
758 SetCurrentItems( static_cast< FmFilterItems* >( pItem->GetChildren()[ nActiveTerm ] ) );
761 catch( const Exception& )
763 DBG_UNHANDLED_EXCEPTION();
767 //------------------------------------------------------------------------
768 void FmFilterModel::AppendFilterItems( FmFormItem& _rFormItem )
770 // insert the condition behind the last filter items
771 ::std::vector<FmFilterData*>::reverse_iterator iter;
772 for ( iter = _rFormItem.GetChildren().rbegin();
773 iter != _rFormItem.GetChildren().rend();
774 ++iter
777 if ((*iter)->ISA(FmFilterItems))
778 break;
781 sal_Int32 nInsertPos = iter.base() - _rFormItem.GetChildren().begin();
782 // delegate this to the FilterController, it will notify us, which will let us update our model
785 Reference< XFilterController > xFilterController( _rFormItem.GetFilterController(), UNO_SET_THROW );
786 if ( nInsertPos >= xFilterController->getDisjunctiveTerms() )
787 xFilterController->appendEmptyDisjunctiveTerm();
789 catch( const Exception& )
791 DBG_UNHANDLED_EXCEPTION();
795 //------------------------------------------------------------------------
796 void FmFilterModel::Insert(const ::std::vector<FmFilterData*>::iterator& rPos, FmFilterData* pData)
798 ::std::vector<FmFilterData*>& rItems = pData->GetParent()->GetChildren();
799 sal_Int32 nPos = rPos == rItems.end() ? LIST_APPEND : rPos - rItems.begin();
800 rItems.insert(rPos, pData);
802 // UI benachrichtigen
803 FmFilterInsertedHint aInsertedHint(pData, nPos);
804 Broadcast( aInsertedHint );
807 //------------------------------------------------------------------------
808 void FmFilterModel::Remove(FmFilterData* pData)
810 FmParentData* pParent = pData->GetParent();
811 ::std::vector<FmFilterData*>& rItems = pParent->GetChildren();
813 // erase the item from the model
814 ::std::vector<FmFilterData*>::iterator i = ::std::find(rItems.begin(), rItems.end(), pData);
815 DBG_ASSERT(i != rItems.end(), "FmFilterModel::Remove(): unknown Item");
816 // position within the parent
817 sal_Int32 nPos = i - rItems.begin();
818 if (pData->ISA(FmFilterItems))
820 FmFormItem* pFormItem = (FmFormItem*)pParent;
824 Reference< XFilterController > xFilterController( pFormItem->GetFilterController(), UNO_SET_THROW );
826 bool bEmptyLastTerm = ( ( nPos == 0 ) && xFilterController->getDisjunctiveTerms() == 1 );
827 if ( bEmptyLastTerm )
829 // remove all children (by setting an empty predicate expression)
830 ::std::vector< FmFilterData* >& rChildren = ((FmFilterItems*)pData)->GetChildren();
831 while ( !rChildren.empty() )
833 ::std::vector< FmFilterData* >::iterator removePos = rChildren.end() - 1;
834 FmFilterItem* pFilterItem = PTR_CAST( FmFilterItem, *removePos );
835 m_pAdapter->setText( nPos, pFilterItem, ::rtl::OUString() );
836 Remove( removePos );
839 else
841 xFilterController->removeDisjunctiveTerm( nPos );
844 catch( const Exception& )
846 DBG_UNHANDLED_EXCEPTION();
849 else // FormItems can not be deleted
851 FmFilterItem* pFilterItem = PTR_CAST(FmFilterItem, pData);
853 // if its the last condition remove the parent
854 if (rItems.size() == 1)
855 Remove(pFilterItem->GetParent());
856 else
858 // find the position of the father within his father
859 ::std::vector<FmFilterData*>& rParentParentItems = pData->GetParent()->GetParent()->GetChildren();
860 ::std::vector<FmFilterData*>::iterator j = ::std::find(rParentParentItems.begin(), rParentParentItems.end(), pFilterItem->GetParent());
861 DBG_ASSERT(j != rParentParentItems.end(), "FmFilterModel::Remove(): unknown Item");
862 sal_Int32 nParentPos = j - rParentParentItems.begin();
864 // EmptyText removes the filter
865 m_pAdapter->setText(nParentPos, pFilterItem, ::rtl::OUString());
866 Remove( i );
871 //------------------------------------------------------------------------
872 void FmFilterModel::Remove( const ::std::vector<FmFilterData*>::iterator& rPos )
874 // remove from parent's child list
875 FmFilterData* pData = *rPos;
876 pData->GetParent()->GetChildren().erase( rPos );
878 // notify the view, this will remove the actual SvLBoxEntry
879 FmFilterRemovedHint aRemoveHint( pData );
880 Broadcast( aRemoveHint );
882 delete pData;
885 //------------------------------------------------------------------------
886 sal_Bool FmFilterModel::ValidateText(FmFilterItem* pItem, UniString& rText, UniString& rErrorMsg) const
888 FmFormItem* pFormItem = PTR_CAST( FmFormItem, pItem->GetParent()->GetParent() );
891 Reference< XFormController > xFormController( pFormItem->GetController() );
892 // obtain the connection of the form belonging to the controller
893 OStaticDataAccessTools aStaticTools;
894 Reference< XRowSet > xRowSet( xFormController->getModel(), UNO_QUERY_THROW );
895 Reference< XConnection > xConnection( aStaticTools.getRowSetConnection( xRowSet ) );
897 // obtain a number formatter for this connection
898 // TODO: shouldn't this be cached?
899 Reference< XNumberFormatsSupplier > xFormatSupplier = aStaticTools.getNumberFormats( xConnection, sal_True );
900 Reference< XNumberFormatter > xFormatter( m_xORB->createInstance( FM_NUMBER_FORMATTER ), UNO_QUERY );
901 xFormatter->attachNumberFormatsSupplier( xFormatSupplier );
903 // get the field (database column) which the item is responsible for
904 Reference< XFilterController > xFilterController( xFormController, UNO_QUERY_THROW );
905 Reference< XPropertySet > xField( lcl_getBoundField_nothrow( xFilterController->getFilterComponent( pItem->GetComponentIndex() ) ), UNO_SET_THROW );
907 // parse the given text as filter predicate
908 ::rtl::OUString aErr, aTxt( rText );
909 ::rtl::Reference< ISQLParseNode > xParseNode = predicateTree( aErr, aTxt, xFormatter, xField );
910 rErrorMsg = aErr;
911 rText = aTxt;
912 if ( xParseNode.is() )
914 ::rtl::OUString aPreparedText;
915 Locale aAppLocale = Application::GetSettings().GetUILocale();
916 xParseNode->parseNodeToPredicateStr(
917 aPreparedText, xConnection, xFormatter, xField, aAppLocale, '.', getParseContext() );
918 rText = aPreparedText;
919 return sal_True;
922 catch( const Exception& )
924 DBG_UNHANDLED_EXCEPTION();
927 return sal_False;
930 //------------------------------------------------------------------------
931 void FmFilterModel::Append(FmFilterItems* pItems, FmFilterItem* pFilterItem)
933 Insert(pItems->GetChildren().end(), pFilterItem);
936 //------------------------------------------------------------------------
937 void FmFilterModel::SetTextForItem(FmFilterItem* pItem, const ::rtl::OUString& rText)
939 ::std::vector<FmFilterData*>& rItems = pItem->GetParent()->GetParent()->GetChildren();
940 ::std::vector<FmFilterData*>::iterator i = ::std::find(rItems.begin(), rItems.end(), pItem->GetParent());
941 sal_Int32 nParentPos = i - rItems.begin();
943 m_pAdapter->setText(nParentPos, pItem, rText);
945 if (rText.isEmpty())
946 Remove(pItem);
947 else
949 // Change the text
950 pItem->SetText(rText);
951 FmFilterTextChangedHint aChangeHint(pItem);
952 Broadcast( aChangeHint );
956 //------------------------------------------------------------------------
957 void FmFilterModel::SetCurrentItems(FmFilterItems* pCurrent)
959 if (m_pCurrentItems == pCurrent)
960 return;
962 // search for the condition
963 if (pCurrent)
965 FmFormItem* pFormItem = (FmFormItem*)pCurrent->GetParent();
966 ::std::vector<FmFilterData*>& rItems = pFormItem->GetChildren();
967 ::std::vector<FmFilterData*>::const_iterator i = ::std::find(rItems.begin(), rItems.end(), pCurrent);
969 if (i != rItems.end())
971 // determine the filter position
972 sal_Int32 nPos = i - rItems.begin();
975 Reference< XFilterController > xFilterController( pFormItem->GetFilterController(), UNO_SET_THROW );
976 xFilterController->setActiveTerm( nPos );
978 catch( const Exception& )
980 DBG_UNHANDLED_EXCEPTION();
983 if ( m_xController != pFormItem->GetController() )
984 // calls SetCurrentItems again
985 SetCurrentController( pFormItem->GetController() );
986 else
987 m_pCurrentItems = pCurrent;
989 else
990 m_pCurrentItems = NULL;
992 else
993 m_pCurrentItems = NULL;
996 // UI benachrichtigen
997 FmFilterCurrentChangedHint aHint;
998 Broadcast( aHint );
1001 //------------------------------------------------------------------------
1002 void FmFilterModel::EnsureEmptyFilterRows( FmParentData& _rItem )
1004 // checks whether for each form there's one free level for input
1005 ::std::vector< FmFilterData* >& rChildren = _rItem.GetChildren();
1006 sal_Bool bAppendLevel = _rItem.ISA( FmFormItem );
1008 for ( ::std::vector<FmFilterData*>::iterator i = rChildren.begin();
1009 i != rChildren.end();
1013 FmFilterItems* pItems = PTR_CAST(FmFilterItems, *i);
1014 if ( pItems && pItems->GetChildren().empty() )
1016 bAppendLevel = sal_False;
1017 break;
1020 FmFormItem* pFormItem = PTR_CAST(FmFormItem, *i);
1021 if (pFormItem)
1023 EnsureEmptyFilterRows( *pFormItem );
1024 continue;
1028 if ( bAppendLevel )
1030 FmFormItem* pFormItem = PTR_CAST( FmFormItem, &_rItem );
1031 OSL_ENSURE( pFormItem, "FmFilterModel::EnsureEmptyFilterRows: no FmFormItem, but a FmFilterItems child?" );
1032 if ( pFormItem )
1033 AppendFilterItems( *pFormItem );
1037 //========================================================================
1038 // class FmFilterItemsString
1039 //========================================================================
1040 class FmFilterItemsString : public SvLBoxString
1042 public:
1043 FmFilterItemsString( SvLBoxEntry* pEntry, sal_uInt16 nFlags, const XubString& rStr )
1044 :SvLBoxString(pEntry,nFlags,rStr){}
1046 virtual void Paint(const Point& rPos, SvLBox& rDev, sal_uInt16 nFlags, SvLBoxEntry* pEntry);
1047 virtual void InitViewData( SvLBox* pView,SvLBoxEntry* pEntry, SvViewDataItem* pViewData);
1050 const int nxDBmp = 12;
1051 //------------------------------------------------------------------------
1052 void FmFilterItemsString::Paint(const Point& rPos, SvLBox& rDev, sal_uInt16 /*nFlags*/, SvLBoxEntry* pEntry )
1054 FmFilterItems* pRow = (FmFilterItems*)pEntry->GetUserData();
1055 FmFormItem* pForm = (FmFormItem*)pRow->GetParent();
1057 // current filter is significant painted
1058 const bool bIsCurrentFilter = pForm->GetChildren()[ pForm->GetFilterController()->getActiveTerm() ] == pRow;
1059 if ( bIsCurrentFilter )
1061 rDev.Push( PUSH_LINECOLOR );
1063 rDev.SetLineColor( rDev.GetTextColor() );
1065 Rectangle aRect( rPos, GetSize( &rDev, pEntry ) );
1066 Point aFirst( rPos.X(), aRect.Bottom() - 6 );
1067 Point aSecond(aFirst .X() + 2, aFirst.Y() + 3 );
1069 rDev.DrawLine( aFirst, aSecond );
1071 aFirst = aSecond;
1072 aFirst.X() += 1;
1073 aSecond.X() += 6;
1074 aSecond.Y() -= 5;
1076 rDev.DrawLine( aFirst, aSecond );
1078 rDev.Pop();
1081 rDev.DrawText( Point(rPos.X() + nxDBmp, rPos.Y()), GetText() );
1084 //------------------------------------------------------------------------
1085 void FmFilterItemsString::InitViewData( SvLBox* pView,SvLBoxEntry* pEntry, SvViewDataItem* pViewData)
1087 if( !pViewData )
1088 pViewData = pView->GetViewDataItem( pEntry, this );
1090 Size aSize(pView->GetTextWidth(GetText()), pView->GetTextHeight());
1091 aSize.Width() += nxDBmp;
1092 pViewData->aSize = aSize;
1095 //========================================================================
1096 // class FmFilterString
1097 //========================================================================
1098 class FmFilterString : public SvLBoxString
1100 UniString m_aName;
1102 public:
1103 FmFilterString( SvLBoxEntry* pEntry, sal_uInt16 nFlags, const XubString& rStr, const UniString& aName)
1104 :SvLBoxString(pEntry,nFlags,rStr)
1105 ,m_aName(aName)
1107 m_aName.AppendAscii(": ");
1110 virtual void Paint(const Point& rPos, SvLBox& rDev, sal_uInt16 nFlags, SvLBoxEntry* pEntry);
1111 virtual void InitViewData( SvLBox* pView,SvLBoxEntry* pEntry, SvViewDataItem* pViewData);
1114 const int nxD = 4;
1116 //------------------------------------------------------------------------
1117 void FmFilterString::InitViewData( SvLBox* pView,SvLBoxEntry* pEntry, SvViewDataItem* pViewData)
1119 if( !pViewData )
1120 pViewData = pView->GetViewDataItem( pEntry, this );
1122 Font aOldFont( pView->GetFont());
1123 Font aFont( aOldFont );
1124 aFont.SetWeight(WEIGHT_BOLD);
1125 pView->SetFont( aFont );
1127 Size aSize(pView->GetTextWidth(m_aName), pView->GetTextHeight());
1128 pView->SetFont( aOldFont );
1129 aSize.Width() += pView->GetTextWidth(GetText()) + nxD;
1130 pViewData->aSize = aSize;
1133 //------------------------------------------------------------------------
1134 void FmFilterString::Paint(const Point& rPos, SvLBox& rDev, sal_uInt16 /*nFlags*/, SvLBoxEntry* /*pEntry*/ )
1136 Font aOldFont( rDev.GetFont());
1137 Font aFont( aOldFont );
1138 aFont.SetWeight(WEIGHT_BOLD);
1139 rDev.SetFont( aFont );
1141 Point aPos(rPos);
1142 rDev.DrawText( aPos, m_aName );
1144 // position for the second text
1145 aPos.X() += rDev.GetTextWidth(m_aName) + nxD;
1146 rDev.SetFont( aOldFont );
1147 rDev.DrawText( aPos, GetText() );
1150 //========================================================================
1151 // class FmFilterNavigator
1152 //========================================================================
1153 FmFilterNavigator::FmFilterNavigator( Window* pParent )
1154 :SvTreeListBox( pParent, WB_HASBUTTONS|WB_HASLINES|WB_BORDER|WB_HASBUTTONSATROOT )
1155 ,m_pModel( NULL )
1156 ,m_pEditingCurrently( NULL )
1157 ,m_aControlExchange( this )
1158 ,m_aTimerCounter( 0 )
1159 ,m_aDropActionType( DA_SCROLLUP )
1161 SetHelpId( HID_FILTER_NAVIGATOR );
1164 ImageList aNavigatorImages( SVX_RES( RID_SVXIMGLIST_FMEXPL ) );
1165 SetNodeBitmaps(
1166 aNavigatorImages.GetImage( RID_SVXIMG_COLLAPSEDNODE ),
1167 aNavigatorImages.GetImage( RID_SVXIMG_EXPANDEDNODE )
1171 m_pModel = new FmFilterModel(comphelper::getProcessServiceFactory());
1172 StartListening( *m_pModel );
1174 EnableInplaceEditing( sal_True );
1175 SetSelectionMode(MULTIPLE_SELECTION);
1177 SetDragDropMode(0xFFFF);
1179 m_aDropActionTimer.SetTimeoutHdl(LINK(this, FmFilterNavigator, OnDropActionTimer));
1182 //------------------------------------------------------------------------
1183 FmFilterNavigator::~FmFilterNavigator()
1185 EndListening( *m_pModel );
1186 delete m_pModel;
1189 //------------------------------------------------------------------------
1190 void FmFilterNavigator::UpdateContent(const Reference< XIndexAccess > & xControllers, const Reference< XFormController > & xCurrent)
1192 if (xCurrent == m_pModel->GetCurrentController())
1193 return;
1195 m_pModel->Update(xControllers, xCurrent);
1197 // expand the filters for the current controller
1198 SvLBoxEntry* pEntry = FindEntry(m_pModel->GetCurrentForm());
1199 if (pEntry && !IsExpanded(pEntry))
1201 SelectAll(sal_False);
1203 if (!IsExpanded(pEntry))
1204 Expand(pEntry);
1206 pEntry = FindEntry(m_pModel->GetCurrentItems());
1207 if (pEntry)
1209 if (!IsExpanded(pEntry))
1210 Expand(pEntry);
1211 Select(pEntry, sal_True);
1216 //------------------------------------------------------------------------
1217 sal_Bool FmFilterNavigator::EditingEntry( SvLBoxEntry* pEntry, Selection& rSelection )
1219 m_pEditingCurrently = pEntry;
1220 if (!SvTreeListBox::EditingEntry( pEntry, rSelection ))
1221 return sal_False;
1223 return pEntry && ((FmFilterData*)pEntry->GetUserData())->ISA(FmFilterItem);
1226 //------------------------------------------------------------------------
1227 sal_Bool FmFilterNavigator::EditedEntry( SvLBoxEntry* pEntry, const rtl::OUString& rNewText )
1229 DBG_ASSERT(pEntry == m_pEditingCurrently, "FmFilterNavigator::EditedEntry: suspicious entry!");
1230 m_pEditingCurrently = NULL;
1232 if (EditingCanceled())
1233 return sal_True;
1235 DBG_ASSERT(((FmFilterData*)pEntry->GetUserData())->ISA(FmFilterItem),
1236 "FmFilterNavigator::EditedEntry() wrong entry");
1238 UniString aText(rNewText);
1239 aText.EraseTrailingChars();
1240 aText.EraseLeadingChars();
1241 if (aText.Len() == 0)
1243 // deleting the entry asynchron
1244 sal_uLong nEvent;
1245 PostUserEvent(nEvent, LINK(this, FmFilterNavigator, OnRemove), pEntry);
1247 else
1249 UniString aErrorMsg;
1251 if (m_pModel->ValidateText((FmFilterItem*)pEntry->GetUserData(), aText, aErrorMsg))
1253 GrabFocus();
1254 // this will set the text at the FmFilterItem, as well as update any filter controls
1255 // which are connected to this particular entry
1256 m_pModel->SetTextForItem( static_cast< FmFilterItem* >( pEntry->GetUserData() ), aText );
1258 SetCursor( pEntry, sal_True );
1259 SetEntryText( pEntry, aText );
1261 else
1263 // display the error and return sal_False
1264 SQLContext aError;
1265 aError.Message = String(SVX_RES(RID_STR_SYNTAXERROR));
1266 aError.Details = aErrorMsg;
1267 displayException(aError, this);
1269 return sal_False;
1272 return sal_True;
1275 //------------------------------------------------------------------------
1276 IMPL_LINK( FmFilterNavigator, OnRemove, SvLBoxEntry*, pEntry )
1278 // now remove the entry
1279 m_pModel->Remove((FmFilterData*) pEntry->GetUserData());
1280 return 0L;
1283 //------------------------------------------------------------------------
1284 IMPL_LINK_NOARG(FmFilterNavigator, OnDropActionTimer)
1286 if (--m_aTimerCounter > 0)
1287 return 0L;
1289 switch (m_aDropActionType)
1291 case DA_SCROLLUP :
1292 ScrollOutputArea(1);
1293 m_aTimerCounter = DROP_ACTION_TIMER_SCROLL_TICKS;
1294 break;
1295 case DA_SCROLLDOWN :
1296 ScrollOutputArea(-1);
1297 m_aTimerCounter = DROP_ACTION_TIMER_SCROLL_TICKS;
1298 break;
1299 case DA_EXPANDNODE:
1301 SvLBoxEntry* pToExpand = GetEntry(m_aTimerTriggered);
1302 if (pToExpand && (GetChildCount(pToExpand) > 0) && !IsExpanded(pToExpand))
1303 // tja, eigentlich muesste ich noch testen, ob die Node nicht schon expandiert ist, aber ich
1304 // habe dazu weder in den Basisklassen noch im Model eine Methode gefunden ...
1305 // aber ich denke, die BK sollte es auch so vertragen
1306 Expand(pToExpand);
1308 // nach dem Expand habe ich im Gegensatz zum Scrollen natuerlich nix mehr zu tun
1309 m_aDropActionTimer.Stop();
1311 break;
1313 return 0L;
1317 //------------------------------------------------------------------------
1318 sal_Int8 FmFilterNavigator::AcceptDrop( const AcceptDropEvent& rEvt )
1320 Point aDropPos = rEvt.maPosPixel;
1322 // kuemmern wir uns erst mal um moeglich DropActions (Scrollen und Aufklappen)
1323 if (rEvt.mbLeaving)
1325 if (m_aDropActionTimer.IsActive())
1326 m_aDropActionTimer.Stop();
1328 else
1330 sal_Bool bNeedTrigger = sal_False;
1331 // auf dem ersten Eintrag ?
1332 if ((aDropPos.Y() >= 0) && (aDropPos.Y() < GetEntryHeight()))
1334 m_aDropActionType = DA_SCROLLUP;
1335 bNeedTrigger = sal_True;
1337 else
1339 // auf dem letzten (bzw. in dem Bereich, den ein Eintrag einnehmen wuerde, wenn er unten genau buendig
1340 // abschliessen wuerde) ?
1341 if ((aDropPos.Y() < GetSizePixel().Height()) && (aDropPos.Y() >= GetSizePixel().Height() - GetEntryHeight()))
1343 m_aDropActionType = DA_SCROLLDOWN;
1344 bNeedTrigger = sal_True;
1346 else
1347 { // is it an entry whith children, and not yet expanded?
1348 SvLBoxEntry* pDropppedOn = GetEntry(aDropPos);
1349 if (pDropppedOn && (GetChildCount(pDropppedOn) > 0) && !IsExpanded(pDropppedOn))
1351 // -> aufklappen
1352 m_aDropActionType = DA_EXPANDNODE;
1353 bNeedTrigger = sal_True;
1357 if (bNeedTrigger && (m_aTimerTriggered != aDropPos))
1359 // neu anfangen zu zaehlen
1360 m_aTimerCounter = DROP_ACTION_TIMER_INITIAL_TICKS;
1361 // die Pos merken, da ich auch QueryDrops bekomme, wenn sich die Maus gar nicht bewegt hat
1362 m_aTimerTriggered = aDropPos;
1363 // und den Timer los
1364 if (!m_aDropActionTimer.IsActive()) // gibt es den Timer schon ?
1366 m_aDropActionTimer.SetTimeout(DROP_ACTION_TIMER_TICK_BASE);
1367 m_aDropActionTimer.Start();
1370 else if (!bNeedTrigger)
1371 m_aDropActionTimer.Stop();
1375 // Hat das Object das richtige Format?
1376 if (!m_aControlExchange.isDragSource())
1377 return DND_ACTION_NONE;
1379 if (!m_aControlExchange->hasFormat(GetDataFlavorExVector()))
1380 return DND_ACTION_NONE;
1382 // do we conain the formitem?
1383 if (!FindEntry(m_aControlExchange->getFormItem()))
1384 return DND_ACTION_NONE;
1386 SvLBoxEntry* pDropTarget = GetEntry(aDropPos);
1387 if (!pDropTarget)
1388 return DND_ACTION_NONE;
1390 FmFilterData* pData = (FmFilterData*)pDropTarget->GetUserData();
1391 FmFormItem* pForm = NULL;
1392 if (pData->ISA(FmFilterItem))
1394 pForm = PTR_CAST(FmFormItem,pData->GetParent()->GetParent());
1395 if (pForm != m_aControlExchange->getFormItem())
1396 return DND_ACTION_NONE;
1398 else if (pData->ISA(FmFilterItems))
1400 pForm = PTR_CAST(FmFormItem,pData->GetParent());
1401 if (pForm != m_aControlExchange->getFormItem())
1402 return DND_ACTION_NONE;
1404 else
1405 return DND_ACTION_NONE;
1407 return rEvt.mnAction;
1409 // -----------------------------------------------------------------------------
1410 namespace
1412 FmFilterItems* getTargetItems(SvLBoxEntry* _pTarget)
1414 FmFilterData* pData = static_cast<FmFilterData*>(_pTarget->GetUserData());
1415 FmFilterItems* pTargetItems = pData->ISA(FmFilterItems)
1417 PTR_CAST(FmFilterItems,pData)
1419 PTR_CAST(FmFilterItems,pData->GetParent());
1420 return pTargetItems;
1423 //------------------------------------------------------------------------
1424 sal_Int8 FmFilterNavigator::ExecuteDrop( const ExecuteDropEvent& rEvt )
1426 // ware schlecht, wenn nach dem Droppen noch gescrollt wird ...
1427 if (m_aDropActionTimer.IsActive())
1428 m_aDropActionTimer.Stop();
1430 // Format-Ueberpruefung
1431 if (!m_aControlExchange.isDragSource())
1432 return DND_ACTION_NONE;
1434 // das Ziel des Drop sowie einige Daten darueber
1435 Point aDropPos = rEvt.maPosPixel;
1436 SvLBoxEntry* pDropTarget = GetEntry( aDropPos );
1437 if (!pDropTarget)
1438 return DND_ACTION_NONE;
1440 // search the container where to add the items
1441 FmFilterItems* pTargetItems = getTargetItems(pDropTarget);
1442 SelectAll(sal_False);
1443 SvLBoxEntry* pEntry = FindEntry(pTargetItems);
1444 Select(pEntry, sal_True);
1445 SetCurEntry(pEntry);
1447 insertFilterItem(m_aControlExchange->getDraggedEntries(),pTargetItems,DND_ACTION_COPY == rEvt.mnAction);
1449 return sal_True;
1452 //------------------------------------------------------------------------
1453 void FmFilterNavigator::InitEntry(SvLBoxEntry* pEntry,
1454 const XubString& rStr,
1455 const Image& rImg1,
1456 const Image& rImg2,
1457 SvLBoxButtonKind eButtonKind)
1459 SvTreeListBox::InitEntry( pEntry, rStr, rImg1, rImg2, eButtonKind );
1460 SvLBoxString* pString = NULL;
1462 if (((FmFilterData*)pEntry->GetUserData())->ISA(FmFilterItem))
1463 pString = new FmFilterString(pEntry, 0, rStr, ((FmFilterItem*)pEntry->GetUserData())->GetFieldName());
1464 else if (((FmFilterData*)pEntry->GetUserData())->ISA(FmFilterItems))
1465 pString = new FmFilterItemsString(pEntry, 0, rStr );
1467 if (pString)
1468 pEntry->ReplaceItem( pString, 1 );
1471 //------------------------------------------------------------------------
1472 sal_Bool FmFilterNavigator::Select( SvLBoxEntry* pEntry, sal_Bool bSelect )
1474 if (bSelect == IsSelected(pEntry)) // das passiert manchmal, ich glaube, die Basisklasse geht zu sehr auf Nummer sicher ;)
1475 return sal_True;
1477 if (SvTreeListBox::Select(pEntry, bSelect))
1479 if (bSelect)
1481 FmFormItem* pFormItem = NULL;
1482 if (((FmFilterData*)pEntry->GetUserData())->ISA(FmFilterItem))
1483 pFormItem = (FmFormItem*)((FmFilterItem*)pEntry->GetUserData())->GetParent()->GetParent();
1484 else if (((FmFilterData*)pEntry->GetUserData())->ISA(FmFilterItems))
1485 pFormItem = (FmFormItem*)((FmFilterItem*)pEntry->GetUserData())->GetParent()->GetParent();
1486 else if (((FmFilterData*)pEntry->GetUserData())->ISA(FmFormItem))
1487 pFormItem = (FmFormItem*)pEntry->GetUserData();
1489 if (pFormItem)
1491 // will the controller be exchanged?
1492 if (((FmFilterData*)pEntry->GetUserData())->ISA(FmFilterItem))
1493 m_pModel->SetCurrentItems((FmFilterItems*)((FmFilterItem*)pEntry->GetUserData())->GetParent());
1494 else if (((FmFilterData*)pEntry->GetUserData())->ISA(FmFilterItems))
1495 m_pModel->SetCurrentItems((FmFilterItems*)pEntry->GetUserData());
1496 else if (((FmFilterData*)pEntry->GetUserData())->ISA(FmFormItem))
1497 m_pModel->SetCurrentController(((FmFormItem*)pEntry->GetUserData())->GetController());
1500 return sal_True;
1502 else
1503 return sal_False;
1506 //------------------------------------------------------------------------
1507 void FmFilterNavigator::Notify( SfxBroadcaster& /*rBC*/, const SfxHint& rHint )
1509 if (rHint.ISA(FmFilterInsertedHint))
1511 FmFilterInsertedHint* pHint = (FmFilterInsertedHint*)&rHint;
1512 Insert(pHint->GetData(), pHint->GetPos());
1514 else if( rHint.ISA(FilterClearingHint) )
1516 SvTreeListBox::Clear();
1518 else if( rHint.ISA(FmFilterRemovedHint) )
1520 FmFilterRemovedHint* pHint = (FmFilterRemovedHint*)&rHint;
1521 Remove(pHint->GetData());
1523 else if( rHint.ISA(FmFilterTextChangedHint) )
1525 FmFilterTextChangedHint* pHint = (FmFilterTextChangedHint*)&rHint;
1526 SvLBoxEntry* pEntry = FindEntry(pHint->GetData());
1527 if (pEntry)
1528 SetEntryText( pEntry, pHint->GetData()->GetText());
1530 else if( rHint.ISA(FmFilterCurrentChangedHint) )
1532 // invalidate the entries
1533 for (SvLBoxEntry* pEntry = First(); pEntry != NULL;
1534 pEntry = Next(pEntry))
1535 GetModel()->InvalidateEntry( pEntry );
1539 //------------------------------------------------------------------------
1540 SvLBoxEntry* FmFilterNavigator::FindEntry(const FmFilterData* pItem) const
1542 SvLBoxEntry* pEntry = NULL;
1543 if (pItem)
1545 for (pEntry = First(); pEntry != NULL; pEntry = Next( pEntry ))
1547 FmFilterData* pEntryItem = (FmFilterData*)pEntry->GetUserData();
1548 if (pEntryItem == pItem)
1549 break;
1552 return pEntry;
1555 //------------------------------------------------------------------------
1556 void FmFilterNavigator::Insert(FmFilterData* pItem, sal_Int32 nPos)
1558 const FmParentData* pParent = pItem->GetParent() ? pItem->GetParent() : GetFilterModel();
1560 // insert the item
1561 SvLBoxEntry* pParentEntry = FindEntry( pParent );
1562 InsertEntry( pItem->GetText(), pItem->GetImage(), pItem->GetImage(), pParentEntry, sal_False, nPos, pItem );
1563 if ( pParentEntry )
1564 Expand( pParentEntry );
1567 //------------------------------------------------------------------------
1568 void FmFilterNavigator::Remove(FmFilterData* pItem)
1570 // der Entry zu den Daten
1571 SvLBoxEntry* pEntry = FindEntry(pItem);
1573 if (pEntry == m_pEditingCurrently)
1574 // cancel editing
1575 EndEditing(sal_True);
1577 if (pEntry)
1578 GetModel()->Remove( pEntry );
1580 // -----------------------------------------------------------------------------
1581 FmFormItem* FmFilterNavigator::getSelectedFilterItems(::std::vector<FmFilterItem*>& _rItemList)
1583 // be sure that the data is only used within only one form!
1584 FmFormItem* pFirstItem = NULL;
1586 sal_Bool bHandled = sal_True;
1587 sal_Bool bFoundSomething = sal_False;
1588 for (SvLBoxEntry* pEntry = FirstSelected();
1589 bHandled && pEntry != NULL;
1590 pEntry = NextSelected(pEntry))
1592 FmFilterItem* pFilter = PTR_CAST(FmFilterItem, (FmFilterData*)pEntry->GetUserData());
1593 if (pFilter)
1595 FmFormItem* pForm = PTR_CAST(FmFormItem,pFilter->GetParent()->GetParent());
1596 if (!pForm)
1597 bHandled = sal_False;
1598 else if (!pFirstItem)
1599 pFirstItem = pForm;
1600 else if (pFirstItem != pForm)
1601 bHandled = sal_False;
1603 if (bHandled)
1605 _rItemList.push_back(pFilter);
1606 bFoundSomething = sal_True;
1610 if ( !bHandled || !bFoundSomething )
1611 pFirstItem = NULL;
1612 return pFirstItem;
1614 // -----------------------------------------------------------------------------
1615 void FmFilterNavigator::insertFilterItem(const ::std::vector<FmFilterItem*>& _rFilterList,FmFilterItems* _pTargetItems,sal_Bool _bCopy)
1617 ::std::vector<FmFilterItem*>::const_iterator aEnd = _rFilterList.end();
1618 for ( ::std::vector< FmFilterItem* >::const_iterator i = _rFilterList.begin();
1619 i != aEnd;
1623 FmFilterItem* pLookupItem( *i );
1624 if ( pLookupItem->GetParent() == _pTargetItems )
1625 continue;
1627 FmFilterItem* pFilterItem = _pTargetItems->Find( pLookupItem->GetComponentIndex() );
1628 String aText = pLookupItem->GetText();
1629 if ( !pFilterItem )
1631 pFilterItem = new FmFilterItem( m_pModel->getORB(), _pTargetItems, pLookupItem->GetFieldName(), aText, pLookupItem->GetComponentIndex() );
1632 m_pModel->Append( _pTargetItems, pFilterItem );
1635 if ( !_bCopy )
1636 m_pModel->Remove( pLookupItem );
1638 // now set the text for the new dragged item
1639 m_pModel->SetTextForItem( pFilterItem, aText );
1642 m_pModel->EnsureEmptyFilterRows( *_pTargetItems->GetParent() );
1645 //------------------------------------------------------------------------------
1646 void FmFilterNavigator::StartDrag( sal_Int8 /*_nAction*/, const Point& /*_rPosPixel*/ )
1648 EndSelection();
1650 // be sure that the data is only used within a only one form!
1651 m_aControlExchange.prepareDrag();
1653 ::std::vector<FmFilterItem*> aItemList;
1654 if ( FmFormItem* pFirstItem = getSelectedFilterItems(aItemList) )
1656 m_aControlExchange->setDraggedEntries(aItemList);
1657 m_aControlExchange->setFormItem(pFirstItem);
1658 m_aControlExchange.startDrag( DND_ACTION_COPYMOVE );
1662 //------------------------------------------------------------------------------
1663 void FmFilterNavigator::Command( const CommandEvent& rEvt )
1665 sal_Bool bHandled = sal_False;
1666 switch (rEvt.GetCommand())
1668 case COMMAND_CONTEXTMENU:
1670 // die Stelle, an der geklickt wurde
1671 Point aWhere;
1672 SvLBoxEntry* pClicked = NULL;
1673 if (rEvt.IsMouseEvent())
1675 aWhere = rEvt.GetMousePosPixel();
1676 pClicked = GetEntry(aWhere);
1677 if (pClicked == NULL)
1678 break;
1680 if (!IsSelected(pClicked))
1682 SelectAll(sal_False);
1683 Select(pClicked, sal_True);
1684 SetCurEntry(pClicked);
1687 else
1689 pClicked = GetCurEntry();
1690 if (!pClicked)
1691 break;
1692 aWhere = GetEntryPosition( pClicked );
1695 ::std::vector<FmFilterData*> aSelectList;
1696 for (SvLBoxEntry* pEntry = FirstSelected();
1697 pEntry != NULL;
1698 pEntry = NextSelected(pEntry))
1700 // don't delete forms
1701 FmFormItem* pForm = PTR_CAST(FmFormItem, (FmFilterData*)pEntry->GetUserData());
1702 if (!pForm)
1703 aSelectList.push_back((FmFilterData*)pEntry->GetUserData());
1705 if (aSelectList.size() == 1)
1707 // don't delete the only empty row of a form
1708 FmFilterItems* pFilterItems = PTR_CAST(FmFilterItems, aSelectList[0]);
1709 if (pFilterItems && pFilterItems->GetChildren().empty()
1710 && pFilterItems->GetParent()->GetChildren().size() == 1)
1711 aSelectList.clear();
1714 PopupMenu aContextMenu(SVX_RES(RID_FM_FILTER_MENU));
1716 // every condition could be deleted except the first one if its the only one
1717 aContextMenu.EnableItem( SID_FM_DELETE, !aSelectList.empty() );
1720 sal_Bool bEdit = PTR_CAST(FmFilterItem, (FmFilterData*)pClicked->GetUserData()) != NULL &&
1721 IsSelected(pClicked) && GetSelectionCount() == 1;
1723 aContextMenu.EnableItem( SID_FM_FILTER_EDIT,
1724 bEdit );
1725 aContextMenu.EnableItem( SID_FM_FILTER_IS_NULL,
1726 bEdit );
1727 aContextMenu.EnableItem( SID_FM_FILTER_IS_NOT_NULL,
1728 bEdit );
1730 aContextMenu.RemoveDisabledEntries(sal_True, sal_True);
1731 sal_uInt16 nSlotId = aContextMenu.Execute( this, aWhere );
1732 switch( nSlotId )
1734 case SID_FM_FILTER_EDIT:
1736 EditEntry( pClicked );
1737 } break;
1738 case SID_FM_FILTER_IS_NULL:
1739 case SID_FM_FILTER_IS_NOT_NULL:
1741 UniString aErrorMsg;
1742 UniString aText;
1743 if (nSlotId == SID_FM_FILTER_IS_NULL)
1744 aText.AssignAscii("IS NULL");
1745 else
1746 aText.AssignAscii("IS NOT NULL");
1748 m_pModel->ValidateText((FmFilterItem*)pClicked->GetUserData(),
1749 aText, aErrorMsg);
1750 m_pModel->SetTextForItem((FmFilterItem*)pClicked->GetUserData(), aText);
1751 } break;
1752 case SID_FM_DELETE:
1754 DeleteSelection();
1755 } break;
1757 bHandled = sal_True;
1758 } break;
1761 if (!bHandled)
1762 SvTreeListBox::Command( rEvt );
1764 // -----------------------------------------------------------------------------
1765 SvLBoxEntry* FmFilterNavigator::getNextEntry(SvLBoxEntry* _pStartWith)
1767 SvLBoxEntry* pEntry = _pStartWith ? _pStartWith : LastSelected();
1768 pEntry = Next(pEntry);
1769 // we need the next filter entry
1770 while( pEntry && GetChildCount( pEntry ) == 0 && pEntry != Last() )
1771 pEntry = Next(pEntry);
1772 return pEntry;
1774 // -----------------------------------------------------------------------------
1775 SvLBoxEntry* FmFilterNavigator::getPrevEntry(SvLBoxEntry* _pStartWith)
1777 SvLBoxEntry* pEntry = _pStartWith ? _pStartWith : FirstSelected();
1778 pEntry = Prev(pEntry);
1779 // check if the previous entry is a filter, if so get the next prev
1780 if ( pEntry && GetChildCount( pEntry ) != 0 )
1782 pEntry = Prev(pEntry);
1783 // if the entry is still no leaf return
1784 if ( pEntry && GetChildCount( pEntry ) != 0 )
1785 pEntry = NULL;
1787 return pEntry;
1789 //------------------------------------------------------------------------
1790 void FmFilterNavigator::KeyInput(const KeyEvent& rKEvt)
1792 const KeyCode& rKeyCode = rKEvt.GetKeyCode();
1794 switch ( rKeyCode.GetCode() )
1796 case KEY_UP:
1797 case KEY_DOWN:
1799 if ( !rKeyCode.IsMod1() || !rKeyCode.IsMod2() || rKeyCode.IsShift() )
1800 break;
1802 ::std::vector<FmFilterItem*> aItemList;
1803 if ( !getSelectedFilterItems( aItemList ) )
1804 break;
1806 ::std::mem_fun1_t<SvLBoxEntry*,FmFilterNavigator,SvLBoxEntry*> getter = ::std::mem_fun(&FmFilterNavigator::getNextEntry);
1807 if ( rKeyCode.GetCode() == KEY_UP )
1808 getter = ::std::mem_fun(&FmFilterNavigator::getPrevEntry);
1810 SvLBoxEntry* pTarget = getter( this, NULL );
1811 if ( !pTarget )
1812 break;
1814 FmFilterItems* pTargetItems = getTargetItems( pTarget );
1815 if ( !pTargetItems )
1816 break;
1818 ::std::vector<FmFilterItem*>::const_iterator aEnd = aItemList.end();
1819 sal_Bool bNextTargetItem = sal_True;
1820 while ( bNextTargetItem )
1822 ::std::vector<FmFilterItem*>::const_iterator i = aItemList.begin();
1823 for (; i != aEnd; ++i)
1825 if ( (*i)->GetParent() == pTargetItems )
1827 pTarget = getter(this,pTarget);
1828 if ( !pTarget )
1829 return;
1830 pTargetItems = getTargetItems( pTarget );
1831 break;
1833 else
1835 FmFilterItem* pFilterItem = pTargetItems->Find( (*i)->GetComponentIndex() );
1836 // we found the text component so jump above
1837 if ( pFilterItem )
1839 pTarget = getter( this, pTarget );
1840 if ( !pTarget )
1841 return;
1843 pTargetItems = getTargetItems( pTarget );
1844 break;
1848 bNextTargetItem = i != aEnd && pTargetItems;
1851 if ( pTargetItems )
1853 insertFilterItem( aItemList, pTargetItems );
1854 return;
1857 break;
1859 case KEY_DELETE:
1861 if ( rKeyCode.GetModifier() )
1862 break;
1864 if ( !IsSelected( First() ) || GetEntryCount() > 1 )
1865 DeleteSelection();
1866 return;
1870 SvTreeListBox::KeyInput(rKEvt);
1873 //------------------------------------------------------------------------------
1874 void FmFilterNavigator::DeleteSelection()
1876 // to avoid the deletion of an entry twice (e.g. deletion of a parent and afterward
1877 // the deletion of it's child, i have to shrink the selecton list
1878 ::std::vector<SvLBoxEntry*> aEntryList;
1879 for (SvLBoxEntry* pEntry = FirstSelected();
1880 pEntry != NULL;
1881 pEntry = NextSelected(pEntry))
1883 FmFilterItem* pFilterItem = PTR_CAST(FmFilterItem, (FmFilterData*)pEntry->GetUserData());
1884 if (pFilterItem && IsSelected(GetParent(pEntry)))
1885 continue;
1887 FmFormItem* pForm = PTR_CAST(FmFormItem, (FmFilterData*)pEntry->GetUserData());
1888 if (!pForm)
1889 aEntryList.push_back(pEntry);
1892 // Remove the selection
1893 SelectAll(sal_False);
1895 for (::std::vector<SvLBoxEntry*>::reverse_iterator i = aEntryList.rbegin();
1896 // link problems with operator ==
1897 i.base() != aEntryList.rend().base(); ++i)
1899 m_pModel->Remove((FmFilterData*)(*i)->GetUserData());
1902 // -----------------------------------------------------------------------------
1904 //========================================================================
1905 // class FmFilterNavigatorWin
1906 //========================================================================
1907 FmFilterNavigatorWin::FmFilterNavigatorWin( SfxBindings* _pBindings, SfxChildWindow* _pMgr,
1908 Window* _pParent )
1909 :SfxDockingWindow( _pBindings, _pMgr, _pParent, WinBits(WB_STDMODELESS|WB_SIZEABLE|WB_ROLLABLE|WB_3DLOOK|WB_DOCKABLE) )
1910 ,SfxControllerItem( SID_FM_FILTER_NAVIGATOR_CONTROL, *_pBindings )
1912 SetHelpId( HID_FILTER_NAVIGATOR_WIN );
1914 m_pNavigator = new FmFilterNavigator( this );
1915 m_pNavigator->Show();
1916 SetText( SVX_RES(RID_STR_FILTER_NAVIGATOR) );
1917 SfxDockingWindow::SetFloatingSize( Size(200,200) );
1920 //------------------------------------------------------------------------
1921 FmFilterNavigatorWin::~FmFilterNavigatorWin()
1923 delete m_pNavigator;
1926 //-----------------------------------------------------------------------
1927 void FmFilterNavigatorWin::UpdateContent(FmFormShell* pFormShell)
1929 if (!pFormShell)
1930 m_pNavigator->UpdateContent( NULL, NULL );
1931 else
1933 Reference< XFormController > xController(pFormShell->GetImpl()->getActiveInternalController());
1934 Reference< XIndexAccess > xContainer;
1935 if (xController.is())
1937 Reference< XChild > xChild(xController, UNO_QUERY);
1938 for (Reference< XInterface > xParent(xChild->getParent());
1939 xParent.is();
1940 xParent = xChild.is() ? xChild->getParent() : Reference< XInterface > ())
1942 xContainer = Reference< XIndexAccess > (xParent, UNO_QUERY);
1943 xChild = Reference< XChild > (xParent, UNO_QUERY);
1946 m_pNavigator->UpdateContent(xContainer, xController);
1950 //-----------------------------------------------------------------------
1951 void FmFilterNavigatorWin::StateChanged( sal_uInt16 nSID, SfxItemState eState, const SfxPoolItem* pState )
1953 if( !pState || SID_FM_FILTER_NAVIGATOR_CONTROL != nSID )
1954 return;
1956 if( eState >= SFX_ITEM_AVAILABLE )
1958 FmFormShell* pShell = PTR_CAST( FmFormShell,((SfxObjectItem*)pState)->GetShell() );
1959 UpdateContent( pShell );
1961 else
1962 UpdateContent( NULL );
1965 //-----------------------------------------------------------------------
1966 sal_Bool FmFilterNavigatorWin::Close()
1968 if ( m_pNavigator && m_pNavigator->IsEditingActive() )
1969 m_pNavigator->EndEditing();
1971 if ( m_pNavigator && m_pNavigator->IsEditingActive() )
1972 // the EndEditing was vetoed (perhaps of an syntax error or such)
1973 return sal_False;
1975 UpdateContent( NULL );
1976 return SfxDockingWindow::Close();
1979 //-----------------------------------------------------------------------
1980 void FmFilterNavigatorWin::FillInfo( SfxChildWinInfo& rInfo ) const
1982 SfxDockingWindow::FillInfo( rInfo );
1983 rInfo.bVisible = sal_False;
1986 //-----------------------------------------------------------------------
1987 Size FmFilterNavigatorWin::CalcDockingSize( SfxChildAlignment eAlign )
1989 if ( ( eAlign == SFX_ALIGN_TOP ) || ( eAlign == SFX_ALIGN_BOTTOM ) )
1990 return Size();
1992 return SfxDockingWindow::CalcDockingSize( eAlign );
1995 //-----------------------------------------------------------------------
1996 SfxChildAlignment FmFilterNavigatorWin::CheckAlignment( SfxChildAlignment eActAlign, SfxChildAlignment eAlign )
1998 switch (eAlign)
2000 case SFX_ALIGN_LEFT:
2001 case SFX_ALIGN_RIGHT:
2002 case SFX_ALIGN_NOALIGNMENT:
2003 return (eAlign);
2004 default:
2005 break;
2008 return (eActAlign);
2011 //------------------------------------------------------------------------
2012 void FmFilterNavigatorWin::Resize()
2014 SfxDockingWindow::Resize();
2016 Size aLogOutputSize = PixelToLogic( GetOutputSizePixel(), MAP_APPFONT );
2017 Size aLogExplSize = aLogOutputSize;
2018 aLogExplSize.Width() -= 6;
2019 aLogExplSize.Height() -= 6;
2021 Point aExplPos = LogicToPixel( Point(3,3), MAP_APPFONT );
2022 Size aExplSize = LogicToPixel( aLogExplSize, MAP_APPFONT );
2024 m_pNavigator->SetPosSizePixel( aExplPos, aExplSize );
2026 // -----------------------------------------------------------------------------
2027 void FmFilterNavigatorWin::GetFocus()
2029 // oj #97405#
2030 if ( m_pNavigator )
2031 m_pNavigator->GrabFocus();
2033 // -----------------------------------------------------------------------------
2036 //========================================================================
2037 // class FmFilterNavigatorWinMgr
2038 //========================================================================
2039 SFX_IMPL_DOCKINGWINDOW( FmFilterNavigatorWinMgr, SID_FM_FILTER_NAVIGATOR )
2041 //-----------------------------------------------------------------------
2042 FmFilterNavigatorWinMgr::FmFilterNavigatorWinMgr( Window *_pParent, sal_uInt16 _nId,
2043 SfxBindings *_pBindings, SfxChildWinInfo* _pInfo )
2044 :SfxChildWindow( _pParent, _nId )
2046 pWindow = new FmFilterNavigatorWin( _pBindings, this, _pParent );
2047 eChildAlignment = SFX_ALIGN_NOALIGNMENT;
2048 ((SfxDockingWindow*)pWindow)->Initialize( _pInfo );
2051 //........................................................................
2052 } // namespace svxform
2053 //........................................................................
2055 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */