LCOV - code coverage report
Current view: top level - libreoffice/svx/source/form - filtnav.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 1 917 0.1 %
Date: 2012-12-27 Functions: 1 174 0.6 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10