merge the formfield patch from ooo-build
[ooovba.git] / svx / source / form / filtnav.cxx
blob9c5ddf8280e1d56613f2b4a931b2ab5644d79ec5
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: filtnav.cxx,v $
10 * $Revision: 1.48.216.1 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_svx.hxx"
33 #ifndef _SVX_FMRESIDS_HRC
34 #include "fmresids.hrc"
35 #endif
36 #include "fmctrler.hxx"
37 #include "filtnav.hxx"
38 #include <com/sun/star/util/XNumberFormatter.hpp>
39 #include <com/sun/star/form/XFormController.hpp>
40 #include <fmexch.hxx>
41 #include "fmitems.hxx"
43 #ifndef _SVX_SVXIDS_HRC
44 #include <svx/svxids.hrc>
45 #endif
47 #ifndef _SVX_FMPROP_HRC
48 #include "fmprop.hrc"
49 #endif
51 #ifndef _SVX_FMHELP_HRC
52 #include "fmhelp.hrc"
53 #endif
54 #include <svx/dialmgr.hxx>
55 #include <sfx2/dispatch.hxx>
56 #include <sfx2/objsh.hxx>
57 #include <sfx2/objitem.hxx>
58 #include <sfx2/request.hxx>
59 #include <tools/shl.hxx>
61 #ifndef _WRKWIN_HXX //autogen
62 #include <vcl/wrkwin.hxx>
63 #endif
64 #include <svx/fmshell.hxx>
65 #include <fmshimp.hxx>
66 #include <fmservs.hxx>
67 #include <fmtools.hxx>
68 #include <cppuhelper/implbase1.hxx>
69 #include <comphelper/property.hxx>
70 #include <comphelper/uno3.hxx>
71 #include <connectivity/dbtools.hxx>
72 #include <comphelper/processfactory.hxx>
73 #include <com/sun/star/lang/XUnoTunnel.hpp>
74 #include <comphelper/sequence.hxx>
75 #include "gridcell.hxx"
76 #include <rtl/logfile.hxx>
78 #include <functional>
80 #define SYNC_DELAY 200
81 #define DROP_ACTION_TIMER_INITIAL_TICKS 10
82 // solange dauert es, bis das Scrollen anspringt
83 #define DROP_ACTION_TIMER_SCROLL_TICKS 3
84 // in diesen Intervallen wird jeweils eine Zeile gescrollt
85 #define DROP_ACTION_TIMER_TICK_BASE 10
86 // das ist die Basis, mit der beide Angaben multipliziert werden (in ms)
88 using namespace ::com::sun::star::uno;
89 using namespace ::com::sun::star::lang;
90 using namespace ::com::sun::star::sdbc;
91 using namespace ::com::sun::star::sdb;
92 using namespace ::com::sun::star::beans;
93 using namespace ::svxform;
94 using namespace ::connectivity::simple;
95 using namespace ::connectivity;
98 //........................................................................
99 namespace svxform
101 //........................................................................
103 //========================================================================
104 OFilterItemExchange::OFilterItemExchange()
108 //------------------------------------------------------------------------
109 void OFilterItemExchange::AddSupportedFormats()
111 AddFormat(getFormatId());
114 //------------------------------------------------------------------------
115 sal_uInt32 OFilterItemExchange::getFormatId()
117 static sal_uInt32 s_nFormat = (sal_uInt32)-1;
118 if ((sal_uInt32)-1 == s_nFormat)
120 s_nFormat = SotExchange::RegisterFormatName(String::CreateFromAscii("application/x-openoffice;windows_formatname=\"form.FilterControlExchange\""));
121 DBG_ASSERT((sal_uInt32)-1 != s_nFormat, "OFilterExchangeHelper::getFormatId: bad exchange id!");
123 return s_nFormat;
126 //------------------------------------------------------------------------
127 OLocalExchange* OFilterExchangeHelper::createExchange() const
129 return new OFilterItemExchange;
132 //========================================================================
133 TYPEINIT0(FmFilterData);
134 Image FmFilterData::GetImage( BmpColorMode /*_eMode*/ ) const
136 return Image();
139 //========================================================================
140 TYPEINIT1(FmParentData, FmFilterData);
141 //------------------------------------------------------------------------
142 FmParentData::~FmParentData()
144 for (::std::vector<FmFilterData*>::const_iterator i = m_aChilds.begin();
145 i != m_aChilds.end(); i++)
146 delete (*i);
149 //========================================================================
150 TYPEINIT1(FmFormItem, FmParentData);
151 //------------------------------------------------------------------------
152 Image FmFormItem::GetImage( BmpColorMode _eMode ) const
154 static Image aImage;
155 static Image aImage_HC;
157 if (!aImage)
159 ImageList aNavigatorImages( SVX_RES( RID_SVXIMGLIST_FMEXPL ) );
160 ImageList aNavigatorImages_HC( SVX_RES( RID_SVXIMGLIST_FMEXPL_HC ) );
162 aImage = aNavigatorImages.GetImage( RID_SVXIMG_FORM );
163 aImage_HC = aNavigatorImages_HC.GetImage( RID_SVXIMG_FORM );
165 return ( BMP_COLOR_HIGHCONTRAST == _eMode ) ? aImage_HC : aImage;
168 //========================================================================
169 TYPEINIT1(FmFilterItems, FmParentData);
170 //------------------------------------------------------------------------
171 FmFilterItem* FmFilterItems::Find(const Reference< ::com::sun::star::awt::XTextComponent > & _xText) const
173 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmFilterItems::Find" );
174 for (::std::vector<FmFilterData*>::const_iterator i = m_aChilds.begin();
175 i != m_aChilds.end(); ++i)
177 FmFilterItem* pCond = PTR_CAST(FmFilterItem, *i);
178 DBG_ASSERT(pCond, "Wrong element in container");
179 if (_xText == pCond->GetTextComponent())
180 return pCond;
182 return NULL;
185 //------------------------------------------------------------------------
186 Image FmFilterItems::GetImage( BmpColorMode _eMode ) const
188 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmFilterItems::GetImage" );
189 static Image aImage;
190 static Image aImage_HC;
192 if (!aImage)
194 ImageList aNavigatorImages( SVX_RES( RID_SVXIMGLIST_FMEXPL ) );
195 ImageList aNavigatorImages_HC( SVX_RES( RID_SVXIMGLIST_FMEXPL_HC ) );
197 aImage = aNavigatorImages.GetImage( RID_SVXIMG_FILTER );
198 aImage_HC = aNavigatorImages_HC.GetImage( RID_SVXIMG_FILTER );
200 return ( BMP_COLOR_HIGHCONTRAST == _eMode ) ? aImage_HC : aImage;
203 //========================================================================
204 TYPEINIT1(FmFilterItem, FmFilterData);
205 //------------------------------------------------------------------------
206 FmFilterItem::FmFilterItem(const Reference< ::com::sun::star::lang::XMultiServiceFactory >& _rxFactory,
207 FmFilterItems* pParent,
208 const ::rtl::OUString& aFieldName,
209 const ::rtl::OUString& aText,
210 const Reference< ::com::sun::star::awt::XTextComponent > & _xText)
211 :FmFilterData(_rxFactory,pParent, aText)
212 ,m_aFieldName(aFieldName)
213 ,m_xText(_xText)
215 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmFilterItems::FmFilterItem" );
218 //------------------------------------------------------------------------
219 Image FmFilterItem::GetImage( BmpColorMode _eMode ) const
221 static Image aImage;
222 static Image aImage_HC;
224 if (!aImage)
226 ImageList aNavigatorImages( SVX_RES( RID_SVXIMGLIST_FMEXPL ) );
227 ImageList aNavigatorImages_HC( SVX_RES( RID_SVXIMGLIST_FMEXPL_HC ) );
229 aImage = aNavigatorImages.GetImage( RID_SVXIMG_FIELD );
230 aImage_HC = aNavigatorImages_HC.GetImage( RID_SVXIMG_FIELD );
232 return ( BMP_COLOR_HIGHCONTRAST == _eMode ) ? aImage_HC : aImage;
235 //========================================================================
236 // Hints for communicatition between model and view
237 //========================================================================
238 class FmFilterHint : public SfxHint
240 FmFilterData* m_pData;
242 public:
243 TYPEINFO();
244 FmFilterHint(FmFilterData* pData):m_pData(pData){}
245 FmFilterData* GetData() const { return m_pData; }
247 TYPEINIT1( FmFilterHint, SfxHint );
249 //========================================================================
250 class FmFilterInsertedHint : public FmFilterHint
252 sal_Int32 m_nPos; // Position relative to the parent of the data
254 public:
255 TYPEINFO();
256 FmFilterInsertedHint(FmFilterData* pData, sal_Int32 nRelPos)
257 :FmFilterHint(pData)
258 ,m_nPos(nRelPos){}
260 sal_Int32 GetPos() const { return m_nPos; }
262 TYPEINIT1( FmFilterInsertedHint, FmFilterHint );
264 //========================================================================
265 class FmFilterReplacedHint : public FmFilterHint
267 public:
268 TYPEINFO();
269 FmFilterReplacedHint(FmFilterData* pData)
270 :FmFilterHint(pData){}
273 TYPEINIT1( FmFilterReplacedHint, FmFilterHint );
275 //========================================================================
276 class FmFilterRemovedHint : public FmFilterHint
278 public:
279 TYPEINFO();
280 FmFilterRemovedHint(FmFilterData* pData)
281 :FmFilterHint(pData){}
284 TYPEINIT1( FmFilterRemovedHint, FmFilterHint );
286 //========================================================================
287 class FmFilterTextChangedHint : public FmFilterHint
289 public:
290 TYPEINFO();
291 FmFilterTextChangedHint(FmFilterData* pData)
292 :FmFilterHint(pData){}
295 TYPEINIT1( FmFilterTextChangedHint, FmFilterHint );
297 //========================================================================
298 class FilterClearingHint : public SfxHint
300 public:
301 TYPEINFO();
302 FilterClearingHint(){}
304 TYPEINIT1( FilterClearingHint, SfxHint );
306 //========================================================================
307 class FmFilterCurrentChangedHint : public SfxHint
309 public:
310 TYPEINFO();
311 FmFilterCurrentChangedHint(){}
313 TYPEINIT1( FmFilterCurrentChangedHint, SfxHint );
315 //========================================================================
316 // class FmFilterAdapter, Listener an den FilterControls
317 //========================================================================
318 class FmFilterAdapter : public ::cppu::WeakImplHelper1< ::com::sun::star::awt::XTextListener >
320 FmFilterControls m_aFilterControls;
321 FmFilterModel* m_pModel;
323 public:
324 FmFilterAdapter(FmFilterModel* pModel, const Reference< ::com::sun::star::container::XIndexAccess >& xControllers);
326 // ::com::sun::star::lang::XEventListener
327 virtual void SAL_CALL disposing(const ::com::sun::star::lang::EventObject& Source) throw( RuntimeException );
329 // ::com::sun::star::awt::XTextListener
330 virtual void SAL_CALL textChanged(const ::com::sun::star::awt::TextEvent& e) throw( ::com::sun::star::uno::RuntimeException );
332 // helpers
333 void dispose() throw( RuntimeException );
335 void InsertElements(const Reference< ::com::sun::star::container::XIndexAccess >& xControllers);
336 void RemoveElement(const Reference< ::com::sun::star::awt::XTextComponent > & xText);
338 Reference< ::com::sun::star::beans::XPropertySet > getField(const Reference< ::com::sun::star::awt::XTextComponent > & xText) const;
339 void setText(sal_Int32 nPos,
340 const FmFilterItem* pFilterItem,
341 const ::rtl::OUString& rText);
342 void DeleteItemsByText(::std::vector<FmFilterData*>& rItems, const Reference< ::com::sun::star::awt::XTextComponent > & xText);
343 Reference< ::com::sun::star::form::XForm > findForm(const Reference< ::com::sun::star::container::XChild >& xChild);
346 //------------------------------------------------------------------------
347 FmFilterAdapter::FmFilterAdapter(FmFilterModel* pModel, const Reference< ::com::sun::star::container::XIndexAccess >& xControllers)
348 :m_pModel(pModel)
350 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmFilterAdapter::FmFilterAdapter" );
351 InsertElements(xControllers);
353 // listen on all controls as text listener
354 for (FmFilterControls::const_iterator iter = m_aFilterControls.begin();
355 iter != m_aFilterControls.end(); iter++)
356 (*iter).first->addTextListener(this);
359 //------------------------------------------------------------------------
360 void FmFilterAdapter::dispose() throw( RuntimeException )
362 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmFilterAdapter::dispose" );
363 // clear the filter control map
364 for (FmFilterControls::const_iterator iter = m_aFilterControls.begin();
365 iter != m_aFilterControls.end(); iter++)
366 (*iter).first->removeTextListener(this);
368 m_aFilterControls.clear();
371 //------------------------------------------------------------------------------
372 // delete all items relate to the control
373 void FmFilterAdapter::DeleteItemsByText(::std::vector<FmFilterData*>& _rItems,
374 const Reference< ::com::sun::star::awt::XTextComponent > & xText)
376 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmFilterAdapter::DeleteItemsByText" );
377 for (::std::vector<FmFilterData*>::reverse_iterator i = _rItems.rbegin();
378 // link problems with operator ==
379 i.base() != _rItems.rend().base(); i++)
381 FmFilterItems* pFilterItems = PTR_CAST(FmFilterItems, *i);
382 if (pFilterItems)
384 FmFilterItem* pFilterItem = pFilterItems->Find(xText);
385 if (pFilterItem)
387 // remove the condition
388 ::std::vector<FmFilterData*>& rItems = pFilterItems->GetChilds();
389 ::std::vector<FmFilterData*>::iterator j = ::std::find(rItems.begin(), rItems.end(), pFilterItem);
390 if (j != rItems.end())
391 m_pModel->Remove(j, pFilterItem);
393 continue;
395 FmFormItem* pFormItem = PTR_CAST(FmFormItem, *i);
396 if (pFormItem)
397 DeleteItemsByText(pFormItem->GetChilds(), xText);
401 //------------------------------------------------------------------------
402 void FmFilterAdapter::InsertElements(const Reference< ::com::sun::star::container::XIndexAccess >& xControllers)
404 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmFilterAdapter::InsertElements" );
405 for (sal_Int32 i = 0, nLen = xControllers->getCount(); i < nLen; ++i)
407 Reference< ::com::sun::star::container::XIndexAccess > xElement;
408 xControllers->getByIndex(i) >>= xElement;
410 // Insert the Elements of the controller
411 InsertElements(xElement);
413 // store the filter controls
414 FmXFormController* pController = FmXFormController::getImplementation( xElement.get() );
415 DBG_ASSERT( pController, "FmFilterAdapter::InsertElements: no controller!" );
417 const FmFilterControls& rControls = pController->getFilterControls();
418 for (FmFilterControls::const_iterator iter = rControls.begin(); iter != rControls.end(); ++iter )
419 m_aFilterControls.insert(*iter);
423 //------------------------------------------------------------------------------
424 void FmFilterAdapter::RemoveElement(const Reference< ::com::sun::star::awt::XTextComponent > & xText)
426 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmFilterAdapter::RemoveElement" );
427 if (xText.is())
429 // alle Level durchlaufen und eintraege entfernen
430 if (m_pModel)
431 DeleteItemsByText(m_pModel->GetChilds(), xText);
433 FmFilterControls::iterator iter = m_aFilterControls.find(xText);
434 if (iter != m_aFilterControls.end())
435 m_aFilterControls.erase(iter);
439 //------------------------------------------------------------------------
440 Reference< ::com::sun::star::beans::XPropertySet > FmFilterAdapter::getField(const Reference< ::com::sun::star::awt::XTextComponent > & xText) const
442 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmFilterAdapter::getField" );
443 Reference< ::com::sun::star::beans::XPropertySet > xField;
444 FmFilterControls::const_iterator i = m_aFilterControls.find(xText);
445 if (i != m_aFilterControls.end())
446 xField = (*i).second;
448 return xField;
451 //------------------------------------------------------------------------
452 void FmFilterAdapter::setText(sal_Int32 nRowPos,
453 const FmFilterItem* pFilterItem,
454 const ::rtl::OUString& rText)
456 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmFilterAdapter::setText" );
457 // set the text for the text component
458 Reference< ::com::sun::star::awt::XTextComponent > xText(pFilterItem->GetTextComponent());
459 xText->setText(rText);
461 // get the controller of the text component and its filter rows
462 FmFormItem* pFormItem = PTR_CAST(FmFormItem,pFilterItem->GetParent()->GetParent());
463 FmXFormController* pController = FmXFormController::getImplementation( pFormItem->GetController().get() );
464 DBG_ASSERT( pController, "FmFilterAdapter::setText: no controller!" );
465 FmFilterRows& rRows = pController->getFilterRows();
467 DBG_ASSERT(nRowPos < (sal_Int32)rRows.size(), "wrong row pos");
468 // Suchen der aktuellen Row
469 FmFilterRow& rRow = rRows[nRowPos];
471 // do we have a new filter
472 if (rText.getLength())
473 rRow[xText] = rText;
474 else
476 // do we have the control in the row
477 FmFilterRow::iterator iter = rRow.find(xText);
478 // erase the entry out of the row
479 if (iter != rRow.end())
480 rRow.erase(iter);
485 // ::com::sun::star::lang::XEventListener
486 //------------------------------------------------------------------------
487 void SAL_CALL FmFilterAdapter::disposing(const ::com::sun::star::lang::EventObject& e) throw( RuntimeException )
489 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmFilterAdapter::disposing" );
490 Reference< ::com::sun::star::awt::XTextComponent > xText(e.Source,UNO_QUERY);
491 if (xText.is())
492 RemoveElement(xText);
495 // XTextListener
496 //------------------------------------------------------------------------
497 Reference< ::com::sun::star::form::XForm > FmFilterAdapter::findForm(const Reference< ::com::sun::star::container::XChild >& xChild)
499 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmFilterAdapter::findForm" );
500 Reference< ::com::sun::star::form::XForm > xForm;
501 if (xChild.is())
503 xForm = Reference< ::com::sun::star::form::XForm >(xChild->getParent(), UNO_QUERY);
504 if (!xForm.is())
505 xForm = findForm(Reference< ::com::sun::star::container::XChild >(xChild->getParent(), UNO_QUERY));
507 return xForm;
510 // XTextListener
511 //------------------------------------------------------------------------
512 void FmFilterAdapter::textChanged(const ::com::sun::star::awt::TextEvent& e) throw( ::com::sun::star::uno::RuntimeException )
514 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmFilterAdapter::textChanged" );
515 // Find the according formitem in the
516 Reference< ::com::sun::star::awt::XControl > xControl(e.Source, UNO_QUERY);
517 if (!m_pModel || !xControl.is())
518 return;
520 Reference< ::com::sun::star::form::XForm > xForm(findForm(Reference< ::com::sun::star::container::XChild >(xControl->getModel(), UNO_QUERY)));
521 if (!xForm.is())
522 return;
524 FmFormItem* pFormItem = m_pModel->Find(m_pModel->m_aChilds, xForm);
525 if (pFormItem)
527 Reference< ::com::sun::star::awt::XTextComponent > xText(e.Source, UNO_QUERY);
528 FmFilterItems* pFilter = PTR_CAST(FmFilterItems, pFormItem->GetChilds()[pFormItem->GetCurrentPosition()]);
529 FmFilterItem* pFilterItem = pFilter->Find(xText);
530 if (pFilterItem)
532 if (xText->getText().getLength())
534 pFilterItem->SetText(xText->getText());
535 // UI benachrichtigen
536 FmFilterTextChangedHint aChangeHint(pFilterItem);
537 m_pModel->Broadcast( aChangeHint );
539 else
541 // no text anymore so remove the condition
542 m_pModel->Remove(pFilterItem);
545 else
547 // searching the component by field name
548 ::rtl::OUString aFieldName = getLabelName(Reference< ::com::sun::star::beans::XPropertySet > (Reference< ::com::sun::star::awt::XControl > (xText, UNO_QUERY)->getModel(),UNO_QUERY));
550 pFilterItem = new FmFilterItem(m_pModel->getORB(),pFilter, aFieldName, xText->getText(), xText);
551 m_pModel->Insert(pFilter->GetChilds().end(), pFilterItem);
553 m_pModel->CheckIntegrity(pFormItem);
557 //========================================================================
558 // class FmFilterModel
559 //========================================================================
560 TYPEINIT1(FmFilterModel, FmParentData);
561 //------------------------------------------------------------------------
562 FmFilterModel::FmFilterModel(const Reference< ::com::sun::star::lang::XMultiServiceFactory >& _rxFactory)
563 :FmParentData(_rxFactory,NULL, ::rtl::OUString())
564 ,OSQLParserClient(_rxFactory)
565 ,m_xORB(_rxFactory)
566 ,m_pAdapter(NULL)
567 ,m_pCurrentItems(NULL)
569 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmFilterModel::FmFilterModel" );
572 //------------------------------------------------------------------------
573 FmFilterModel::~FmFilterModel()
575 Clear();
578 //------------------------------------------------------------------------
579 void FmFilterModel::Clear()
581 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmFilterModel::Clear" );
582 // notify
583 FilterClearingHint aClearedHint;
584 Broadcast( aClearedHint );
586 // loose endings
587 if (m_pAdapter)
589 m_pAdapter->dispose();
590 m_pAdapter->release();
591 m_pAdapter= NULL;
594 m_pCurrentItems = NULL;
595 m_xController = NULL;
596 m_xControllers = NULL;
598 for (::std::vector<FmFilterData*>::const_iterator i = m_aChilds.begin();
599 i != m_aChilds.end(); i++)
600 delete (*i);
602 m_aChilds.clear();
605 //------------------------------------------------------------------------
606 void FmFilterModel::Update(const Reference< ::com::sun::star::container::XIndexAccess > & xControllers, const Reference< ::com::sun::star::form::XFormController > & xCurrent)
608 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmFilterModel::Update" );
609 if ((::com::sun::star::form::XFormController*) xCurrent.get() == (::com::sun::star::form::XFormController*) m_xController.get())
610 return;
612 if (!xControllers.is())
614 Clear();
615 return;
618 // there is only a new current controller
619 if ((::com::sun::star::container::XIndexAccess*)m_xControllers.get() != (::com::sun::star::container::XIndexAccess*)xControllers.get())
621 Clear();
623 m_xControllers = xControllers;
624 Update(m_xControllers, this);
626 DBG_ASSERT(xCurrent.is(), "FmFilterModel::Update(...) no current controller");
628 // Listening for TextChanges
629 m_pAdapter = new FmFilterAdapter(this, xControllers);
630 m_pAdapter->acquire();
632 SetCurrentController(xCurrent);
633 CheckIntegrity(this);
635 else
636 SetCurrentController(xCurrent);
639 //------------------------------------------------------------------------
640 void FmFilterModel::Update(const Reference< ::com::sun::star::container::XIndexAccess > & xControllers, FmParentData* pParent)
642 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmFilterModel::Update" );
643 sal_Int32 nCount = xControllers->getCount();
644 for (sal_Int32 i = 0; i < nCount; i++)
646 Reference< ::com::sun::star::form::XFormController > xController;
647 xControllers->getByIndex(i) >>= xController;
648 Reference< ::com::sun::star::beans::XPropertySet > xModelAsSet(xController->getModel(), UNO_QUERY);
649 ::rtl::OUString aName = ::comphelper::getString(xModelAsSet->getPropertyValue(FM_PROP_NAME));
651 // Insert a new ::com::sun::star::form
652 FmFormItem* pFormItem = new FmFormItem(m_xORB,pParent, xController, aName);
653 Insert(pParent->GetChilds().end(), pFormItem);
655 // And now insert the filters for the form
656 FmXFormController* pController = FmXFormController::getImplementation( pFormItem->GetController().get() );
657 DBG_ASSERT( pController, "FmFilterAdapter::Update: no controller!" );
659 INT32 nPos = pController->getCurrentFilterPosition();
660 pFormItem->SetCurrentPosition(nPos);
662 String aTitle(SVX_RES(RID_STR_FILTER_FILTER_FOR));
663 const FmFilterRows& rRows = pController->getFilterRows();
664 for (FmFilterRows::const_iterator iter = rRows.begin(); iter != rRows.end(); ++iter)
666 const FmFilterRow& rRow = *iter;
667 // now add the filter rows
668 // One Row always exists
670 FmFilterItems* pFilterItems = new FmFilterItems(m_xORB,pFormItem, aTitle);
671 Insert(pFormItem->GetChilds().end(), pFilterItems);
672 for (FmFilterRow::const_iterator iter1 = rRow.begin(); iter1 != rRow.end(); ++iter1)
674 // insert new and conditons
675 ::rtl::OUString aFieldName = getLabelName(Reference< ::com::sun::star::beans::XPropertySet > (Reference< ::com::sun::star::awt::XControl > ((*iter1).first, UNO_QUERY)->getModel(),UNO_QUERY));
676 FmFilterItem* pANDCondition = new FmFilterItem(m_xORB,pFilterItems, aFieldName, (*iter1).second, (*iter1).first);
677 Insert(pFilterItems->GetChilds().end(), pANDCondition);
679 // title for the next conditions
680 aTitle = SVX_RES(RID_STR_FILTER_FILTER_OR);
683 // now add dependent controllers
684 Reference< ::com::sun::star::container::XIndexAccess > xControllerAsIndex(xController, UNO_QUERY);
685 Update(xControllerAsIndex, pFormItem);
689 //------------------------------------------------------------------------
690 FmFormItem* FmFilterModel::Find(const ::std::vector<FmFilterData*>& rItems, const Reference< ::com::sun::star::form::XFormController > & xController) const
692 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmFilterModel::Find" );
693 for (::std::vector<FmFilterData*>::const_iterator i = rItems.begin();
694 i != rItems.end(); i++)
696 FmFormItem* pForm = PTR_CAST(FmFormItem,*i);
697 if (pForm)
699 if ((::com::sun::star::form::XFormController*)xController.get() == (::com::sun::star::form::XFormController*)pForm->GetController().get())
700 return pForm;
701 else
703 pForm = Find(pForm->GetChilds(), xController);
704 if (pForm)
705 return pForm;
709 return NULL;
712 //------------------------------------------------------------------------
713 FmFormItem* FmFilterModel::Find(const ::std::vector<FmFilterData*>& rItems, const Reference< ::com::sun::star::form::XForm >& xForm) const
715 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmFilterModel::Find" );
716 for (::std::vector<FmFilterData*>::const_iterator i = rItems.begin();
717 i != rItems.end(); i++)
719 FmFormItem* pForm = PTR_CAST(FmFormItem,*i);
720 if (pForm)
722 if (xForm == pForm->GetController()->getModel())
723 return pForm;
724 else
726 pForm = Find(pForm->GetChilds(), xForm);
727 if (pForm)
728 return pForm;
732 return NULL;
735 //------------------------------------------------------------------------
736 void FmFilterModel::SetCurrentController(const Reference< ::com::sun::star::form::XFormController > & xCurrent)
738 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmFilterModel::SetCurrentController" );
739 if ((::com::sun::star::form::XFormController*) xCurrent.get() == (::com::sun::star::form::XFormController*) m_xController.get())
740 return;
742 m_xController = xCurrent;
744 FmFormItem* pItem = Find(m_aChilds, xCurrent);
745 if (pItem)
747 if ( (USHORT)pItem->GetChilds().size() > pItem->GetCurrentPosition() )
748 SetCurrentItems( static_cast< FmFilterItems* >( pItem->GetChilds()[ pItem->GetCurrentPosition() ] ) );
752 //------------------------------------------------------------------------
753 void FmFilterModel::AppendFilterItems(FmFormItem* pFormItem)
755 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmFilterModel::AppendFilterItems" );
756 DBG_ASSERT(pFormItem, "AppendFilterItems(): no form item present");
758 FmFilterItems* pFilterItems = new FmFilterItems(m_xORB,pFormItem, ::rtl::OUString(String(SVX_RES(RID_STR_FILTER_FILTER_OR))));
759 // insert the condition behind the last filter items
760 ::std::vector<FmFilterData*>::reverse_iterator iter;
761 for (iter = pFormItem->GetChilds().rbegin();
762 // link problems with operator ==
763 iter.base() != pFormItem->GetChilds().rend().base(); iter++)
765 if ((*iter)->ISA(FmFilterItems))
766 break;
768 sal_Int32 nInsertPos = iter.base() - pFormItem->GetChilds().rend().base();
769 ::std::vector<FmFilterData*>::iterator i = pFormItem->GetChilds().begin() + nInsertPos;
771 Insert(i, pFilterItems);
773 // do we need a new row
774 FmXFormController* pController = FmXFormController::getImplementation( pFormItem->GetController().get() );
775 DBG_ASSERT( pController, "FmFilterAdapter::AppendFilterItems: no controller!" );
776 FmFilterRows& rRows = pController->getFilterRows();
778 // determine the filter position
779 if (nInsertPos >= (sal_Int32)rRows.size())
780 rRows.push_back(FmFilterRow());
783 //------------------------------------------------------------------------
784 void FmFilterModel::Insert(const ::std::vector<FmFilterData*>::iterator& rPos, FmFilterData* pData)
786 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmFilterModel::Insert" );
787 ::std::vector<FmFilterData*>& rItems = pData->GetParent()->GetChilds();
788 sal_Int32 nPos = rPos == rItems.end() ? LIST_APPEND : rPos - rItems.begin();
789 rItems.insert(rPos, pData);
791 // UI benachrichtigen
792 FmFilterInsertedHint aInsertedHint(pData, nPos);
793 Broadcast( aInsertedHint );
796 //------------------------------------------------------------------------
797 void FmFilterModel::Remove(FmFilterData* pData)
799 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmFilterModel::Remove" );
800 FmParentData* pParent = pData->GetParent();
801 ::std::vector<FmFilterData*>& rItems = pParent->GetChilds();
803 // erase the item from the model
804 ::std::vector<FmFilterData*>::iterator i = ::std::find(rItems.begin(), rItems.end(), pData);
805 DBG_ASSERT(i != rItems.end(), "FmFilterModel::Remove(): unknown Item");
806 // position within the parent
807 sal_Int32 nPos = i - rItems.begin();
808 if (pData->ISA(FmFilterItems))
810 FmFormItem* pFormItem = (FmFormItem*)pParent;
811 FmXFormController* pController = FmXFormController::getImplementation( pFormItem->GetController().get() );
812 DBG_ASSERT( pController, "FmFilterAdapter::Remove: no controller!" );
813 FmFilterRows& rRows = pController->getFilterRows();
815 // how many entries do we have
816 // it's the last row than we just empty it
817 if (nPos == (sal_Int32)(rRows.size() - 1))
819 // remove all childs and stay current
820 ::std::vector<FmFilterData*>& rChilds = ((FmFilterItems*)pData)->GetChilds();
821 while (!rChilds.empty())
823 ::std::vector<FmFilterData*>::iterator j = rChilds.end();
824 j--;
826 // we stay on the level so delete each item explizit to clean the controls
827 sal_Int32 nParentPos = j - rChilds.begin();
828 // EmptyText removes the filter
829 FmFilterItem* pFilterItem = PTR_CAST(FmFilterItem, *j);
830 m_pAdapter->setText(nParentPos, pFilterItem, ::rtl::OUString());
831 Remove(j, pFilterItem);
834 else // delete the row
836 // if the row is on the current position we have to away from that position.
837 // than we can delete it
838 if (nPos == pFormItem->GetCurrentPosition())
840 ::std::vector<FmFilterData*>::iterator j = i;
842 // give a new current postion
843 if (nPos < (sal_Int32)(rRows.size() - 1))
844 // set it to the next row
845 ++j;
846 else
847 // set it to the previous row
848 --j;
850 // if necessary we have the formItem for the current controller
851 // than we have to adjust the data displayed in the form
852 pFormItem->SetCurrentPosition(j - rItems.begin());
853 pController->setCurrentFilterPosition(j - rItems.begin());
855 // Keep the view consistent and force and new painting
856 FmFilterTextChangedHint aChangeHint(*j);
857 Broadcast( aChangeHint );
860 // now delete the entry
861 // before deleting we have to shift the current position of the form if necessary
862 if (nPos < pFormItem->GetCurrentPosition())
864 pFormItem->SetCurrentPosition(pFormItem->GetCurrentPosition() - 1);
865 pController->decrementCurrentFilterPosition();
867 // is it the first row, than the nex row has to recieve a different name
868 if (nPos == 0)
870 // ensure that the text labels are consistent
871 rItems[1]->SetText(String(SVX_RES(RID_STR_FILTER_FILTER_FOR)));
872 FmFilterTextChangedHint aChangeHint(rItems[1]);
873 Broadcast( aChangeHint );
877 // delete it
878 rRows.erase(rRows.begin() + nPos);
880 // and keep the controller consistent
881 DBG_ASSERT(rRows.size() != 0, "wrong row size");
883 // and remove it from the model
884 Remove(i, pData);
887 else // FormItems can not be deleted
889 FmFilterItem* pFilterItem = PTR_CAST(FmFilterItem, pData);
891 // if its the last condition remove the parent
892 if (rItems.size() == 1)
893 Remove(pFilterItem->GetParent());
894 else
896 // find the position of the father within his father
897 ::std::vector<FmFilterData*>& rParentParentItems = pData->GetParent()->GetParent()->GetChilds();
898 ::std::vector<FmFilterData*>::iterator j = ::std::find(rParentParentItems.begin(), rParentParentItems.end(), pFilterItem->GetParent());
899 DBG_ASSERT(j != rParentParentItems.end(), "FmFilterModel::Remove(): unknown Item");
900 sal_Int32 nParentPos = j - rParentParentItems.begin();
902 // EmptyText removes the filter
903 m_pAdapter->setText(nParentPos, pFilterItem, ::rtl::OUString());
904 Remove(i, pData);
909 //------------------------------------------------------------------------
910 void FmFilterModel::Remove(const ::std::vector<FmFilterData*>::iterator& rPos, FmFilterData* pData)
912 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmFilterModel::Remove" );
913 ::std::vector<FmFilterData*>& rItems = pData->GetParent()->GetChilds();
914 rItems.erase(rPos);
916 // UI benachrichtigen
917 FmFilterRemovedHint aRemoveHint( pData );
918 Broadcast( aRemoveHint );
920 delete pData;
923 //------------------------------------------------------------------------
924 sal_Bool FmFilterModel::ValidateText(FmFilterItem* pItem, UniString& rText, UniString& rErrorMsg) const
926 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmFilterModel::ValidateText" );
927 // check the input
928 Reference< XPropertySet > xField(m_pAdapter->getField(pItem->GetTextComponent()));
930 OStaticDataAccessTools aStaticTools;
931 Reference< XConnection > xConnection(aStaticTools.getRowSetConnection(Reference< XRowSet > (m_xController->getModel(), UNO_QUERY)));
932 Reference< ::com::sun::star::util::XNumberFormatsSupplier > xFormatSupplier = aStaticTools.getNumberFormats(xConnection, sal_True);
934 Reference< ::com::sun::star::util::XNumberFormatter > xFormatter(m_xORB->createInstance(FM_NUMBER_FORMATTER), UNO_QUERY);
935 xFormatter->attachNumberFormatsSupplier(xFormatSupplier);
937 ::rtl::OUString aErr, aTxt(rText);
938 ::rtl::Reference< ISQLParseNode > xParseNode = predicateTree(aErr, aTxt, xFormatter, xField);
939 rErrorMsg = aErr;
940 rText = aTxt;
941 if (xParseNode.is())
943 ::rtl::OUString aPreparedText;
944 ::com::sun::star::lang::Locale aAppLocale = Application::GetSettings().GetUILocale();
945 xParseNode->parseNodeToPredicateStr(
946 aPreparedText, xConnection, xFormatter, xField, aAppLocale, '.', getParseContext() );
947 rText = aPreparedText;
948 return sal_True;
950 else
951 return sal_False;
954 //------------------------------------------------------------------------
955 void FmFilterModel::Append(FmFilterItems* pItems, FmFilterItem* pFilterItem)
957 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmFilterModel::Append" );
958 Insert(pItems->GetChilds().end(), pFilterItem);
961 //------------------------------------------------------------------------
962 void FmFilterModel::SetTextForItem(FmFilterItem* pItem, const ::rtl::OUString& rText)
964 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmFilterModel::SetTextForItem" );
965 ::std::vector<FmFilterData*>& rItems = pItem->GetParent()->GetParent()->GetChilds();
966 ::std::vector<FmFilterData*>::iterator i = ::std::find(rItems.begin(), rItems.end(), pItem->GetParent());
967 sal_Int32 nParentPos = i - rItems.begin();
969 m_pAdapter->setText(nParentPos, pItem, rText);
971 if (!rText)
972 Remove(pItem);
973 else
975 // Change the text
976 pItem->SetText(rText);
977 FmFilterTextChangedHint aChangeHint(pItem);
978 Broadcast( aChangeHint );
982 //------------------------------------------------------------------------
983 void FmFilterModel::SetCurrentItems(FmFilterItems* pCurrent)
985 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmFilterModel::SetCurrentItems" );
986 if (m_pCurrentItems == pCurrent)
987 return;
989 // search for the condition
990 if (pCurrent)
992 FmFormItem* pFormItem = (FmFormItem*)pCurrent->GetParent();
993 ::std::vector<FmFilterData*>& rItems = pFormItem->GetChilds();
994 ::std::vector<FmFilterData*>::const_iterator i = ::std::find(rItems.begin(), rItems.end(), pCurrent);
996 if (i != rItems.end())
998 // determine the filter position
999 sal_Int32 nPos = i - rItems.begin();
1000 FmXFormController* pController = FmXFormController::getImplementation( pFormItem->GetController().get() );
1001 DBG_ASSERT( pController, "FmFilterAdapter::SetCurrentItems: no controller!" );
1002 pController->setCurrentFilterPosition(nPos);
1003 pFormItem->SetCurrentPosition(nPos);
1005 if ((::com::sun::star::form::XFormController*)m_xController.get() != (::com::sun::star::form::XFormController*)pFormItem->GetController().get())
1006 // calls SetCurrentItems again
1007 SetCurrentController(pFormItem->GetController());
1008 else
1009 m_pCurrentItems = pCurrent;
1011 else
1012 m_pCurrentItems = NULL;
1014 else
1015 m_pCurrentItems = NULL;
1018 // UI benachrichtigen
1019 FmFilterCurrentChangedHint aHint;
1020 Broadcast( aHint );
1023 //------------------------------------------------------------------------
1024 void FmFilterModel::CheckIntegrity(FmParentData* pItem)
1026 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmFilterModel::CheckIntegrity" );
1027 // checks whether for each form there's one free level for input
1029 ::std::vector<FmFilterData*>& rItems = pItem->GetChilds();
1030 sal_Bool bAppendLevel = sal_False;
1032 for (::std::vector<FmFilterData*>::iterator i = rItems.begin();
1033 i != rItems.end(); i++)
1035 FmFilterItems* pItems = PTR_CAST(FmFilterItems, *i);
1036 if (pItems)
1038 bAppendLevel = !pItems->GetChilds().empty();
1039 continue;
1042 FmFormItem* pFormItem = PTR_CAST(FmFormItem, *i);
1043 if (pFormItem)
1045 CheckIntegrity(pFormItem);
1046 continue;
1049 if (bAppendLevel)
1050 AppendFilterItems((FmFormItem*)pItem);
1053 //========================================================================
1054 // class FmFilterItemsString
1055 //========================================================================
1056 class FmFilterItemsString : public SvLBoxString
1058 public:
1059 FmFilterItemsString( SvLBoxEntry* pEntry, sal_uInt16 nFlags, const XubString& rStr )
1060 :SvLBoxString(pEntry,nFlags,rStr){}
1062 virtual void Paint(const Point& rPos, SvLBox& rDev, sal_uInt16 nFlags, SvLBoxEntry* pEntry);
1063 virtual void InitViewData( SvLBox* pView,SvLBoxEntry* pEntry, SvViewDataItem* pViewData);
1066 const int nxDBmp = 12;
1067 //------------------------------------------------------------------------
1068 void FmFilterItemsString::Paint(const Point& rPos, SvLBox& rDev, sal_uInt16 /*nFlags*/, SvLBoxEntry* pEntry )
1070 FmFilterItems* pRow = (FmFilterItems*)pEntry->GetUserData();
1071 FmFormItem* pForm = (FmFormItem*)pRow->GetParent();
1072 // current filter is significant painted
1073 if (pForm->GetChilds()[pForm->GetCurrentPosition()] == pRow)
1075 Color aLineColor(rDev.GetLineColor());
1076 Rectangle aRect(rPos, GetSize(&rDev, pEntry ));
1077 Point aFirst(rPos.X(), aRect.Bottom() - 6);
1078 Point aSecond(aFirst.X() + 2, aFirst.Y() + 3);
1080 rDev.SetLineColor(rDev.GetTextColor());
1081 rDev.DrawLine(aFirst, aSecond);
1083 aFirst = aSecond;
1084 aFirst.X() += 1;
1085 aSecond.X() += 6;
1086 aSecond.Y() -= 5;
1088 rDev.DrawLine(aFirst, aSecond);
1089 rDev.SetLineColor( aLineColor );
1091 rDev.DrawText( Point(rPos.X() + nxDBmp, rPos.Y()), GetText() );
1094 //------------------------------------------------------------------------
1095 void FmFilterItemsString::InitViewData( SvLBox* pView,SvLBoxEntry* pEntry, SvViewDataItem* pViewData)
1097 if( !pViewData )
1098 pViewData = pView->GetViewDataItem( pEntry, this );
1100 Size aSize(pView->GetTextWidth(GetText()), pView->GetTextHeight());
1101 aSize.Width() += nxDBmp;
1102 pViewData->aSize = aSize;
1105 //========================================================================
1106 // class FmFilterString
1107 //========================================================================
1108 class FmFilterString : public SvLBoxString
1110 UniString m_aName;
1112 public:
1113 FmFilterString( SvLBoxEntry* pEntry, sal_uInt16 nFlags, const XubString& rStr, const UniString& aName)
1114 :SvLBoxString(pEntry,nFlags,rStr)
1115 ,m_aName(aName)
1117 m_aName.AppendAscii(": ");
1120 virtual void Paint(const Point& rPos, SvLBox& rDev, sal_uInt16 nFlags, SvLBoxEntry* pEntry);
1121 virtual void InitViewData( SvLBox* pView,SvLBoxEntry* pEntry, SvViewDataItem* pViewData);
1124 const int nxD = 4;
1126 //------------------------------------------------------------------------
1127 void FmFilterString::InitViewData( SvLBox* pView,SvLBoxEntry* pEntry, SvViewDataItem* pViewData)
1129 if( !pViewData )
1130 pViewData = pView->GetViewDataItem( pEntry, this );
1132 Font aOldFont( pView->GetFont());
1133 Font aFont( aOldFont );
1134 aFont.SetWeight(WEIGHT_BOLD);
1135 pView->SetFont( aFont );
1137 Size aSize(pView->GetTextWidth(m_aName), pView->GetTextHeight());
1138 pView->SetFont( aOldFont );
1139 aSize.Width() += pView->GetTextWidth(GetText()) + nxD;
1140 pViewData->aSize = aSize;
1143 //------------------------------------------------------------------------
1144 void FmFilterString::Paint(const Point& rPos, SvLBox& rDev, sal_uInt16 /*nFlags*/, SvLBoxEntry* /*pEntry*/ )
1146 Font aOldFont( rDev.GetFont());
1147 Font aFont( aOldFont );
1148 aFont.SetWeight(WEIGHT_BOLD);
1149 rDev.SetFont( aFont );
1151 Point aPos(rPos);
1152 rDev.DrawText( aPos, m_aName );
1154 // position for the second text
1155 aPos.X() += rDev.GetTextWidth(m_aName) + nxD;
1156 rDev.SetFont( aOldFont );
1157 rDev.DrawText( aPos, GetText() );
1160 //========================================================================
1161 // class FmFilterNavigator
1162 //========================================================================
1163 FmFilterNavigator::FmFilterNavigator( Window* pParent )
1164 :SvTreeListBox( pParent, WB_HASBUTTONS|WB_HASLINES|WB_BORDER|WB_HASBUTTONSATROOT )
1165 ,m_pModel( NULL )
1166 ,m_pEditingCurrently( NULL )
1167 ,m_aControlExchange( this )
1168 ,m_aTimerCounter( 0 )
1169 ,m_aDropActionType( DA_SCROLLUP )
1171 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmFilterNavigator::FmFilterNavigator" );
1172 SetHelpId( HID_FILTER_NAVIGATOR );
1176 ImageList aNavigatorImages( SVX_RES( RID_SVXIMGLIST_FMEXPL ) );
1177 SetNodeBitmaps(
1178 aNavigatorImages.GetImage( RID_SVXIMG_COLLAPSEDNODE ),
1179 aNavigatorImages.GetImage( RID_SVXIMG_EXPANDEDNODE ),
1180 BMP_COLOR_NORMAL
1184 ImageList aNavigatorImages( SVX_RES( RID_SVXIMGLIST_FMEXPL_HC ) );
1185 SetNodeBitmaps(
1186 aNavigatorImages.GetImage( RID_SVXIMG_COLLAPSEDNODE ),
1187 aNavigatorImages.GetImage( RID_SVXIMG_EXPANDEDNODE ),
1188 BMP_COLOR_HIGHCONTRAST
1193 m_pModel = new FmFilterModel(comphelper::getProcessServiceFactory());
1194 StartListening( *m_pModel );
1196 EnableInplaceEditing( sal_True );
1197 SetSelectionMode(MULTIPLE_SELECTION);
1199 SetDragDropMode(0xFFFF);
1201 m_aDropActionTimer.SetTimeoutHdl(LINK(this, FmFilterNavigator, OnDropActionTimer));
1204 //------------------------------------------------------------------------
1205 FmFilterNavigator::~FmFilterNavigator()
1207 EndListening( *m_pModel );
1208 delete m_pModel;
1211 //------------------------------------------------------------------------
1212 void FmFilterNavigator::Clear()
1214 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmFilterNavigator::Clear" );
1215 m_pModel->Clear();
1218 //------------------------------------------------------------------------
1219 void FmFilterNavigator::UpdateContent(const Reference< ::com::sun::star::container::XIndexAccess > & xControllers, const Reference< ::com::sun::star::form::XFormController > & xCurrent)
1221 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmFilterNavigator::UpdateContent" );
1222 if (xCurrent == m_pModel->GetCurrentController())
1223 return;
1225 m_pModel->Update(xControllers, xCurrent);
1227 // expand the filters for the current controller
1228 SvLBoxEntry* pEntry = FindEntry(m_pModel->GetCurrentForm());
1229 if (pEntry && !IsExpanded(pEntry))
1231 SelectAll(sal_False);
1233 if (!IsExpanded(pEntry))
1234 Expand(pEntry);
1236 pEntry = FindEntry(m_pModel->GetCurrentItems());
1237 if (pEntry)
1239 if (!IsExpanded(pEntry))
1240 Expand(pEntry);
1241 Select(pEntry, sal_True);
1246 //------------------------------------------------------------------------
1247 sal_Bool FmFilterNavigator::EditingEntry( SvLBoxEntry* pEntry, Selection& rSelection )
1249 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmFilterNavigator::EditingEntry" );
1250 m_pEditingCurrently = pEntry;
1251 if (!SvTreeListBox::EditingEntry( pEntry, rSelection ))
1252 return sal_False;
1254 return pEntry && ((FmFilterData*)pEntry->GetUserData())->ISA(FmFilterItem);
1257 //------------------------------------------------------------------------
1258 sal_Bool FmFilterNavigator::EditedEntry( SvLBoxEntry* pEntry, const XubString& rNewText )
1260 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmFilterNavigator::EditedEntry" );
1261 DBG_ASSERT(pEntry == m_pEditingCurrently, "FmFilterNavigator::EditedEntry: suspicious entry!");
1262 m_pEditingCurrently = NULL;
1264 if (EditingCanceled())
1265 return sal_True;
1267 DBG_ASSERT(((FmFilterData*)pEntry->GetUserData())->ISA(FmFilterItem),
1268 "FmFilterNavigator::EditedEntry() wrong entry");
1270 UniString aText(rNewText);
1271 aText.EraseTrailingChars();
1272 aText.EraseLeadingChars();
1273 if (aText.Len() == 0)
1275 // deleting the entry asynchron
1276 ULONG nEvent;
1277 PostUserEvent(nEvent, LINK(this, FmFilterNavigator, OnRemove), pEntry);
1279 else
1281 UniString aErrorMsg;
1283 if (m_pModel->ValidateText((FmFilterItem*)pEntry->GetUserData(), aText, aErrorMsg))
1285 GrabFocus();
1286 // this will set the text at the FmFilterItem, as well as update any filter controls
1287 // which are connected to this particular entry
1288 m_pModel->SetTextForItem( static_cast< FmFilterItem* >( pEntry->GetUserData() ), aText );
1290 SetCursor( pEntry, sal_True );
1291 SetEntryText( pEntry, aText );
1293 else
1295 // display the error and return sal_False
1297 SQLContext aError;
1298 aError.Message = String(SVX_RES(RID_STR_SYNTAXERROR));
1299 aError.Details = aErrorMsg;
1300 displayException(aError, this);
1302 return sal_False;
1305 return sal_True;
1308 //------------------------------------------------------------------------
1309 IMPL_LINK( FmFilterNavigator, OnRemove, SvLBoxEntry*, pEntry )
1311 // now remove the entry
1312 m_pModel->Remove((FmFilterData*) pEntry->GetUserData());
1313 return 0L;
1316 //------------------------------------------------------------------------
1317 IMPL_LINK( FmFilterNavigator, OnDropActionTimer, void*, EMPTYARG )
1319 if (--m_aTimerCounter > 0)
1320 return 0L;
1322 switch (m_aDropActionType)
1324 case DA_SCROLLUP :
1325 ScrollOutputArea(1);
1326 m_aTimerCounter = DROP_ACTION_TIMER_SCROLL_TICKS;
1327 break;
1328 case DA_SCROLLDOWN :
1329 ScrollOutputArea(-1);
1330 m_aTimerCounter = DROP_ACTION_TIMER_SCROLL_TICKS;
1331 break;
1332 case DA_EXPANDNODE:
1334 SvLBoxEntry* pToExpand = GetEntry(m_aTimerTriggered);
1335 if (pToExpand && (GetChildCount(pToExpand) > 0) && !IsExpanded(pToExpand))
1336 // tja, eigentlich muesste ich noch testen, ob die Node nicht schon expandiert ist, aber ich
1337 // habe dazu weder in den Basisklassen noch im Model eine Methode gefunden ...
1338 // aber ich denke, die BK sollte es auch so vertragen
1339 Expand(pToExpand);
1341 // nach dem Expand habe ich im Gegensatz zum Scrollen natuerlich nix mehr zu tun
1342 m_aDropActionTimer.Stop();
1344 break;
1346 return 0L;
1350 //------------------------------------------------------------------------
1351 sal_Int8 FmFilterNavigator::AcceptDrop( const AcceptDropEvent& rEvt )
1353 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmFilterNavigator::AcceptDrop" );
1354 Point aDropPos = rEvt.maPosPixel;
1356 // kuemmern wir uns erst mal um moeglich DropActions (Scrollen und Aufklappen)
1357 if (rEvt.mbLeaving)
1359 if (m_aDropActionTimer.IsActive())
1360 m_aDropActionTimer.Stop();
1362 else
1364 sal_Bool bNeedTrigger = sal_False;
1365 // auf dem ersten Eintrag ?
1366 if ((aDropPos.Y() >= 0) && (aDropPos.Y() < GetEntryHeight()))
1368 m_aDropActionType = DA_SCROLLUP;
1369 bNeedTrigger = sal_True;
1371 else
1373 // auf dem letzten (bzw. in dem Bereich, den ein Eintrag einnehmen wuerde, wenn er unten genau buendig
1374 // abschliessen wuerde) ?
1375 if ((aDropPos.Y() < GetSizePixel().Height()) && (aDropPos.Y() >= GetSizePixel().Height() - GetEntryHeight()))
1377 m_aDropActionType = DA_SCROLLDOWN;
1378 bNeedTrigger = sal_True;
1380 else
1381 { // auf einem Entry mit Childs, der nicht aufgeklappt ist ?
1382 SvLBoxEntry* pDropppedOn = GetEntry(aDropPos);
1383 if (pDropppedOn && (GetChildCount(pDropppedOn) > 0) && !IsExpanded(pDropppedOn))
1385 // -> aufklappen
1386 m_aDropActionType = DA_EXPANDNODE;
1387 bNeedTrigger = sal_True;
1391 if (bNeedTrigger && (m_aTimerTriggered != aDropPos))
1393 // neu anfangen zu zaehlen
1394 m_aTimerCounter = DROP_ACTION_TIMER_INITIAL_TICKS;
1395 // die Pos merken, da ich auch QueryDrops bekomme, wenn sich die Maus gar nicht bewegt hat
1396 m_aTimerTriggered = aDropPos;
1397 // und den Timer los
1398 if (!m_aDropActionTimer.IsActive()) // gibt es den Timer schon ?
1400 m_aDropActionTimer.SetTimeout(DROP_ACTION_TIMER_TICK_BASE);
1401 m_aDropActionTimer.Start();
1404 else if (!bNeedTrigger)
1405 m_aDropActionTimer.Stop();
1409 // Hat das Object das richtige Format?
1410 if (!m_aControlExchange.isDragSource())
1411 return DND_ACTION_NONE;
1413 if (!m_aControlExchange->hasFormat(GetDataFlavorExVector()))
1414 return DND_ACTION_NONE;
1416 // do we conain the formitem?
1417 if (!FindEntry(m_aControlExchange->getFormItem()))
1418 return DND_ACTION_NONE;
1420 SvLBoxEntry* pDropTarget = GetEntry(aDropPos);
1421 if (!pDropTarget)
1422 return DND_ACTION_NONE;
1424 FmFilterData* pData = (FmFilterData*)pDropTarget->GetUserData();
1425 FmFormItem* pForm = NULL;
1426 if (pData->ISA(FmFilterItem))
1428 pForm = PTR_CAST(FmFormItem,pData->GetParent()->GetParent());
1429 if (pForm != m_aControlExchange->getFormItem())
1430 return DND_ACTION_NONE;
1432 else if (pData->ISA(FmFilterItems))
1434 pForm = PTR_CAST(FmFormItem,pData->GetParent());
1435 if (pForm != m_aControlExchange->getFormItem())
1436 return DND_ACTION_NONE;
1438 else
1439 return DND_ACTION_NONE;
1441 return rEvt.mnAction;
1443 // -----------------------------------------------------------------------------
1444 namespace
1446 FmFilterItems* getTargetItems(SvLBoxEntry* _pTarget)
1448 FmFilterData* pData = static_cast<FmFilterData*>(_pTarget->GetUserData());
1449 FmFilterItems* pTargetItems = pData->ISA(FmFilterItems)
1451 PTR_CAST(FmFilterItems,pData)
1453 PTR_CAST(FmFilterItems,pData->GetParent());
1454 return pTargetItems;
1457 //------------------------------------------------------------------------
1458 sal_Int8 FmFilterNavigator::ExecuteDrop( const ExecuteDropEvent& rEvt )
1460 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmFilterNavigator::ExecuteDrop" );
1461 // ware schlecht, wenn nach dem Droppen noch gescrollt wird ...
1462 if (m_aDropActionTimer.IsActive())
1463 m_aDropActionTimer.Stop();
1465 // Format-Ueberpruefung
1466 if (!m_aControlExchange.isDragSource())
1467 return DND_ACTION_NONE;
1469 // das Ziel des Drop sowie einige Daten darueber
1470 Point aDropPos = rEvt.maPosPixel;
1471 SvLBoxEntry* pDropTarget = GetEntry( aDropPos );
1472 if (!pDropTarget)
1473 return DND_ACTION_NONE;
1475 // search the container where to add the items
1476 FmFilterItems* pTargetItems = getTargetItems(pDropTarget);
1477 SelectAll(sal_False);
1478 SvLBoxEntry* pEntry = FindEntry(pTargetItems);
1479 Select(pEntry, sal_True);
1480 SetCurEntry(pEntry);
1482 insertFilterItem(m_aControlExchange->getDraggedEntries(),pTargetItems,DND_ACTION_COPY == rEvt.mnAction);
1484 return sal_True;
1487 //------------------------------------------------------------------------
1488 void FmFilterNavigator::InitEntry(SvLBoxEntry* pEntry,
1489 const XubString& rStr,
1490 const Image& rImg1,
1491 const Image& rImg2,
1492 SvLBoxButtonKind eButtonKind)
1494 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmFilterNavigator::InitEntry" );
1495 SvTreeListBox::InitEntry( pEntry, rStr, rImg1, rImg2, eButtonKind );
1496 SvLBoxString* pString = NULL;
1498 if (((FmFilterData*)pEntry->GetUserData())->ISA(FmFilterItem))
1499 pString = new FmFilterString(pEntry, 0, rStr, ((FmFilterItem*)pEntry->GetUserData())->GetFieldName());
1500 else if (((FmFilterData*)pEntry->GetUserData())->ISA(FmFilterItems))
1501 pString = new FmFilterItemsString(pEntry, 0, rStr );
1503 if (pString)
1504 pEntry->ReplaceItem( pString, 1 );
1507 //------------------------------------------------------------------------
1508 sal_Bool FmFilterNavigator::Select( SvLBoxEntry* pEntry, sal_Bool bSelect )
1510 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmFilterNavigator::Select" );
1511 if (bSelect == IsSelected(pEntry)) // das passiert manchmal, ich glaube, die Basisklasse geht zu sehr auf Nummer sicher ;)
1512 return sal_True;
1514 if (SvTreeListBox::Select(pEntry, bSelect))
1516 if (bSelect)
1518 FmFormItem* pFormItem = NULL;
1519 if (((FmFilterData*)pEntry->GetUserData())->ISA(FmFilterItem))
1520 pFormItem = (FmFormItem*)((FmFilterItem*)pEntry->GetUserData())->GetParent()->GetParent();
1521 else if (((FmFilterData*)pEntry->GetUserData())->ISA(FmFilterItems))
1522 pFormItem = (FmFormItem*)((FmFilterItem*)pEntry->GetUserData())->GetParent()->GetParent();
1523 else if (((FmFilterData*)pEntry->GetUserData())->ISA(FmFormItem))
1524 pFormItem = (FmFormItem*)pEntry->GetUserData();
1526 if (pFormItem)
1528 // will the controller be exchanged?
1529 if (((FmFilterData*)pEntry->GetUserData())->ISA(FmFilterItem))
1530 m_pModel->SetCurrentItems((FmFilterItems*)((FmFilterItem*)pEntry->GetUserData())->GetParent());
1531 else if (((FmFilterData*)pEntry->GetUserData())->ISA(FmFilterItems))
1532 m_pModel->SetCurrentItems((FmFilterItems*)pEntry->GetUserData());
1533 else if (((FmFilterData*)pEntry->GetUserData())->ISA(FmFormItem))
1534 m_pModel->SetCurrentController(((FmFormItem*)pEntry->GetUserData())->GetController());
1537 return sal_True;
1539 else
1540 return sal_False;
1543 //------------------------------------------------------------------------
1544 void FmFilterNavigator::Notify( SfxBroadcaster& /*rBC*/, const SfxHint& rHint )
1546 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmFilterNavigator::Notify" );
1547 if (rHint.ISA(FmFilterInsertedHint))
1549 FmFilterInsertedHint* pHint = (FmFilterInsertedHint*)&rHint;
1550 Insert(pHint->GetData(), pHint->GetPos());
1552 else if( rHint.ISA(FilterClearingHint) )
1554 SvTreeListBox::Clear();
1556 else if( rHint.ISA(FmFilterRemovedHint) )
1558 FmFilterRemovedHint* pHint = (FmFilterRemovedHint*)&rHint;
1559 Remove(pHint->GetData());
1561 else if( rHint.ISA(FmFilterTextChangedHint) )
1563 FmFilterTextChangedHint* pHint = (FmFilterTextChangedHint*)&rHint;
1564 SvLBoxEntry* pEntry = FindEntry(pHint->GetData());
1565 if (pEntry)
1566 SetEntryText( pEntry, pHint->GetData()->GetText());
1568 else if( rHint.ISA(FmFilterCurrentChangedHint) )
1570 // invalidate the entries
1571 for (SvLBoxEntry* pEntry = First(); pEntry != NULL;
1572 pEntry = Next(pEntry))
1573 GetModel()->InvalidateEntry( pEntry );
1577 //------------------------------------------------------------------------
1578 SvLBoxEntry* FmFilterNavigator::FindEntry(const FmFilterData* pItem) const
1580 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmFilterNavigator::FindEntry" );
1581 SvLBoxEntry* pEntry = NULL;
1582 if (pItem)
1584 for (pEntry = First(); pEntry != NULL; pEntry = Next( pEntry ))
1586 FmFilterData* pEntryItem = (FmFilterData*)pEntry->GetUserData();
1587 if (pEntryItem == pItem)
1588 break;
1591 return pEntry;
1594 //------------------------------------------------------------------------
1595 void FmFilterNavigator::Insert(FmFilterData* pItem, sal_Int32 nPos)
1597 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmFilterNavigator::Insert" );
1598 const FmParentData* pParent = pItem->GetParent() ? pItem->GetParent() : GetFilterModel();
1600 // insert the item
1601 SvLBoxEntry* pParentEntry = FindEntry(pParent);
1602 SvLBoxEntry* pNewEntry = InsertEntry(pItem->GetText(), pItem->GetImage(), pItem->GetImage(), pParentEntry, sal_False, nPos, pItem );
1603 if ( pNewEntry )
1605 SetExpandedEntryBmp( pNewEntry, pItem->GetImage( BMP_COLOR_HIGHCONTRAST ), BMP_COLOR_HIGHCONTRAST );
1606 SetCollapsedEntryBmp( pNewEntry, pItem->GetImage( BMP_COLOR_HIGHCONTRAST ), BMP_COLOR_HIGHCONTRAST );
1610 //------------------------------------------------------------------------
1611 void FmFilterNavigator::Remove(FmFilterData* pItem)
1613 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmFilterNavigator::Remove" );
1614 // der Entry zu den Daten
1615 SvLBoxEntry* pEntry = FindEntry(pItem);
1617 if (pEntry == m_pEditingCurrently)
1618 // cancel editing
1619 EndEditing(sal_True);
1621 if (pEntry)
1622 GetModel()->Remove( pEntry );
1624 // -----------------------------------------------------------------------------
1625 FmFormItem* FmFilterNavigator::getSelectedFilterItems(::std::vector<FmFilterItem*>& _rItemList)
1627 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmFilterNavigator::getSelectedFilterItems" );
1628 // be sure that the data is only used within only one form!
1629 FmFormItem* pFirstItem = NULL;
1631 sal_Bool bHandled = sal_True;
1632 sal_Bool bFoundSomething = sal_False;
1633 for (SvLBoxEntry* pEntry = FirstSelected();
1634 bHandled && pEntry != NULL;
1635 pEntry = NextSelected(pEntry))
1637 FmFilterItem* pFilter = PTR_CAST(FmFilterItem, (FmFilterData*)pEntry->GetUserData());
1638 if (pFilter)
1640 FmFormItem* pForm = PTR_CAST(FmFormItem,pFilter->GetParent()->GetParent());
1641 if (!pForm)
1642 bHandled = sal_False;
1643 else if (!pFirstItem)
1644 pFirstItem = pForm;
1645 else if (pFirstItem != pForm)
1646 bHandled = sal_False;
1648 if (bHandled)
1650 _rItemList.push_back(pFilter);
1651 bFoundSomething = sal_True;
1655 if ( !bHandled || !bFoundSomething )
1656 pFirstItem = NULL;
1657 return pFirstItem;
1659 // -----------------------------------------------------------------------------
1660 void FmFilterNavigator::insertFilterItem(const ::std::vector<FmFilterItem*>& _rFilterList,FmFilterItems* _pTargetItems,sal_Bool _bCopy)
1662 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmFilterNavigator::insertFilterItem" );
1663 ::std::vector<FmFilterItem*>::const_iterator aEnd = _rFilterList.end();
1664 for (::std::vector<FmFilterItem*>::const_iterator i = _rFilterList.begin(); i != aEnd; ++i)
1666 if ((*i)->GetParent() == _pTargetItems)
1667 continue;
1668 else
1670 FmFilterItem* pFilterItem = _pTargetItems->Find((*i)->GetTextComponent());
1671 String aText = (*i)->GetText();
1672 if ( !pFilterItem )
1674 pFilterItem = new FmFilterItem(m_pModel->getORB(),_pTargetItems, (*i)->GetFieldName(), aText, (*i)->GetTextComponent());
1675 m_pModel->Append(_pTargetItems, pFilterItem);
1678 if ( !_bCopy )
1679 m_pModel->Remove(*i);
1681 // now set the text for the new dragged item
1682 m_pModel->SetTextForItem(pFilterItem, aText);
1685 m_pModel->CheckIntegrity((FmFormItem*)_pTargetItems->GetParent());
1687 //------------------------------------------------------------------------------
1688 void FmFilterNavigator::StartDrag( sal_Int8 /*_nAction*/, const Point& /*_rPosPixel*/ )
1690 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmFilterNavigator::StartDrag" );
1691 EndSelection();
1693 // be sure that the data is only used within a only one form!
1694 m_aControlExchange.prepareDrag();
1696 ::std::vector<FmFilterItem*> aItemList;
1697 if ( FmFormItem* pFirstItem = getSelectedFilterItems(aItemList) )
1699 m_aControlExchange->setDraggedEntries(aItemList);
1700 m_aControlExchange->setFormItem(pFirstItem);
1701 m_aControlExchange.startDrag( DND_ACTION_COPYMOVE );
1705 //------------------------------------------------------------------------------
1706 void FmFilterNavigator::Command( const CommandEvent& rEvt )
1708 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmFilterNavigator::Command" );
1709 sal_Bool bHandled = sal_False;
1710 switch (rEvt.GetCommand())
1712 case COMMAND_CONTEXTMENU:
1714 // die Stelle, an der geklickt wurde
1715 Point aWhere;
1716 SvLBoxEntry* pClicked = NULL;
1717 if (rEvt.IsMouseEvent())
1719 aWhere = rEvt.GetMousePosPixel();
1720 pClicked = GetEntry(aWhere);
1721 if (pClicked == NULL)
1722 break;
1724 if (!IsSelected(pClicked))
1726 SelectAll(sal_False);
1727 Select(pClicked, sal_True);
1728 SetCurEntry(pClicked);
1731 else
1733 pClicked = GetCurEntry();
1734 if (!pClicked)
1735 break;
1736 aWhere = GetEntryPosition( pClicked );
1739 ::std::vector<FmFilterData*> aSelectList;
1740 for (SvLBoxEntry* pEntry = FirstSelected();
1741 pEntry != NULL;
1742 pEntry = NextSelected(pEntry))
1744 // don't delete forms
1745 FmFormItem* pForm = PTR_CAST(FmFormItem, (FmFilterData*)pEntry->GetUserData());
1746 if (!pForm)
1747 aSelectList.push_back((FmFilterData*)pEntry->GetUserData());
1749 if (aSelectList.size() == 1)
1751 // don't delete the only empty row of a form
1752 FmFilterItems* pFilterItems = PTR_CAST(FmFilterItems, aSelectList[0]);
1753 if (pFilterItems && pFilterItems->GetChilds().empty()
1754 && pFilterItems->GetParent()->GetChilds().size() == 1)
1755 aSelectList.clear();
1758 PopupMenu aContextMenu(SVX_RES(RID_FM_FILTER_MENU));
1760 // every condition could be deleted except the first one if its the only one
1761 aContextMenu.EnableItem( SID_FM_DELETE, !aSelectList.empty() );
1764 sal_Bool bEdit = PTR_CAST(FmFilterItem, (FmFilterData*)pClicked->GetUserData()) != NULL &&
1765 IsSelected(pClicked) && GetSelectionCount() == 1;
1767 aContextMenu.EnableItem( SID_FM_FILTER_EDIT,
1768 bEdit );
1769 aContextMenu.EnableItem( SID_FM_FILTER_IS_NULL,
1770 bEdit );
1771 aContextMenu.EnableItem( SID_FM_FILTER_IS_NOT_NULL,
1772 bEdit );
1774 aContextMenu.RemoveDisabledEntries(sal_True, sal_True);
1775 sal_uInt16 nSlotId = aContextMenu.Execute( this, aWhere );
1776 switch( nSlotId )
1778 case SID_FM_FILTER_EDIT:
1780 EditEntry( pClicked );
1781 } break;
1782 case SID_FM_FILTER_IS_NULL:
1783 case SID_FM_FILTER_IS_NOT_NULL:
1785 UniString aErrorMsg;
1786 UniString aText;
1787 if (nSlotId == SID_FM_FILTER_IS_NULL)
1788 aText.AssignAscii("IS NULL");
1789 else
1790 aText.AssignAscii("IS NOT NULL");
1792 m_pModel->ValidateText((FmFilterItem*)pClicked->GetUserData(),
1793 aText, aErrorMsg);
1794 m_pModel->SetTextForItem((FmFilterItem*)pClicked->GetUserData(), aText);
1795 } break;
1796 case SID_FM_DELETE:
1798 DeleteSelection();
1799 } break;
1801 bHandled = sal_True;
1802 } break;
1805 if (!bHandled)
1806 SvTreeListBox::Command( rEvt );
1808 // -----------------------------------------------------------------------------
1809 SvLBoxEntry* FmFilterNavigator::getNextEntry(SvLBoxEntry* _pStartWith)
1811 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmFilterNavigator::getNextEntry" );
1812 SvLBoxEntry* pEntry = _pStartWith ? _pStartWith : LastSelected();
1813 pEntry = Next(pEntry);
1814 // we need the next filter entry
1815 while( pEntry && GetChildCount( pEntry ) == 0 && pEntry != Last() )
1816 pEntry = Next(pEntry);
1817 return pEntry;
1819 // -----------------------------------------------------------------------------
1820 SvLBoxEntry* FmFilterNavigator::getPrevEntry(SvLBoxEntry* _pStartWith)
1822 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmFilterNavigator::getPrevEntry" );
1823 SvLBoxEntry* pEntry = _pStartWith ? _pStartWith : FirstSelected();
1824 pEntry = Prev(pEntry);
1825 // check if the previous entry is a filter, if so get the next prev
1826 if ( pEntry && GetChildCount( pEntry ) != 0 )
1828 pEntry = Prev(pEntry);
1829 // if the entry is still no leaf return
1830 if ( pEntry && GetChildCount( pEntry ) != 0 )
1831 pEntry = NULL;
1833 return pEntry;
1835 //------------------------------------------------------------------------
1836 void FmFilterNavigator::KeyInput(const KeyEvent& rKEvt)
1838 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmFilterNavigator::KeyInput" );
1839 const KeyCode& rKeyCode = rKEvt.GetKeyCode();
1840 if ( rKeyCode.IsMod1()
1841 && rKeyCode.IsMod2()
1842 && !rKeyCode.IsShift()
1843 && ( rKeyCode.GetCode() == KEY_UP || rKeyCode.GetCode() == KEY_DOWN )
1846 ::std::vector<FmFilterItem*> aItemList;
1847 if ( getSelectedFilterItems(aItemList) )
1849 ::std::mem_fun1_t<SvLBoxEntry*,FmFilterNavigator,SvLBoxEntry*> aGetEntry = ::std::mem_fun(&FmFilterNavigator::getNextEntry);
1850 if ( rKeyCode.GetCode() == KEY_UP )
1851 aGetEntry = ::std::mem_fun(&FmFilterNavigator::getPrevEntry);
1853 SvLBoxEntry* pTarget = aGetEntry(this,NULL);
1855 if ( pTarget )
1857 FmFilterItems* pTargetItems = getTargetItems(pTarget);
1858 if ( pTargetItems )
1860 ::std::vector<FmFilterItem*>::const_iterator aEnd = aItemList.end();
1861 sal_Bool bNextTargetItem = sal_True;
1862 while ( bNextTargetItem )
1864 ::std::vector<FmFilterItem*>::const_iterator i = aItemList.begin();
1865 for (; i != aEnd; ++i)
1867 if ( (*i)->GetParent() == pTargetItems )
1869 pTarget = aGetEntry(this,pTarget);
1870 if ( !pTarget )
1871 return;
1872 pTargetItems = getTargetItems(pTarget);
1873 break;
1875 else
1877 FmFilterItem* pFilterItem = pTargetItems->Find((*i)->GetTextComponent());
1878 // we found the text component so jump above
1879 if ( pFilterItem )
1881 pTarget = aGetEntry(this,pTarget);
1882 if ( !pTarget )
1883 return;
1884 pTargetItems = getTargetItems(pTarget);
1885 break;
1889 bNextTargetItem = i != aEnd && pTargetItems;
1891 if ( pTargetItems )
1893 insertFilterItem(aItemList,pTargetItems);
1894 return;
1900 else if (rKeyCode.GetCode() == KEY_DELETE && !rKeyCode.GetModifier())
1902 if (!IsSelected(First()) || GetEntryCount() > 1)
1903 DeleteSelection();
1904 return;
1906 SvTreeListBox::KeyInput(rKEvt);
1909 //------------------------------------------------------------------------------
1910 void FmFilterNavigator::DeleteSelection()
1912 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmFilterNavigator::DeleteSelection" );
1913 // to avoid the deletion of an entry twice (e.g. deletion of a parent and afterward
1914 // the deletion of it's child, i have to shrink the selecton list
1915 ::std::vector<SvLBoxEntry*> aEntryList;
1916 for (SvLBoxEntry* pEntry = FirstSelected();
1917 pEntry != NULL;
1918 pEntry = NextSelected(pEntry))
1920 FmFilterItem* pFilterItem = PTR_CAST(FmFilterItem, (FmFilterData*)pEntry->GetUserData());
1921 if (pFilterItem && IsSelected(GetParent(pEntry)))
1922 continue;
1924 FmFormItem* pForm = PTR_CAST(FmFormItem, (FmFilterData*)pEntry->GetUserData());
1925 if (!pForm)
1926 aEntryList.push_back(pEntry);
1929 // Remove the selection
1930 SelectAll(FALSE);
1932 for (::std::vector<SvLBoxEntry*>::reverse_iterator i = aEntryList.rbegin();
1933 // link problems with operator ==
1934 i.base() != aEntryList.rend().base(); i++)
1936 m_pModel->Remove((FmFilterData*)(*i)->GetUserData());
1939 // now check if we need to insert new items
1940 m_pModel->CheckIntegrity(m_pModel);
1942 // -----------------------------------------------------------------------------
1944 //========================================================================
1945 // class FmFilterNavigatorWin
1946 //========================================================================
1947 FmFilterNavigatorWin::FmFilterNavigatorWin( SfxBindings* _pBindings, SfxChildWindow* _pMgr,
1948 Window* _pParent )
1949 :SfxDockingWindow( _pBindings, _pMgr, _pParent, WinBits(WB_STDMODELESS|WB_SIZEABLE|WB_ROLLABLE|WB_3DLOOK|WB_DOCKABLE) )
1950 ,SfxControllerItem( SID_FM_FILTER_NAVIGATOR_CONTROL, *_pBindings )
1952 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmFilterNavigatorWin::FmFilterNavigatorWin" );
1953 SetHelpId( HID_FILTER_NAVIGATOR_WIN );
1955 m_pNavigator = new FmFilterNavigator( this );
1956 m_pNavigator->Show();
1957 SetText( SVX_RES(RID_STR_FILTER_NAVIGATOR) );
1958 SfxDockingWindow::SetFloatingSize( Size(200,200) );
1961 //------------------------------------------------------------------------
1962 FmFilterNavigatorWin::~FmFilterNavigatorWin()
1964 delete m_pNavigator;
1967 //-----------------------------------------------------------------------
1968 void FmFilterNavigatorWin::UpdateContent(FmFormShell* pFormShell)
1970 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmFilterNavigatorWin::UpdateContent" );
1971 if (!pFormShell)
1972 m_pNavigator->UpdateContent( NULL, NULL );
1973 else
1975 Reference< ::com::sun::star::form::XFormController > xController(pFormShell->GetImpl()->getActiveInternalController());
1976 Reference< ::com::sun::star::container::XIndexAccess > xContainer;
1977 if (xController.is())
1979 Reference< ::com::sun::star::container::XChild > xChild(xController, UNO_QUERY);
1980 for (Reference< XInterface > xParent(xChild->getParent());
1981 xParent.is();
1982 xParent = xChild.is() ? xChild->getParent() : Reference< XInterface > ())
1984 xContainer = Reference< ::com::sun::star::container::XIndexAccess > (xParent, UNO_QUERY);
1985 xChild = Reference< ::com::sun::star::container::XChild > (xParent, UNO_QUERY);
1988 m_pNavigator->UpdateContent(xContainer, xController);
1992 //-----------------------------------------------------------------------
1993 void FmFilterNavigatorWin::StateChanged( sal_uInt16 nSID, SfxItemState eState, const SfxPoolItem* pState )
1995 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmFilterNavigatorWin::StateChanged" );
1996 if( !pState || SID_FM_FILTER_NAVIGATOR_CONTROL != nSID )
1997 return;
1999 if( eState >= SFX_ITEM_AVAILABLE )
2001 FmFormShell* pShell = PTR_CAST( FmFormShell,((SfxObjectItem*)pState)->GetShell() );
2002 UpdateContent( pShell );
2004 else
2005 UpdateContent( NULL );
2008 //-----------------------------------------------------------------------
2009 sal_Bool FmFilterNavigatorWin::Close()
2011 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmFilterNavigatorWin::Close" );
2012 if ( m_pNavigator && m_pNavigator->IsEditingActive() )
2013 m_pNavigator->EndEditing();
2015 if ( m_pNavigator && m_pNavigator->IsEditingActive() )
2016 // the EndEditing was vetoed (perhaps of an syntax error or such)
2017 return sal_False;
2019 UpdateContent( NULL );
2020 return SfxDockingWindow::Close();
2023 //-----------------------------------------------------------------------
2024 void FmFilterNavigatorWin::FillInfo( SfxChildWinInfo& rInfo ) const
2026 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmFilterNavigatorWin::FillInfo" );
2027 SfxDockingWindow::FillInfo( rInfo );
2028 rInfo.bVisible = sal_False;
2031 //-----------------------------------------------------------------------
2032 Size FmFilterNavigatorWin::CalcDockingSize( SfxChildAlignment eAlign )
2034 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmFilterNavigatorWin::CalcDockingSize" );
2035 if ( ( eAlign == SFX_ALIGN_TOP ) || ( eAlign == SFX_ALIGN_BOTTOM ) )
2036 return Size();
2038 return SfxDockingWindow::CalcDockingSize( eAlign );
2041 //-----------------------------------------------------------------------
2042 SfxChildAlignment FmFilterNavigatorWin::CheckAlignment( SfxChildAlignment eActAlign, SfxChildAlignment eAlign )
2044 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmFilterNavigatorWin::CheckAlignment" );
2045 switch (eAlign)
2047 case SFX_ALIGN_LEFT:
2048 case SFX_ALIGN_RIGHT:
2049 case SFX_ALIGN_NOALIGNMENT:
2050 return (eAlign);
2051 default:
2052 break;
2055 return (eActAlign);
2058 //------------------------------------------------------------------------
2059 void FmFilterNavigatorWin::Resize()
2061 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmFilterNavigatorWin::Resize" );
2062 SfxDockingWindow::Resize();
2064 Size aLogOutputSize = PixelToLogic( GetOutputSizePixel(), MAP_APPFONT );
2065 Size aLogExplSize = aLogOutputSize;
2066 aLogExplSize.Width() -= 6;
2067 aLogExplSize.Height() -= 6;
2069 Point aExplPos = LogicToPixel( Point(3,3), MAP_APPFONT );
2070 Size aExplSize = LogicToPixel( aLogExplSize, MAP_APPFONT );
2072 m_pNavigator->SetPosSizePixel( aExplPos, aExplSize );
2074 // -----------------------------------------------------------------------------
2075 void FmFilterNavigatorWin::GetFocus()
2077 RTL_LOGFILE_CONTEXT_AUTHOR( aLogger, "svx", "Ocke.Janssen@sun.com", "FmFilterNavigatorWin::GetFocus" );
2078 // oj #97405#
2079 if ( m_pNavigator )
2080 m_pNavigator->GrabFocus();
2082 // -----------------------------------------------------------------------------
2085 //========================================================================
2086 // class FmFilterNavigatorWinMgr
2087 //========================================================================
2088 SFX_IMPL_DOCKINGWINDOW( FmFilterNavigatorWinMgr, SID_FM_FILTER_NAVIGATOR )
2090 //-----------------------------------------------------------------------
2091 FmFilterNavigatorWinMgr::FmFilterNavigatorWinMgr( Window *_pParent, sal_uInt16 _nId,
2092 SfxBindings *_pBindings, SfxChildWinInfo* _pInfo )
2093 :SfxChildWindow( _pParent, _nId )
2095 pWindow = new FmFilterNavigatorWin( _pBindings, this, _pParent );
2096 eChildAlignment = SFX_ALIGN_NOALIGNMENT;
2097 ((SfxDockingWindow*)pWindow)->Initialize( _pInfo );
2100 //........................................................................
2101 } // namespace svxform
2102 //........................................................................