1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: fmgridif.cxx,v $
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"
34 #include "fmgridif.hxx"
36 #include "fmservs.hxx"
37 #include "fmtools.hxx"
39 #include "formcontrolfactory.hxx"
40 #include "gridcell.hxx"
41 #include "sdbdatacolumn.hxx"
42 #include "svx/fmgridcl.hxx"
43 #include "svx/svxids.hrc"
45 #include <com/sun/star/awt/PosSize.hpp>
46 #include <com/sun/star/beans/PropertyAttribute.hpp>
47 #include <com/sun/star/form/FormComponentType.hpp>
48 #include <com/sun/star/form/XFormComponent.hpp>
49 #include <com/sun/star/form/XLoadable.hpp>
50 #include <com/sun/star/lang/DisposedException.hpp>
51 #include <com/sun/star/sdbc/ResultSetType.hpp>
52 #include <com/sun/star/sdbcx/XColumnsSupplier.hpp>
53 #include <com/sun/star/util/XURLTransformer.hpp>
54 #include <com/sun/star/view/XSelectionSupplier.hpp>
56 #include <comphelper/container.hxx>
57 #include <comphelper/enumhelper.hxx>
58 #include <comphelper/extract.hxx>
59 #include <comphelper/processfactory.hxx>
60 #include <comphelper/property.hxx>
61 #include <comphelper/sequence.hxx>
62 #include <comphelper/types.hxx>
63 #include <cppuhelper/typeprovider.hxx>
64 #include <toolkit/helper/vclunohelper.hxx>
65 #include <tools/diagnose_ex.h>
67 using namespace ::svxform
;
68 using namespace ::com::sun::star::container
;
69 using namespace ::com::sun::star::sdbc
;
70 using namespace ::com::sun::star::uno
;
71 using namespace ::com::sun::star::view
;
72 using namespace ::com::sun::star::beans
;
73 using namespace ::com::sun::star::lang
;
74 using namespace ::com::sun::star::form
;
75 using namespace ::com::sun::star::util
;
76 using namespace ::com::sun::star
;
78 using ::com::sun::star::sdbcx::XColumnsSupplier
;
79 using ::com::sun::star::frame::XDispatchProviderInterceptor
;
80 using ::com::sun::star::frame::XDispatchProvider
;
81 using ::com::sun::star::accessibility::XAccessible
;
82 using ::com::sun::star::accessibility::XAccessibleContext
;
83 using ::com::sun::star::sdb::XRowSetSupplier
;
84 using ::com::sun::star::awt::XVclWindowPeer
;
87 //------------------------------------------------------------------
88 ::com::sun::star::awt::FontDescriptor
ImplCreateFontDescriptor( const Font
& rFont
)
90 ::com::sun::star::awt::FontDescriptor aFD
;
91 aFD
.Name
= rFont
.GetName();
92 aFD
.StyleName
= rFont
.GetStyleName();
93 aFD
.Height
= (sal_Int16
)rFont
.GetSize().Height();
94 aFD
.Width
= (sal_Int16
)rFont
.GetSize().Width();
95 aFD
.Family
= (sal_Int16
)rFont
.GetFamily();
96 aFD
.CharSet
= rFont
.GetCharSet();
97 aFD
.Pitch
= (sal_Int16
)rFont
.GetPitch();
98 aFD
.CharacterWidth
= VCLUnoHelper::ConvertFontWidth( rFont
.GetWidthType() );
99 aFD
.Weight
= VCLUnoHelper::ConvertFontWeight( rFont
.GetWeight() );
100 aFD
.Slant
= (::com::sun::star::awt::FontSlant
)rFont
.GetItalic();
101 aFD
.Underline
= (sal_Int16
)rFont
.GetUnderline();
102 aFD
.Strikeout
= (sal_Int16
)rFont
.GetStrikeout();
103 aFD
.Orientation
= rFont
.GetOrientation();
104 aFD
.Kerning
= rFont
.IsKerning();
105 aFD
.WordLineMode
= rFont
.IsWordLineMode();
106 aFD
.Type
= 0; // ??? => Nur an Metric...
110 //------------------------------------------------------------------
111 Font
ImplCreateFont( const ::com::sun::star::awt::FontDescriptor
& rDescr
)
114 aFont
.SetName( rDescr
.Name
);
115 aFont
.SetStyleName( rDescr
.StyleName
);
116 aFont
.SetSize( ::Size( rDescr
.Width
, rDescr
.Height
) );
117 aFont
.SetFamily( (FontFamily
)rDescr
.Family
);
118 aFont
.SetCharSet( (CharSet
)rDescr
.CharSet
);
119 aFont
.SetPitch( (FontPitch
)rDescr
.Pitch
);
120 aFont
.SetWidthType( VCLUnoHelper::ConvertFontWidth( rDescr
.CharacterWidth
) );
121 aFont
.SetWeight( VCLUnoHelper::ConvertFontWeight( rDescr
.Weight
) );
122 aFont
.SetItalic( (FontItalic
)rDescr
.Slant
);
123 aFont
.SetUnderline( (::FontUnderline
)rDescr
.Underline
);
124 aFont
.SetStrikeout( (::FontStrikeout
)rDescr
.Strikeout
);
125 aFont
.SetOrientation( (sal_Int16
)rDescr
.Orientation
);
126 aFont
.SetKerning( rDescr
.Kerning
);
127 aFont
.SetWordLineMode( rDescr
.WordLineMode
);
131 //==================================================================
132 //= FmXModifyMultiplexer
133 //==================================================================
134 //------------------------------------------------------------------
135 FmXModifyMultiplexer::FmXModifyMultiplexer( ::cppu::OWeakObject
& rSource
, ::osl::Mutex
& _rMutex
)
136 :OWeakSubObject( rSource
)
137 ,OInterfaceContainerHelper( _rMutex
)
141 //------------------------------------------------------------------
142 Any SAL_CALL
FmXModifyMultiplexer::queryInterface(const Type
& _rType
) throw (RuntimeException
)
145 aReturn
= ::cppu::queryInterface(_rType
,
146 static_cast< ::com::sun::star::util::XModifyListener
*>(this),
147 static_cast< XEventListener
*>(this)
150 if (!aReturn
.hasValue())
151 aReturn
= OWeakSubObject::queryInterface( _rType
);
156 //------------------------------------------------------------------
157 void FmXModifyMultiplexer::disposing(const EventObject
& ) throw( RuntimeException
)
161 //------------------------------------------------------------------
162 void FmXModifyMultiplexer::modified(const EventObject
& e
) throw( RuntimeException
)
164 EventObject
aMulti( e
);
165 aMulti
.Source
= &m_rParent
;
166 notifyEach( &XModifyListener::modified
, aMulti
);
169 //==================================================================
170 //= FmXUpdateMultiplexer
171 //==================================================================
172 //------------------------------------------------------------------
173 FmXUpdateMultiplexer::FmXUpdateMultiplexer( ::cppu::OWeakObject
& rSource
, ::osl::Mutex
& _rMutex
)
174 :OWeakSubObject( rSource
)
175 ,OInterfaceContainerHelper( _rMutex
)
179 //------------------------------------------------------------------
180 Any SAL_CALL
FmXUpdateMultiplexer::queryInterface(const Type
& _rType
) throw (RuntimeException
)
183 aReturn
= ::cppu::queryInterface(_rType
,
184 static_cast< XUpdateListener
*>(this),
185 static_cast< XEventListener
*>(this)
188 if (!aReturn
.hasValue())
189 aReturn
= OWeakSubObject::queryInterface( _rType
);
194 //------------------------------------------------------------------
195 void FmXUpdateMultiplexer::disposing(const EventObject
& ) throw( RuntimeException
)
199 //------------------------------------------------------------------
200 sal_Bool
FmXUpdateMultiplexer::approveUpdate(const EventObject
&e
) throw( RuntimeException
)
202 EventObject
aMulti( e
);
203 aMulti
.Source
= &m_rParent
;
205 sal_Bool bResult
= sal_True
;
208 ::cppu::OInterfaceIteratorHelper
aIter(*this);
209 while ( bResult
&& aIter
.hasMoreElements() )
210 bResult
= static_cast< XUpdateListener
* >( aIter
.next() )->approveUpdate( aMulti
);
216 //------------------------------------------------------------------
217 void FmXUpdateMultiplexer::updated(const EventObject
&e
) throw( RuntimeException
)
219 EventObject
aMulti( e
);
220 aMulti
.Source
= &m_rParent
;
221 notifyEach( &XUpdateListener::updated
, aMulti
);
225 //==================================================================
226 //= FmXSelectionMultiplexer
227 //==================================================================
228 //------------------------------------------------------------------
229 FmXSelectionMultiplexer::FmXSelectionMultiplexer( ::cppu::OWeakObject
& rSource
, ::osl::Mutex
& _rMutex
)
230 :OWeakSubObject( rSource
)
231 ,OInterfaceContainerHelper( _rMutex
)
235 //------------------------------------------------------------------
236 Any SAL_CALL
FmXSelectionMultiplexer::queryInterface(const Type
& _rType
) throw (RuntimeException
)
239 aReturn
= ::cppu::queryInterface(_rType
,
240 static_cast< XSelectionChangeListener
*>(this),
241 static_cast< XEventListener
*>(this)
244 if (!aReturn
.hasValue())
245 aReturn
= OWeakSubObject::queryInterface( _rType
);
250 //------------------------------------------------------------------
251 void FmXSelectionMultiplexer::disposing(const EventObject
& ) throw( RuntimeException
)
255 //------------------------------------------------------------------
256 void SAL_CALL
FmXSelectionMultiplexer::selectionChanged( const EventObject
& _rEvent
) throw (RuntimeException
)
258 EventObject
aMulti(_rEvent
);
259 aMulti
.Source
= &m_rParent
;
260 notifyEach( &XSelectionChangeListener::selectionChanged
, aMulti
);
263 //==================================================================
264 //= FmXContainerMultiplexer
265 //==================================================================
266 //------------------------------------------------------------------
267 FmXContainerMultiplexer::FmXContainerMultiplexer( ::cppu::OWeakObject
& rSource
, ::osl::Mutex
& _rMutex
)
268 :OWeakSubObject( rSource
)
269 ,OInterfaceContainerHelper( _rMutex
)
273 //------------------------------------------------------------------
274 Any SAL_CALL
FmXContainerMultiplexer::queryInterface(const Type
& _rType
) throw (RuntimeException
)
277 aReturn
= ::cppu::queryInterface(_rType
,
278 static_cast< XContainerListener
*>(this),
279 static_cast< XEventListener
*>(this)
282 if (!aReturn
.hasValue())
283 aReturn
= OWeakSubObject::queryInterface( _rType
);
288 //------------------------------------------------------------------
289 void FmXContainerMultiplexer::disposing(const EventObject
& ) throw( RuntimeException
)
292 //------------------------------------------------------------------
293 void FmXContainerMultiplexer::elementInserted(const ContainerEvent
& e
) throw( RuntimeException
)
295 ContainerEvent
aMulti( e
);
296 aMulti
.Source
= &m_rParent
;
297 notifyEach( &XContainerListener::elementInserted
, aMulti
);
300 //------------------------------------------------------------------
301 void FmXContainerMultiplexer::elementRemoved(const ContainerEvent
& e
) throw( RuntimeException
)
303 ContainerEvent
aMulti( e
);
304 aMulti
.Source
= &m_rParent
;
305 notifyEach( &XContainerListener::elementRemoved
, aMulti
);
309 //------------------------------------------------------------------
310 void FmXContainerMultiplexer::elementReplaced(const ContainerEvent
& e
) throw( RuntimeException
)
312 ContainerEvent
aMulti( e
);
313 aMulti
.Source
= &m_rParent
;
314 notifyEach( &XContainerListener::elementReplaced
, aMulti
);
317 //==================================================================
318 //= FmXGridControlMultiplexer
319 //==================================================================
320 //------------------------------------------------------------------
321 FmXGridControlMultiplexer::FmXGridControlMultiplexer( ::cppu::OWeakObject
& rSource
, ::osl::Mutex
& _rMutex
)
322 :OWeakSubObject( rSource
)
323 ,OInterfaceContainerHelper( _rMutex
)
327 //------------------------------------------------------------------
328 Any SAL_CALL
FmXGridControlMultiplexer::queryInterface(const Type
& _rType
) throw (RuntimeException
)
331 aReturn
= ::cppu::queryInterface( _rType
,
332 static_cast< XGridControlListener
*>(this)
335 if (!aReturn
.hasValue())
336 aReturn
= OWeakSubObject::queryInterface( _rType
);
341 //------------------------------------------------------------------
342 void FmXGridControlMultiplexer::disposing( const EventObject
& ) throw( RuntimeException
)
346 //------------------------------------------------------------------
347 void SAL_CALL
FmXGridControlMultiplexer::columnChanged( const EventObject
& _event
) throw (RuntimeException
)
349 EventObject
aForwardedEvent( _event
);
350 aForwardedEvent
.Source
= &m_rParent
;
351 notifyEach( &XGridControlListener::columnChanged
, aForwardedEvent
);
354 //==================================================================
356 //==================================================================
358 //------------------------------------------------------------------
359 Reference
< XInterface
> SAL_CALL
FmXGridControl_NewInstance_Impl(const Reference
< XMultiServiceFactory
>& _rxFactory
)
361 return *(new FmXGridControl(_rxFactory
));
363 DBG_NAME(FmXGridControl
)
364 //------------------------------------------------------------------------------
365 FmXGridControl::FmXGridControl(const Reference
< XMultiServiceFactory
>& _rxFactory
)
366 :m_aModifyListeners(*this, GetMutex())
367 ,m_aUpdateListeners(*this, GetMutex())
368 ,m_aContainerListeners(*this, GetMutex())
369 ,m_aSelectionListeners(*this, GetMutex())
370 ,m_aGridControlListeners(*this, GetMutex())
371 ,m_nPeerCreationLevel(0)
372 ,m_bInDraw(sal_False
)
373 ,m_xServiceFactory(_rxFactory
)
375 DBG_CTOR(FmXGridControl
,NULL
);
378 //------------------------------------------------------------------------------
379 FmXGridControl::~FmXGridControl()
381 DBG_DTOR(FmXGridControl
,NULL
);
384 //------------------------------------------------------------------
385 Any SAL_CALL
FmXGridControl::queryAggregation(const Type
& _rType
) throw (RuntimeException
)
387 Any aReturn
= FmXGridControl_BASE::queryInterface(_rType
);
389 if (!aReturn
.hasValue())
390 aReturn
= UnoControl::queryAggregation( _rType
);
394 //------------------------------------------------------------------
395 Sequence
< Type
> SAL_CALL
FmXGridControl::getTypes( ) throw(RuntimeException
)
397 return comphelper::concatSequences(UnoControl::getTypes(),FmXGridControl_BASE::getTypes());
400 //------------------------------------------------------------------
401 Sequence
<sal_Int8
> SAL_CALL
FmXGridControl::getImplementationId( ) throw(RuntimeException
)
403 static ::cppu::OImplementationId
* pId
= 0;
406 ::osl::MutexGuard
aGuard( ::osl::Mutex::getGlobalMutex() );
409 static ::cppu::OImplementationId aId
;
413 return pId
->getImplementationId();
417 //------------------------------------------------------------------------------
418 sal_Bool SAL_CALL
FmXGridControl::supportsService(const ::rtl::OUString
& ServiceName
) throw()
420 ::comphelper::StringSequence aSupported
= getSupportedServiceNames();
421 const ::rtl::OUString
* pArray
= aSupported
.getConstArray();
422 for( sal_Int32 i
= 0; i
< aSupported
.getLength(); i
++ )
423 if( pArray
[i
] == ServiceName
)
428 //------------------------------------------------------------------------------
429 ::rtl::OUString SAL_CALL
FmXGridControl::getImplementationName() throw()
431 return ::rtl::OUString::createFromAscii("com.sun.star.form.FmXGridControl");
434 //------------------------------------------------------------------------------
435 ::comphelper::StringSequence SAL_CALL
FmXGridControl::getSupportedServiceNames() throw()
437 Sequence
< ::rtl::OUString
> aServiceNames(2);
438 aServiceNames
[0] = FM_SUN_CONTROL_GRIDCONTROL
;
439 aServiceNames
[1] = ::rtl::OUString::createFromAscii("com.sun.star.awt.UnoControl");
440 return aServiceNames
;
443 //------------------------------------------------------------------------------
444 void SAL_CALL
FmXGridControl::dispose() throw( RuntimeException
)
446 ::vos::OGuard
aGuard( Application::GetSolarMutex() );
449 aEvt
.Source
= static_cast< ::cppu::OWeakObject
* >(this);
450 m_aModifyListeners
.disposeAndClear(aEvt
);
451 m_aUpdateListeners
.disposeAndClear(aEvt
);
452 m_aContainerListeners
.disposeAndClear(aEvt
);
454 UnoControl::dispose();
457 //------------------------------------------------------------------------------
458 ::rtl::OUString
FmXGridControl::GetComponentServiceName()
460 ::rtl::OUString aName
= ::rtl::OUString::createFromAscii("DBGrid");
464 //------------------------------------------------------------------------------
465 sal_Bool SAL_CALL
FmXGridControl::setModel(const Reference
< ::com::sun::star::awt::XControlModel
>& rModel
) throw( RuntimeException
)
467 ::vos::OGuard
aGuard( Application::GetSolarMutex() );
469 if (!UnoControl::setModel(rModel
))
472 Reference
< XGridPeer
> xGridPeer(getPeer(), UNO_QUERY
);
475 Reference
< XIndexContainer
> xCols(mxModel
, UNO_QUERY
);
476 xGridPeer
->setColumns(xCols
);
481 //------------------------------------------------------------------------------
482 FmXGridPeer
* FmXGridControl::imp_CreatePeer(Window
* pParent
)
484 FmXGridPeer
* pReturn
= new FmXGridPeer(m_xServiceFactory
);
486 // translate properties into WinBits
487 WinBits nStyle
= WB_TABSTOP
;
488 Reference
< XPropertySet
> xModelSet(getModel(), UNO_QUERY
);
493 if (::comphelper::getINT16(xModelSet
->getPropertyValue(FM_PROP_BORDER
)))
496 catch(const Exception
&)
498 OSL_ASSERT(!"Can not get style");
502 pReturn
->Create(pParent
, nStyle
);
506 //------------------------------------------------------------------------------
507 void SAL_CALL
FmXGridControl::createPeer(const Reference
< ::com::sun::star::awt::XToolkit
>& /*rToolkit*/, const Reference
< ::com::sun::star::awt::XWindowPeer
>& rParentPeer
) throw( RuntimeException
)
510 throw DisposedException( ::rtl::OUString(), *this );
512 DBG_ASSERT(/*(0 == m_nPeerCreationLevel) && */!mbCreatingPeer
, "FmXGridControl::createPeer : recursion!");
513 // I think this should never assert, now that we're using the base class' mbCreatingPeer in addition to
514 // our own m_nPeerCreationLevel
515 // But I'm not sure as I don't _fully_ understand the underlying toolkit implementations ....
516 // (if this asserts, we still need m_nPeerCreationLevel. If not, we could omit it ....)
517 // 14.05.2001 - 86836 - frank.schoenheit@germany.sun.com
519 // TODO: why the hell this whole class does not use any mutex?
523 mbCreatingPeer
= sal_True
;
524 // mbCreatingPeer is virtually the same as m_nPeerCreationLevel, but it's the base class' method
525 // to prevent recursion.
527 Window
* pParentWin
= NULL
;
528 if (rParentPeer
.is())
530 VCLXWindow
* pParent
= VCLXWindow::GetImplementation(rParentPeer
);
532 pParentWin
= pParent
->GetWindow();
535 FmXGridPeer
* pPeer
= imp_CreatePeer(pParentWin
);
536 DBG_ASSERT(pPeer
!= NULL
, "FmXGridControl::createPeer : imp_CreatePeer didn't return a peer !");
539 // lesen der properties aus dem model
540 // ++m_nPeerCreationLevel;
543 // folgendes unschoene Szenario : updateFromModel fuehrt zu einem propertiesChanged am Control,
544 // das stellt fest, dass sich eine 'kritische' Property geaendert hat (zum Beispiel "Border") und
545 // legt daraufhin eine neue Peer an, was wieder hier im createPeer landet, wir legen also eine
546 // zweite FmXGridPeer an und initialisieren die. Dann kommen wir in der ersten Inkarnation aus
547 // dem updsateFromModel raus und arbeiten dort weiter mit dem pPeer, das jetzt eigentlich schon
548 // veraltet ist (da ja in der zweiten Inkarnation eine andere Peer angelegt wurde).
549 // Deswegen also der Aufwand mit dem PeerCreationLevel, das stellt sicher, dass wir die in dem
550 // tiefsten Level angelegte Peer wirklich verwenden, sie aber erst im top-level
552 // if (--m_nPeerCreationLevel == 0)
554 DBG_ASSERT(getPeer().is(), "FmXGridControl::createPeer : something went wrong ... no top level peer !");
555 pPeer
= FmXGridPeer::getImplementation(getPeer());
557 setPosSize( maComponentInfos
.nX
, maComponentInfos
.nY
, maComponentInfos
.nWidth
, maComponentInfos
.nHeight
, ::com::sun::star::awt::PosSize::POSSIZE
);
559 Reference
< XIndexContainer
> xColumns(getModel(), UNO_QUERY
);
561 pPeer
->setColumns(xColumns
);
563 if (maComponentInfos
.bVisible
)
564 pPeer
->setVisible(sal_True
);
566 if (!maComponentInfos
.bEnable
)
567 pPeer
->setEnable(sal_False
);
569 if (maWindowListeners
.getLength())
570 pPeer
->addWindowListener( &maWindowListeners
);
572 if (maFocusListeners
.getLength())
573 pPeer
->addFocusListener( &maFocusListeners
);
575 if (maKeyListeners
.getLength())
576 pPeer
->addKeyListener( &maKeyListeners
);
578 if (maMouseListeners
.getLength())
579 pPeer
->addMouseListener( &maMouseListeners
);
581 if (maMouseMotionListeners
.getLength())
582 pPeer
->addMouseMotionListener( &maMouseMotionListeners
);
584 if (maPaintListeners
.getLength())
585 pPeer
->addPaintListener( &maPaintListeners
);
587 if (m_aModifyListeners
.getLength())
588 pPeer
->addModifyListener( &m_aModifyListeners
);
590 if (m_aUpdateListeners
.getLength())
591 pPeer
->addUpdateListener( &m_aUpdateListeners
);
593 if (m_aContainerListeners
.getLength())
594 pPeer
->addContainerListener( &m_aContainerListeners
);
596 // forward the design mode
597 sal_Bool bForceAlivePeer
= m_bInDraw
&& !maComponentInfos
.bVisible
;
598 // (we force a alive-mode peer if we're in "draw", cause in this case the peer will be used for drawing in
599 // foreign devices. We ensure this with the visibility check as an living peer is assumed to be noncritical
600 // only if invisible)
601 Any aOldCursorBookmark
;
602 if (!mbDesignMode
|| bForceAlivePeer
)
604 Reference
< XFormComponent
> xComp(getModel(), UNO_QUERY
);
607 Reference
< XRowSet
> xForm(xComp
->getParent(), UNO_QUERY
);
608 // is the form alive?
609 // we can see that if the form contains columns
610 Reference
< ::com::sun::star::sdbcx::XColumnsSupplier
> xColumnsSupplier(xForm
, UNO_QUERY
);
611 if (xColumnsSupplier
.is())
613 if (Reference
< XIndexAccess
> (xColumnsSupplier
->getColumns(),UNO_QUERY
)->getCount())
615 // we get only a new bookmark if the resultset is not forwardonly
616 if (::comphelper::getINT32(Reference
< XPropertySet
> (xForm
, UNO_QUERY
)->getPropertyValue(FM_PROP_RESULTSET_TYPE
)) != ResultSetType::FORWARD_ONLY
)
618 // as the FmGridControl touches the data source it is connected to we have to remember the current
619 // cursor position (and restore afterwards)
620 // OJ: but only when we stand on a valid row
621 Reference
< XResultSet
> xResultSet(xForm
, UNO_QUERY
);
622 if ( !xResultSet
->isBeforeFirst() && !xResultSet
->isAfterLast() )
626 aOldCursorBookmark
= Reference
< ::com::sun::star::sdbcx::XRowLocate
> (xForm
, UNO_QUERY
)->getBookmark();
628 catch( const Exception
& e
)
630 DBG_UNHANDLED_EXCEPTION();
637 pPeer
->setRowSet(xForm
);
640 pPeer
->setDesignMode(mbDesignMode
&& !bForceAlivePeer
);
644 if (aOldCursorBookmark
.hasValue())
645 { // we have a valid bookmark, so we have to restore the cursor's position
646 Reference
< XFormComponent
> xComp(getModel(), UNO_QUERY
);
647 Reference
< ::com::sun::star::sdbcx::XRowLocate
> xLocate(xComp
->getParent(), UNO_QUERY
);
648 xLocate
->moveToBookmark(aOldCursorBookmark
);
651 catch( const Exception
& e
)
653 DBG_UNHANDLED_EXCEPTION();
657 Reference
< ::com::sun::star::awt::XView
> xPeerView(getPeer(), UNO_QUERY
);
658 xPeerView
->setZoom( maComponentInfos
.nZoomX
, maComponentInfos
.nZoomY
);
659 xPeerView
->setGraphics( mxGraphics
);
661 mbCreatingPeer
= sal_False
;
665 //------------------------------------------------------------------------------
666 void FmXGridControl::addModifyListener(const Reference
< ::com::sun::star::util::XModifyListener
>& l
) throw( RuntimeException
)
668 m_aModifyListeners
.addInterface( l
);
669 if( getPeer().is() && m_aModifyListeners
.getLength() == 1 )
671 Reference
< ::com::sun::star::util::XModifyBroadcaster
> xGrid(getPeer(), UNO_QUERY
);
672 xGrid
->addModifyListener( &m_aModifyListeners
);
676 //------------------------------------------------------------------------------
677 sal_Bool SAL_CALL
FmXGridControl::select( const Any
& _rSelection
) throw (IllegalArgumentException
, RuntimeException
)
679 ::vos::OGuard
aGuard( Application::GetSolarMutex() );
680 Reference
< XSelectionSupplier
> xPeer(getPeer(), UNO_QUERY
);
681 return xPeer
->select(_rSelection
);
684 //------------------------------------------------------------------------------
685 Any SAL_CALL
FmXGridControl::getSelection( ) throw (RuntimeException
)
687 ::vos::OGuard
aGuard( Application::GetSolarMutex() );
688 Reference
< XSelectionSupplier
> xPeer(getPeer(), UNO_QUERY
);
689 return xPeer
->getSelection();
692 //------------------------------------------------------------------------------
693 void SAL_CALL
FmXGridControl::addSelectionChangeListener( const Reference
< XSelectionChangeListener
>& _rxListener
) throw (RuntimeException
)
695 m_aSelectionListeners
.addInterface( _rxListener
);
696 if( getPeer().is() && 1 == m_aSelectionListeners
.getLength() )
698 Reference
< XSelectionSupplier
> xGrid(getPeer(), UNO_QUERY
);
699 xGrid
->addSelectionChangeListener( &m_aSelectionListeners
);
703 //------------------------------------------------------------------------------
704 void SAL_CALL
FmXGridControl::removeSelectionChangeListener( const Reference
< XSelectionChangeListener
>& _rxListener
) throw (RuntimeException
)
706 if( getPeer().is() && 1 == m_aSelectionListeners
.getLength() )
708 Reference
< XSelectionSupplier
> xGrid(getPeer(), UNO_QUERY
);
709 xGrid
->removeSelectionChangeListener( &m_aSelectionListeners
);
711 m_aSelectionListeners
.removeInterface( _rxListener
);
714 //------------------------------------------------------------------------------
715 Sequence
< sal_Bool
> SAL_CALL
FmXGridControl::queryFieldDataType( const Type
& xType
) throw(RuntimeException
)
719 Reference
< XGridFieldDataSupplier
> xPeerSupplier(getPeer(), UNO_QUERY
);
720 if (xPeerSupplier
.is())
721 return xPeerSupplier
->queryFieldDataType(xType
);
724 return Sequence
<sal_Bool
>();
727 //------------------------------------------------------------------------------
728 Sequence
< Any
> SAL_CALL
FmXGridControl::queryFieldData( sal_Int32 nRow
, const Type
& xType
) throw(RuntimeException
)
732 Reference
< XGridFieldDataSupplier
> xPeerSupplier(getPeer(), UNO_QUERY
);
733 if (xPeerSupplier
.is())
734 return xPeerSupplier
->queryFieldData(nRow
, xType
);
737 return Sequence
< Any
>();
740 //------------------------------------------------------------------------------
741 void SAL_CALL
FmXGridControl::removeModifyListener(const Reference
< ::com::sun::star::util::XModifyListener
>& l
) throw( RuntimeException
)
743 if( getPeer().is() && m_aModifyListeners
.getLength() == 1 )
745 Reference
< ::com::sun::star::util::XModifyBroadcaster
> xGrid(getPeer(), UNO_QUERY
);
746 xGrid
->removeModifyListener( &m_aModifyListeners
);
748 m_aModifyListeners
.removeInterface( l
);
751 //------------------------------------------------------------------------------
752 void SAL_CALL
FmXGridControl::draw( sal_Int32 x
, sal_Int32 y
) throw( RuntimeException
)
754 ::vos::OGuard
aGuard( Application::GetSolarMutex() );
755 m_bInDraw
= sal_True
;
756 UnoControl::draw(x
, y
);
757 m_bInDraw
= sal_False
;
760 //------------------------------------------------------------------------------
761 void SAL_CALL
FmXGridControl::setDesignMode(sal_Bool bOn
) throw( RuntimeException
)
763 ::com::sun::star::util::ModeChangeEvent aModeChangeEvent
;
765 // --- <mutex_lock> ---
767 ::vos::OGuard
aGuard( Application::GetSolarMutex() );
769 Reference
< XRowSetSupplier
> xGrid(getPeer(), UNO_QUERY
);
771 if (xGrid
.is() && (bOn
!= mbDesignMode
|| (!bOn
&& !xGrid
->getRowSet().is())))
775 xGrid
->setRowSet(Reference
< XRowSet
> ());
779 Reference
< XFormComponent
> xComp(getModel(), UNO_QUERY
);
782 Reference
< XRowSet
> xForm(xComp
->getParent(), UNO_QUERY
);
783 xGrid
->setRowSet(xForm
);
789 Reference
< XVclWindowPeer
> xVclWindowPeer( getPeer(), UNO_QUERY
);
790 if (xVclWindowPeer
.is())
791 xVclWindowPeer
->setDesignMode(bOn
);
795 // dispose our current AccessibleContext, if we have one
796 // (changing the design mode implies having a new implementation for this context,
797 // so the old one must be declared DEFUNC)
798 disposeAccessibleContext();
800 // prepare firing an event
801 aModeChangeEvent
.Source
= *this;
802 aModeChangeEvent
.NewMode
= ::rtl::OUString::createFromAscii( mbDesignMode
? "design" : "alive" );
805 // --- </mutex_lock> ---
806 maModeChangeListeners
.notifyEach( &XModeChangeListener::modeChanged
, aModeChangeEvent
);
810 //------------------------------------------------------------------------------
811 void SAL_CALL
FmXGridControl::addUpdateListener(const Reference
< XUpdateListener
>& l
) throw( RuntimeException
)
813 m_aUpdateListeners
.addInterface( l
);
814 if( getPeer().is() && m_aUpdateListeners
.getLength() == 1 )
816 Reference
< XBoundComponent
> xBound(getPeer(), UNO_QUERY
);
817 xBound
->addUpdateListener( &m_aUpdateListeners
);
821 //------------------------------------------------------------------------------
822 void SAL_CALL
FmXGridControl::removeUpdateListener(const Reference
< XUpdateListener
>& l
) throw( RuntimeException
)
824 if( getPeer().is() && m_aUpdateListeners
.getLength() == 1 )
826 Reference
< XBoundComponent
> xBound(getPeer(), UNO_QUERY
);
827 xBound
->removeUpdateListener( &m_aUpdateListeners
);
829 m_aUpdateListeners
.removeInterface( l
);
832 //------------------------------------------------------------------------------
833 sal_Bool SAL_CALL
FmXGridControl::commit() throw( RuntimeException
)
835 Reference
< XBoundComponent
> xBound(getPeer(), UNO_QUERY
);
837 return xBound
->commit();
843 //------------------------------------------------------------------------------
844 void SAL_CALL
FmXGridControl::addContainerListener(const Reference
< XContainerListener
>& l
) throw( RuntimeException
)
846 m_aContainerListeners
.addInterface( l
);
847 if( getPeer().is() && m_aContainerListeners
.getLength() == 1 )
849 Reference
< XContainer
> xContainer(getPeer(), UNO_QUERY
);
850 xContainer
->addContainerListener( &m_aContainerListeners
);
854 //------------------------------------------------------------------------------
855 void SAL_CALL
FmXGridControl::removeContainerListener(const Reference
< XContainerListener
>& l
) throw( RuntimeException
)
857 if( getPeer().is() && m_aContainerListeners
.getLength() == 1 )
859 Reference
< XContainer
> xContainer(getPeer(), UNO_QUERY
);
860 xContainer
->removeContainerListener( &m_aContainerListeners
);
862 m_aContainerListeners
.removeInterface( l
);
865 //------------------------------------------------------------------------------
866 Reference
< ::com::sun::star::frame::XDispatch
> SAL_CALL
FmXGridControl::queryDispatch(const ::com::sun::star::util::URL
& aURL
, const ::rtl::OUString
& aTargetFrameName
, sal_Int32 nSearchFlags
) throw( RuntimeException
)
868 Reference
< ::com::sun::star::frame::XDispatchProvider
> xPeerProvider(getPeer(), UNO_QUERY
);
869 if (xPeerProvider
.is())
870 return xPeerProvider
->queryDispatch(aURL
, aTargetFrameName
, nSearchFlags
);
872 return Reference
< ::com::sun::star::frame::XDispatch
> ();
875 //------------------------------------------------------------------------------
876 Sequence
< Reference
< ::com::sun::star::frame::XDispatch
> > SAL_CALL
FmXGridControl::queryDispatches(const Sequence
< ::com::sun::star::frame::DispatchDescriptor
>& aDescripts
) throw( RuntimeException
)
878 Reference
< ::com::sun::star::frame::XDispatchProvider
> xPeerProvider(getPeer(), UNO_QUERY
);
879 if (xPeerProvider
.is())
880 return xPeerProvider
->queryDispatches(aDescripts
);
882 return Sequence
< Reference
< ::com::sun::star::frame::XDispatch
> >();
885 //------------------------------------------------------------------------------
886 void SAL_CALL
FmXGridControl::registerDispatchProviderInterceptor(const Reference
< ::com::sun::star::frame::XDispatchProviderInterceptor
>& _xInterceptor
) throw( RuntimeException
)
888 Reference
< ::com::sun::star::frame::XDispatchProviderInterception
> xPeerInterception(getPeer(), UNO_QUERY
);
889 if (xPeerInterception
.is())
890 xPeerInterception
->registerDispatchProviderInterceptor(_xInterceptor
);
893 //------------------------------------------------------------------------------
894 void SAL_CALL
FmXGridControl::releaseDispatchProviderInterceptor(const Reference
< ::com::sun::star::frame::XDispatchProviderInterceptor
>& _xInterceptor
) throw( RuntimeException
)
896 Reference
< ::com::sun::star::frame::XDispatchProviderInterception
> xPeerInterception(getPeer(), UNO_QUERY
);
897 if (xPeerInterception
.is())
898 xPeerInterception
->releaseDispatchProviderInterceptor(_xInterceptor
);
901 //------------------------------------------------------------------------------
902 void SAL_CALL
FmXGridControl::addGridControlListener( const Reference
< XGridControlListener
>& _listener
) throw( RuntimeException
)
904 ::osl::MutexGuard
aGuard( GetMutex() );
906 m_aGridControlListeners
.addInterface( _listener
);
907 if ( getPeer().is() && 1 == m_aGridControlListeners
.getLength() )
909 Reference
< XGridControl
> xPeerGrid( getPeer(), UNO_QUERY
);
910 if ( xPeerGrid
.is() )
911 xPeerGrid
->addGridControlListener( &m_aGridControlListeners
);
915 //------------------------------------------------------------------------------
916 void SAL_CALL
FmXGridControl::removeGridControlListener( const Reference
< XGridControlListener
>& _listener
) throw( RuntimeException
)
918 ::osl::MutexGuard
aGuard( GetMutex() );
920 if( getPeer().is() && 1 == m_aGridControlListeners
.getLength() )
922 Reference
< XGridControl
> xPeerGrid( getPeer(), UNO_QUERY
);
923 if ( xPeerGrid
.is() )
924 xPeerGrid
->removeGridControlListener( &m_aGridControlListeners
);
927 m_aGridControlListeners
.removeInterface( _listener
);
930 //------------------------------------------------------------------------------
931 sal_Int16 SAL_CALL
FmXGridControl::getCurrentColumnPosition() throw( RuntimeException
)
933 Reference
< XGridControl
> xGrid( getPeer(), UNO_QUERY
);
934 return xGrid
.is() ? xGrid
->getCurrentColumnPosition() : -1;
937 //------------------------------------------------------------------------------
938 void SAL_CALL
FmXGridControl::setCurrentColumnPosition(sal_Int16 nPos
) throw( RuntimeException
)
940 Reference
< XGridControl
> xGrid( getPeer(), UNO_QUERY
);
943 ::vos::OGuard
aGuard( Application::GetSolarMutex() );
944 xGrid
->setCurrentColumnPosition( nPos
);
949 //------------------------------------------------------------------------------
950 sal_Bool SAL_CALL
FmXGridControl::hasElements() throw( RuntimeException
)
952 Reference
< XElementAccess
> xPeer(getPeer(), UNO_QUERY
);
953 return xPeer
.is() ? xPeer
->hasElements() : 0;
956 //------------------------------------------------------------------------------
957 Type SAL_CALL
FmXGridControl::getElementType( ) throw(RuntimeException
)
959 return ::getCppuType((const Reference
< ::com::sun::star::awt::XTextComponent
>*)NULL
);
962 // XEnumerationAccess
963 //------------------------------------------------------------------------------
964 Reference
< XEnumeration
> SAL_CALL
FmXGridControl::createEnumeration() throw( RuntimeException
)
966 Reference
< XEnumerationAccess
> xPeer(getPeer(), UNO_QUERY
);
968 return xPeer
->createEnumeration();
970 return new ::comphelper::OEnumerationByIndex(this);
974 //------------------------------------------------------------------------------
975 sal_Int32 SAL_CALL
FmXGridControl::getCount() throw( RuntimeException
)
977 Reference
< XIndexAccess
> xPeer(getPeer(), UNO_QUERY
);
978 return xPeer
.is() ? xPeer
->getCount() : 0;
981 //------------------------------------------------------------------------------
982 Any SAL_CALL
FmXGridControl::getByIndex(sal_Int32 _nIndex
) throw( IndexOutOfBoundsException
, WrappedTargetException
, RuntimeException
)
984 Reference
< XIndexAccess
> xPeer(getPeer(), UNO_QUERY
);
986 throw IndexOutOfBoundsException();
988 return xPeer
->getByIndex(_nIndex
);
991 // ::com::sun::star::util::XModeSelector
992 //------------------------------------------------------------------------------
993 void SAL_CALL
FmXGridControl::setMode(const ::rtl::OUString
& Mode
) throw( NoSupportException
, RuntimeException
)
995 Reference
< ::com::sun::star::util::XModeSelector
> xPeer(getPeer(), UNO_QUERY
);
997 throw NoSupportException();
999 xPeer
->setMode(Mode
);
1002 //------------------------------------------------------------------------------
1003 ::rtl::OUString SAL_CALL
FmXGridControl::getMode() throw( RuntimeException
)
1005 Reference
< ::com::sun::star::util::XModeSelector
> xPeer(getPeer(), UNO_QUERY
);
1006 return xPeer
.is() ? xPeer
->getMode() : ::rtl::OUString();
1009 //------------------------------------------------------------------------------
1010 ::comphelper::StringSequence SAL_CALL
FmXGridControl::getSupportedModes() throw( RuntimeException
)
1012 Reference
< ::com::sun::star::util::XModeSelector
> xPeer(getPeer(), UNO_QUERY
);
1013 return xPeer
.is() ? xPeer
->getSupportedModes() : ::comphelper::StringSequence();
1016 //------------------------------------------------------------------------------
1017 sal_Bool SAL_CALL
FmXGridControl::supportsMode(const ::rtl::OUString
& Mode
) throw( RuntimeException
)
1019 Reference
< ::com::sun::star::util::XModeSelector
> xPeer(getPeer(), UNO_QUERY
);
1020 return xPeer
.is() ? xPeer
->supportsMode(Mode
) : sal_False
;
1023 //==============================================================================
1025 //==============================================================================
1026 // helper class which prevents that in the peer's header the FmGridListener must be known
1027 class FmXGridPeer::GridListenerDelegator
: public FmGridListener
1030 FmXGridPeer
* m_pPeer
;
1033 GridListenerDelegator( FmXGridPeer
* _pPeer
);
1036 virtual void selectionChanged();
1037 virtual void columnChanged();
1040 //------------------------------------------------------------------
1041 FmXGridPeer::GridListenerDelegator::GridListenerDelegator(FmXGridPeer
* _pPeer
)
1044 DBG_ASSERT(m_pPeer
, "GridListenerDelegator::GridListenerDelegator");
1047 //------------------------------------------------------------------
1048 void FmXGridPeer::GridListenerDelegator::selectionChanged()
1050 m_pPeer
->selectionChanged();
1053 //------------------------------------------------------------------
1054 void FmXGridPeer::GridListenerDelegator::columnChanged()
1056 m_pPeer
->columnChanged();
1059 //==============================================================================
1060 //------------------------------------------------------------------
1061 Reference
< XInterface
> FmXGridPeer_CreateInstance(const Reference
< XMultiServiceFactory
>& _rxFactory
)
1063 FmXGridPeer
* pNewObject
= new FmXGridPeer(_rxFactory
);
1064 pNewObject
->Create(NULL
, WB_TABSTOP
);
1068 //------------------------------------------------------------------
1069 Sequence
< Type
> SAL_CALL
FmXGridPeer::getTypes( ) throw(RuntimeException
)
1071 return comphelper::concatSequences( VCLXWindow::getTypes(), FmXGridPeer_BASE::getTypes() );
1074 //------------------------------------------------------------------
1075 Sequence
<sal_Int8
> SAL_CALL
FmXGridPeer::getImplementationId( ) throw(RuntimeException
)
1077 static ::cppu::OImplementationId
* pId
= 0;
1080 ::osl::MutexGuard
aGuard( ::osl::Mutex::getGlobalMutex() );
1083 static ::cppu::OImplementationId aId
;
1087 return pId
->getImplementationId();
1090 //------------------------------------------------------------------
1091 Any SAL_CALL
FmXGridPeer::queryInterface(const Type
& _rType
) throw (RuntimeException
)
1093 Any aReturn
= FmXGridPeer_BASE::queryInterface(_rType
);
1095 if (!aReturn
.hasValue())
1096 aReturn
= VCLXWindow::queryInterface( _rType
);
1101 //------------------------------------------------------------------
1102 void FmXGridPeer::selectionChanged()
1104 EventObject aSource
;
1105 aSource
.Source
= static_cast< ::cppu::OWeakObject
* >(this);
1106 m_aSelectionListeners
.notifyEach( &XSelectionChangeListener::selectionChanged
, aSource
);
1109 //------------------------------------------------------------------
1110 void FmXGridPeer::columnChanged()
1112 EventObject
aEvent( *this );
1113 m_aGridControlListeners
.notifyEach( &XGridControlListener::columnChanged
, aEvent
);
1116 //------------------------------------------------------------------
1119 const ::rtl::OUString
getDataModeIdentifier()
1121 static ::rtl::OUString s_sDataModeIdentifier
= DATA_MODE
;
1122 return s_sDataModeIdentifier
;
1125 using namespace fmgridif
;
1127 //------------------------------------------------------------------
1128 FmXGridPeer::FmXGridPeer(const Reference
< XMultiServiceFactory
>& _rxFactory
)
1129 :m_aModifyListeners(m_aMutex
)
1130 ,m_aUpdateListeners(m_aMutex
)
1131 ,m_aContainerListeners(m_aMutex
)
1132 ,m_aSelectionListeners(m_aMutex
)
1133 ,m_aGridControlListeners(m_aMutex
)
1134 ,m_aMode( getDataModeIdentifier() )
1135 ,m_nCursorListening(0)
1136 ,m_bInterceptingDispatch(sal_False
)
1137 ,m_pStateCache(NULL
)
1138 ,m_pDispatchers(NULL
)
1139 ,m_pGridListener(NULL
)
1140 ,m_xServiceFactory(_rxFactory
)
1142 // nach diesem Constructor muss Create gerufen werden !
1143 m_pGridListener
= new GridListenerDelegator( this );
1146 //------------------------------------------------------------------------------
1147 FmGridControl
* FmXGridPeer::imp_CreateControl(Window
* pParent
, WinBits nStyle
)
1149 return new FmGridControl(m_xServiceFactory
, pParent
, this, nStyle
);
1152 //------------------------------------------------------------------------------
1153 void FmXGridPeer::Create(Window
* pParent
, WinBits nStyle
)
1155 FmGridControl
* pWin
= imp_CreateControl(pParent
, nStyle
);
1156 DBG_ASSERT(pWin
!= NULL
, "FmXGridPeer::Create : imp_CreateControl didn't return a control !");
1158 pWin
->SetStateProvider(LINK(this, FmXGridPeer
, OnQueryGridSlotState
));
1159 pWin
->SetSlotExecutor(LINK(this, FmXGridPeer
, OnExecuteGridSlot
));
1161 // want to hear about row selections
1162 pWin
->setGridListener( m_pGridListener
);
1164 // Init muß immer aufgerufen werden
1166 pWin
->SetComponentInterface(this);
1171 //------------------------------------------------------------------------------
1172 FmXGridPeer::~FmXGridPeer()
1174 setRowSet(Reference
< XRowSet
> ());
1175 setColumns(Reference
< XIndexContainer
> ());
1177 delete m_pGridListener
;
1180 //------------------------------------------------------------------------------
1181 const Sequence
< sal_Int8
>& FmXGridPeer::getUnoTunnelImplementationId() throw()
1183 static Sequence
< sal_Int8
> * pSeq
= 0;
1186 ::osl::MutexGuard
aGuard( ::osl::Mutex::getGlobalMutex() );
1189 static Sequence
< sal_Int8
> aSeq( 16 );
1190 rtl_createUuid( (sal_uInt8
*)aSeq
.getArray(), 0, sal_True
);
1197 //------------------------------------------------------------------------------
1198 FmXGridPeer
* FmXGridPeer::getImplementation( const Reference
< XInterface
>& _rxIFace
) throw()
1200 FmXGridPeer
* pReturn
= NULL
;
1201 Reference
< XUnoTunnel
> xTunnel(_rxIFace
, UNO_QUERY
);
1203 pReturn
= reinterpret_cast<FmXGridPeer
*>(xTunnel
->getSomething(getUnoTunnelImplementationId()));
1208 //------------------------------------------------------------------------------
1209 sal_Int64 SAL_CALL
FmXGridPeer::getSomething( const Sequence
< sal_Int8
>& _rIdentifier
) throw(RuntimeException
)
1211 sal_Int64
nReturn(0);
1213 if ( (_rIdentifier
.getLength() == 16)
1214 && (0 == rtl_compareMemory( getUnoTunnelImplementationId().getConstArray(), _rIdentifier
.getConstArray(), 16 ))
1217 nReturn
= reinterpret_cast<sal_Int64
>(this);
1220 nReturn
= VCLXWindow::getSomething(_rIdentifier
);
1226 //------------------------------------------------------------------------------
1227 void FmXGridPeer::disposing(const EventObject
& e
) throw( RuntimeException
)
1229 using namespace ::com::sun::star::util
;
1230 bool bKnownSender
= false;
1232 Reference
< XIndexContainer
> xCols( e
.Source
, UNO_QUERY
);
1235 setColumns(Reference
< XIndexContainer
> ());
1236 bKnownSender
= true;
1239 Reference
< XRowSet
> xCursor(e
.Source
, UNO_QUERY
);
1242 setRowSet( m_xCursor
);
1244 bKnownSender
= true;
1248 if ( !bKnownSender
&& m_pDispatchers
)
1250 const Sequence
< URL
>& aSupportedURLs
= getSupportedURLs();
1251 const URL
* pSupportedURLs
= aSupportedURLs
.getConstArray();
1252 for ( sal_uInt16 i
=0; i
< ( aSupportedURLs
.getLength() ) && !bKnownSender
; ++i
, ++pSupportedURLs
)
1254 if ( m_pDispatchers
[i
] == e
.Source
)
1256 m_pDispatchers
[i
]->removeStatusListener( static_cast< ::com::sun::star::frame::XStatusListener
* >( this ), *pSupportedURLs
);
1257 m_pDispatchers
[i
] = NULL
;
1258 m_pStateCache
[i
] = 0;
1259 bKnownSender
= true;
1264 if ( !bKnownSender
)
1265 VCLXWindow::disposing(e
);
1268 //------------------------------------------------------------------------------
1269 void FmXGridPeer::addModifyListener(const Reference
< ::com::sun::star::util::XModifyListener
>& l
) throw( RuntimeException
)
1271 m_aModifyListeners
.addInterface( l
);
1274 //------------------------------------------------------------------------------
1275 void FmXGridPeer::removeModifyListener(const Reference
< ::com::sun::star::util::XModifyListener
>& l
) throw( RuntimeException
)
1277 m_aModifyListeners
.removeInterface( l
);
1280 //------------------------------------------------------------------------------
1281 #define LAST_KNOWN_TYPE FormComponentType::PATTERNFIELD
1282 Sequence
< sal_Bool
> SAL_CALL
FmXGridPeer::queryFieldDataType( const Type
& xType
) throw(RuntimeException
)
1284 // eine 'Konvertierungstabelle'
1285 static sal_Bool bCanConvert
[LAST_KNOWN_TYPE
][4] =
1287 { sal_False
, sal_False
, sal_False
, sal_False
}, // FormComponentType::CONTROL
1288 { sal_False
, sal_False
, sal_False
, sal_False
}, // FormComponentType::COMMANDBUTTON
1289 { sal_False
, sal_False
, sal_False
, sal_False
}, // FormComponentType::RADIOBUTTON
1290 { sal_False
, sal_False
, sal_False
, sal_False
}, // FormComponentType::IMAGEBUTTON
1291 { sal_False
, sal_False
, sal_False
, sal_True
}, // FormComponentType::CHECKBOX
1292 { sal_False
, sal_False
, sal_False
, sal_False
}, // FormComponentType::LISTBOX
1293 { sal_False
, sal_False
, sal_False
, sal_False
}, // FormComponentType::COMBOBOX
1294 { sal_False
, sal_False
, sal_False
, sal_False
}, // FormComponentType::GROUPBOX
1295 { sal_True
, sal_False
, sal_False
, sal_False
}, // FormComponentType::TEXTFIELD
1296 { sal_False
, sal_False
, sal_False
, sal_False
}, // FormComponentType::FIXEDTEXT
1297 { sal_False
, sal_False
, sal_False
, sal_False
}, // FormComponentType::GRIDCONTROL
1298 { sal_False
, sal_False
, sal_False
, sal_False
}, // FormComponentType::FILECONTROL
1299 { sal_False
, sal_False
, sal_False
, sal_False
}, // FormComponentType::HIDDENCONTROL
1300 { sal_False
, sal_False
, sal_False
, sal_False
}, // FormComponentType::IMAGECONTROL
1301 { sal_True
, sal_True
, sal_True
, sal_False
}, // FormComponentType::DATEFIELD
1302 { sal_True
, sal_True
, sal_False
, sal_False
}, // FormComponentType::TIMEFIELD
1303 { sal_True
, sal_True
, sal_False
, sal_False
}, // FormComponentType::NUMERICFIELD
1304 { sal_True
, sal_True
, sal_False
, sal_False
}, // FormComponentType::CURRENCYFIELD
1305 { sal_True
, sal_False
, sal_False
, sal_False
} // FormComponentType::PATTERNFIELD
1309 sal_Int16 nMapColumn
= -1;
1310 switch (xType
.getTypeClass())
1312 case TypeClass_STRING
: nMapColumn
= 0; break;
1313 case TypeClass_FLOAT
:
1314 case TypeClass_DOUBLE
: nMapColumn
= 1; break;
1315 case TypeClass_SHORT
:
1316 case TypeClass_LONG
:
1317 case TypeClass_UNSIGNED_LONG
:
1318 case TypeClass_UNSIGNED_SHORT
: nMapColumn
= 2; break;
1319 case TypeClass_BOOLEAN
: nMapColumn
= 3; break;
1324 Reference
< XIndexContainer
> xColumns
= getColumns();
1326 FmGridControl
* pGrid
= (FmGridControl
*) GetWindow();
1327 sal_Int32 nColumns
= pGrid
->GetViewColCount();
1329 DbGridColumns aColumns
= pGrid
->GetColumns();
1331 Sequence
<sal_Bool
> aReturnSequence(nColumns
);
1332 sal_Bool
* pReturnArray
= aReturnSequence
.getArray();
1334 sal_Bool bRequestedAsAny
= (xType
.getTypeClass() == TypeClass_ANY
);
1337 Reference
< ::com::sun::star::sdb::XColumn
> xFieldContent
;
1338 Reference
< XPropertySet
> xCurrentColumn
;
1339 for (sal_Int32 i
=0; i
<nColumns
; ++i
)
1341 if (bRequestedAsAny
)
1343 pReturnArray
[i
] = sal_True
;
1347 pReturnArray
[i
] = sal_False
;
1349 sal_uInt16 nModelPos
= pGrid
->GetModelColumnPos(pGrid
->GetColumnIdFromViewPos((sal_uInt16
)i
));
1350 DBG_ASSERT(nModelPos
!= (sal_uInt16
)-1, "FmXGridPeer::queryFieldDataType : no model pos !");
1352 pCol
= aColumns
.GetObject(nModelPos
);
1353 const DbGridRowRef xRow
= pGrid
->GetSeekRow();
1354 xFieldContent
= (xRow
.Is() && xRow
->HasField(pCol
->GetFieldPos())) ? xRow
->GetField(pCol
->GetFieldPos()).getColumn() : Reference
< ::com::sun::star::sdb::XColumn
> ();
1355 if (!xFieldContent
.is())
1356 // can't supply anything without a field content
1357 // FS - 07.12.99 - 54391
1360 xColumns
->getByIndex(nModelPos
) >>= xCurrentColumn
;
1361 if (!::comphelper::hasProperty(FM_PROP_CLASSID
, xCurrentColumn
))
1364 sal_Int16 nClassId
= sal_Int16();
1365 xCurrentColumn
->getPropertyValue(FM_PROP_CLASSID
) >>= nClassId
;
1366 if (nClassId
>LAST_KNOWN_TYPE
)
1368 DBG_ASSERT(nClassId
>0, "FmXGridPeer::queryFieldDataType : somebody changed the definition of the FormComponentType enum !");
1370 if (nMapColumn
!= -1)
1371 pReturnArray
[i
] = bCanConvert
[nClassId
-1][nMapColumn
];
1374 return aReturnSequence
;
1377 //------------------------------------------------------------------------------
1378 Sequence
< Any
> SAL_CALL
FmXGridPeer::queryFieldData( sal_Int32 nRow
, const Type
& xType
) throw(RuntimeException
)
1380 FmGridControl
* pGrid
= (FmGridControl
*) GetWindow();
1381 DBG_ASSERT(pGrid
&& pGrid
->IsOpen(), "FmXGridPeer::queryFieldData : have no valid grid window !");
1382 if (!pGrid
|| !pGrid
->IsOpen())
1383 return Sequence
< Any
>();
1385 // das Control zur angegebenen Row fahren
1386 if (!pGrid
->SeekRow(nRow
))
1388 throw IllegalArgumentException();
1391 // don't use GetCurrentRow as this isn't affected by the above SeekRow
1392 // FS - 30.09.99 - 68644
1393 DbGridRowRef aRow
= pGrid
->GetSeekRow();
1394 DBG_ASSERT(aRow
.Is(), "FmXGridPeer::queryFieldData : invalid current Row !");
1396 // die Columns des Controls brauche ich fuer GetFieldText
1397 DbGridColumns aColumns
= pGrid
->GetColumns();
1399 // und durch alle Spalten durch
1400 sal_Int32 nColumnCount
= pGrid
->GetViewColCount();
1402 Sequence
< Any
> aReturnSequence(nColumnCount
);
1403 Any
* pReturnArray
= aReturnSequence
.getArray();
1405 sal_Bool bRequestedAsAny
= (xType
.getTypeClass() == TypeClass_ANY
);
1406 Reference
< ::com::sun::star::sdb::XColumn
> xFieldContent
;
1408 for (sal_Int32 i
=0; i
< nColumnCount
; ++i
)
1410 sal_uInt16 nModelPos
= pGrid
->GetModelColumnPos(pGrid
->GetColumnIdFromViewPos((sal_uInt16
)i
));
1411 DBG_ASSERT(nModelPos
!= (sal_uInt16
)-1, "FmXGridPeer::queryFieldData : invalid model pos !");
1413 // don't use GetCurrentFieldValue to determine the field content as this isn't affected by the above SeekRow
1414 // FS - 30.09.99 - 68644
1415 pCol
= aColumns
.GetObject(nModelPos
);
1416 const DbGridRowRef xRow
= pGrid
->GetSeekRow();
1417 xFieldContent
= (xRow
.Is() && xRow
->HasField(pCol
->GetFieldPos())) ? xRow
->GetField(pCol
->GetFieldPos()).getColumn() : Reference
< ::com::sun::star::sdb::XColumn
> ();
1419 if (xFieldContent
.is())
1421 if (bRequestedAsAny
)
1423 Reference
< XPropertySet
> xFieldSet(xFieldContent
, UNO_QUERY
);
1424 pReturnArray
[i
] = xFieldSet
->getPropertyValue(FM_PROP_VALUE
);
1428 switch (xType
.getTypeClass())
1430 // Strings werden direkt ueber das GetFieldText abgehandelt
1431 case TypeClass_STRING
:
1433 String sText
= aColumns
.GetObject(nModelPos
)->GetCellText(aRow
, pGrid
->getNumberFormatter());
1434 pReturnArray
[i
] <<= ::rtl::OUString(sText
);
1437 // alles andere wird an der DatabaseVariant erfragt
1438 case TypeClass_FLOAT
: pReturnArray
[i
] <<= xFieldContent
->getFloat(); break;
1439 case TypeClass_DOUBLE
: pReturnArray
[i
] <<= xFieldContent
->getDouble(); break;
1440 case TypeClass_SHORT
: pReturnArray
[i
] <<= (sal_Int16
)xFieldContent
->getShort(); break;
1441 case TypeClass_LONG
: pReturnArray
[i
] <<= (sal_Int32
)xFieldContent
->getLong(); break;
1442 case TypeClass_UNSIGNED_SHORT
: pReturnArray
[i
] <<= (sal_uInt16
)xFieldContent
->getShort(); break;
1443 case TypeClass_UNSIGNED_LONG
: pReturnArray
[i
] <<= (sal_uInt32
)xFieldContent
->getLong(); break;
1444 case TypeClass_BOOLEAN
: ::comphelper::setBOOL(pReturnArray
[i
],xFieldContent
->getBoolean()); break;
1447 throw IllegalArgumentException();
1453 return aReturnSequence
;
1456 //------------------------------------------------------------------------------
1457 void FmXGridPeer::CellModified()
1460 aEvt
.Source
= static_cast< ::cppu::OWeakObject
* >(this);
1461 m_aModifyListeners
.notifyEach( &XModifyListener::modified
, aEvt
);
1464 // XPropertyChangeListener
1465 //------------------------------------------------------------------------------
1466 void FmXGridPeer::propertyChange(const PropertyChangeEvent
& evt
) throw( RuntimeException
)
1468 ::vos::OGuard
aGuard( Application::GetSolarMutex() );
1469 // want to do a lot of VCL stuff here ...
1470 // this should not be (deadlock) critical, as by definition, every component should release
1471 // any own mutexes before notifying
1473 FmGridControl
* pGrid
= (FmGridControl
*) GetWindow();
1478 Reference
< XRowSet
> xCursor(evt
.Source
, UNO_QUERY
);
1479 if (evt
.PropertyName
== FM_PROP_VALUE
|| m_xCursor
== evt
.Source
)
1480 pGrid
->propertyChange(evt
);
1481 else if (pGrid
&& m_xColumns
.is() && m_xColumns
->hasElements())
1483 // zunaechst raussuchen welche Column sich geaendert hat
1484 ::comphelper::InterfaceRef xCurrent
;
1487 for ( i
= 0; i
< m_xColumns
->getCount(); i
++)
1489 ::cppu::extractInterface(xCurrent
, m_xColumns
->getByIndex(i
));
1490 if (evt
.Source
== xCurrent
)
1494 if (i
>= m_xColumns
->getCount())
1495 // this is valid because we are listening at the cursor, too (RecordCount, -status, edit mode)
1498 sal_uInt16 nId
= pGrid
->GetColumnIdFromModelPos((sal_uInt16
)i
);
1499 sal_Bool bInvalidateColumn
= sal_False
;
1501 if (evt
.PropertyName
== FM_PROP_LABEL
)
1503 String aName
= ::comphelper::getString(evt
.NewValue
);
1504 if (aName
!= pGrid
->GetColumnTitle(nId
))
1505 pGrid
->SetColumnTitle(nId
, aName
);
1507 else if (evt
.PropertyName
== FM_PROP_WIDTH
)
1509 sal_Int32 nWidth
= 0;
1510 if (evt
.NewValue
.getValueType().getTypeClass() == TypeClass_VOID
)
1511 nWidth
= pGrid
->GetDefaultColumnWidth(pGrid
->GetColumnTitle(nId
));
1512 // GetDefaultColumnWidth already considerd the zoom factor
1515 sal_Int32 nTest
= 0;
1516 if (evt
.NewValue
>>= nTest
)
1518 nWidth
= pGrid
->LogicToPixel(Point(nTest
,0),MAP_10TH_MM
).X();
1519 // take the zoom factor into account
1520 nWidth
= pGrid
->CalcZoom(nWidth
);
1523 if (nWidth
!= (sal_Int32(pGrid
->GetColumnWidth(nId
))))
1525 if (pGrid
->IsEditing())
1527 pGrid
->DeactivateCell();
1528 pGrid
->ActivateCell();
1530 pGrid
->SetColumnWidth(nId
, nWidth
);
1533 else if (evt
.PropertyName
== FM_PROP_HIDDEN
)
1535 DBG_ASSERT(evt
.NewValue
.getValueType().getTypeClass() == TypeClass_BOOLEAN
,
1536 "FmXGridPeer::propertyChange : the property 'hidden' should be of type boolean !");
1537 if (::comphelper::getBOOL(evt
.NewValue
))
1538 pGrid
->HideColumn(nId
);
1540 pGrid
->ShowColumn(nId
);
1542 else if (evt
.PropertyName
== FM_PROP_ALIGN
)
1544 // it design mode it doesn't matter
1545 if (!isDesignMode())
1547 DbGridColumn
* pCol
= pGrid
->GetColumns().GetObject(i
);
1549 pCol
->SetAlignmentFromModel(-1);
1550 bInvalidateColumn
= sal_True
;
1553 else if (evt
.PropertyName
== FM_PROP_FORMATKEY
)
1555 if (!isDesignMode())
1556 bInvalidateColumn
= sal_True
;
1559 // need to invalidate the affected column ?
1560 if (bInvalidateColumn
)
1562 sal_Bool bWasEditing
= pGrid
->IsEditing();
1564 pGrid
->DeactivateCell();
1566 ::Rectangle aColRect
= pGrid
->GetFieldRect(nId
);
1568 aColRect
.Bottom() = pGrid
->GetSizePixel().Height();
1569 pGrid
->Invalidate(aColRect
);
1572 pGrid
->ActivateCell();
1578 //------------------------------------------------------------------------------
1579 void FmXGridPeer::addUpdateListener(const Reference
< XUpdateListener
>& l
) throw( RuntimeException
)
1581 m_aUpdateListeners
.addInterface(l
);
1584 //------------------------------------------------------------------------------
1585 void FmXGridPeer::removeUpdateListener(const Reference
< XUpdateListener
>& l
) throw( RuntimeException
)
1587 m_aUpdateListeners
.removeInterface(l
);
1590 //------------------------------------------------------------------------------
1591 sal_Bool
FmXGridPeer::commit() throw( RuntimeException
)
1593 FmGridControl
* pGrid
= (FmGridControl
*) GetWindow();
1594 if (!m_xCursor
.is() || !pGrid
)
1597 EventObject
aEvt(static_cast< ::cppu::OWeakObject
* >(this));
1598 ::cppu::OInterfaceIteratorHelper
aIter(m_aUpdateListeners
);
1599 sal_Bool bCancel
= sal_False
;
1600 while (aIter
.hasMoreElements() && !bCancel
)
1601 if ( !static_cast< XUpdateListener
* >( aIter
.next() )->approveUpdate( aEvt
) )
1605 bCancel
= !pGrid
->commit();
1608 m_aUpdateListeners
.notifyEach( &XUpdateListener::updated
, aEvt
);
1613 //------------------------------------------------------------------------------
1614 void FmXGridPeer::cursorMoved(const EventObject
& _rEvent
) throw( RuntimeException
)
1616 FmGridControl
* pGrid
= (FmGridControl
*) GetWindow();
1617 // we are not interested in move to insert row only in the resetted event
1618 // which is fired after positioning an the insert row
1619 if (pGrid
&& pGrid
->IsOpen() && !::comphelper::getBOOL(Reference
< XPropertySet
> (_rEvent
.Source
, UNO_QUERY
)->getPropertyValue(FM_PROP_ISNEW
)))
1620 pGrid
->positioned(_rEvent
);
1623 //------------------------------------------------------------------------------
1624 void FmXGridPeer::rowChanged(const EventObject
& _rEvent
) throw( RuntimeException
)
1626 FmGridControl
* pGrid
= (FmGridControl
*) GetWindow();
1627 if (pGrid
&& pGrid
->IsOpen())
1629 if (m_xCursor
->rowUpdated() && !pGrid
->IsCurrentAppending())
1630 pGrid
->RowModified(pGrid
->GetCurrentPos());
1631 else if (m_xCursor
->rowInserted())
1632 pGrid
->inserted(_rEvent
);
1636 //------------------------------------------------------------------------------
1637 void FmXGridPeer::rowSetChanged(const EventObject
& /*event*/) throw( RuntimeException
)
1639 // not interested in ...
1640 // (our parent is a form which means we get a loaded or reloaded after this rowSetChanged)
1644 //------------------------------------------------------------------------------
1645 void FmXGridPeer::loaded(const EventObject
& /*rEvent*/) throw( RuntimeException
)
1647 updateGrid(m_xCursor
);
1650 //------------------------------------------------------------------------------
1651 void FmXGridPeer::unloaded(const EventObject
& /*rEvent*/) throw( RuntimeException
)
1653 updateGrid( Reference
< XRowSet
> (NULL
) );
1656 //------------------------------------------------------------------------------
1657 void FmXGridPeer::reloading(const EventObject
& /*aEvent*/) throw( RuntimeException
)
1660 updateGrid( Reference
< XRowSet
> (NULL
) );
1663 //------------------------------------------------------------------------------
1664 void FmXGridPeer::unloading(const EventObject
& /*aEvent*/) throw( RuntimeException
)
1667 updateGrid( Reference
< XRowSet
> (NULL
) );
1670 //------------------------------------------------------------------------------
1671 void FmXGridPeer::reloaded(const EventObject
& /*aEvent*/) throw( RuntimeException
)
1673 updateGrid(m_xCursor
);
1677 //------------------------------------------------------------------------------
1678 Reference
< XIndexContainer
> FmXGridPeer::getColumns() throw( RuntimeException
)
1683 //------------------------------------------------------------------------------
1684 void FmXGridPeer::addColumnListeners(const Reference
< XPropertySet
>& xCol
)
1686 static const ::rtl::OUString aPropsListenedTo
[] =
1688 FM_PROP_LABEL
, FM_PROP_WIDTH
, FM_PROP_HIDDEN
, FM_PROP_ALIGN
, FM_PROP_FORMATKEY
1691 // as not all properties have to be supported by all columns we have to check this
1692 // before adding a listener
1693 Reference
< XPropertySetInfo
> xInfo
= xCol
->getPropertySetInfo();
1695 const ::rtl::OUString
* pProps
= aPropsListenedTo
;
1696 const ::rtl::OUString
* pPropsEnd
= pProps
+ sizeof( aPropsListenedTo
) / sizeof( aPropsListenedTo
[ 0 ] );
1697 for (; pProps
!= pPropsEnd
; ++pProps
)
1699 if ( xInfo
->hasPropertyByName( *pProps
) )
1701 aPropDesc
= xInfo
->getPropertyByName( *pProps
);
1702 if ( 0 != ( aPropDesc
.Attributes
& PropertyAttribute::BOUND
) )
1703 xCol
->addPropertyChangeListener( *pProps
, this );
1708 //------------------------------------------------------------------------------
1709 void FmXGridPeer::removeColumnListeners(const Reference
< XPropertySet
>& xCol
)
1711 // the same props as in addColumnListeners ... linux has problems with global static UStrings, so
1712 // we have to do it this way ....
1713 static ::rtl::OUString aPropsListenedTo
[] =
1715 FM_PROP_LABEL
, FM_PROP_WIDTH
, FM_PROP_HIDDEN
, FM_PROP_ALIGN
, FM_PROP_FORMATKEY
1718 Reference
< XPropertySetInfo
> xInfo
= xCol
->getPropertySetInfo();
1719 for (sal_uInt16 i
=0; i
<sizeof(aPropsListenedTo
)/sizeof(aPropsListenedTo
[0]); ++i
)
1720 if (xInfo
->hasPropertyByName(aPropsListenedTo
[i
]))
1721 xCol
->removePropertyChangeListener(aPropsListenedTo
[i
], this);
1724 //------------------------------------------------------------------------------
1725 void FmXGridPeer::setColumns(const Reference
< XIndexContainer
>& Columns
) throw( RuntimeException
)
1727 FmGridControl
* pGrid
= static_cast< FmGridControl
* >( GetWindow() );
1729 if (m_xColumns
.is())
1731 Reference
< XPropertySet
> xCol
;
1732 for (sal_Int32 i
= 0; i
< m_xColumns
->getCount(); i
++)
1734 ::cppu::extractInterface(xCol
, m_xColumns
->getByIndex(i
));
1735 removeColumnListeners(xCol
);
1737 Reference
< XContainer
> xContainer(m_xColumns
, UNO_QUERY
);
1738 xContainer
->removeContainerListener(this);
1740 Reference
< XSelectionSupplier
> xSelSupplier(m_xColumns
, UNO_QUERY
);
1741 xSelSupplier
->removeSelectionChangeListener(this);
1743 Reference
< XReset
> xColumnReset(m_xColumns
, UNO_QUERY
);
1744 if (xColumnReset
.is())
1745 xColumnReset
->removeResetListener((XResetListener
*)this);
1749 Reference
< XContainer
> xContainer(Columns
, UNO_QUERY
);
1750 xContainer
->addContainerListener(this);
1752 Reference
< XSelectionSupplier
> xSelSupplier(Columns
, UNO_QUERY
);
1753 xSelSupplier
->addSelectionChangeListener(this);
1755 Reference
< XPropertySet
> xCol
;
1756 for (sal_Int32 i
= 0; i
< Columns
->getCount(); i
++)
1758 ::cppu::extractInterface(xCol
, Columns
->getByIndex(i
));
1759 addColumnListeners(xCol
);
1762 Reference
< XReset
> xColumnReset(Columns
, UNO_QUERY
);
1763 if (xColumnReset
.is())
1764 xColumnReset
->addResetListener((XResetListener
*)this);
1766 m_xColumns
= Columns
;
1769 pGrid
->InitColumnsByModels(m_xColumns
);
1771 if (m_xColumns
.is())
1773 EventObject
aEvt(m_xColumns
);
1774 selectionChanged(aEvt
);
1779 //------------------------------------------------------------------------------
1780 void FmXGridPeer::setDesignMode(sal_Bool bOn
) throw( RuntimeException
)
1782 if (bOn
!= isDesignMode())
1784 Window
* pWin
= GetWindow();
1786 ((FmGridControl
*) pWin
)->SetDesignMode(bOn
);
1790 DisConnectFromDispatcher();
1792 UpdateDispatches(); // will connect if not already connected and just update else
1795 //------------------------------------------------------------------------------
1796 sal_Bool
FmXGridPeer::isDesignMode() throw( RuntimeException
)
1798 Window
* pWin
= GetWindow();
1800 return ((FmGridControl
*) pWin
)->IsDesignMode();
1805 //------------------------------------------------------------------------------
1806 void FmXGridPeer::elementInserted(const ContainerEvent
& evt
) throw( RuntimeException
)
1808 ::vos::OGuard
aGuard( Application::GetSolarMutex() );
1810 FmGridControl
* pGrid
= (FmGridControl
*) GetWindow();
1811 // Handle Column beruecksichtigen
1812 if (!pGrid
|| !m_xColumns
.is() || pGrid
->IsInColumnMove() || m_xColumns
->getCount() == ((sal_Int32
)pGrid
->GetModelColCount()))
1815 Reference
< XPropertySet
> xSet
;
1816 ::cppu::extractInterface(xSet
, evt
.Element
);
1817 addColumnListeners(xSet
);
1819 Reference
< XPropertySet
> xNewColumn(xSet
);
1820 String aName
= ::comphelper::getString(xNewColumn
->getPropertyValue(FM_PROP_LABEL
));
1821 Any aWidth
= xNewColumn
->getPropertyValue(FM_PROP_WIDTH
);
1822 sal_Int32 nWidth
= 0;
1823 if (aWidth
>>= nWidth
)
1824 nWidth
= pGrid
->LogicToPixel(Point(nWidth
,0),MAP_10TH_MM
).X();
1826 pGrid
->AppendColumn(aName
, (sal_uInt16
)nWidth
, (sal_Int16
)::comphelper::getINT32(evt
.Accessor
));
1828 // jetzt die Spalte setzen
1829 DbGridColumn
* pCol
= pGrid
->GetColumns().GetObject(::comphelper::getINT32(evt
.Accessor
));
1830 pCol
->setModel(xNewColumn
);
1832 Any aHidden
= xNewColumn
->getPropertyValue(FM_PROP_HIDDEN
);
1833 if (::comphelper::getBOOL(aHidden
))
1834 pGrid
->HideColumn(pCol
->GetId());
1836 FormControlFactory( m_xServiceFactory
).initializeTextFieldLineEnds( xNewColumn
);
1839 //------------------------------------------------------------------------------
1840 void FmXGridPeer::elementReplaced(const ContainerEvent
& evt
) throw( RuntimeException
)
1842 ::vos::OGuard
aGuard( Application::GetSolarMutex() );
1844 FmGridControl
* pGrid
= (FmGridControl
*) GetWindow();
1846 // Handle Column beruecksichtigen
1847 if (!pGrid
|| !m_xColumns
.is() || pGrid
->IsInColumnMove())
1850 Reference
< XPropertySet
> xNewColumn
;
1851 Reference
< XPropertySet
> xOldColumn
;
1852 ::cppu::extractInterface(xNewColumn
, evt
.Element
);
1853 ::cppu::extractInterface(xOldColumn
, evt
.ReplacedElement
);
1855 sal_Bool bWasEditing
= pGrid
->IsEditing();
1857 pGrid
->DeactivateCell();
1859 pGrid
->RemoveColumn(pGrid
->GetColumnIdFromModelPos((sal_uInt16
)::comphelper::getINT32(evt
.Accessor
)));
1861 removeColumnListeners(xOldColumn
);
1862 addColumnListeners(xNewColumn
);
1864 String aName
= ::comphelper::getString(xNewColumn
->getPropertyValue(FM_PROP_LABEL
));
1865 Any aWidth
= xNewColumn
->getPropertyValue(FM_PROP_WIDTH
);
1866 sal_Int32 nWidth
= 0;
1867 if (aWidth
>>= nWidth
)
1868 nWidth
= pGrid
->LogicToPixel(Point(nWidth
,0),MAP_10TH_MM
).X();
1869 sal_uInt16 nNewId
= pGrid
->AppendColumn(aName
, (sal_uInt16
)nWidth
, (sal_Int16
)::comphelper::getINT32(evt
.Accessor
));
1870 sal_uInt16 nNewPos
= pGrid
->GetModelColumnPos(nNewId
);
1872 // set the model of the new column
1873 DbGridColumn
* pCol
= pGrid
->GetColumns().GetObject(nNewPos
);
1875 // for initializong this grid column, we need the fields of the grid's data source
1876 Reference
< XColumnsSupplier
> xSuppColumns
;
1877 CursorWrapper
* pGridDataSource
= pGrid
->getDataSource();
1878 if ( pGridDataSource
)
1879 xSuppColumns
= xSuppColumns
.query( (Reference
< XInterface
>)( *pGridDataSource
) );
1880 Reference
< XNameAccess
> xColumnsByName
;
1881 if ( xSuppColumns
.is() )
1882 xColumnsByName
= xSuppColumns
->getColumns();
1883 Reference
< XIndexAccess
> xColumnsByIndex( xColumnsByName
, UNO_QUERY
);
1885 if ( xColumnsByIndex
.is() )
1886 pGrid
->InitColumnByField( pCol
, xNewColumn
, xColumnsByName
, xColumnsByIndex
);
1888 // the simple version, applies when the grid is not yet connected to a data source
1889 pCol
->setModel(xNewColumn
);
1892 pGrid
->ActivateCell();
1895 //------------------------------------------------------------------------------
1896 void FmXGridPeer::elementRemoved(const ContainerEvent
& evt
) throw( RuntimeException
)
1898 ::vos::OGuard
aGuard( Application::GetSolarMutex() );
1900 FmGridControl
* pGrid
= (FmGridControl
*) GetWindow();
1902 // Handle Column beruecksichtigen
1903 if (!pGrid
|| !m_xColumns
.is() || pGrid
->IsInColumnMove() || m_xColumns
->getCount() == ((sal_Int32
)pGrid
->GetModelColCount()))
1906 pGrid
->RemoveColumn(pGrid
->GetColumnIdFromModelPos((sal_uInt16
)::comphelper::getINT32(evt
.Accessor
)));
1908 Reference
< XPropertySet
> xOldColumn
;
1909 ::cppu::extractInterface(xOldColumn
, evt
.Element
);
1910 removeColumnListeners(xOldColumn
);
1913 //------------------------------------------------------------------------------
1914 void FmXGridPeer::setProperty( const ::rtl::OUString
& PropertyName
, const Any
& Value
) throw( RuntimeException
)
1916 ::vos::OGuard
aGuard( Application::GetSolarMutex() );
1918 FmGridControl
* pGrid
= (FmGridControl
*) GetWindow();
1920 sal_Bool bVoid
= !Value
.hasValue();
1922 if ( 0 == PropertyName
.compareTo( FM_PROP_TEXTLINECOLOR
) )
1924 ::Color
aTextLineColor( bVoid
? COL_TRANSPARENT
: ::comphelper::getINT32( Value
) );
1927 pGrid
->SetTextLineColor();
1928 pGrid
->GetDataWindow().SetTextLineColor();
1932 pGrid
->SetTextLineColor(aTextLineColor
);
1933 pGrid
->GetDataWindow().SetTextLineColor(aTextLineColor
);
1936 // need to forward this to the columns
1937 DbGridColumns
& rColumns
= const_cast<DbGridColumns
&>(pGrid
->GetColumns());
1938 DbGridColumn
* pLoop
= rColumns
.First();
1941 FmXGridCell
* pXCell
= pLoop
->GetCell();
1945 pXCell
->SetTextLineColor();
1947 pXCell
->SetTextLineColor(aTextLineColor
);
1950 pLoop
= rColumns
.Next();
1954 pGrid
->Invalidate();
1956 else if ( 0 == PropertyName
.compareTo( FM_PROP_FONTEMPHASISMARK
) )
1958 Font aGridFont
= pGrid
->GetControlFont();
1959 sal_Int16 nValue
= ::comphelper::getINT16(Value
);
1960 aGridFont
.SetEmphasisMark( nValue
);
1961 pGrid
->SetControlFont( aGridFont
);
1963 else if ( 0 == PropertyName
.compareTo( FM_PROP_FONTRELIEF
) )
1965 Font aGridFont
= pGrid
->GetControlFont();
1966 sal_Int16 nValue
= ::comphelper::getINT16(Value
);
1967 aGridFont
.SetRelief( (FontRelief
)nValue
);
1968 pGrid
->SetControlFont( aGridFont
);
1970 else if ( 0 == PropertyName
.compareTo( FM_PROP_HELPURL
) )
1972 String
sHelpURL(::comphelper::getString(Value
));
1974 sPattern
.AssignAscii("HID:");
1975 if (sHelpURL
.Equals(sPattern
, 0, sPattern
.Len()))
1977 String sID
= sHelpURL
.Copy(sPattern
.Len());
1978 pGrid
->SetHelpId(sID
.ToInt32());
1981 else if ( 0 == PropertyName
.compareTo( FM_PROP_DISPLAYSYNCHRON
) )
1983 pGrid
->setDisplaySynchron(::comphelper::getBOOL(Value
));
1985 else if ( 0 == PropertyName
.compareTo( FM_PROP_CURSORCOLOR
) )
1988 pGrid
->SetCursorColor(COL_TRANSPARENT
);
1990 pGrid
->SetCursorColor( ::Color(::comphelper::getINT32(Value
)));
1992 pGrid
->Invalidate();
1994 else if ( 0 == PropertyName
.compareTo( FM_PROP_ALWAYSSHOWCURSOR
) )
1996 pGrid
->EnablePermanentCursor(::comphelper::getBOOL(Value
));
1998 pGrid
->Invalidate();
2000 else if ( 0 == PropertyName
.compareTo( FM_PROP_FONT
) )
2003 pGrid
->SetControlFont( Font() );
2006 ::com::sun::star::awt::FontDescriptor aFont
;
2007 if (Value
>>= aFont
)
2010 if (::comphelper::operator!=(aFont
, ::comphelper::getDefaultFont())) // ist das der Default
2011 aNewVclFont
= ImplCreateFont( aFont
);
2013 // need to add relief and emphasis (they're stored in a VCL-Font, but not in a FontDescriptor
2014 Font aOldVclFont
= pGrid
->GetControlFont();
2015 aNewVclFont
.SetRelief( aOldVclFont
.GetRelief() );
2016 aNewVclFont
.SetEmphasisMark( aOldVclFont
.GetEmphasisMark() );
2019 pGrid
->SetControlFont( aNewVclFont
);
2021 // if our row-height property is void (which means "calculate it font-dependent") we have
2022 // to adjust the control's row height
2023 Reference
< XPropertySet
> xModelSet(getColumns(), UNO_QUERY
);
2024 if (xModelSet
.is() && ::comphelper::hasProperty(FM_PROP_ROWHEIGHT
, xModelSet
))
2026 Any aHeight
= xModelSet
->getPropertyValue(FM_PROP_ROWHEIGHT
);
2027 if (!aHeight
.hasValue())
2028 pGrid
->SetDataRowHeight(0);
2034 else if ( 0 == PropertyName
.compareTo( FM_PROP_BACKGROUNDCOLOR
) )
2038 pGrid
->SetControlBackground();
2042 ::Color
aColor( ::comphelper::getINT32(Value
) );
2043 pGrid
->SetBackground( aColor
);
2044 pGrid
->SetControlBackground( aColor
);
2047 else if ( 0 == PropertyName
.compareTo( FM_PROP_TEXTCOLOR
) )
2051 pGrid
->SetControlForeground();
2055 ::Color
aColor( ::comphelper::getINT32(Value
) );
2056 pGrid
->SetTextColor( aColor
);
2057 pGrid
->SetControlForeground( aColor
);
2060 else if ( 0 == PropertyName
.compareTo( FM_PROP_ROWHEIGHT
) )
2062 sal_Int32
nLogHeight(0);
2063 if (Value
>>= nLogHeight
)
2065 sal_Int32 nHeight
= pGrid
->LogicToPixel(Point(0,nLogHeight
),MAP_10TH_MM
).Y();
2066 // take the zoom factor into account
2067 nHeight
= pGrid
->CalcZoom(nHeight
);
2068 pGrid
->SetDataRowHeight(nHeight
);
2071 pGrid
->SetDataRowHeight(0);
2073 else if ( 0 == PropertyName
.compareTo( FM_PROP_HASNAVIGATION
) )
2075 if (Value
.getValueType() == ::getBooleanCppuType())
2076 pGrid
->EnableNavigationBar(*(sal_Bool
*)Value
.getValue());
2078 else if ( 0 == PropertyName
.compareTo( FM_PROP_RECORDMARKER
) )
2080 if (Value
.getValueType() == ::getBooleanCppuType())
2081 pGrid
->EnableHandle(*(sal_Bool
*)Value
.getValue());
2083 else if ( 0 == PropertyName
.compareTo( FM_PROP_ENABLED
) )
2085 if (Value
.getValueType() == ::getBooleanCppuType())
2087 // Im DesignModus nur das Datenfenster disablen
2088 // Sonst kann das Control nicht mehr konfiguriert werden
2090 pGrid
->GetDataWindow().Enable(*(sal_Bool
*)Value
.getValue());
2092 pGrid
->Enable(*(sal_Bool
*)Value
.getValue());
2096 VCLXWindow::setProperty( PropertyName
, Value
);
2099 //------------------------------------------------------------------------------
2100 Reference
< XAccessibleContext
> FmXGridPeer::CreateAccessibleContext()
2102 Reference
< XAccessibleContext
> xContext
;
2104 // use the AccessibleContext provided by the VCL window
2105 Window
* pGrid
= GetWindow();
2108 Reference
< XAccessible
> xAcc( pGrid
->GetAccessible( TRUE
) );
2110 xContext
= xAcc
->getAccessibleContext();
2111 // TODO: this has a slight conceptual problem:
2113 // We know that the XAccessible and XAccessibleContext implementation of the browse
2114 // box is the same (the class implements both interfaces), which, speaking strictly,
2115 // is bad here (means when a browse box acts as UnoControl): We (the FmXGridPeer) are
2116 // the XAccessible here, and the browse box should be able to provide us an XAccessibleContext,
2117 // but it should _not_ be the XAccessible itself.
2118 // However, as long as no client implementation uses dirty hacks such as querying an
2119 // XAccessibleContext for XAccessible, this should not be a problem.
2122 if ( !xContext
.is() )
2123 xContext
= VCLXWindow::CreateAccessibleContext( );
2128 //------------------------------------------------------------------------------
2129 Any
FmXGridPeer::getProperty( const ::rtl::OUString
& _rPropertyName
) throw( RuntimeException
)
2134 FmGridControl
* pGrid
= (FmGridControl
*) GetWindow();
2135 Window
* pDataWindow
= &pGrid
->GetDataWindow();
2137 if ( 0 == _rPropertyName
.compareTo( FM_PROP_NAME
) )
2139 Font aFont
= pDataWindow
->GetControlFont();
2140 aProp
<<= ImplCreateFontDescriptor( aFont
);
2142 else if ( 0 == _rPropertyName
.compareTo( FM_PROP_TEXTCOLOR
) )
2144 aProp
<<= (sal_Int32
)pDataWindow
->GetControlForeground().GetColor();
2146 else if ( 0 == _rPropertyName
.compareTo( FM_PROP_BACKGROUNDCOLOR
) )
2148 aProp
<<= (sal_Int32
)pDataWindow
->GetControlBackground().GetColor();
2150 else if ( 0 == _rPropertyName
.compareTo( FM_PROP_ROWHEIGHT
) )
2152 sal_Int32 nPixelHeight
= pGrid
->GetDataRowHeight();
2153 // take the zoom factor into account
2154 nPixelHeight
= pGrid
->CalcReverseZoom(nPixelHeight
);
2155 aProp
<<= (sal_Int32
)pGrid
->PixelToLogic(Point(0,nPixelHeight
),MAP_10TH_MM
).Y();
2157 else if ( 0 == _rPropertyName
.compareTo( FM_PROP_HASNAVIGATION
) )
2159 sal_Bool bHasNavBar
= pGrid
->HasNavigationBar();
2160 aProp
<<= (sal_Bool
)bHasNavBar
;
2162 else if ( 0 == _rPropertyName
.compareTo( FM_PROP_RECORDMARKER
) )
2164 sal_Bool bHasHandle
= pGrid
->HasHandle();
2165 aProp
<<= (sal_Bool
)bHasHandle
;
2167 else if ( 0 == _rPropertyName
.compareTo( FM_PROP_ENABLED
) )
2169 aProp
<<= (sal_Bool
)pDataWindow
->IsEnabled();
2172 aProp
= VCLXWindow::getProperty( _rPropertyName
);
2177 //------------------------------------------------------------------------------
2178 void FmXGridPeer::dispose() throw( RuntimeException
)
2181 aEvt
.Source
= static_cast< ::cppu::OWeakObject
* >(this);
2182 m_aModifyListeners
.disposeAndClear(aEvt
);
2183 m_aUpdateListeners
.disposeAndClear(aEvt
);
2184 m_aContainerListeners
.disposeAndClear(aEvt
);
2185 VCLXWindow::dispose();
2187 // release all interceptors
2188 // discovered during #100312# - 2002-10-23 - fs@openoffice.org
2189 Reference
< XDispatchProviderInterceptor
> xInterceptor( m_xFirstDispatchInterceptor
);
2190 m_xFirstDispatchInterceptor
.clear();
2191 while ( xInterceptor
.is() )
2193 // tell the interceptor it has a new (means no) predecessor
2194 xInterceptor
->setMasterDispatchProvider( NULL
);
2196 // ask for it's successor
2197 Reference
< XDispatchProvider
> xSlave
= xInterceptor
->getSlaveDispatchProvider();
2198 // and give it the new (means no) successoert
2199 xInterceptor
->setSlaveDispatchProvider( NULL
);
2201 // start over with the next chain element
2202 xInterceptor
= xInterceptor
.query( xSlave
);
2205 DisConnectFromDispatcher();
2206 setRowSet(Reference
< XRowSet
> ());
2210 //------------------------------------------------------------------------------
2211 void FmXGridPeer::addContainerListener(const Reference
< XContainerListener
>& l
) throw( RuntimeException
)
2213 m_aContainerListeners
.addInterface( l
);
2215 //------------------------------------------------------------------------------
2216 void FmXGridPeer::removeContainerListener(const Reference
< XContainerListener
>& l
) throw( RuntimeException
)
2218 m_aContainerListeners
.removeInterface( l
);
2221 // ::com::sun::star::data::XDatabaseCursorSupplier
2222 //------------------------------------------------------------------------------
2223 void FmXGridPeer::startCursorListening()
2225 if (!m_nCursorListening
)
2227 Reference
< XRowSet
> xRowSet(m_xCursor
, UNO_QUERY
);
2229 xRowSet
->addRowSetListener(this);
2231 Reference
< XReset
> xReset(m_xCursor
, UNO_QUERY
);
2233 xReset
->addResetListener(this);
2235 // alle Listener anmelden
2236 Reference
< XPropertySet
> xSet(m_xCursor
, UNO_QUERY
);
2239 xSet
->addPropertyChangeListener(FM_PROP_ISMODIFIED
, this);
2240 xSet
->addPropertyChangeListener(FM_PROP_ROWCOUNT
, this);
2243 m_nCursorListening
++;
2246 //------------------------------------------------------------------------------
2247 void FmXGridPeer::stopCursorListening()
2249 if (!--m_nCursorListening
)
2251 Reference
< XRowSet
> xRowSet(m_xCursor
, UNO_QUERY
);
2253 xRowSet
->removeRowSetListener(this);
2255 Reference
< XReset
> xReset(m_xCursor
, UNO_QUERY
);
2257 xReset
->removeResetListener(this);
2259 Reference
< XPropertySet
> xSet(m_xCursor
, UNO_QUERY
);
2262 xSet
->removePropertyChangeListener(FM_PROP_ISMODIFIED
, this);
2263 xSet
->removePropertyChangeListener(FM_PROP_ROWCOUNT
, this);
2268 //------------------------------------------------------------------------------
2269 void FmXGridPeer::updateGrid(const Reference
< XRowSet
>& _rxCursor
)
2271 FmGridControl
* pGrid
= (FmGridControl
*)GetWindow();
2273 pGrid
->setDataSource(_rxCursor
);
2276 //------------------------------------------------------------------------------
2277 Reference
< XRowSet
> FmXGridPeer::getRowSet() throw( RuntimeException
)
2282 //------------------------------------------------------------------------------
2283 void FmXGridPeer::setRowSet(const Reference
< XRowSet
>& _rDatabaseCursor
) throw( RuntimeException
)
2285 FmGridControl
* pGrid
= (FmGridControl
*) GetWindow();
2286 if (!pGrid
|| !m_xColumns
.is() || !m_xColumns
->getCount())
2288 // alle Listener abmelden
2291 Reference
< XLoadable
> xLoadable(m_xCursor
, UNO_QUERY
);
2292 // only if the form is loaded we set the rowset
2295 stopCursorListening();
2296 xLoadable
->removeLoadListener(this);
2300 m_xCursor
= _rDatabaseCursor
;
2304 Reference
< XLoadable
> xLoadable(m_xCursor
, UNO_QUERY
);
2305 // only if the form is loaded we set the rowset
2306 if (xLoadable
.is() && xLoadable
->isLoaded())
2307 pGrid
->setDataSource(m_xCursor
);
2309 pGrid
->setDataSource(Reference
< XRowSet
> ());
2313 startCursorListening();
2314 xLoadable
->addLoadListener(this);
2319 //------------------------------------------------------------------------------
2320 void SAL_CALL
FmXGridPeer::addGridControlListener( const Reference
< XGridControlListener
>& _listener
) throw( RuntimeException
)
2322 m_aGridControlListeners
.addInterface( _listener
);
2325 //------------------------------------------------------------------------------
2326 void SAL_CALL
FmXGridPeer::removeGridControlListener( const Reference
< XGridControlListener
>& _listener
) throw( RuntimeException
)
2328 m_aGridControlListeners
.removeInterface( _listener
);
2331 //------------------------------------------------------------------------------
2332 sal_Int16
FmXGridPeer::getCurrentColumnPosition() throw( RuntimeException
)
2334 FmGridControl
* pGrid
= (FmGridControl
*) GetWindow();
2335 return pGrid
? pGrid
->GetViewColumnPos(pGrid
->GetCurColumnId()) : -1;
2338 //------------------------------------------------------------------------------
2339 void FmXGridPeer::setCurrentColumnPosition(sal_Int16 nPos
) throw( RuntimeException
)
2341 FmGridControl
* pGrid
= (FmGridControl
*) GetWindow();
2343 pGrid
->GoToColumnId(pGrid
->GetColumnIdFromViewPos(nPos
));
2346 //------------------------------------------------------------------------------
2347 void FmXGridPeer::selectionChanged(const EventObject
& evt
) throw( RuntimeException
)
2349 ::vos::OGuard
aGuard(Application::GetSolarMutex());
2351 FmGridControl
* pGrid
= (FmGridControl
*) GetWindow();
2354 Reference
< ::com::sun::star::view::XSelectionSupplier
> xSelSupplier(evt
.Source
, UNO_QUERY
);
2355 Any aSelection
= xSelSupplier
->getSelection();
2356 DBG_ASSERT(aSelection
.getValueType().getTypeClass() == TypeClass_INTERFACE
, "FmXGridPeer::selectionChanged : invalid selection !");
2357 Reference
< XPropertySet
> xSelection
;
2358 aSelection
>>= xSelection
;
2359 if (xSelection
.is())
2361 Reference
< XPropertySet
> xCol
;
2363 sal_Int32 nColCount
= m_xColumns
->getCount();
2365 for (; i
< nColCount
; ++i
)
2367 m_xColumns
->getByIndex(i
) >>= xCol
;
2368 if ( xCol
== xSelection
)
2370 pGrid
->markColumn(pGrid
->GetColumnIdFromModelPos((sal_uInt16
)i
));
2374 // fuer das VCL-Control muessen die Columns 1-basiert sein
2375 // die Selektion an das VCL-Control weiterreichen, wenn noetig
2376 if ( i
!= pGrid
->GetSelectedColumn() )
2377 { // (wenn das nicht greift, wurde das selectionChanged implizit von dem Control selber ausgeloest
2378 if ( i
< nColCount
)
2380 pGrid
->SelectColumnPos(pGrid
->GetViewColumnPos(pGrid
->GetColumnIdFromModelPos( (sal_uInt16
)i
)) + 1, sal_True
);
2381 // SelectColumnPos hat wieder zu einem impliziten ActivateCell gefuehrt
2382 if (pGrid
->IsEditing())
2383 pGrid
->DeactivateCell();
2386 pGrid
->SetNoSelection();
2390 pGrid
->markColumn(USHRT_MAX
);
2395 //------------------------------------------------------------------------------
2396 sal_Bool
FmXGridPeer::hasElements() throw( RuntimeException
)
2398 return getCount() != 0;
2401 //------------------------------------------------------------------------------
2402 Type SAL_CALL
FmXGridPeer::getElementType( ) throw(RuntimeException
)
2404 return ::getCppuType((Reference
< ::com::sun::star::awt::XControl
> *)NULL
);
2407 // XEnumerationAccess
2408 //------------------------------------------------------------------------------
2409 Reference
< XEnumeration
> FmXGridPeer::createEnumeration() throw( RuntimeException
)
2411 return new ::comphelper::OEnumerationByIndex(this);
2415 //------------------------------------------------------------------------------
2416 sal_Int32
FmXGridPeer::getCount() throw( RuntimeException
)
2418 FmGridControl
* pGrid
= (FmGridControl
*) GetWindow();
2420 return pGrid
->GetViewColCount();
2425 //------------------------------------------------------------------------------
2426 Any
FmXGridPeer::getByIndex(sal_Int32 _nIndex
) throw( IndexOutOfBoundsException
, WrappedTargetException
, RuntimeException
)
2428 FmGridControl
* pGrid
= (FmGridControl
*) GetWindow();
2430 _nIndex
>= getCount() || !pGrid
)
2431 throw IndexOutOfBoundsException();
2435 sal_uInt16 nId
= pGrid
->GetColumnIdFromViewPos((sal_uInt16
)_nIndex
);
2436 // get the list position
2437 sal_uInt16 nPos
= pGrid
->GetModelColumnPos(nId
);
2439 DbGridColumn
* pCol
= pGrid
->GetColumns().GetObject(nPos
);
2440 // DBG_ASSERT(pCol && pCol->GetCell(), "FmXGridPeer::getByIndex(): Invalid cell");
2441 Reference
< ::com::sun::star::awt::XControl
> xControl(pCol
->GetCell());
2442 aElement
<<= xControl
;
2447 // ::com::sun::star::util::XModeSelector
2448 //------------------------------------------------------------------------------
2449 void FmXGridPeer::setMode(const ::rtl::OUString
& Mode
) throw( NoSupportException
, RuntimeException
)
2451 if (!supportsMode(Mode
))
2452 throw NoSupportException();
2454 if (Mode
== m_aMode
)
2459 FmGridControl
* pGrid
= (FmGridControl
*) GetWindow();
2460 if (Mode
== FILTER_MODE
)
2461 pGrid
->SetFilterMode(sal_True
);
2464 pGrid
->SetFilterMode(sal_False
);
2465 pGrid
->setDataSource(m_xCursor
);
2469 //------------------------------------------------------------------------------
2470 ::rtl::OUString
FmXGridPeer::getMode() throw( RuntimeException
)
2475 //------------------------------------------------------------------------------
2476 ::comphelper::StringSequence
FmXGridPeer::getSupportedModes() throw( RuntimeException
)
2478 static ::comphelper::StringSequence aModes
;
2479 if (!aModes
.getLength())
2482 ::rtl::OUString
* pModes
= aModes
.getArray();
2483 pModes
[0] = DATA_MODE
;
2484 pModes
[1] = FILTER_MODE
;
2489 //------------------------------------------------------------------------------
2490 sal_Bool
FmXGridPeer::supportsMode(const ::rtl::OUString
& Mode
) throw( RuntimeException
)
2492 ::comphelper::StringSequence
aModes(getSupportedModes());
2493 const ::rtl::OUString
* pModes
= aModes
.getConstArray();
2494 for (sal_Int32 i
= aModes
.getLength(); i
> 0; )
2496 if (pModes
[--i
] == Mode
)
2502 //------------------------------------------------------------------------------
2503 void FmXGridPeer::columnVisible(DbGridColumn
* pColumn
)
2505 FmGridControl
* pGrid
= (FmGridControl
*) GetWindow();
2507 sal_Int32 _nIndex
= pGrid
->GetModelColumnPos(pColumn
->GetId());
2508 Reference
< ::com::sun::star::awt::XControl
> xControl(pColumn
->GetCell());
2509 ContainerEvent aEvt
;
2510 aEvt
.Source
= (XContainer
*)this;
2511 aEvt
.Accessor
<<= _nIndex
;
2512 aEvt
.Element
<<= xControl
;
2514 m_aContainerListeners
.notifyEach( &XContainerListener::elementInserted
, aEvt
);
2517 //------------------------------------------------------------------------------
2518 void FmXGridPeer::columnHidden(DbGridColumn
* pColumn
)
2520 FmGridControl
* pGrid
= (FmGridControl
*) GetWindow();
2522 sal_Int32 _nIndex
= pGrid
->GetModelColumnPos(pColumn
->GetId());
2523 Reference
< ::com::sun::star::awt::XControl
> xControl(pColumn
->GetCell());
2524 ContainerEvent aEvt
;
2525 aEvt
.Source
= (XContainer
*)this;
2526 aEvt
.Accessor
<<= _nIndex
;
2527 aEvt
.Element
<<= xControl
;
2529 m_aContainerListeners
.notifyEach( &XContainerListener::elementRemoved
, aEvt
);
2532 //------------------------------------------------------------------------------
2533 void FmXGridPeer::draw( sal_Int32 x
, sal_Int32 y
) throw( RuntimeException
)
2535 FmGridControl
* pGrid
= (FmGridControl
*) GetWindow();
2536 sal_Int32 nOldFlags
= pGrid
->GetBrowserFlags();
2537 pGrid
->SetBrowserFlags(nOldFlags
| EBBF_NOROWPICTURE
);
2539 VCLXWindow::draw(x
, y
);
2541 pGrid
->SetBrowserFlags(nOldFlags
);
2544 //------------------------------------------------------------------------------
2545 Reference
< ::com::sun::star::frame::XDispatch
> FmXGridPeer::queryDispatch(const ::com::sun::star::util::URL
& aURL
, const ::rtl::OUString
& aTargetFrameName
, sal_Int32 nSearchFlags
) throw( RuntimeException
)
2547 Reference
< ::com::sun::star::frame::XDispatch
> xResult
;
2549 // first ask our interceptor chain
2550 if (m_xFirstDispatchInterceptor
.is() && !m_bInterceptingDispatch
)
2552 m_bInterceptingDispatch
= sal_True
;
2553 // safety against recursion : as we are master of the first chain element and slave of the last one we would
2554 // have an infinite loop without this if no dispatcher can fullfill the rewuest)
2555 xResult
= m_xFirstDispatchInterceptor
->queryDispatch(aURL
, aTargetFrameName
, nSearchFlags
);
2556 m_bInterceptingDispatch
= sal_False
;
2559 // then ask ourself : we don't have any dispatches
2563 //------------------------------------------------------------------------------
2564 Sequence
< Reference
< ::com::sun::star::frame::XDispatch
> > FmXGridPeer::queryDispatches(const Sequence
< ::com::sun::star::frame::DispatchDescriptor
>& aDescripts
) throw( RuntimeException
)
2566 if (m_xFirstDispatchInterceptor
.is())
2567 return m_xFirstDispatchInterceptor
->queryDispatches(aDescripts
);
2569 // then ask ourself : we don't have any dispatches
2570 return Sequence
< Reference
< ::com::sun::star::frame::XDispatch
> >();
2573 //------------------------------------------------------------------------------
2574 void FmXGridPeer::registerDispatchProviderInterceptor(const Reference
< ::com::sun::star::frame::XDispatchProviderInterceptor
>& _xInterceptor
) throw( RuntimeException
)
2576 if (_xInterceptor
.is())
2578 if (m_xFirstDispatchInterceptor
.is())
2580 Reference
< ::com::sun::star::frame::XDispatchProvider
> xFirstProvider(m_xFirstDispatchInterceptor
, UNO_QUERY
);
2581 // there is already an interceptor; the new one will become its master
2582 _xInterceptor
->setSlaveDispatchProvider(xFirstProvider
);
2583 m_xFirstDispatchInterceptor
->setMasterDispatchProvider(xFirstProvider
);
2587 // it is the first interceptor; set ourself as slave
2588 _xInterceptor
->setSlaveDispatchProvider((::com::sun::star::frame::XDispatchProvider
*)this);
2591 // we are the master of the chain's first interceptor
2592 m_xFirstDispatchInterceptor
= _xInterceptor
;
2593 m_xFirstDispatchInterceptor
->setMasterDispatchProvider((::com::sun::star::frame::XDispatchProvider
*)this);
2595 // we have a new interceptor and we're alive ?
2596 if (!isDesignMode())
2597 // -> check for new dispatchers
2602 //------------------------------------------------------------------------------
2603 void FmXGridPeer::releaseDispatchProviderInterceptor(const Reference
< ::com::sun::star::frame::XDispatchProviderInterceptor
>& _xInterceptor
) throw( RuntimeException
)
2605 if (!_xInterceptor
.is())
2608 Reference
< ::com::sun::star::frame::XDispatchProviderInterceptor
> xChainWalk(m_xFirstDispatchInterceptor
);
2610 if (m_xFirstDispatchInterceptor
== _xInterceptor
)
2611 { // our chain will have a new first element
2612 Reference
< ::com::sun::star::frame::XDispatchProviderInterceptor
> xSlave(m_xFirstDispatchInterceptor
->getSlaveDispatchProvider(), UNO_QUERY
);
2613 m_xFirstDispatchInterceptor
= xSlave
;
2615 // do this before removing the interceptor from the chain as we won't know it's slave afterwards)
2617 while (xChainWalk
.is())
2619 // walk along the chain of interceptors and look for the interceptor that has to be removed
2620 Reference
< ::com::sun::star::frame::XDispatchProviderInterceptor
> xSlave(xChainWalk
->getSlaveDispatchProvider(), UNO_QUERY
);
2622 if (xChainWalk
== _xInterceptor
)
2624 // old master may be an interceptor too
2625 Reference
< ::com::sun::star::frame::XDispatchProviderInterceptor
> xMaster(xChainWalk
->getMasterDispatchProvider(), UNO_QUERY
);
2627 // unchain the interceptor that has to be removed
2628 xChainWalk
->setSlaveDispatchProvider(Reference
< ::com::sun::star::frame::XDispatchProvider
> ());
2629 xChainWalk
->setMasterDispatchProvider(Reference
< ::com::sun::star::frame::XDispatchProvider
> ());
2631 // reconnect the chain
2635 xMaster
->setSlaveDispatchProvider(Reference
< ::com::sun::star::frame::XDispatchProvider
>::query(xSlave
));
2637 // it's the first interceptor of the chain, set ourself as slave
2638 xMaster
->setSlaveDispatchProvider((::com::sun::star::frame::XDispatchProvider
*)this);
2642 // the chain's first element was removed, set ourself as new master of the second one
2644 xSlave
->setMasterDispatchProvider((::com::sun::star::frame::XDispatchProvider
*)this);
2648 xChainWalk
= xSlave
;
2650 // our interceptor chain has changed and we're alive ?
2651 if (!isDesignMode())
2652 // -> check the dispatchers
2656 //------------------------------------------------------------------------------
2657 void FmXGridPeer::statusChanged(const ::com::sun::star::frame::FeatureStateEvent
& Event
) throw( RuntimeException
)
2659 DBG_ASSERT(m_pStateCache
, "FmXGridPeer::statusChanged : invalid call !");
2660 DBG_ASSERT(m_pDispatchers
, "FmXGridPeer::statusChanged : invalid call !");
2662 Sequence
< ::com::sun::star::util::URL
>& aUrls
= getSupportedURLs();
2663 const ::com::sun::star::util::URL
* pUrls
= aUrls
.getConstArray();
2665 Sequence
<sal_uInt16
> aSlots
= getSupportedGridSlots();
2666 const sal_uInt16
* pSlots
= aSlots
.getConstArray();
2669 for (i
=0; i
<aUrls
.getLength(); ++i
, ++pUrls
, ++pSlots
)
2671 if (pUrls
->Main
== Event
.FeatureURL
.Main
)
2673 DBG_ASSERT(m_pDispatchers
[i
] == Event
.Source
, "FmXGridPeer::statusChanged : the event source is a little bit suspect !");
2674 m_pStateCache
[i
] = Event
.IsEnabled
;
2675 FmGridControl
* pGrid
= (FmGridControl
*) GetWindow();
2676 if (*pSlots
!= SID_FM_RECORD_UNDO
)
2677 pGrid
->GetNavigationBar().InvalidateState(*pSlots
);
2681 DBG_ASSERT(i
<aUrls
.getLength(), "FmXGridPeer::statusChanged : got a call for an unknown url !");
2684 //------------------------------------------------------------------------------
2685 sal_Bool
FmXGridPeer::approveReset(const EventObject
& /*rEvent*/) throw( RuntimeException
)
2690 //------------------------------------------------------------------------------
2691 sal_Bool SAL_CALL
FmXGridPeer::select( const Any
& _rSelection
) throw (IllegalArgumentException
, RuntimeException
)
2693 Sequence
< Any
> aBookmarks
;
2694 if ( !( _rSelection
>>= aBookmarks
) )
2695 throw IllegalArgumentException();
2697 FmGridControl
* pVclControl
= static_cast<FmGridControl
*>(GetWindow());
2698 return pVclControl
->selectBookmarks(aBookmarks
);
2701 // speaking strictly, we would have to adjust our model, as our ColumnSelection may have changed.
2702 // Our model is a XSelectionSupplier, too, it handles the selection of single columns.
2703 // This is somewhat strange, as selection should be a view (not a model) aspect.
2704 // So for a clean solution, we should handle column selection ourself, and the model shouldn't
2705 // deal with selection at all.
2708 //------------------------------------------------------------------------------
2709 Any SAL_CALL
FmXGridPeer::getSelection( ) throw (RuntimeException
)
2711 FmGridControl
* pVclControl
= static_cast<FmGridControl
*>(GetWindow());
2712 Sequence
< Any
> aSelectionBookmarks
= pVclControl
->getSelectionBookmarks();
2713 return makeAny(aSelectionBookmarks
);
2716 //------------------------------------------------------------------------------
2717 void SAL_CALL
FmXGridPeer::addSelectionChangeListener( const Reference
< XSelectionChangeListener
>& _rxListener
) throw (RuntimeException
)
2719 m_aSelectionListeners
.addInterface( _rxListener
);
2722 //------------------------------------------------------------------------------
2723 void SAL_CALL
FmXGridPeer::removeSelectionChangeListener( const Reference
< XSelectionChangeListener
>& _rxListener
) throw (RuntimeException
)
2725 m_aSelectionListeners
.removeInterface( _rxListener
);
2728 //------------------------------------------------------------------------------
2729 void FmXGridPeer::resetted(const EventObject
& rEvent
) throw( RuntimeException
)
2731 if (m_xColumns
== rEvent
.Source
)
2732 { // my model was reset -> refresh the grid content
2733 FmGridControl
* pGrid
= (FmGridControl
*)GetWindow();
2736 ::vos::OGuard
aGuard( Application::GetSolarMutex() );
2737 pGrid
->resetCurrentRow();
2739 // if the cursor fired a reset event we seem to be on the insert row
2740 else if (m_xCursor
== rEvent
.Source
)
2742 ::vos::OGuard
aGuard( Application::GetSolarMutex() );
2743 FmGridControl
* pGrid
= (FmGridControl
*) GetWindow();
2744 if (pGrid
&& pGrid
->IsOpen())
2745 pGrid
->positioned(rEvent
);
2749 //------------------------------------------------------------------------------
2750 Sequence
<sal_uInt16
>& FmXGridPeer::getSupportedGridSlots()
2752 static Sequence
<sal_uInt16
> aSupported
;
2753 if (aSupported
.getLength() == 0)
2755 sal_uInt16 nSupported
[] = {
2756 DbGridControl::NavigationBar::RECORD_FIRST
,
2757 DbGridControl::NavigationBar::RECORD_PREV
,
2758 DbGridControl::NavigationBar::RECORD_NEXT
,
2759 DbGridControl::NavigationBar::RECORD_LAST
,
2760 DbGridControl::NavigationBar::RECORD_NEW
,
2763 aSupported
.realloc(sizeof(nSupported
)/sizeof(nSupported
[0]));
2764 sal_uInt16
* pSupported
= aSupported
.getArray();
2765 for (sal_uInt16 i
=0; i
<aSupported
.getLength(); ++i
, ++pSupported
)
2766 *pSupported
= nSupported
[i
];
2771 //------------------------------------------------------------------------------
2772 Sequence
< ::com::sun::star::util::URL
>& FmXGridPeer::getSupportedURLs()
2774 static Sequence
< ::com::sun::star::util::URL
> aSupported
;
2775 if (aSupported
.getLength() == 0)
2777 static ::rtl::OUString sSupported
[] = {
2778 FMURL_RECORD_MOVEFIRST
,
2779 FMURL_RECORD_MOVEPREV
,
2780 FMURL_RECORD_MOVENEXT
,
2781 FMURL_RECORD_MOVELAST
,
2782 FMURL_RECORD_MOVETONEW
,
2785 aSupported
.realloc(sizeof(sSupported
)/sizeof(sSupported
[0]));
2786 ::com::sun::star::util::URL
* pSupported
= aSupported
.getArray();
2789 for ( i
= 0; i
< aSupported
.getLength(); ++i
, ++pSupported
)
2790 pSupported
->Complete
= sSupported
[i
];
2792 // let an ::com::sun::star::util::URL-transformer normalize the URLs
2793 Reference
< ::com::sun::star::util::XURLTransformer
> xTransformer(
2794 ::comphelper::getProcessServiceFactory()->createInstance(
2795 ::rtl::OUString::createFromAscii("com.sun.star.util.URLTransformer")),
2797 pSupported
= aSupported
.getArray();
2798 if (xTransformer
.is())
2800 for (i
=0; i
<aSupported
.getLength(); ++i
)
2801 xTransformer
->parseStrict(pSupported
[i
]);
2808 //------------------------------------------------------------------------------
2809 void FmXGridPeer::UpdateDispatches()
2812 { // we don't have any dispatchers yet -> do the initial connect
2813 ConnectToDispatcher();
2817 sal_uInt16 nDispatchersGot
= 0;
2818 const Sequence
< ::com::sun::star::util::URL
>& aSupportedURLs
= getSupportedURLs();
2819 const ::com::sun::star::util::URL
* pSupportedURLs
= aSupportedURLs
.getConstArray();
2820 Reference
< ::com::sun::star::frame::XDispatch
> xNewDispatch
;
2821 for (sal_uInt16 i
=0; i
<aSupportedURLs
.getLength(); ++i
, ++pSupportedURLs
)
2823 xNewDispatch
= queryDispatch(*pSupportedURLs
, rtl::OUString(), 0);
2824 if (xNewDispatch
!= m_pDispatchers
[i
])
2826 if (m_pDispatchers
[i
].is())
2827 m_pDispatchers
[i
]->removeStatusListener((::com::sun::star::frame::XStatusListener
*)this, *pSupportedURLs
);
2828 m_pDispatchers
[i
] = xNewDispatch
;
2829 if (m_pDispatchers
[i
].is())
2830 m_pDispatchers
[i
]->addStatusListener((::com::sun::star::frame::XStatusListener
*)this, *pSupportedURLs
);
2832 if (m_pDispatchers
[i
].is())
2836 if (!nDispatchersGot
)
2838 delete[] m_pStateCache
;
2839 delete[] m_pDispatchers
;
2840 m_pStateCache
= NULL
;
2841 m_pDispatchers
= NULL
;
2845 //------------------------------------------------------------------------------
2846 void FmXGridPeer::ConnectToDispatcher()
2848 DBG_ASSERT((m_pStateCache
!= NULL
) == (m_pDispatchers
!= NULL
), "FmXGridPeer::ConnectToDispatcher : inconsistent !");
2850 { // already connected -> just do an update
2855 const Sequence
< ::com::sun::star::util::URL
>& aSupportedURLs
= getSupportedURLs();
2857 // _before_ adding the status listeners (as the add should result in a statusChanged-call) !
2858 m_pStateCache
= new sal_Bool
[aSupportedURLs
.getLength()];
2859 m_pDispatchers
= new Reference
< ::com::sun::star::frame::XDispatch
> [aSupportedURLs
.getLength()];
2861 sal_uInt16 nDispatchersGot
= 0;
2862 const ::com::sun::star::util::URL
* pSupportedURLs
= aSupportedURLs
.getConstArray();
2863 for (sal_uInt16 i
=0; i
<aSupportedURLs
.getLength(); ++i
, ++pSupportedURLs
)
2865 m_pStateCache
[i
] = 0;
2866 m_pDispatchers
[i
] = queryDispatch(*pSupportedURLs
, rtl::OUString(), 0);
2867 if (m_pDispatchers
[i
].is())
2869 m_pDispatchers
[i
]->addStatusListener((::com::sun::star::frame::XStatusListener
*)this, *pSupportedURLs
);
2874 if (!nDispatchersGot
)
2876 delete[] m_pStateCache
;
2877 delete[] m_pDispatchers
;
2878 m_pStateCache
= NULL
;
2879 m_pDispatchers
= NULL
;
2883 //------------------------------------------------------------------------------
2884 void FmXGridPeer::DisConnectFromDispatcher()
2886 if (!m_pStateCache
|| !m_pDispatchers
)
2888 // we're not connected
2890 const Sequence
< ::com::sun::star::util::URL
>& aSupportedURLs
= getSupportedURLs();
2891 const ::com::sun::star::util::URL
* pSupportedURLs
= aSupportedURLs
.getConstArray();
2892 for (sal_uInt16 i
=0; i
<aSupportedURLs
.getLength(); ++i
, ++pSupportedURLs
)
2894 if (m_pDispatchers
[i
].is())
2895 m_pDispatchers
[i
]->removeStatusListener((::com::sun::star::frame::XStatusListener
*)this, *pSupportedURLs
);
2898 delete[] m_pStateCache
;
2899 delete[] m_pDispatchers
;
2900 m_pStateCache
= NULL
;
2901 m_pDispatchers
= NULL
;
2904 //------------------------------------------------------------------------------
2905 IMPL_LINK(FmXGridPeer
, OnQueryGridSlotState
, void*, pSlot
)
2908 return -1; // unspecified
2910 sal_uInt16 nSlot
= (sal_uInt16
)(sal_uIntPtr
)pSlot
;
2912 // search the given slot with our supported sequence
2913 Sequence
<sal_uInt16
>& aSupported
= getSupportedGridSlots();
2914 const sal_uInt16
* pSlots
= aSupported
.getConstArray();
2915 for (sal_uInt16 i
=0; i
<aSupported
.getLength(); ++i
)
2917 if (pSlots
[i
] == nSlot
)
2919 if (!m_pDispatchers
[i
].is())
2920 return -1; // nothing known about this slot
2922 return m_pStateCache
[i
];
2929 //------------------------------------------------------------------------------
2930 IMPL_LINK(FmXGridPeer
, OnExecuteGridSlot
, void*, pSlot
)
2932 if (!m_pDispatchers
)
2933 return 0; // not handled
2935 Sequence
< ::com::sun::star::util::URL
>& aUrls
= getSupportedURLs();
2936 const ::com::sun::star::util::URL
* pUrls
= aUrls
.getConstArray();
2938 Sequence
<sal_uInt16
> aSlots
= getSupportedGridSlots();
2939 const sal_uInt16
* pSlots
= aSlots
.getConstArray();
2941 DBG_ASSERT(aSlots
.getLength() == aUrls
.getLength(), "FmXGridPeer::OnExecuteGridSlot : inconstent data returned by getSupportedURLs/getSupportedGridSlots !");
2943 sal_uInt16 nSlot
= (sal_uInt16
)(sal_uIntPtr
)pSlot
;
2944 for (sal_uInt16 i
=0; i
<aSlots
.getLength(); ++i
, ++pUrls
, ++pSlots
)
2946 if (*pSlots
== nSlot
)
2948 if (m_pDispatchers
[i
].is())
2950 // commit any changes done so far, if it's not the undoRecord URL
2951 if ( 0 == pUrls
->Complete
.compareTo( FMURL_RECORD_UNDO
) || commit() )
2952 m_pDispatchers
[i
]->dispatch(*pUrls
, Sequence
< PropertyValue
>());
2954 return 1; // handled
2959 return 0; // not handled