Files
libreoffice/svx/source/form/filtnav.cxx

2156 lines
77 KiB
C++
Raw Normal View History

2000-09-18 16:07:07 +00:00
/*************************************************************************
*
* OpenOffice.org - a multi-platform office productivity suite
2000-09-18 16:07:07 +00:00
*
* $RCSfile: filtnav.cxx,v $
2000-09-18 16:07:07 +00:00
*
* $Revision: 1.41 $
2000-09-18 16:07:07 +00:00
*
* last change: $Author: hr $ $Date: 2006-04-19 13:49:36 $
2000-09-18 16:07:07 +00:00
*
* The Contents of this file are made available subject to
* the terms of GNU Lesser General Public License Version 2.1.
2000-09-18 16:07:07 +00:00
*
*
* GNU Lesser General Public License Version 2.1
* =============================================
* Copyright 2005 by Sun Microsystems, Inc.
* 901 San Antonio Road, Palo Alto, CA 94303, USA
2000-09-18 16:07:07 +00:00
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License version 2.1, as published by the Free Software Foundation.
2000-09-18 16:07:07 +00:00
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
2000-09-18 16:07:07 +00:00
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston,
* MA 02111-1307 USA
2000-09-18 16:07:07 +00:00
*
************************************************************************/
#ifndef _SVX_FMRESIDS_HRC
#include "fmresids.hrc"
#endif
#ifndef _SVX_FMCTRLER_HXX
#include "fmctrler.hxx"
#endif
#ifndef _SVX_FILTNAV_HXX
#include "filtnav.hxx"
#endif
#ifndef _COM_SUN_STAR_UTIL_XNUMBERFORMATTER_HPP_
#include <com/sun/star/util/XNumberFormatter.hpp>
#endif
#ifndef _COM_SUN_STAR_FORM_XFORMCONTROLLER_HPP_
#include <com/sun/star/form/XFormController.hpp>
#endif
#ifndef _SVX_FMEXCH_HXX
#include <fmexch.hxx>
#endif
#ifndef _SVX_FMITEMS_HXX
#include "fmitems.hxx"
#endif
#ifndef _SVX_SVXIDS_HRC
#include "svxids.hrc"
#endif
#ifndef _SVX_FMPROP_HRC
#include "fmprop.hrc"
#endif
#ifndef _SVX_FMHELP_HRC
#include "fmhelp.hrc"
#endif
#ifndef _SVX_DIALMGR_HXX //autogen
#include "dialmgr.hxx"
#endif
#ifndef _SFXDISPATCH_HXX //autogen
#include <sfx2/dispatch.hxx>
#endif
#ifndef _SFX_OBJSH_HXX //autogen
#include <sfx2/objsh.hxx>
#endif
#ifndef _SFX_OBJITEM_HXX //autogen
#include <sfx2/objitem.hxx>
#endif
#ifndef _SFXREQUEST_HXX
#include <sfx2/request.hxx>
#endif
#ifndef _SHL_HXX
#include <tools/shl.hxx>
#endif
#ifndef _WRKWIN_HXX //autogen
#include <vcl/wrkwin.hxx>
#endif
#ifndef _SVX_FMSHELL_HXX //autogen
#include <fmshell.hxx>
#endif
#ifndef _SVX_FMSHIMP_HXX
#include <fmshimp.hxx>
#endif
#ifndef _SVX_FMSERVS_HXX
#include <fmservs.hxx>
#endif
#ifndef _SVX_FMTOOLS_HXX
#include <fmtools.hxx>
#endif
#ifndef _CPPUHELPER_IMPLBASE1_HXX_
#include <cppuhelper/implbase1.hxx>
#endif
2000-10-20 13:18:57 +00:00
#ifndef _COMPHELPER_PROPERTY_HXX_
#include <comphelper/property.hxx>
2000-09-18 16:07:07 +00:00
#endif
2000-10-20 13:18:57 +00:00
#ifndef _COMPHELPER_UNO3_HXX_
#include <comphelper/uno3.hxx>
2000-09-18 16:07:07 +00:00
#endif
2000-10-20 13:18:57 +00:00
#ifndef _CONNECTIVITY_DBTOOLS_HXX_
#include <connectivity/dbtools.hxx>
2000-09-18 16:07:07 +00:00
#endif
2000-10-20 13:18:57 +00:00
#ifndef _COMPHELPER_PROCESSFACTORY_HXX_
#include <comphelper/processfactory.hxx>
2000-09-18 16:07:07 +00:00
#endif
#ifndef _COM_SUN_STAR_LANG_XUNOTUNNEL_HPP_
#include <com/sun/star/lang/XUnoTunnel.hpp>
#endif
2000-10-20 13:18:57 +00:00
#ifndef _COMPHELPER_SEQUENCE_HXX_
#include <comphelper/sequence.hxx>
2000-09-18 16:07:07 +00:00
#endif
#ifndef _SVX_GRIDCELL_HXX
#include "gridcell.hxx"
#endif
#include <functional>
2000-09-18 16:07:07 +00:00
#define SYNC_DELAY 200
#define DROP_ACTION_TIMER_INITIAL_TICKS 10
// solange dauert es, bis das Scrollen anspringt
#define DROP_ACTION_TIMER_SCROLL_TICKS 3
// in diesen Intervallen wird jeweils eine Zeile gescrollt
#define DROP_ACTION_TIMER_TICK_BASE 10
// das ist die Basis, mit der beide Angaben multipliziert werden (in ms)
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::lang;
using namespace ::com::sun::star::sdbc;
using namespace ::com::sun::star::sdb;
using namespace ::com::sun::star::beans;
using namespace ::svxform;
using namespace ::connectivity::simple;
using namespace ::connectivity;
2000-09-18 16:07:07 +00:00
2001-04-09 10:19:35 +00:00
//........................................................................
namespace svxform
{
//........................................................................
2000-09-18 16:07:07 +00:00
//========================================================================
2001-04-09 10:19:35 +00:00
OFilterItemExchange::OFilterItemExchange()
2000-09-18 16:07:07 +00:00
{
}
//------------------------------------------------------------------------
2001-04-09 10:19:35 +00:00
void OFilterItemExchange::AddSupportedFormats()
2000-09-18 16:07:07 +00:00
{
2001-04-09 10:19:35 +00:00
AddFormat(getFormatId());
}
//------------------------------------------------------------------------
sal_uInt32 OFilterItemExchange::getFormatId()
{
static sal_uInt32 s_nFormat = (sal_uInt32)-1;
if ((sal_uInt32)-1 == s_nFormat)
{
s_nFormat = SotExchange::RegisterFormatName(String::CreateFromAscii("application/x-openoffice;windows_formatname=\"form.FilterControlExchange\""));
2001-04-09 10:19:35 +00:00
DBG_ASSERT((sal_uInt32)-1 != s_nFormat, "OFilterExchangeHelper::getFormatId: bad exchange id!");
}
return s_nFormat;
}
//------------------------------------------------------------------------
OLocalExchange* OFilterExchangeHelper::createExchange() const
{
return new OFilterItemExchange;
2000-09-18 16:07:07 +00:00
}
//========================================================================
TYPEINIT0(FmFilterData);
2002-05-17 07:41:57 +00:00
Image FmFilterData::GetImage( BmpColorMode _eMode ) const
{
return Image();
}
2000-09-18 16:07:07 +00:00
//========================================================================
TYPEINIT1(FmParentData, FmFilterData);
//------------------------------------------------------------------------
FmParentData::~FmParentData()
{
for (::std::vector<FmFilterData*>::const_iterator i = m_aChilds.begin();
i != m_aChilds.end(); i++)
delete (*i);
}
//========================================================================
TYPEINIT1(FmFormItem, FmParentData);
//------------------------------------------------------------------------
2002-05-17 07:41:57 +00:00
Image FmFormItem::GetImage( BmpColorMode _eMode ) const
2000-09-18 16:07:07 +00:00
{
static Image aImage;
2002-05-17 07:41:57 +00:00
static Image aImage_HC;
2000-09-18 16:07:07 +00:00
if (!aImage)
{
2002-05-17 07:41:57 +00:00
ImageList aNavigatorImages( SVX_RES( RID_SVXIMGLIST_FMEXPL ) );
ImageList aNavigatorImages_HC( SVX_RES( RID_SVXIMGLIST_FMEXPL_HC ) );
2000-09-18 16:07:07 +00:00
aImage = aNavigatorImages.GetImage( RID_SVXIMG_FORM );
2002-05-17 07:41:57 +00:00
aImage_HC = aNavigatorImages_HC.GetImage( RID_SVXIMG_FORM );
2000-09-18 16:07:07 +00:00
}
2002-05-17 07:41:57 +00:00
return ( BMP_COLOR_HIGHCONTRAST == _eMode ) ? aImage_HC : aImage;
2000-09-18 16:07:07 +00:00
}
//========================================================================
TYPEINIT1(FmFilterItems, FmParentData);
//------------------------------------------------------------------------
FmFilterItem* FmFilterItems::Find(const Reference< ::com::sun::star::awt::XTextComponent > & _xText) const
{
for (vector<FmFilterData*>::const_iterator i = m_aChilds.begin();
i != m_aChilds.end(); ++i)
2000-09-18 16:07:07 +00:00
{
FmFilterItem* pCond = PTR_CAST(FmFilterItem, *i);
DBG_ASSERT(pCond, "Wrong element in container");
if (_xText == pCond->GetTextComponent())
return pCond;
}
return NULL;
}
//------------------------------------------------------------------------
2002-05-17 07:41:57 +00:00
Image FmFilterItems::GetImage( BmpColorMode _eMode ) const
2000-09-18 16:07:07 +00:00
{
static Image aImage;
2002-05-17 07:41:57 +00:00
static Image aImage_HC;
2000-09-18 16:07:07 +00:00
if (!aImage)
{
2002-05-17 07:41:57 +00:00
ImageList aNavigatorImages( SVX_RES( RID_SVXIMGLIST_FMEXPL ) );
ImageList aNavigatorImages_HC( SVX_RES( RID_SVXIMGLIST_FMEXPL_HC ) );
2000-09-18 16:07:07 +00:00
aImage = aNavigatorImages.GetImage( RID_SVXIMG_FILTER );
2002-05-17 07:41:57 +00:00
aImage_HC = aNavigatorImages_HC.GetImage( RID_SVXIMG_FILTER );
2000-09-18 16:07:07 +00:00
}
2002-05-17 07:41:57 +00:00
return ( BMP_COLOR_HIGHCONTRAST == _eMode ) ? aImage_HC : aImage;
2000-09-18 16:07:07 +00:00
}
//========================================================================
TYPEINIT1(FmFilterItem, FmFilterData);
//------------------------------------------------------------------------
FmFilterItem::FmFilterItem(const Reference< ::com::sun::star::lang::XMultiServiceFactory >& _rxFactory,
2000-11-06 06:19:53 +00:00
FmFilterItems* pParent,
2000-09-18 16:07:07 +00:00
const ::rtl::OUString& aFieldName,
const ::rtl::OUString& aText,
const Reference< ::com::sun::star::awt::XTextComponent > & _xText)
2000-11-06 06:19:53 +00:00
:FmFilterData(_rxFactory,pParent, aText)
2000-09-18 16:07:07 +00:00
,m_aFieldName(aFieldName)
,m_xText(_xText)
{
}
//------------------------------------------------------------------------
2002-05-17 07:41:57 +00:00
Image FmFilterItem::GetImage( BmpColorMode _eMode ) const
2000-09-18 16:07:07 +00:00
{
static Image aImage;
2002-05-17 07:41:57 +00:00
static Image aImage_HC;
2000-09-18 16:07:07 +00:00
if (!aImage)
{
2002-05-17 07:41:57 +00:00
ImageList aNavigatorImages( SVX_RES( RID_SVXIMGLIST_FMEXPL ) );
ImageList aNavigatorImages_HC( SVX_RES( RID_SVXIMGLIST_FMEXPL_HC ) );
2000-09-18 16:07:07 +00:00
aImage = aNavigatorImages.GetImage( RID_SVXIMG_FIELD );
2002-05-17 07:41:57 +00:00
aImage_HC = aNavigatorImages_HC.GetImage( RID_SVXIMG_FIELD );
2000-09-18 16:07:07 +00:00
}
2002-05-17 07:41:57 +00:00
return ( BMP_COLOR_HIGHCONTRAST == _eMode ) ? aImage_HC : aImage;
2000-09-18 16:07:07 +00:00
}
//========================================================================
// Hints for communicatition between model and view
//========================================================================
class FmFilterHint : public SfxHint
{
FmFilterData* m_pData;
public:
TYPEINFO();
FmFilterHint(FmFilterData* pData):m_pData(pData){}
FmFilterData* GetData() const { return m_pData; }
};
TYPEINIT1( FmFilterHint, SfxHint );
//========================================================================
class FmFilterInsertedHint : public FmFilterHint
{
sal_Int32 m_nPos; // Position relative to the parent of the data
public:
TYPEINFO();
FmFilterInsertedHint(FmFilterData* pData, sal_Int32 nRelPos)
:FmFilterHint(pData)
,m_nPos(nRelPos){}
sal_Int32 GetPos() const { return m_nPos; }
};
TYPEINIT1( FmFilterInsertedHint, FmFilterHint );
//========================================================================
class FmFilterReplacedHint : public FmFilterHint
{
public:
TYPEINFO();
FmFilterReplacedHint(FmFilterData* pData)
:FmFilterHint(pData){}
};
TYPEINIT1( FmFilterReplacedHint, FmFilterHint );
//========================================================================
class FmFilterRemovedHint : public FmFilterHint
{
public:
TYPEINFO();
FmFilterRemovedHint(FmFilterData* pData)
:FmFilterHint(pData){}
};
TYPEINIT1( FmFilterRemovedHint, FmFilterHint );
//========================================================================
class FmFilterTextChangedHint : public FmFilterHint
{
public:
TYPEINFO();
FmFilterTextChangedHint(FmFilterData* pData)
:FmFilterHint(pData){}
};
TYPEINIT1( FmFilterTextChangedHint, FmFilterHint );
//========================================================================
class FilterClearingHint : public SfxHint
2000-09-18 16:07:07 +00:00
{
public:
TYPEINFO();
FilterClearingHint(){}
2000-09-18 16:07:07 +00:00
};
TYPEINIT1( FilterClearingHint, SfxHint );
2000-09-18 16:07:07 +00:00
//========================================================================
class FmFilterCurrentChangedHint : public SfxHint
{
public:
TYPEINFO();
FmFilterCurrentChangedHint(){}
};
TYPEINIT1( FmFilterCurrentChangedHint, SfxHint );
//========================================================================
// class FmFilterAdapter, Listener an den FilterControls
//========================================================================
class FmFilterAdapter : public ::cppu::WeakImplHelper1< ::com::sun::star::awt::XTextListener >
{
FmFilterControls m_aFilterControls;
FmFilterModel* m_pModel;
public:
FmFilterAdapter(FmFilterModel* pModel, const Reference< ::com::sun::star::container::XIndexAccess >& xControllers);
// ::com::sun::star::lang::XEventListener
virtual void SAL_CALL disposing(const ::com::sun::star::lang::EventObject& Source) throw( RuntimeException );
// ::com::sun::star::awt::XTextListener
2001-09-12 17:11:08 +00:00
virtual void SAL_CALL textChanged(const ::com::sun::star::awt::TextEvent& e) throw( ::com::sun::star::uno::RuntimeException );
2000-09-18 16:07:07 +00:00
// helpers
void dispose() throw( RuntimeException );
void InsertElements(const Reference< ::com::sun::star::container::XIndexAccess >& xControllers);
void RemoveElement(const Reference< ::com::sun::star::awt::XTextComponent > & xText);
Reference< ::com::sun::star::beans::XPropertySet > getField(const Reference< ::com::sun::star::awt::XTextComponent > & xText) const;
void setText(sal_Int32 nPos,
const FmFilterItem* pFilterItem,
const ::rtl::OUString& rText);
void DeleteItemsByText(::std::vector<FmFilterData*>& rItems, const Reference< ::com::sun::star::awt::XTextComponent > & xText);
Reference< ::com::sun::star::form::XForm > findForm(const Reference< ::com::sun::star::container::XChild >& xChild);
};
//------------------------------------------------------------------------
FmFilterAdapter::FmFilterAdapter(FmFilterModel* pModel, const Reference< ::com::sun::star::container::XIndexAccess >& xControllers)
:m_pModel(pModel)
{
InsertElements(xControllers);
// listen on all controls as text listener
for (FmFilterControls::const_iterator iter = m_aFilterControls.begin();
iter != m_aFilterControls.end(); iter++)
(*iter).first->addTextListener(this);
}
//------------------------------------------------------------------------
void FmFilterAdapter::dispose() throw( RuntimeException )
{
// clear the filter control map
for (FmFilterControls::const_iterator iter = m_aFilterControls.begin();
iter != m_aFilterControls.end(); iter++)
(*iter).first->removeTextListener(this);
m_aFilterControls.clear();
}
//------------------------------------------------------------------------------
// delete all items relate to the control
void FmFilterAdapter::DeleteItemsByText(::std::vector<FmFilterData*>& rItems,
const Reference< ::com::sun::star::awt::XTextComponent > & xText)
{
for (::std::vector<FmFilterData*>::reverse_iterator i = rItems.rbegin();
// link problems with operator ==
i.base() != rItems.rend().base(); i++)
{
FmFilterItems* pFilterItems = PTR_CAST(FmFilterItems, *i);
if (pFilterItems)
{
FmFilterItem* pFilterItem = pFilterItems->Find(xText);
if (pFilterItem)
{
// remove the condition
::std::vector<FmFilterData*>& rItems = pFilterItems->GetChilds();
::std::vector<FmFilterData*>::iterator j = find(rItems.begin(), rItems.end(), pFilterItem);
if (j != rItems.end())
m_pModel->Remove(j, pFilterItem);
}
continue;
}
FmFormItem* pFormItem = PTR_CAST(FmFormItem, *i);
if (pFormItem)
DeleteItemsByText(pFormItem->GetChilds(), xText);
}
}
//------------------------------------------------------------------------
void FmFilterAdapter::InsertElements(const Reference< ::com::sun::star::container::XIndexAccess >& xControllers)
{
for (sal_Int32 i = 0, nLen = xControllers->getCount(); i < nLen; ++i)
{
Reference< ::com::sun::star::container::XIndexAccess > xElement;
xControllers->getByIndex(i) >>= xElement;
// Insert the Elements of the controller
InsertElements(xElement);
// store the filter controls
FmXFormController* pController = NULL;
2000-10-20 13:18:57 +00:00
// ::comphelper::getImplementation(pController, Reference<XUnoTunnel>(xElement, UNO_QUERY));
Reference< ::com::sun::star::lang::XUnoTunnel > xTunnel(xElement,UNO_QUERY);
2000-09-18 16:07:07 +00:00
DBG_ASSERT(xTunnel.is(), "FmFilterAdapter::InsertElements : xTunnel is invalid!");
if(xTunnel.is())
{
pController = (FmXFormController*)xTunnel->getSomething(FmXFormController::getUnoTunnelImplementationId());
}
const FmFilterControls& rControls = pController->getFilterControls();
for (FmFilterControls::const_iterator iter = rControls.begin(); iter != rControls.end(); ++iter )
m_aFilterControls.insert(*iter);
}
}
//------------------------------------------------------------------------------
void FmFilterAdapter::RemoveElement(const Reference< ::com::sun::star::awt::XTextComponent > & xText)
{
if (xText.is())
{
// alle Level durchlaufen und eintraege entfernen
if (m_pModel)
DeleteItemsByText(m_pModel->GetChilds(), xText);
FmFilterControls::iterator iter = m_aFilterControls.find(xText);
if (iter != m_aFilterControls.end())
m_aFilterControls.erase(iter);
}
}
//------------------------------------------------------------------------
Reference< ::com::sun::star::beans::XPropertySet > FmFilterAdapter::getField(const Reference< ::com::sun::star::awt::XTextComponent > & xText) const
{
Reference< ::com::sun::star::beans::XPropertySet > xField;
FmFilterControls::const_iterator i = m_aFilterControls.find(xText);
if (i != m_aFilterControls.end())
xField = (*i).second;
return xField;
}
//------------------------------------------------------------------------
void FmFilterAdapter::setText(sal_Int32 nRowPos,
const FmFilterItem* pFilterItem,
const ::rtl::OUString& rText)
{
// set the text for the text component
Reference< ::com::sun::star::awt::XTextComponent > xText(pFilterItem->GetTextComponent());
xText->setText(rText);
// get the controller of the text component and its filter rows
FmFormItem* pFormItem = PTR_CAST(FmFormItem,pFilterItem->GetParent()->GetParent());
FmXFormController* pController = NULL;
Reference< ::com::sun::star::lang::XUnoTunnel > xTunnel(pFormItem->GetController(),UNO_QUERY);
2000-09-18 16:07:07 +00:00
DBG_ASSERT(xTunnel.is(), "FmFilterAdapter::InsertElements : xTunnel is invalid!");
if(xTunnel.is())
{
pController = (FmXFormController*)xTunnel->getSomething(FmXFormController::getUnoTunnelImplementationId());
}
2000-10-20 13:18:57 +00:00
// ::comphelper::getImplementation(pController, Reference<XUnoTunnel>(pFormItem->GetController(),UNO_QUERY));
2000-09-18 16:07:07 +00:00
FmFilterRows& rRows = pController->getFilterRows();
2001-04-09 10:19:35 +00:00
DBG_ASSERT(nRowPos < (sal_Int32)rRows.size(), "wrong row pos");
2000-09-18 16:07:07 +00:00
// Suchen der aktuellen Row
FmFilterRow& rRow = rRows[nRowPos];
// do we have a new filter
2001-05-11 15:07:05 +00:00
if (rText.getLength())
2000-09-18 16:07:07 +00:00
rRow[xText] = rText;
else
{
// do we have the control in the row
FmFilterRow::iterator iter = rRow.find(xText);
// erase the entry out of the row
if (iter != rRow.end())
rRow.erase(iter);
}
}
// ::com::sun::star::lang::XEventListener
//------------------------------------------------------------------------
void SAL_CALL FmFilterAdapter::disposing(const ::com::sun::star::lang::EventObject& e) throw( RuntimeException )
{
Reference< ::com::sun::star::awt::XTextComponent > xText(e.Source,UNO_QUERY);
if (xText.is())
RemoveElement(xText);
}
// XTextListener
//------------------------------------------------------------------------
Reference< ::com::sun::star::form::XForm > FmFilterAdapter::findForm(const Reference< ::com::sun::star::container::XChild >& xChild)
{
Reference< ::com::sun::star::form::XForm > xForm;
if (xChild.is())
{
xForm = Reference< ::com::sun::star::form::XForm >(xChild->getParent(), UNO_QUERY);
if (!xForm.is())
xForm = findForm(Reference< ::com::sun::star::container::XChild >(xChild->getParent(), UNO_QUERY));
}
return xForm;
}
// XTextListener
//------------------------------------------------------------------------
2001-09-12 17:11:08 +00:00
void FmFilterAdapter::textChanged(const ::com::sun::star::awt::TextEvent& e) throw( ::com::sun::star::uno::RuntimeException )
2000-09-18 16:07:07 +00:00
{
// Find the according formitem in the
Reference< ::com::sun::star::awt::XControl > xControl(e.Source, UNO_QUERY);
2000-09-18 16:07:07 +00:00
if (!m_pModel || !xControl.is())
return;
Reference< ::com::sun::star::form::XForm > xForm(findForm(Reference< ::com::sun::star::container::XChild >(xControl->getModel(), UNO_QUERY)));
if (!xForm.is())
return;
FmFormItem* pFormItem = m_pModel->Find(m_pModel->m_aChilds, xForm);
if (pFormItem)
{
Reference< ::com::sun::star::awt::XTextComponent > xText(e.Source, UNO_QUERY);
FmFilterItems* pFilter = PTR_CAST(FmFilterItems, pFormItem->GetChilds()[pFormItem->GetCurrentPosition()]);
FmFilterItem* pFilterItem = pFilter->Find(xText);
if (pFilterItem)
{
2001-05-11 15:07:05 +00:00
if (xText->getText().getLength())
2000-09-18 16:07:07 +00:00
{
pFilterItem->SetText(xText->getText());
// UI benachrichtigen
FmFilterTextChangedHint aChangeHint(pFilterItem);
m_pModel->Broadcast( aChangeHint );
}
else
{
// no text anymore so remove the condition
m_pModel->Remove(pFilterItem);
}
}
else
{
// searching the component by field name
::rtl::OUString aFieldName = getLabelName(Reference< ::com::sun::star::beans::XPropertySet > (Reference< ::com::sun::star::awt::XControl > (xText, UNO_QUERY)->getModel(),UNO_QUERY));
2000-11-06 06:19:53 +00:00
pFilterItem = new FmFilterItem(m_pModel->getORB(),pFilter, aFieldName, xText->getText(), xText);
2000-09-18 16:07:07 +00:00
m_pModel->Insert(pFilter->GetChilds().end(), pFilterItem);
}
m_pModel->CheckIntegrity(pFormItem);
}
}
//========================================================================
// class FmFilterModel
//========================================================================
TYPEINIT1(FmFilterModel, FmParentData);
//------------------------------------------------------------------------
FmFilterModel::FmFilterModel(const Reference< ::com::sun::star::lang::XMultiServiceFactory >& _rxFactory)
2000-11-06 06:19:53 +00:00
:FmParentData(_rxFactory,NULL, ::rtl::OUString())
,OSQLParserClient(_rxFactory)
2000-09-18 16:07:07 +00:00
,m_pAdapter(NULL)
,m_pCurrentItems(NULL)
2000-11-06 06:19:53 +00:00
,m_xORB(_rxFactory)
2000-09-18 16:07:07 +00:00
{
}
//------------------------------------------------------------------------
FmFilterModel::~FmFilterModel()
{
Clear();
}
//------------------------------------------------------------------------
void FmFilterModel::Clear()
{
// notify
FilterClearingHint aClearedHint;
Broadcast( aClearedHint );
// loose endings
2000-09-18 16:07:07 +00:00
if (m_pAdapter)
{
m_pAdapter->dispose();
m_pAdapter->release();
m_pAdapter= NULL;
}
m_pCurrentItems = NULL;
m_xController = NULL;
m_xControllers = NULL;
for (::std::vector<FmFilterData*>::const_iterator i = m_aChilds.begin();
i != m_aChilds.end(); i++)
delete (*i);
m_aChilds.clear();
}
//------------------------------------------------------------------------
void FmFilterModel::Update(const Reference< ::com::sun::star::container::XIndexAccess > & xControllers, const Reference< ::com::sun::star::form::XFormController > & xCurrent)
{
if ((::com::sun::star::form::XFormController*) xCurrent.get() == (::com::sun::star::form::XFormController*) m_xController.get())
return;
if (!xControllers.is())
{
Clear();
return;
}
// there is only a new current controller
if ((::com::sun::star::container::XIndexAccess*)m_xControllers.get() != (::com::sun::star::container::XIndexAccess*)xControllers.get())
{
Clear();
m_xControllers = xControllers;
Update(m_xControllers, this);
DBG_ASSERT(xCurrent.is(), "FmFilterModel::Update(...) no current controller");
// Listening for TextChanges
m_pAdapter = new FmFilterAdapter(this, xControllers);
m_pAdapter->acquire();
SetCurrentController(xCurrent);
CheckIntegrity(this);
}
else
SetCurrentController(xCurrent);
}
//------------------------------------------------------------------------
void FmFilterModel::Update(const Reference< ::com::sun::star::container::XIndexAccess > & xControllers, FmParentData* pParent)
{
sal_Int32 nCount = xControllers->getCount();
for (sal_Int32 i = 0; i < nCount; i++)
{
2000-11-07 12:16:50 +00:00
Reference< ::com::sun::star::form::XFormController > xController;
xControllers->getByIndex(i) >>= xController;
2000-09-18 16:07:07 +00:00
Reference< ::com::sun::star::beans::XPropertySet > xModelAsSet(xController->getModel(), UNO_QUERY);
2000-10-20 13:18:57 +00:00
::rtl::OUString aName = ::comphelper::getString(xModelAsSet->getPropertyValue(FM_PROP_NAME));
2000-09-18 16:07:07 +00:00
// Insert a new ::com::sun::star::form
2000-11-06 06:19:53 +00:00
FmFormItem* pFormItem = new FmFormItem(m_xORB,pParent, xController, aName);
2000-09-18 16:07:07 +00:00
Insert(pParent->GetChilds().end(), pFormItem);
// And now insert the filters for the form
FmXFormController* pController = NULL;
Reference< ::com::sun::star::lang::XUnoTunnel > xTunnel(pFormItem->GetController(),UNO_QUERY);
2000-09-18 16:07:07 +00:00
DBG_ASSERT(xTunnel.is(), "FmFilterAdapter::InsertElements : xTunnel is invalid!");
if(xTunnel.is())
{
pController = (FmXFormController*)xTunnel->getSomething(FmXFormController::getUnoTunnelImplementationId());
}
2000-10-20 13:18:57 +00:00
// ::comphelper::getImplementation(pController, Reference<XUnoTunnel>(pFormItem->GetController(),UNO_QUERY));
2000-09-18 16:07:07 +00:00
INT32 nPos = pController->getCurrentFilterPosition();
pFormItem->SetCurrentPosition(nPos);
String aTitle(SVX_RES(RID_STR_FILTER_FILTER_FOR));
const FmFilterRows& rRows = pController->getFilterRows();
for (FmFilterRows::const_iterator iter = rRows.begin(); iter != rRows.end(); ++iter)
{
const FmFilterRow& rRow = *iter;
// now add the filter rows
// One Row always exists
2000-11-06 06:19:53 +00:00
FmFilterItems* pFilterItems = new FmFilterItems(m_xORB,pFormItem, aTitle);
2000-09-18 16:07:07 +00:00
Insert(pFormItem->GetChilds().end(), pFilterItems);
for (FmFilterRow::const_iterator iter1 = rRow.begin(); iter1 != rRow.end(); ++iter1)
{
// insert new and conditons
::rtl::OUString aFieldName = getLabelName(Reference< ::com::sun::star::beans::XPropertySet > (Reference< ::com::sun::star::awt::XControl > ((*iter1).first, UNO_QUERY)->getModel(),UNO_QUERY));
2000-11-06 06:19:53 +00:00
FmFilterItem* pANDCondition = new FmFilterItem(m_xORB,pFilterItems, aFieldName, (*iter1).second, (*iter1).first);
2000-09-18 16:07:07 +00:00
Insert(pFilterItems->GetChilds().end(), pANDCondition);
}
// title for the next conditions
aTitle = SVX_RES(RID_STR_FILTER_FILTER_OR);
}
// now add dependent controllers
Reference< ::com::sun::star::container::XIndexAccess > xControllerAsIndex(xController, UNO_QUERY);
Update(xControllerAsIndex, pFormItem);
}
}
//------------------------------------------------------------------------
FmFormItem* FmFilterModel::Find(const ::std::vector<FmFilterData*>& rItems, const Reference< ::com::sun::star::form::XFormController > & xController) const
{
for (::std::vector<FmFilterData*>::const_iterator i = rItems.begin();
i != rItems.end(); i++)
{
FmFormItem* pForm = PTR_CAST(FmFormItem,*i);
if (pForm)
{
if ((::com::sun::star::form::XFormController*)xController.get() == (::com::sun::star::form::XFormController*)pForm->GetController().get())
return pForm;
else
{
pForm = Find(pForm->GetChilds(), xController);
if (pForm)
return pForm;
}
}
}
return NULL;
}
//------------------------------------------------------------------------
FmFormItem* FmFilterModel::Find(const ::std::vector<FmFilterData*>& rItems, const Reference< ::com::sun::star::form::XForm >& xForm) const
{
for (::std::vector<FmFilterData*>::const_iterator i = rItems.begin();
i != rItems.end(); i++)
{
FmFormItem* pForm = PTR_CAST(FmFormItem,*i);
if (pForm)
{
if (xForm == pForm->GetController()->getModel())
return pForm;
else
{
pForm = Find(pForm->GetChilds(), xForm);
if (pForm)
return pForm;
}
}
}
return NULL;
}
//------------------------------------------------------------------------
void FmFilterModel::SetCurrentController(const Reference< ::com::sun::star::form::XFormController > & xCurrent)
{
if ((::com::sun::star::form::XFormController*) xCurrent.get() == (::com::sun::star::form::XFormController*) m_xController.get())
return;
m_xController = xCurrent;
FmFormItem* pItem = Find(m_aChilds, xCurrent);
if (pItem)
{
if ( (USHORT)pItem->GetChilds().size() > pItem->GetCurrentPosition() )
SetCurrentItems( static_cast< FmFilterItems* >( pItem->GetChilds()[ pItem->GetCurrentPosition() ] ) );
}
2000-09-18 16:07:07 +00:00
}
//------------------------------------------------------------------------
void FmFilterModel::AppendFilterItems(FmFormItem* pFormItem)
{
DBG_ASSERT(pFormItem, "AppendFilterItems(): no form item present");
FmFilterItems* pFilterItems = new FmFilterItems(m_xORB,pFormItem, ::rtl::OUString(String(SVX_RES(RID_STR_FILTER_FILTER_OR))));
2000-09-18 16:07:07 +00:00
// insert the condition behind the last filter items
::std::vector<FmFilterData*>::reverse_iterator iter;
for (iter = pFormItem->GetChilds().rbegin();
// link problems with operator ==
iter.base() != pFormItem->GetChilds().rend().base(); iter++)
{
if ((*iter)->ISA(FmFilterItems))
break;
}
sal_Int32 nInsertPos = iter.base() - pFormItem->GetChilds().rend().base();
::std::vector<FmFilterData*>::iterator i = pFormItem->GetChilds().begin() + nInsertPos;
Insert(i, pFilterItems);
// do we need a new row
FmXFormController* pController = NULL;
Reference< ::com::sun::star::lang::XUnoTunnel > xTunnel(pFormItem->GetController(),UNO_QUERY);
2000-09-18 16:07:07 +00:00
DBG_ASSERT(xTunnel.is(), "FmFilterAdapter::InsertElements : xTunnel is invalid!");
if(xTunnel.is())
{
pController = (FmXFormController*)xTunnel->getSomething(FmXFormController::getUnoTunnelImplementationId());
}
2000-10-20 13:18:57 +00:00
// ::comphelper::getImplementation(pController, Reference<XUnoTunnel>(pFormItem->GetController(),UNO_QUERY));
2000-09-18 16:07:07 +00:00
FmFilterRows& rRows = pController->getFilterRows();
// determine the filter position
2001-04-09 10:19:35 +00:00
if (nInsertPos >= (sal_Int32)rRows.size())
2000-09-18 16:07:07 +00:00
rRows.push_back(FmFilterRow());
}
//------------------------------------------------------------------------
void FmFilterModel::Insert(const ::std::vector<FmFilterData*>::iterator& rPos, FmFilterData* pData)
{
::std::vector<FmFilterData*>& rItems = pData->GetParent()->GetChilds();
sal_Int32 nPos = rPos == rItems.end() ? LIST_APPEND : rPos - rItems.begin();
rItems.insert(rPos, pData);
// UI benachrichtigen
FmFilterInsertedHint aInsertedHint(pData, nPos);
Broadcast( aInsertedHint );
}
//------------------------------------------------------------------------
void FmFilterModel::Remove(FmFilterData* pData)
{
FmParentData* pParent = pData->GetParent();
::std::vector<FmFilterData*>& rItems = pParent->GetChilds();
// erase the item from the model
::std::vector<FmFilterData*>::iterator i = find(rItems.begin(), rItems.end(), pData);
DBG_ASSERT(i != rItems.end(), "FmFilterModel::Remove(): unknown Item");
// position within the parent
sal_Int32 nPos = i - rItems.begin();
if (pData->ISA(FmFilterItems))
{
FmFormItem* pFormItem = (FmFormItem*)pParent;
FmXFormController* pController = NULL;
Reference< ::com::sun::star::lang::XUnoTunnel > xTunnel(pFormItem->GetController(),UNO_QUERY);
2000-09-18 16:07:07 +00:00
DBG_ASSERT(xTunnel.is(), "FmFilterAdapter::InsertElements : xTunnel is invalid!");
if(xTunnel.is())
{
pController = (FmXFormController*)xTunnel->getSomething(FmXFormController::getUnoTunnelImplementationId());
}
2000-10-20 13:18:57 +00:00
// ::comphelper::getImplementation(pController, Reference<XUnoTunnel>(pFormItem->GetController(),UNO_QUERY));
2000-09-18 16:07:07 +00:00
FmFilterRows& rRows = pController->getFilterRows();
// how many entries do we have
// it's the last row than we just empty it
2001-04-09 10:19:35 +00:00
if (nPos == (sal_Int32)(rRows.size() - 1))
2000-09-18 16:07:07 +00:00
{
// remove all childs and stay current
::std::vector<FmFilterData*>& rChilds = ((FmFilterItems*)pData)->GetChilds();
while (!rChilds.empty())
{
::std::vector<FmFilterData*>::iterator j = rChilds.end();
j--;
// we stay on the level so delete each item explizit to clean the controls
sal_Int32 nParentPos = j - rChilds.begin();
// EmptyText removes the filter
FmFilterItem* pFilterItem = PTR_CAST(FmFilterItem, *j);
m_pAdapter->setText(nParentPos, pFilterItem, ::rtl::OUString());
Remove(j, pFilterItem);
}
}
else // delete the row
{
// if the row is on the current position we have to away from that position.
// than we can delete it
if (nPos == pFormItem->GetCurrentPosition())
{
::std::vector<FmFilterData*>::iterator j = i;
// give a new current postion
2001-04-09 10:19:35 +00:00
if (nPos < (sal_Int32)(rRows.size() - 1))
2000-09-18 16:07:07 +00:00
// set it to the next row
++j;
else
// set it to the previous row
--j;
// if necessary we have the formItem for the current controller
// than we have to adjust the data displayed in the form
pFormItem->SetCurrentPosition(j - rItems.begin());
pController->setCurrentFilterPosition(j - rItems.begin());
// Keep the view consistent and force and new painting
FmFilterTextChangedHint aChangeHint(*j);
Broadcast( aChangeHint );
}
// now delete the entry
// before deleting we have to shift the current position of the form if necessary
if (nPos < pFormItem->GetCurrentPosition())
{
pFormItem->SetCurrentPosition(pFormItem->GetCurrentPosition() - 1);
pController->decrementCurrentFilterPosition();
// is it the first row, than the nex row has to recieve a different name
if (nPos == 0)
{
// ensure that the text labels are consistent
rItems[1]->SetText(String(SVX_RES(RID_STR_FILTER_FILTER_FOR)));
FmFilterTextChangedHint aChangeHint(rItems[1]);
Broadcast( aChangeHint );
}
}
// delete it
rRows.erase(rRows.begin() + nPos);
// and keep the controller consistent
DBG_ASSERT(rRows.size() != 0, "wrong row size");
// and remove it from the model
Remove(i, pData);
}
}
else // FormItems can not be deleted
{
FmFilterItem* pFilterItem = PTR_CAST(FmFilterItem, pData);
// if its the last condition remove the parent
if (rItems.size() == 1)
Remove(pFilterItem->GetParent());
else
{
// find the position of the father within his father
::std::vector<FmFilterData*>& rItems = pData->GetParent()->GetParent()->GetChilds();
::std::vector<FmFilterData*>::iterator j = find(rItems.begin(), rItems.end(), pFilterItem->GetParent());
DBG_ASSERT(j != rItems.end(), "FmFilterModel::Remove(): unknown Item");
sal_Int32 nParentPos = j - rItems.begin();
// EmptyText removes the filter
m_pAdapter->setText(nParentPos, pFilterItem, ::rtl::OUString());
Remove(i, pData);
}
}
}
//------------------------------------------------------------------------
void FmFilterModel::Remove(const ::std::vector<FmFilterData*>::iterator& rPos, FmFilterData* pData)
{
::std::vector<FmFilterData*>& rItems = pData->GetParent()->GetChilds();
rItems.erase(rPos);
// UI benachrichtigen
FmFilterRemovedHint aRemoveHint( pData );
Broadcast( aRemoveHint );
delete pData;
}
2000-09-18 16:07:07 +00:00
//------------------------------------------------------------------------
sal_Bool FmFilterModel::ValidateText(FmFilterItem* pItem, UniString& rText, UniString& rErrorMsg) const
{
// check the input
Reference< XPropertySet > xField(m_pAdapter->getField(pItem->GetTextComponent()));
OStaticDataAccessTools aStaticTools;
Reference< XConnection > xConnection(aStaticTools.getRowSetConnection(Reference< XRowSet > (m_xController->getModel(), UNO_QUERY)));
Reference< ::com::sun::star::util::XNumberFormatsSupplier > xFormatSupplier = aStaticTools.getNumberFormats(xConnection, sal_True);
Reference< ::com::sun::star::util::XNumberFormatter > xFormatter(m_xORB->createInstance(FM_NUMBER_FORMATTER), UNO_QUERY);
xFormatter->attachNumberFormatsSupplier(xFormatSupplier);
2000-09-18 16:07:07 +00:00
::rtl::OUString aErr, aTxt(rText);
::rtl::Reference< ISQLParseNode > xParseNode = predicateTree(aErr, aTxt, xFormatter, xField);
rErrorMsg = aErr;
rText = aTxt;
if (xParseNode.is())
2000-09-18 16:07:07 +00:00
{
2000-11-06 06:19:53 +00:00
::rtl::OUString aPreparedText;
::com::sun::star::lang::Locale aAppLocale = Application::GetSettings().GetUILocale();
xParseNode->parseNodeToPredicateStr(aPreparedText,
2000-09-18 16:07:07 +00:00
xConnection->getMetaData(),
xFormatter,
2002-09-27 13:06:42 +00:00
xField,aAppLocale,'.',
getParseContext());
2000-09-18 16:07:07 +00:00
rText = aPreparedText;
return sal_True;
}
else
return sal_False;
}
//------------------------------------------------------------------------
void FmFilterModel::Append(FmFilterItems* pItems, FmFilterItem* pFilterItem)
{
::std::vector<FmFilterData*>& rParentItems = pItems->GetParent()->GetChilds();
::std::vector<FmFilterData*>::iterator i = find(rParentItems.begin(), rParentItems.end(), pItems);
sal_Int32 nParentPos = i - rParentItems.begin();
Insert(pItems->GetChilds().end(), pFilterItem);
}
//------------------------------------------------------------------------
void FmFilterModel::SetText(FmFilterItem* pItem, const ::rtl::OUString& rText)
{
::std::vector<FmFilterData*>& rItems = pItem->GetParent()->GetParent()->GetChilds();
::std::vector<FmFilterData*>::iterator i = find(rItems.begin(), rItems.end(), pItem->GetParent());
sal_Int32 nParentPos = i - rItems.begin();
m_pAdapter->setText(nParentPos, pItem, rText);
if (!rText)
Remove(pItem);
else
{
// Change the text
pItem->SetText(rText);
FmFilterTextChangedHint aChangeHint(pItem);
Broadcast( aChangeHint );
}
}
//------------------------------------------------------------------------
void FmFilterModel::SetCurrentItems(FmFilterItems* pCurrent)
{
if (m_pCurrentItems == pCurrent)
return;
// search for the condition
if (pCurrent)
{
FmFormItem* pFormItem = (FmFormItem*)pCurrent->GetParent();
::std::vector<FmFilterData*>& rItems = pFormItem->GetChilds();
::std::vector<FmFilterData*>::const_iterator i = find(rItems.begin(), rItems.end(), pCurrent);
if (i != rItems.end())
{
// determine the filter position
sal_Int32 nPos = i - rItems.begin();
FmXFormController* pController = NULL;
Reference< ::com::sun::star::lang::XUnoTunnel > xTunnel(pFormItem->GetController(),UNO_QUERY);
2000-09-18 16:07:07 +00:00
DBG_ASSERT(xTunnel.is(), "FmFilterAdapter::InsertElements : xTunnel is invalid!");
if(xTunnel.is())
{
pController = (FmXFormController*)xTunnel->getSomething(FmXFormController::getUnoTunnelImplementationId());
}
2000-10-20 13:18:57 +00:00
// ::comphelper::getImplementation(pController, Reference<XUnoTunnel>(pFormItem->GetController(),UNO_QUERY));
2000-09-18 16:07:07 +00:00
pController->setCurrentFilterPosition(nPos);
pFormItem->SetCurrentPosition(nPos);
if ((::com::sun::star::form::XFormController*)m_xController.get() != (::com::sun::star::form::XFormController*)pFormItem->GetController().get())
// calls SetCurrentItems again
SetCurrentController(pFormItem->GetController());
else
m_pCurrentItems = pCurrent;
}
else
m_pCurrentItems = NULL;
}
else
m_pCurrentItems = NULL;
// UI benachrichtigen
FmFilterCurrentChangedHint aHint;
Broadcast( aHint );
}
//------------------------------------------------------------------------
void FmFilterModel::CheckIntegrity(FmParentData* pItem)
{
// checks whether for each form there's one free level for input
::std::vector<FmFilterData*>& rItems = pItem->GetChilds();
sal_Bool bAppendLevel = sal_False;
for (::std::vector<FmFilterData*>::iterator i = rItems.begin();
i != rItems.end(); i++)
{
FmFilterItems* pItems = PTR_CAST(FmFilterItems, *i);
if (pItems)
{
bAppendLevel = !pItems->GetChilds().empty();
continue;
}
FmFormItem* pFormItem = PTR_CAST(FmFormItem, *i);
if (pFormItem)
{
CheckIntegrity(pFormItem);
continue;
}
}
if (bAppendLevel)
AppendFilterItems((FmFormItem*)pItem);
}
//========================================================================
// class FmFilterItemsString
//========================================================================
class FmFilterItemsString : public SvLBoxString
{
public:
FmFilterItemsString( SvLBoxEntry* pEntry, sal_uInt16 nFlags, const XubString& rStr )
:SvLBoxString(pEntry,nFlags,rStr){}
virtual void Paint(const Point& rPos, SvLBox& rDev, sal_uInt16 nFlags, SvLBoxEntry* pEntry);
virtual void InitViewData( SvLBox* pView,SvLBoxEntry* pEntry, SvViewDataItem* pViewData);
};
const int nxDBmp = 12;
//------------------------------------------------------------------------
void FmFilterItemsString::Paint(const Point& rPos, SvLBox& rDev, sal_uInt16 nFlags, SvLBoxEntry* pEntry )
{
FmFilterItems* pRow = (FmFilterItems*)pEntry->GetUserData();
FmFormItem* pForm = (FmFormItem*)pRow->GetParent();
// current filter is significant painted
if (pForm->GetChilds()[pForm->GetCurrentPosition()] == pRow)
{
Color aLineColor(rDev.GetLineColor());
Rectangle aRect(rPos, GetSize(&rDev, pEntry ));
Point aFirst(rPos.X(), aRect.Bottom() - 6);
Point aSecond(aFirst.X() + 2, aFirst.Y() + 3);
rDev.SetLineColor(rDev.GetTextColor());
rDev.DrawLine(aFirst, aSecond);
aFirst = aSecond;
aFirst.X() += 1;
aSecond.X() += 6;
aSecond.Y() -= 5;
rDev.DrawLine(aFirst, aSecond);
rDev.SetLineColor( aLineColor );
}
rDev.DrawText( Point(rPos.X() + nxDBmp, rPos.Y()), GetText() );
}
//------------------------------------------------------------------------
void FmFilterItemsString::InitViewData( SvLBox* pView,SvLBoxEntry* pEntry, SvViewDataItem* pViewData)
{
if( !pViewData )
pViewData = pView->GetViewDataItem( pEntry, this );
Size aSize(pView->GetTextWidth(GetText()), pView->GetTextHeight());
aSize.Width() += nxDBmp;
pViewData->aSize = aSize;
}
//========================================================================
// class FmFilterString
//========================================================================
class FmFilterString : public SvLBoxString
{
UniString m_aName;
public:
FmFilterString( SvLBoxEntry* pEntry, sal_uInt16 nFlags, const XubString& rStr, const UniString& aName)
:SvLBoxString(pEntry,nFlags,rStr)
,m_aName(aName)
{
m_aName.AppendAscii(": ");
}
virtual void Paint(const Point& rPos, SvLBox& rDev, sal_uInt16 nFlags, SvLBoxEntry* pEntry);
virtual void InitViewData( SvLBox* pView,SvLBoxEntry* pEntry, SvViewDataItem* pViewData);
};
const int nxD = 4;
//------------------------------------------------------------------------
void FmFilterString::InitViewData( SvLBox* pView,SvLBoxEntry* pEntry, SvViewDataItem* pViewData)
{
if( !pViewData )
pViewData = pView->GetViewDataItem( pEntry, this );
Font aOldFont( pView->GetFont());
Font aFont( aOldFont );
aFont.SetWeight(WEIGHT_BOLD);
pView->SetFont( aFont );
Size aSize(pView->GetTextWidth(m_aName), pView->GetTextHeight());
pView->SetFont( aOldFont );
aSize.Width() += pView->GetTextWidth(GetText()) + nxD;
pViewData->aSize = aSize;
}
//------------------------------------------------------------------------
void FmFilterString::Paint(const Point& rPos, SvLBox& rDev, sal_uInt16 nFlags, SvLBoxEntry* pEntry )
{
Font aOldFont( rDev.GetFont());
Font aFont( aOldFont );
aFont.SetWeight(WEIGHT_BOLD);
rDev.SetFont( aFont );
Point aPos(rPos);
rDev.DrawText( aPos, m_aName );
// position for the second text
aPos.X() += rDev.GetTextWidth(m_aName) + nxD;
rDev.SetFont( aOldFont );
rDev.DrawText( aPos, GetText() );
}
//========================================================================
// class FmFilterNavigator
//========================================================================
FmFilterNavigator::FmFilterNavigator( Window* pParent )
:SvTreeListBox( pParent, WB_HASBUTTONS|WB_HASLINES|WB_BORDER|WB_HASBUTTONSATROOT )
2001-04-09 10:19:35 +00:00
,m_aControlExchange(this)
,m_pEditingCurrently(NULL)
2000-09-18 16:07:07 +00:00
{
SetHelpId( HID_FILTER_NAVIGATOR );
2002-05-17 07:41:57 +00:00
{
{
ImageList aNavigatorImages( SVX_RES( RID_SVXIMGLIST_FMEXPL ) );
SetNodeBitmaps(
aNavigatorImages.GetImage( RID_SVXIMG_COLLAPSEDNODE ),
aNavigatorImages.GetImage( RID_SVXIMG_EXPANDEDNODE ),
BMP_COLOR_NORMAL
);
}
{
ImageList aNavigatorImages( SVX_RES( RID_SVXIMGLIST_FMEXPL_HC ) );
SetNodeBitmaps(
aNavigatorImages.GetImage( RID_SVXIMG_COLLAPSEDNODE ),
aNavigatorImages.GetImage( RID_SVXIMG_EXPANDEDNODE ),
BMP_COLOR_HIGHCONTRAST
);
}
}
2000-09-18 16:07:07 +00:00
2000-11-06 06:19:53 +00:00
m_pModel = new FmFilterModel(comphelper::getProcessServiceFactory());
2000-09-18 16:07:07 +00:00
StartListening( *m_pModel );
EnableInplaceEditing( sal_True );
SetSelectionMode(MULTIPLE_SELECTION);
SetDragDropMode(0xFFFF);
m_aDropActionTimer.SetTimeoutHdl(LINK(this, FmFilterNavigator, OnDropActionTimer));
}
//------------------------------------------------------------------------
FmFilterNavigator::~FmFilterNavigator()
{
EndListening( *m_pModel );
delete m_pModel;
}
//------------------------------------------------------------------------
void FmFilterNavigator::Clear()
{
m_pModel->Clear();
}
//------------------------------------------------------------------------
void FmFilterNavigator::Update(const Reference< ::com::sun::star::container::XIndexAccess > & xControllers, const Reference< ::com::sun::star::form::XFormController > & xCurrent)
{
if (xCurrent == m_pModel->GetCurrentController())
return;
m_pModel->Update(xControllers, xCurrent);
// expand the filters for the current controller
SvLBoxEntry* pEntry = FindEntry(m_pModel->GetCurrentForm());
if (pEntry && !IsExpanded(pEntry))
{
SelectAll(sal_False);
if (!IsExpanded(pEntry))
Expand(pEntry);
pEntry = FindEntry(m_pModel->GetCurrentItems());
if (pEntry)
{
if (!IsExpanded(pEntry))
Expand(pEntry);
Select(pEntry, sal_True);
}
}
}
//------------------------------------------------------------------------
sal_Bool FmFilterNavigator::EditingEntry( SvLBoxEntry* pEntry, Selection& rSelection )
{
m_pEditingCurrently = pEntry;
2000-09-18 16:07:07 +00:00
if (!SvTreeListBox::EditingEntry( pEntry, rSelection ))
return sal_False;
return pEntry && ((FmFilterData*)pEntry->GetUserData())->ISA(FmFilterItem);
}
//------------------------------------------------------------------------
sal_Bool FmFilterNavigator::EditedEntry( SvLBoxEntry* pEntry, const XubString& rNewText )
{
DBG_ASSERT(pEntry == m_pEditingCurrently, "FmFilterNavigator::EditedEntry: suspicious entry!");
m_pEditingCurrently = NULL;
2000-09-18 16:07:07 +00:00
if (EditingCanceled())
return sal_True;
DBG_ASSERT(((FmFilterData*)pEntry->GetUserData())->ISA(FmFilterItem),
"FmFilterNavigator::EditedEntry() wrong entry");
UniString aText(rNewText);
aText.EraseTrailingChars();
aText.EraseLeadingChars();
if (aText.Len() == 0)
2000-09-18 16:07:07 +00:00
{
// deleting the entry asynchron
ULONG nEvent;
2000-09-18 16:07:07 +00:00
PostUserEvent(nEvent, LINK(this, FmFilterNavigator, OnRemove), pEntry);
}
else
{
UniString aErrorMsg;
if (m_pModel->ValidateText((FmFilterItem*)pEntry->GetUserData(), aText, aErrorMsg))
{
GrabFocus();
// this will set the text at the FmFilterItem, as well as update any filter controls
// which are connected to this particular entry
m_pModel->SetText( static_cast< FmFilterItem* >( pEntry->GetUserData() ), aText );
2000-09-18 16:07:07 +00:00
SetCursor( pEntry, sal_True );
SetEntryText( pEntry, aText );
2000-09-18 16:07:07 +00:00
}
else
{
// display the error and return sal_False
SQLContext aError;
aError.Message = String(SVX_RES(RID_STR_SYNTAXERROR));
aError.Details = aErrorMsg;
displayException(aError, this);
2000-09-18 16:07:07 +00:00
return sal_False;
}
}
return sal_True;
}
//------------------------------------------------------------------------
IMPL_LINK( FmFilterNavigator, OnRemove, SvLBoxEntry*, pEntry )
2000-09-18 16:07:07 +00:00
{
// now remove the entry
m_pModel->Remove((FmFilterData*) pEntry->GetUserData());
2000-09-18 16:07:07 +00:00
return 0L;
}
//------------------------------------------------------------------------
IMPL_LINK( FmFilterNavigator, OnDropActionTimer, void*, EMPTYARG )
{
if (--m_aTimerCounter > 0)
return 0L;
if (m_aDropActionType == DA_EXPANDNODE)
{
SvLBoxEntry* pToExpand = GetEntry(m_aTimerTriggered);
if (pToExpand && (GetChildCount(pToExpand) > 0) && !IsExpanded(pToExpand))
// tja, eigentlich muesste ich noch testen, ob die Node nicht schon expandiert ist, aber ich
// habe dazu weder in den Basisklassen noch im Model eine Methode gefunden ...
// aber ich denke, die BK sollte es auch so vertragen
Expand(pToExpand);
// nach dem Expand habe ich im Gegensatz zum Scrollen natuerlich nix mehr zu tun
m_aDropActionTimer.Stop();
}
else
{
switch (m_aDropActionType)
{
case DA_SCROLLUP :
ScrollOutputArea(1);
break;
case DA_SCROLLDOWN :
ScrollOutputArea(-1);
break;
}
m_aTimerCounter = DROP_ACTION_TIMER_SCROLL_TICKS;
}
return 0L;
}
//------------------------------------------------------------------------
2001-04-09 10:19:35 +00:00
sal_Int8 FmFilterNavigator::AcceptDrop( const AcceptDropEvent& rEvt )
2000-09-18 16:07:07 +00:00
{
2001-04-09 10:19:35 +00:00
Point aDropPos = rEvt.maPosPixel;
2000-09-18 16:07:07 +00:00
// kuemmern wir uns erst mal um moeglich DropActions (Scrollen und Aufklappen)
2001-04-09 10:19:35 +00:00
if (rEvt.mbLeaving)
2000-09-18 16:07:07 +00:00
{
if (m_aDropActionTimer.IsActive())
m_aDropActionTimer.Stop();
}
else
{
sal_Bool bNeedTrigger = sal_False;
// auf dem ersten Eintrag ?
if ((aDropPos.Y() >= 0) && (aDropPos.Y() < GetEntryHeight()))
{
m_aDropActionType = DA_SCROLLUP;
bNeedTrigger = sal_True;
}
else
{
// auf dem letzten (bzw. in dem Bereich, den ein Eintrag einnehmen wuerde, wenn er unten genau buendig
// abschliessen wuerde) ?
if ((aDropPos.Y() < GetSizePixel().Height()) && (aDropPos.Y() >= GetSizePixel().Height() - GetEntryHeight()))
{
m_aDropActionType = DA_SCROLLDOWN;
bNeedTrigger = sal_True;
}
else
{ // auf einem Entry mit Childs, der nicht aufgeklappt ist ?
SvLBoxEntry* pDropppedOn = GetEntry(aDropPos);
if (pDropppedOn && (GetChildCount(pDropppedOn) > 0) && !IsExpanded(pDropppedOn))
{
// -> aufklappen
m_aDropActionType = DA_EXPANDNODE;
bNeedTrigger = sal_True;
}
}
}
if (bNeedTrigger && (m_aTimerTriggered != aDropPos))
{
// neu anfangen zu zaehlen
m_aTimerCounter = DROP_ACTION_TIMER_INITIAL_TICKS;
// die Pos merken, da ich auch QueryDrops bekomme, wenn sich die Maus gar nicht bewegt hat
m_aTimerTriggered = aDropPos;
// und den Timer los
if (!m_aDropActionTimer.IsActive()) // gibt es den Timer schon ?
{
m_aDropActionTimer.SetTimeout(DROP_ACTION_TIMER_TICK_BASE);
m_aDropActionTimer.Start();
}
}
else if (!bNeedTrigger)
m_aDropActionTimer.Stop();
}
// Hat das Object das richtige Format?
2001-04-09 10:19:35 +00:00
if (!m_aControlExchange.isDragSource())
return DND_ACTION_NONE;
2000-09-18 16:07:07 +00:00
2001-04-09 10:19:35 +00:00
if (!m_aControlExchange->hasFormat(GetDataFlavorExVector()))
return DND_ACTION_NONE;
2000-09-18 16:07:07 +00:00
// do we conain the formitem?
2001-04-09 10:19:35 +00:00
if (!FindEntry(m_aControlExchange->getFormItem()))
return DND_ACTION_NONE;
2000-09-18 16:07:07 +00:00
SvLBoxEntry* pDropTarget = GetEntry(aDropPos);
if (!pDropTarget)
2001-04-09 10:19:35 +00:00
return DND_ACTION_NONE;
2000-09-18 16:07:07 +00:00
FmFilterData* pData = (FmFilterData*)pDropTarget->GetUserData();
FmFormItem* pForm = NULL;
if (pData->ISA(FmFilterItem))
{
pForm = PTR_CAST(FmFormItem,pData->GetParent()->GetParent());
2001-04-09 10:19:35 +00:00
if (pForm != m_aControlExchange->getFormItem())
return DND_ACTION_NONE;
2000-09-18 16:07:07 +00:00
}
else if (pData->ISA(FmFilterItems))
{
pForm = PTR_CAST(FmFormItem,pData->GetParent());
2001-04-09 10:19:35 +00:00
if (pForm != m_aControlExchange->getFormItem())
return DND_ACTION_NONE;
2000-09-18 16:07:07 +00:00
}
else
2001-04-09 10:19:35 +00:00
return DND_ACTION_NONE;
2000-09-18 16:07:07 +00:00
2001-04-09 10:19:35 +00:00
return rEvt.mnAction;
2000-09-18 16:07:07 +00:00
}
// -----------------------------------------------------------------------------
namespace
{
FmFilterItems* getTargetItems(SvLBoxEntry* _pTarget)
{
FmFilterData* pData = static_cast<FmFilterData*>(_pTarget->GetUserData());
FmFilterItems* pTargetItems = pData->ISA(FmFilterItems)
?
PTR_CAST(FmFilterItems,pData)
:
PTR_CAST(FmFilterItems,pData->GetParent());
return pTargetItems;
}
}
2000-09-18 16:07:07 +00:00
//------------------------------------------------------------------------
2001-04-09 10:19:35 +00:00
sal_Int8 FmFilterNavigator::ExecuteDrop( const ExecuteDropEvent& rEvt )
2000-09-18 16:07:07 +00:00
{
// ware schlecht, wenn nach dem Droppen noch gescrollt wird ...
if (m_aDropActionTimer.IsActive())
m_aDropActionTimer.Stop();
// Format-Ueberpruefung
2001-04-09 10:19:35 +00:00
if (!m_aControlExchange.isDragSource())
return DND_ACTION_NONE;
2000-09-18 16:07:07 +00:00
// das Ziel des Drop sowie einige Daten darueber
2001-04-09 10:19:35 +00:00
Point aDropPos = rEvt.maPosPixel;
2000-09-18 16:07:07 +00:00
SvLBoxEntry* pDropTarget = GetEntry( aDropPos );
if (!pDropTarget)
2001-04-09 10:29:45 +00:00
return DND_ACTION_NONE;
2000-09-18 16:07:07 +00:00
// search the container where to add the items
FmFilterItems* pTargetItems = getTargetItems(pDropTarget);
2000-09-18 16:07:07 +00:00
SelectAll(sal_False);
SvLBoxEntry* pEntry = FindEntry(pTargetItems);
Select(pEntry, sal_True);
SetCurEntry(pEntry);
insertFilterItem(m_aControlExchange->getDraggedEntries(),pTargetItems,DND_ACTION_COPY == rEvt.mnAction);
2000-09-18 16:07:07 +00:00
return sal_True;
}
//------------------------------------------------------------------------
void FmFilterNavigator::InitEntry(SvLBoxEntry* pEntry,
const XubString& rStr,
const Image& rImg1,
const Image& rImg2)
{
SvTreeListBox::InitEntry( pEntry, rStr, rImg1, rImg2 );
SvLBoxString* pString = NULL;
if (((FmFilterData*)pEntry->GetUserData())->ISA(FmFilterItem))
pString = new FmFilterString(pEntry, 0, rStr, ((FmFilterItem*)pEntry->GetUserData())->GetFieldName());
else if (((FmFilterData*)pEntry->GetUserData())->ISA(FmFilterItems))
pString = new FmFilterItemsString(pEntry, 0, rStr );
if (pString)
pEntry->ReplaceItem( pString, 1 );
}
//------------------------------------------------------------------------
sal_Bool FmFilterNavigator::Select( SvLBoxEntry* pEntry, sal_Bool bSelect )
{
if (bSelect == IsSelected(pEntry)) // das passiert manchmal, ich glaube, die Basisklasse geht zu sehr auf Nummer sicher ;)
return sal_True;
if (SvTreeListBox::Select(pEntry, bSelect))
{
if (bSelect)
{
FmFormItem* pFormItem = NULL;
if (((FmFilterData*)pEntry->GetUserData())->ISA(FmFilterItem))
pFormItem = (FmFormItem*)((FmFilterItem*)pEntry->GetUserData())->GetParent()->GetParent();
else if (((FmFilterData*)pEntry->GetUserData())->ISA(FmFilterItems))
pFormItem = (FmFormItem*)((FmFilterItem*)pEntry->GetUserData())->GetParent()->GetParent();
else if (((FmFilterData*)pEntry->GetUserData())->ISA(FmFormItem))
pFormItem = (FmFormItem*)pEntry->GetUserData();
if (pFormItem)
{
// will the controller be exchanged?
if (((FmFilterData*)pEntry->GetUserData())->ISA(FmFilterItem))
m_pModel->SetCurrentItems((FmFilterItems*)((FmFilterItem*)pEntry->GetUserData())->GetParent());
else if (((FmFilterData*)pEntry->GetUserData())->ISA(FmFilterItems))
m_pModel->SetCurrentItems((FmFilterItems*)pEntry->GetUserData());
else if (((FmFilterData*)pEntry->GetUserData())->ISA(FmFormItem))
m_pModel->SetCurrentController(((FmFormItem*)pEntry->GetUserData())->GetController());
}
}
return sal_True;
}
else
return sal_False;
}
//------------------------------------------------------------------------
void FmFilterNavigator::Notify( SfxBroadcaster& rBC, const SfxHint& rHint )
{
if (rHint.ISA(FmFilterInsertedHint))
{
FmFilterInsertedHint* pHint = (FmFilterInsertedHint*)&rHint;
Insert(pHint->GetData(), pHint->GetPos());
}
else if( rHint.ISA(FilterClearingHint) )
2000-09-18 16:07:07 +00:00
{
SvTreeListBox::Clear();
}
else if( rHint.ISA(FmFilterRemovedHint) )
{
FmFilterRemovedHint* pHint = (FmFilterRemovedHint*)&rHint;
Remove(pHint->GetData());
}
else if( rHint.ISA(FmFilterTextChangedHint) )
{
FmFilterTextChangedHint* pHint = (FmFilterTextChangedHint*)&rHint;
SvLBoxEntry* pEntry = FindEntry(pHint->GetData());
if (pEntry)
SetEntryText( pEntry, pHint->GetData()->GetText());
}
else if( rHint.ISA(FmFilterCurrentChangedHint) )
{
// invalidate the entries
for (SvLBoxEntry* pEntry = First(); pEntry != NULL;
pEntry = Next(pEntry))
GetModel()->InvalidateEntry( pEntry );
}
}
//------------------------------------------------------------------------
SvLBoxEntry* FmFilterNavigator::FindEntry(FmFilterData* pItem)
{
SvLBoxEntry* pEntry = NULL;
if (pItem)
{
for (pEntry = First(); pEntry != NULL; pEntry = Next( pEntry ))
{
FmFilterData* pEntryItem = (FmFilterData*)pEntry->GetUserData();
if (pEntryItem == pItem)
break;
}
}
return pEntry;
}
//------------------------------------------------------------------------
void FmFilterNavigator::Insert(FmFilterData* pItem, sal_Int32 nPos)
{
FmParentData* pParent = pItem->GetParent() ? pItem->GetParent() : GetFilterModel();
// insert the item
SvLBoxEntry* pParentEntry = FindEntry(pParent);
2002-05-17 07:41:57 +00:00
SvLBoxEntry* pNewEntry = InsertEntry(pItem->GetText(), pItem->GetImage(), pItem->GetImage(), pParentEntry, sal_False, nPos, pItem );
if ( pNewEntry )
{
SetExpandedEntryBmp( pNewEntry, pItem->GetImage( BMP_COLOR_HIGHCONTRAST ), BMP_COLOR_HIGHCONTRAST );
SetCollapsedEntryBmp( pNewEntry, pItem->GetImage( BMP_COLOR_HIGHCONTRAST ), BMP_COLOR_HIGHCONTRAST );
}
2000-09-18 16:07:07 +00:00
}
//------------------------------------------------------------------------
void FmFilterNavigator::Remove(FmFilterData* pItem)
{
// der Entry zu den Daten
SvLBoxEntry* pEntry = FindEntry(pItem);
if (pEntry == m_pEditingCurrently)
// cancel editing
EndEditing(sal_True);
2000-09-18 16:07:07 +00:00
if (pEntry)
GetModel()->Remove( pEntry );
}
// -----------------------------------------------------------------------------
FmFormItem* FmFilterNavigator::getSelectedFilterItems(::std::vector<FmFilterItem*>& _rItemList)
2000-09-18 16:07:07 +00:00
{
// be sure that the data is only used within only one form!
2001-04-09 10:19:35 +00:00
FmFormItem* pFirstItem = NULL;
2000-09-18 16:07:07 +00:00
2001-04-09 10:19:35 +00:00
sal_Bool bHandled = sal_True;
sal_Bool bFoundSomething = sal_False;
for (SvLBoxEntry* pEntry = FirstSelected();
bHandled && pEntry != NULL;
pEntry = NextSelected(pEntry))
{
FmFilterItem* pFilter = PTR_CAST(FmFilterItem, (FmFilterData*)pEntry->GetUserData());
if (pFilter)
{
FmFormItem* pForm = PTR_CAST(FmFormItem,pFilter->GetParent()->GetParent());
if (!pForm)
bHandled = sal_False;
else if (!pFirstItem)
pFirstItem = pForm;
else if (pFirstItem != pForm)
bHandled = sal_False;
if (bHandled)
2000-09-18 16:07:07 +00:00
{
_rItemList.push_back(pFilter);
2001-04-09 10:19:35 +00:00
bFoundSomething = sal_True;
2000-09-18 16:07:07 +00:00
}
}
2001-04-09 10:19:35 +00:00
}
if ( !bHandled || !bFoundSomething )
pFirstItem = NULL;
return pFirstItem;
}
// -----------------------------------------------------------------------------
void FmFilterNavigator::insertFilterItem(const ::std::vector<FmFilterItem*>& _rFilterList,FmFilterItems* _pTargetItems,sal_Bool _bCopy)
{
::std::vector<FmFilterItem*>::const_iterator aEnd = _rFilterList.end();
for (::std::vector<FmFilterItem*>::const_iterator i = _rFilterList.begin(); i != aEnd; ++i)
{
if ((*i)->GetParent() == _pTargetItems)
continue;
else
{
FmFilterItem* pFilterItem = _pTargetItems->Find((*i)->GetTextComponent());
String aText = (*i)->GetText();
if ( !pFilterItem )
{
pFilterItem = new FmFilterItem(m_pModel->getORB(),_pTargetItems, (*i)->GetFieldName(), aText, (*i)->GetTextComponent());
m_pModel->Append(_pTargetItems, pFilterItem);
}
if ( !_bCopy )
m_pModel->Remove(*i);
// now set the text for the new dragged item
m_pModel->SetText(pFilterItem, aText);
}
}
m_pModel->CheckIntegrity((FmFormItem*)_pTargetItems->GetParent());
}
//------------------------------------------------------------------------------
void FmFilterNavigator::StartDrag( sal_Int8 _nAction, const Point& _rPosPixel )
{
EndSelection();
// be sure that the data is only used within a only one form!
m_aControlExchange.prepareDrag();
2001-04-09 10:19:35 +00:00
::std::vector<FmFilterItem*> aItemList;
if ( FmFormItem* pFirstItem = getSelectedFilterItems(aItemList) )
{
m_aControlExchange->setDraggedEntries(aItemList);
m_aControlExchange->setFormItem(pFirstItem);
m_aControlExchange.startDrag( DND_ACTION_COPYMOVE );
}
2001-04-09 10:19:35 +00:00
}
//------------------------------------------------------------------------------
void FmFilterNavigator::Command( const CommandEvent& rEvt )
{
sal_Bool bHandled = sal_False;
switch (rEvt.GetCommand())
{
2000-09-18 16:07:07 +00:00
case COMMAND_CONTEXTMENU:
{
// die Stelle, an der geklickt wurde
Point aWhere;
SvLBoxEntry* pClicked = NULL;
if (rEvt.IsMouseEvent())
{
aWhere = rEvt.GetMousePosPixel();
pClicked = GetEntry(aWhere);
if (pClicked == NULL)
break;
if (!IsSelected(pClicked))
{
SelectAll(sal_False);
Select(pClicked, sal_True);
SetCurEntry(pClicked);
}
}
else
{
pClicked = GetCurEntry();
if (!pClicked)
break;
aWhere = GetEntryPos(pClicked);
}
::std::vector<FmFilterData*> aSelectList;
for (SvLBoxEntry* pEntry = FirstSelected();
pEntry != NULL;
pEntry = NextSelected(pEntry))
{
// don't delete forms
FmFormItem* pForm = PTR_CAST(FmFormItem, (FmFilterData*)pEntry->GetUserData());
if (!pForm)
aSelectList.push_back((FmFilterData*)pEntry->GetUserData());
}
if (aSelectList.size() == 1)
{
// don't delete the only empty row of a form
FmFilterItems* pFilterItems = PTR_CAST(FmFilterItems, aSelectList[0]);
if (pFilterItems && pFilterItems->GetChilds().empty()
&& pFilterItems->GetParent()->GetChilds().size() == 1)
aSelectList.clear();
}
PopupMenu aContextMenu(SVX_RES(RID_FM_FILTER_MENU));
// every condition could be deleted except the first one if its the only one
aContextMenu.EnableItem( SID_FM_DELETE, !aSelectList.empty() );
//
sal_Bool bEdit = PTR_CAST(FmFilterItem, (FmFilterData*)pClicked->GetUserData()) != NULL &&
IsSelected(pClicked) && GetSelectionCount() == 1;
aContextMenu.EnableItem( SID_FM_FILTER_EDIT,
bEdit );
aContextMenu.EnableItem( SID_FM_FILTER_IS_NULL,
bEdit );
aContextMenu.EnableItem( SID_FM_FILTER_IS_NOT_NULL,
bEdit );
aContextMenu.RemoveDisabledEntries(sal_True, sal_True);
sal_uInt16 nSlotId = aContextMenu.Execute( this, aWhere );
switch( nSlotId )
{
case SID_FM_FILTER_EDIT:
{
EditEntry( pClicked );
} break;
case SID_FM_FILTER_IS_NULL:
case SID_FM_FILTER_IS_NOT_NULL:
{
UniString aErrorMsg;
UniString aText;
if (nSlotId == SID_FM_FILTER_IS_NULL)
aText.AssignAscii("IS NULL");
else
aText.AssignAscii("IS NOT NULL");
m_pModel->ValidateText((FmFilterItem*)pClicked->GetUserData(),
aText, aErrorMsg);
m_pModel->SetText((FmFilterItem*)pClicked->GetUserData(), aText);
} break;
case SID_FM_DELETE:
{
DeleteSelection();
} break;
}
bHandled = sal_True;
} break;
}
if (!bHandled)
SvTreeListBox::Command( rEvt );
}
// -----------------------------------------------------------------------------
SvLBoxEntry* FmFilterNavigator::getNextEntry(SvLBoxEntry* _pStartWith)
{
SvLBoxEntry* pEntry = _pStartWith ? _pStartWith : LastSelected();
pEntry = Next(pEntry);
// we need the next filter entry
while( pEntry && GetChildCount( pEntry ) == 0 && pEntry != Last() )
pEntry = Next(pEntry);
return pEntry;
}
// -----------------------------------------------------------------------------
SvLBoxEntry* FmFilterNavigator::getPrevEntry(SvLBoxEntry* _pStartWith)
{
SvLBoxEntry* pEntry = _pStartWith ? _pStartWith : FirstSelected();
pEntry = Prev(pEntry);
// check if the previous entry is a filter, if so get the next prev
if ( pEntry && GetChildCount( pEntry ) != 0 )
{
pEntry = Prev(pEntry);
// if the entry is still no leaf return
if ( pEntry && GetChildCount( pEntry ) != 0 )
pEntry = NULL;
}
return pEntry;
}
2000-09-18 16:07:07 +00:00
//------------------------------------------------------------------------
void FmFilterNavigator::KeyInput(const KeyEvent& rKEvt)
{
const KeyCode& rKeyCode = rKEvt.GetKeyCode();
if ( rKeyCode.IsMod1()
&& rKeyCode.IsMod2()
&& !rKeyCode.IsShift()
&& ( rKeyCode.GetCode() == KEY_UP || rKeyCode.GetCode() == KEY_DOWN )
)
{
::std::vector<FmFilterItem*> aItemList;
if ( FmFormItem* pFirstItem = getSelectedFilterItems(aItemList) )
{
::std::mem_fun1_t<SvLBoxEntry*,FmFilterNavigator,SvLBoxEntry*> aGetEntry = ::std::mem_fun(&FmFilterNavigator::getNextEntry);
if ( rKeyCode.GetCode() == KEY_UP )
aGetEntry = ::std::mem_fun(&FmFilterNavigator::getPrevEntry);
SvLBoxEntry* pTarget = aGetEntry(this,NULL);
if ( pTarget )
{
FmFilterItems* pTargetItems = getTargetItems(pTarget);
if ( pTargetItems )
{
::std::vector<FmFilterItem*>::const_iterator aEnd = aItemList.end();
sal_Bool bNextTargetItem = sal_True;
while ( bNextTargetItem )
{
::std::vector<FmFilterItem*>::const_iterator i = aItemList.begin();
for (; i != aEnd; ++i)
{
if ( (*i)->GetParent() == pTargetItems )
{
pTarget = aGetEntry(this,pTarget);
if ( !pTarget )
return;
pTargetItems = getTargetItems(pTarget);
break;
}
else
{
FmFilterItem* pFilterItem = pTargetItems->Find((*i)->GetTextComponent());
// we found the text component so jump above
if ( pFilterItem )
{
pTarget = aGetEntry(this,pTarget);
if ( !pTarget )
return;
pTargetItems = getTargetItems(pTarget);
break;
}
}
}
bNextTargetItem = i != aEnd && pTargetItems;
}
if ( pTargetItems )
{
insertFilterItem(aItemList,pTargetItems);
return;
}
}
}
}
}
else if (rKeyCode.GetCode() == KEY_DELETE && !rKeyCode.GetModifier())
2000-09-18 16:07:07 +00:00
{
if (!IsSelected(First()) || GetEntryCount() > 1)
DeleteSelection();
return;
}
SvTreeListBox::KeyInput(rKEvt);
}
//------------------------------------------------------------------------------
void FmFilterNavigator::DeleteSelection()
{
// to avoid the deletion of an entry twice (e.g. deletion of a parent and afterward
// the deletion of it's child, i have to shrink the selecton list
::std::vector<SvLBoxEntry*> aEntryList;
for (SvLBoxEntry* pEntry = FirstSelected();
pEntry != NULL;
pEntry = NextSelected(pEntry))
{
FmFilterItem* pFilterItem = PTR_CAST(FmFilterItem, (FmFilterData*)pEntry->GetUserData());
if (pFilterItem && IsSelected(GetParent(pEntry)))
continue;
FmFormItem* pForm = PTR_CAST(FmFormItem, (FmFilterData*)pEntry->GetUserData());
if (!pForm)
aEntryList.push_back(pEntry);
}
// Remove the selection
SelectAll(FALSE);
for (::std::vector<SvLBoxEntry*>::reverse_iterator i = aEntryList.rbegin();
// link problems with operator ==
i.base() != aEntryList.rend().base(); i++)
{
m_pModel->Remove((FmFilterData*)(*i)->GetUserData());
}
// now check if we need to insert new items
m_pModel->CheckIntegrity(m_pModel);
}
// -----------------------------------------------------------------------------
2000-09-18 16:07:07 +00:00
//========================================================================
// class FmFilterNavigatorWin
//========================================================================
FmFilterNavigatorWin::FmFilterNavigatorWin( SfxBindings *pBindings, SfxChildWindow *pMgr,
Window* pParent )
:SfxDockingWindow( pBindings, pMgr, pParent, WinBits(WB_STDMODELESS|WB_SIZEABLE|WB_ROLLABLE|WB_3DLOOK|WB_DOCKABLE) )
,SfxControllerItem( SID_FM_FILTER_NAVIGATOR_CONTROL, *pBindings )
{
SetHelpId( HID_FILTER_NAVIGATOR_WIN );
m_pNavigator = new FmFilterNavigator( this );
m_pNavigator->Show();
SetText( SVX_RES(RID_STR_FILTER_NAVIGATOR) );
2001-11-29 09:19:53 +00:00
SfxDockingWindow::SetFloatingSize( Size(200,200) );
2000-09-18 16:07:07 +00:00
}
//------------------------------------------------------------------------
FmFilterNavigatorWin::~FmFilterNavigatorWin()
{
delete m_pNavigator;
}
//-----------------------------------------------------------------------
void FmFilterNavigatorWin::Update(FmFormShell* pFormShell)
{
if (!pFormShell)
m_pNavigator->Update(Reference< ::com::sun::star::container::XIndexAccess > (), Reference< ::com::sun::star::form::XFormController > ());
else
{
Reference< ::com::sun::star::form::XFormController > xController(pFormShell->GetImpl()->getActiveInternalController());
Reference< ::com::sun::star::container::XIndexAccess > xContainer;
if (xController.is())
{
Reference< ::com::sun::star::container::XChild > xChild(xController, UNO_QUERY);
for (Reference< XInterface > xParent(xChild->getParent());
xParent.is();
xParent = xChild.is() ? xChild->getParent() : Reference< XInterface > ())
{
xContainer = Reference< ::com::sun::star::container::XIndexAccess > (xParent, UNO_QUERY);
xChild = Reference< ::com::sun::star::container::XChild > (xParent, UNO_QUERY);
}
}
m_pNavigator->Update(xContainer, xController);
}
}
//-----------------------------------------------------------------------
void FmFilterNavigatorWin::StateChanged( sal_uInt16 nSID, SfxItemState eState, const SfxPoolItem* pState )
{
if( !pState || SID_FM_FILTER_NAVIGATOR_CONTROL != nSID )
return;
if( eState >= SFX_ITEM_AVAILABLE )
{
FmFormShell* pShell = PTR_CAST( FmFormShell,((SfxObjectItem*)pState)->GetShell() );
Update( pShell );
}
else
Update( NULL );
}
//-----------------------------------------------------------------------
sal_Bool FmFilterNavigatorWin::Close()
{
if ( m_pNavigator && m_pNavigator->IsEditingActive() )
m_pNavigator->EndEditing();
if ( m_pNavigator && m_pNavigator->IsEditingActive() )
// the EndEditing was vetoed (perhaps of an syntax error or such)
return sal_False;
2000-09-18 16:07:07 +00:00
Update( NULL );
return SfxDockingWindow::Close();
}
//-----------------------------------------------------------------------
void FmFilterNavigatorWin::FillInfo( SfxChildWinInfo& rInfo ) const
{
SfxDockingWindow::FillInfo( rInfo );
rInfo.bVisible = sal_False;
}
//-----------------------------------------------------------------------
Size FmFilterNavigatorWin::CalcDockingSize( SfxChildAlignment eAlign )
{
Size aSize = SfxDockingWindow::CalcDockingSize( eAlign );
switch( eAlign )
{
case SFX_ALIGN_TOP:
case SFX_ALIGN_BOTTOM:
return Size();
case SFX_ALIGN_LEFT:
case SFX_ALIGN_RIGHT:
break;
}
return aSize;
}
//-----------------------------------------------------------------------
SfxChildAlignment FmFilterNavigatorWin::CheckAlignment( SfxChildAlignment eActAlign, SfxChildAlignment eAlign )
{
switch (eAlign)
{
case SFX_ALIGN_LEFT:
case SFX_ALIGN_RIGHT:
case SFX_ALIGN_NOALIGNMENT:
return (eAlign);
}
return (eActAlign);
}
//------------------------------------------------------------------------
void FmFilterNavigatorWin::Resize()
{
SfxDockingWindow::Resize();
Size aLogOutputSize = PixelToLogic( GetOutputSizePixel(), MAP_APPFONT );
Size aLogExplSize = aLogOutputSize;
aLogExplSize.Width() -= 6;
aLogExplSize.Height() -= 6;
Point aExplPos = LogicToPixel( Point(3,3), MAP_APPFONT );
Size aExplSize = LogicToPixel( aLogExplSize, MAP_APPFONT );
m_pNavigator->SetPosSizePixel( aExplPos, aExplSize );
}
// -----------------------------------------------------------------------------
void FmFilterNavigatorWin::GetFocus()
{
// oj #97405#
if ( m_pNavigator )
m_pNavigator->GrabFocus();
}
// -----------------------------------------------------------------------------
2000-09-18 16:07:07 +00:00
//========================================================================
// class FmFilterNavigatorWinMgr
//========================================================================
SFX_IMPL_DOCKINGWINDOW( FmFilterNavigatorWinMgr, SID_FM_FILTER_NAVIGATOR )
//-----------------------------------------------------------------------
FmFilterNavigatorWinMgr::FmFilterNavigatorWinMgr( Window *pParent, sal_uInt16 nId,
SfxBindings *pBindings, SfxChildWinInfo* pInfo )
:SfxChildWindow( pParent, nId )
{
pWindow = new FmFilterNavigatorWin( pBindings, this, pParent );
eChildAlignment = SFX_ALIGN_NOALIGNMENT;
((SfxDockingWindow*)pWindow)->Initialize( pInfo );
}
2001-04-09 10:19:35 +00:00
//........................................................................
} // namespace svxform
//........................................................................