1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
21 #include "svx/fmgridif.hxx"
23 #include "fmservs.hxx"
24 #include "svx/fmtools.hxx"
26 #include "formcontrolfactory.hxx"
27 #include "gridcell.hxx"
28 #include "sdbdatacolumn.hxx"
29 #include "svx/fmgridcl.hxx"
30 #include "svx/svxids.hrc"
31 #include <tools/urlobj.hxx>
33 #include <com/sun/star/awt/PosSize.hpp>
34 #include <com/sun/star/beans/PropertyAttribute.hpp>
35 #include <com/sun/star/form/FormComponentType.hpp>
36 #include <com/sun/star/form/XFormComponent.hpp>
37 #include <com/sun/star/form/XLoadable.hpp>
38 #include <com/sun/star/lang/DisposedException.hpp>
39 #include <com/sun/star/lang/NoSupportException.hpp>
40 #include <com/sun/star/sdbc/ResultSetType.hpp>
41 #include <com/sun/star/sdbcx/XColumnsSupplier.hpp>
42 #include <com/sun/star/util/URLTransformer.hpp>
43 #include <com/sun/star/util/XURLTransformer.hpp>
44 #include <com/sun/star/view/XSelectionSupplier.hpp>
45 #include <com/sun/star/sdbcx/XRowLocate.hpp>
47 #include <comphelper/container.hxx>
48 #include <comphelper/enumhelper.hxx>
49 #include <comphelper/processfactory.hxx>
50 #include <comphelper/property.hxx>
51 #include <comphelper/sequence.hxx>
52 #include <comphelper/servicehelper.hxx>
53 #include <comphelper/types.hxx>
54 #include <cppuhelper/supportsservice.hxx>
55 #include <cppuhelper/typeprovider.hxx>
56 #include <cppuhelper/queryinterface.hxx>
57 #include <vcl/unohelp.hxx>
58 #include <tools/diagnose_ex.h>
59 #include <sal/macros.h>
61 using namespace ::svxform
;
62 using namespace ::com::sun::star::container
;
63 using namespace ::com::sun::star::sdb
;
64 using namespace ::com::sun::star::sdbc
;
65 using namespace ::com::sun::star::uno
;
66 using namespace ::com::sun::star::view
;
67 using namespace ::com::sun::star::beans
;
68 using namespace ::com::sun::star::lang
;
69 using namespace ::com::sun::star::form
;
70 using namespace ::com::sun::star::util
;
71 using namespace ::com::sun::star
;
73 using ::com::sun::star::sdbcx::XColumnsSupplier
;
74 using ::com::sun::star::frame::XDispatchProviderInterceptor
;
75 using ::com::sun::star::frame::XDispatchProvider
;
76 using ::com::sun::star::accessibility::XAccessible
;
77 using ::com::sun::star::accessibility::XAccessibleContext
;
78 using ::com::sun::star::sdb::XRowSetSupplier
;
79 using ::com::sun::star::awt::XVclWindowPeer
;
82 css::awt::FontDescriptor
ImplCreateFontDescriptor( const vcl::Font
& rFont
)
84 css::awt::FontDescriptor aFD
;
85 aFD
.Name
= rFont
.GetFamilyName();
86 aFD
.StyleName
= rFont
.GetStyleName();
87 aFD
.Height
= (sal_Int16
)rFont
.GetFontSize().Height();
88 aFD
.Width
= (sal_Int16
)rFont
.GetFontSize().Width();
89 aFD
.Family
= (sal_Int16
)rFont
.GetFamilyType();
90 aFD
.CharSet
= rFont
.GetCharSet();
91 aFD
.Pitch
= (sal_Int16
)rFont
.GetPitch();
92 aFD
.CharacterWidth
= vcl::unohelper::ConvertFontWidth( rFont
.GetWidthType() );
93 aFD
.Weight
= vcl::unohelper::ConvertFontWeight( rFont
.GetWeight() );
94 aFD
.Slant
= vcl::unohelper::ConvertFontSlant( rFont
.GetItalic() );
95 aFD
.Underline
= (sal_Int16
)rFont
.GetUnderline();
96 aFD
.Strikeout
= (sal_Int16
)rFont
.GetStrikeout();
97 aFD
.Orientation
= rFont
.GetOrientation();
98 aFD
.Kerning
= rFont
.IsKerning();
99 aFD
.WordLineMode
= rFont
.IsWordLineMode();
100 aFD
.Type
= 0; // ??? => only to metric...
105 vcl::Font
ImplCreateFont( const css::awt::FontDescriptor
& rDescr
)
108 aFont
.SetFamilyName( rDescr
.Name
);
109 aFont
.SetStyleName( rDescr
.StyleName
);
110 aFont
.SetFontSize( ::Size( rDescr
.Width
, rDescr
.Height
) );
111 aFont
.SetFamily( (FontFamily
)rDescr
.Family
);
112 aFont
.SetCharSet( (rtl_TextEncoding
)rDescr
.CharSet
);
113 aFont
.SetPitch( (FontPitch
)rDescr
.Pitch
);
114 aFont
.SetWidthType( vcl::unohelper::ConvertFontWidth( rDescr
.CharacterWidth
) );
115 aFont
.SetWeight( vcl::unohelper::ConvertFontWeight( rDescr
.Weight
) );
116 aFont
.SetItalic( (FontItalic
)rDescr
.Slant
);
117 aFont
.SetUnderline( (::FontLineStyle
)rDescr
.Underline
);
118 aFont
.SetStrikeout( (::FontStrikeout
)rDescr
.Strikeout
);
119 aFont
.SetOrientation( (sal_Int16
)rDescr
.Orientation
);
120 aFont
.SetKerning( static_cast<FontKerning
>(rDescr
.Kerning
) );
121 aFont
.SetWordLineMode( rDescr
.WordLineMode
);
125 FmXModifyMultiplexer::FmXModifyMultiplexer( ::cppu::OWeakObject
& rSource
, ::osl::Mutex
& _rMutex
)
126 :OWeakSubObject( rSource
)
127 ,OInterfaceContainerHelper2( _rMutex
)
132 Any SAL_CALL
FmXModifyMultiplexer::queryInterface(const Type
& _rType
)
135 aReturn
= ::cppu::queryInterface(_rType
,
136 static_cast< css::util::XModifyListener
*>(this),
137 static_cast< XEventListener
*>(this)
140 if (!aReturn
.hasValue())
141 aReturn
= OWeakSubObject::queryInterface( _rType
);
147 void FmXModifyMultiplexer::disposing(const EventObject
& )
152 void FmXModifyMultiplexer::modified(const EventObject
& e
)
154 EventObject
aMulti( e
);
155 aMulti
.Source
= &m_rParent
;
156 notifyEach( &XModifyListener::modified
, aMulti
);
159 FmXUpdateMultiplexer::FmXUpdateMultiplexer( ::cppu::OWeakObject
& rSource
, ::osl::Mutex
& _rMutex
)
160 :OWeakSubObject( rSource
)
161 ,OInterfaceContainerHelper2( _rMutex
)
166 Any SAL_CALL
FmXUpdateMultiplexer::queryInterface(const Type
& _rType
)
169 aReturn
= ::cppu::queryInterface(_rType
,
170 static_cast< XUpdateListener
*>(this),
171 static_cast< XEventListener
*>(this)
174 if (!aReturn
.hasValue())
175 aReturn
= OWeakSubObject::queryInterface( _rType
);
181 void FmXUpdateMultiplexer::disposing(const EventObject
& )
186 sal_Bool
FmXUpdateMultiplexer::approveUpdate(const EventObject
&e
)
188 EventObject
aMulti( e
);
189 aMulti
.Source
= &m_rParent
;
194 ::comphelper::OInterfaceIteratorHelper2
aIter(*this);
195 while ( bResult
&& aIter
.hasMoreElements() )
196 bResult
= static_cast< XUpdateListener
* >( aIter
.next() )->approveUpdate( aMulti
);
203 void FmXUpdateMultiplexer::updated(const EventObject
&e
)
205 EventObject
aMulti( e
);
206 aMulti
.Source
= &m_rParent
;
207 notifyEach( &XUpdateListener::updated
, aMulti
);
210 FmXSelectionMultiplexer::FmXSelectionMultiplexer( ::cppu::OWeakObject
& rSource
, ::osl::Mutex
& _rMutex
)
211 :OWeakSubObject( rSource
)
212 ,OInterfaceContainerHelper2( _rMutex
)
217 Any SAL_CALL
FmXSelectionMultiplexer::queryInterface(const Type
& _rType
)
220 aReturn
= ::cppu::queryInterface(_rType
,
221 static_cast< XSelectionChangeListener
*>(this),
222 static_cast< XEventListener
*>(this)
225 if (!aReturn
.hasValue())
226 aReturn
= OWeakSubObject::queryInterface( _rType
);
232 void FmXSelectionMultiplexer::disposing(const EventObject
& )
237 void SAL_CALL
FmXSelectionMultiplexer::selectionChanged( const EventObject
& _rEvent
)
239 EventObject
aMulti(_rEvent
);
240 aMulti
.Source
= &m_rParent
;
241 notifyEach( &XSelectionChangeListener::selectionChanged
, aMulti
);
244 FmXContainerMultiplexer::FmXContainerMultiplexer( ::cppu::OWeakObject
& rSource
, ::osl::Mutex
& _rMutex
)
245 :OWeakSubObject( rSource
)
246 ,OInterfaceContainerHelper2( _rMutex
)
251 Any SAL_CALL
FmXContainerMultiplexer::queryInterface(const Type
& _rType
)
254 aReturn
= ::cppu::queryInterface(_rType
,
255 static_cast< XContainerListener
*>(this),
256 static_cast< XEventListener
*>(this)
259 if (!aReturn
.hasValue())
260 aReturn
= OWeakSubObject::queryInterface( _rType
);
266 void FmXContainerMultiplexer::disposing(const EventObject
& )
270 void FmXContainerMultiplexer::elementInserted(const ContainerEvent
& e
)
272 ContainerEvent
aMulti( e
);
273 aMulti
.Source
= &m_rParent
;
274 notifyEach( &XContainerListener::elementInserted
, aMulti
);
278 void FmXContainerMultiplexer::elementRemoved(const ContainerEvent
& e
)
280 ContainerEvent
aMulti( e
);
281 aMulti
.Source
= &m_rParent
;
282 notifyEach( &XContainerListener::elementRemoved
, aMulti
);
286 void FmXContainerMultiplexer::elementReplaced(const ContainerEvent
& e
)
288 ContainerEvent
aMulti( e
);
289 aMulti
.Source
= &m_rParent
;
290 notifyEach( &XContainerListener::elementReplaced
, aMulti
);
293 FmXGridControlMultiplexer::FmXGridControlMultiplexer( ::cppu::OWeakObject
& rSource
, ::osl::Mutex
& _rMutex
)
294 :OWeakSubObject( rSource
)
295 ,OInterfaceContainerHelper2( _rMutex
)
300 Any SAL_CALL
FmXGridControlMultiplexer::queryInterface(const Type
& _rType
)
303 aReturn
= ::cppu::queryInterface( _rType
,
304 static_cast< XGridControlListener
*>(this)
307 if (!aReturn
.hasValue())
308 aReturn
= OWeakSubObject::queryInterface( _rType
);
314 void FmXGridControlMultiplexer::disposing( const EventObject
& )
319 void SAL_CALL
FmXGridControlMultiplexer::columnChanged( const EventObject
& _event
)
321 EventObject
aForwardedEvent( _event
);
322 aForwardedEvent
.Source
= &m_rParent
;
323 notifyEach( &XGridControlListener::columnChanged
, aForwardedEvent
);
330 Reference
< XInterface
> SAL_CALL
FmXGridControl_NewInstance_Impl(const Reference
< XMultiServiceFactory
>& _rxFactory
)
332 return *(new FmXGridControl( comphelper::getComponentContext(_rxFactory
) ));
335 FmXGridControl::FmXGridControl(const Reference
< XComponentContext
>& _rxContext
)
337 ,m_aModifyListeners(*this, GetMutex())
338 ,m_aUpdateListeners(*this, GetMutex())
339 ,m_aContainerListeners(*this, GetMutex())
340 ,m_aSelectionListeners(*this, GetMutex())
341 ,m_aGridControlListeners(*this, GetMutex())
343 ,m_xContext(_rxContext
)
348 FmXGridControl::~FmXGridControl()
353 Any SAL_CALL
FmXGridControl::queryAggregation(const Type
& _rType
)
355 Any aReturn
= FmXGridControl_BASE::queryInterface(_rType
);
357 if (!aReturn
.hasValue())
358 aReturn
= UnoControl::queryAggregation( _rType
);
363 Sequence
< Type
> SAL_CALL
FmXGridControl::getTypes( )
365 return comphelper::concatSequences(UnoControl::getTypes(),FmXGridControl_BASE::getTypes());
369 Sequence
<sal_Int8
> SAL_CALL
FmXGridControl::getImplementationId( )
371 return css::uno::Sequence
<sal_Int8
>();
375 sal_Bool SAL_CALL
FmXGridControl::supportsService(const OUString
& ServiceName
)
377 return cppu::supportsService(this, ServiceName
);
380 OUString SAL_CALL
FmXGridControl::getImplementationName()
382 return OUString("com.sun.star.form.FmXGridControl");
385 css::uno::Sequence
<OUString
> SAL_CALL
FmXGridControl::getSupportedServiceNames()
387 Sequence
< OUString
> aServiceNames(2);
388 aServiceNames
[0] = FM_SUN_CONTROL_GRIDCONTROL
;
389 aServiceNames
[1] = "com.sun.star.awt.UnoControl";
390 return aServiceNames
;
394 void SAL_CALL
FmXGridControl::dispose()
396 SolarMutexGuard aGuard
;
399 aEvt
.Source
= static_cast< ::cppu::OWeakObject
* >(this);
400 m_aModifyListeners
.disposeAndClear(aEvt
);
401 m_aUpdateListeners
.disposeAndClear(aEvt
);
402 m_aContainerListeners
.disposeAndClear(aEvt
);
404 UnoControl::dispose();
408 OUString
FmXGridControl::GetComponentServiceName()
410 OUString
aName("DBGrid");
415 sal_Bool SAL_CALL
FmXGridControl::setModel(const Reference
< css::awt::XControlModel
>& rModel
)
417 SolarMutexGuard aGuard
;
419 if (!UnoControl::setModel(rModel
))
422 Reference
< XGridPeer
> xGridPeer(getPeer(), UNO_QUERY
);
425 Reference
< XIndexContainer
> xCols(mxModel
, UNO_QUERY
);
426 xGridPeer
->setColumns(xCols
);
432 FmXGridPeer
* FmXGridControl::imp_CreatePeer(vcl::Window
* pParent
)
434 FmXGridPeer
* pReturn
= new FmXGridPeer(m_xContext
);
436 // translate properties into WinBits
437 WinBits nStyle
= WB_TABSTOP
;
438 Reference
< XPropertySet
> xModelSet(getModel(), UNO_QUERY
);
443 if (::comphelper::getINT16(xModelSet
->getPropertyValue(FM_PROP_BORDER
)))
446 catch(const Exception
&)
448 OSL_FAIL("Can not get style");
452 pReturn
->Create(pParent
, nStyle
);
457 void SAL_CALL
FmXGridControl::createPeer(const Reference
< css::awt::XToolkit
>& /*rToolkit*/, const Reference
< css::awt::XWindowPeer
>& rParentPeer
)
460 throw DisposedException( OUString(), *this );
462 DBG_ASSERT(/*(0 == m_nPeerCreationLevel) && */!mbCreatingPeer
, "FmXGridControl::createPeer : recursion!");
463 // I think this should never assert, now that we're using the base class' mbCreatingPeer in addition to
464 // our own m_nPeerCreationLevel
465 // But I'm not sure as I don't _fully_ understand the underlying toolkit implementations ....
466 // (if this asserts, we still need m_nPeerCreationLevel. If not, we could omit it ....)
467 // 14.05.2001 - 86836 - frank.schoenheit@germany.sun.com
469 // TODO: why the hell this whole class does not use any mutex?
473 mbCreatingPeer
= true;
474 // mbCreatingPeer is virtually the same as m_nPeerCreationLevel, but it's the base class' method
475 // to prevent recursion.
477 vcl::Window
* pParentWin
= nullptr;
478 if (rParentPeer
.is())
480 VCLXWindow
* pParent
= VCLXWindow::GetImplementation(rParentPeer
);
482 pParentWin
= pParent
->GetWindow().get();
485 FmXGridPeer
* pPeer
= imp_CreatePeer(pParentWin
);
486 DBG_ASSERT(pPeer
!= nullptr, "FmXGridControl::createPeer : imp_CreatePeer didn't return a peer !");
489 // reading the properties from the model
490 // ++m_nPeerCreationLevel;
493 // consider the following ugly scenario: updateFromModel leads to a propertiesChanges on the Control,
494 // which determines, dat a "critical" property has changed (e.g. "Border") and therefore starts a new
495 // Peer, which lands again here in createPeer we also start a second FmXGridPeer and initialise it.
496 // Then we exit from the first incarnation's updateFromModel and continue working with the pPeer,
497 // that is in fact now already obsolete (as another peer is being started in the second incarnation).
498 // Therefore the effort with the PeerCreationLevel, which ensures that we really use the Peer
499 // created at the deepest level, but first initialise it in the top-level.
500 // if (--m_nPeerCreationLevel == 0)
502 DBG_ASSERT(getPeer().is(), "FmXGridControl::createPeer : something went wrong ... no top level peer !");
503 pPeer
= FmXGridPeer::getImplementation(getPeer());
505 setPosSize( maComponentInfos
.nX
, maComponentInfos
.nY
, maComponentInfos
.nWidth
, maComponentInfos
.nHeight
, css::awt::PosSize::POSSIZE
);
507 Reference
< XIndexContainer
> xColumns(getModel(), UNO_QUERY
);
509 pPeer
->setColumns(xColumns
);
511 if (maComponentInfos
.bVisible
)
512 pPeer
->setVisible(true);
514 if (!maComponentInfos
.bEnable
)
515 pPeer
->setEnable(false);
517 if (maWindowListeners
.getLength())
518 pPeer
->addWindowListener( &maWindowListeners
);
520 if (maFocusListeners
.getLength())
521 pPeer
->addFocusListener( &maFocusListeners
);
523 if (maKeyListeners
.getLength())
524 pPeer
->addKeyListener( &maKeyListeners
);
526 if (maMouseListeners
.getLength())
527 pPeer
->addMouseListener( &maMouseListeners
);
529 if (maMouseMotionListeners
.getLength())
530 pPeer
->addMouseMotionListener( &maMouseMotionListeners
);
532 if (maPaintListeners
.getLength())
533 pPeer
->addPaintListener( &maPaintListeners
);
535 if (m_aModifyListeners
.getLength())
536 pPeer
->addModifyListener( &m_aModifyListeners
);
538 if (m_aUpdateListeners
.getLength())
539 pPeer
->addUpdateListener( &m_aUpdateListeners
);
541 if (m_aContainerListeners
.getLength())
542 pPeer
->addContainerListener( &m_aContainerListeners
);
544 // forward the design mode
545 bool bForceAlivePeer
= m_bInDraw
&& !maComponentInfos
.bVisible
;
546 // (we force an alive-mode peer if we're in "draw", cause in this case the peer will be used for drawing in
547 // foreign devices. We ensure this with the visibility check as an living peer is assumed to be noncritical
548 // only if invisible)
549 Any aOldCursorBookmark
;
550 if (!mbDesignMode
|| bForceAlivePeer
)
552 Reference
< XFormComponent
> xComp(getModel(), UNO_QUERY
);
555 Reference
< XRowSet
> xForm(xComp
->getParent(), UNO_QUERY
);
556 // is the form alive?
557 // we can see that if the form contains columns
558 Reference
< css::sdbcx::XColumnsSupplier
> xColumnsSupplier(xForm
, UNO_QUERY
);
559 if (xColumnsSupplier
.is())
561 if (Reference
< XIndexAccess
> (xColumnsSupplier
->getColumns(),UNO_QUERY
)->getCount())
563 // we get only a new bookmark if the resultset is not forwardonly
564 if (::comphelper::getINT32(Reference
< XPropertySet
> (xForm
, UNO_QUERY
)->getPropertyValue(FM_PROP_RESULTSET_TYPE
)) != ResultSetType::FORWARD_ONLY
)
566 // as the FmGridControl touches the data source it is connected to we have to remember the current
567 // cursor position (and restore afterwards)
568 // OJ: but only when we stand on a valid row
569 Reference
< XResultSet
> xResultSet(xForm
, UNO_QUERY
);
570 if ( !xResultSet
->isBeforeFirst() && !xResultSet
->isAfterLast() )
574 aOldCursorBookmark
= Reference
< css::sdbcx::XRowLocate
> (xForm
, UNO_QUERY
)->getBookmark();
576 catch( const Exception
& e
)
578 DBG_UNHANDLED_EXCEPTION();
585 pPeer
->setRowSet(xForm
);
588 pPeer
->setDesignMode(mbDesignMode
&& !bForceAlivePeer
);
592 if (aOldCursorBookmark
.hasValue())
593 { // we have a valid bookmark, so we have to restore the cursor's position
594 Reference
< XFormComponent
> xComp(getModel(), UNO_QUERY
);
595 Reference
< css::sdbcx::XRowLocate
> xLocate(xComp
->getParent(), UNO_QUERY
);
596 xLocate
->moveToBookmark(aOldCursorBookmark
);
599 catch( const Exception
& e
)
601 DBG_UNHANDLED_EXCEPTION();
605 Reference
< css::awt::XView
> xPeerView(getPeer(), UNO_QUERY
);
606 xPeerView
->setZoom( maComponentInfos
.nZoomX
, maComponentInfos
.nZoomY
);
607 xPeerView
->setGraphics( mxGraphics
);
609 mbCreatingPeer
= false;
614 void FmXGridControl::addModifyListener(const Reference
< css::util::XModifyListener
>& l
)
616 m_aModifyListeners
.addInterface( l
);
617 if( getPeer().is() && m_aModifyListeners
.getLength() == 1 )
619 Reference
< css::util::XModifyBroadcaster
> xGrid(getPeer(), UNO_QUERY
);
620 xGrid
->addModifyListener( &m_aModifyListeners
);
625 sal_Bool SAL_CALL
FmXGridControl::select( const Any
& _rSelection
)
627 SolarMutexGuard aGuard
;
628 Reference
< XSelectionSupplier
> xPeer(getPeer(), UNO_QUERY
);
629 return xPeer
->select(_rSelection
);
633 Any SAL_CALL
FmXGridControl::getSelection( )
635 SolarMutexGuard aGuard
;
636 Reference
< XSelectionSupplier
> xPeer(getPeer(), UNO_QUERY
);
637 return xPeer
->getSelection();
641 void SAL_CALL
FmXGridControl::addSelectionChangeListener( const Reference
< XSelectionChangeListener
>& _rxListener
)
643 m_aSelectionListeners
.addInterface( _rxListener
);
644 if( getPeer().is() && 1 == m_aSelectionListeners
.getLength() )
646 Reference
< XSelectionSupplier
> xGrid(getPeer(), UNO_QUERY
);
647 xGrid
->addSelectionChangeListener( &m_aSelectionListeners
);
652 void SAL_CALL
FmXGridControl::removeSelectionChangeListener( const Reference
< XSelectionChangeListener
>& _rxListener
)
654 if( getPeer().is() && 1 == m_aSelectionListeners
.getLength() )
656 Reference
< XSelectionSupplier
> xGrid(getPeer(), UNO_QUERY
);
657 xGrid
->removeSelectionChangeListener( &m_aSelectionListeners
);
659 m_aSelectionListeners
.removeInterface( _rxListener
);
663 Sequence
< sal_Bool
> SAL_CALL
FmXGridControl::queryFieldDataType( const Type
& xType
)
667 Reference
< XGridFieldDataSupplier
> xPeerSupplier(getPeer(), UNO_QUERY
);
668 if (xPeerSupplier
.is())
669 return xPeerSupplier
->queryFieldDataType(xType
);
672 return Sequence
<sal_Bool
>();
676 Sequence
< Any
> SAL_CALL
FmXGridControl::queryFieldData( sal_Int32 nRow
, const Type
& xType
)
680 Reference
< XGridFieldDataSupplier
> xPeerSupplier(getPeer(), UNO_QUERY
);
681 if (xPeerSupplier
.is())
682 return xPeerSupplier
->queryFieldData(nRow
, xType
);
685 return Sequence
< Any
>();
689 void SAL_CALL
FmXGridControl::removeModifyListener(const Reference
< css::util::XModifyListener
>& l
)
691 if( getPeer().is() && m_aModifyListeners
.getLength() == 1 )
693 Reference
< css::util::XModifyBroadcaster
> xGrid(getPeer(), UNO_QUERY
);
694 xGrid
->removeModifyListener( &m_aModifyListeners
);
696 m_aModifyListeners
.removeInterface( l
);
700 void SAL_CALL
FmXGridControl::draw( sal_Int32 x
, sal_Int32 y
)
702 SolarMutexGuard aGuard
;
704 UnoControl::draw(x
, y
);
709 void SAL_CALL
FmXGridControl::setDesignMode(sal_Bool bOn
)
711 css::util::ModeChangeEvent aModeChangeEvent
;
713 // --- <mutex_lock> ---
715 SolarMutexGuard aGuard
;
717 Reference
< XRowSetSupplier
> xGrid(getPeer(), UNO_QUERY
);
719 if (xGrid
.is() && (bool(bOn
) != mbDesignMode
|| (!bOn
&& !xGrid
->getRowSet().is())))
723 xGrid
->setRowSet(Reference
< XRowSet
> ());
727 Reference
< XFormComponent
> xComp(getModel(), UNO_QUERY
);
730 Reference
< XRowSet
> xForm(xComp
->getParent(), UNO_QUERY
);
731 xGrid
->setRowSet(xForm
);
737 Reference
< XVclWindowPeer
> xVclWindowPeer( getPeer(), UNO_QUERY
);
738 if (xVclWindowPeer
.is())
739 xVclWindowPeer
->setDesignMode(bOn
);
743 // dispose our current AccessibleContext, if we have one
744 // (changing the design mode implies having a new implementation for this context,
745 // so the old one must be declared DEFUNC)
746 DisposeAccessibleContext(
747 Reference
<XComponent
>(maAccessibleContext
, UNO_QUERY
));
748 maAccessibleContext
.clear();
750 // prepare firing an event
751 aModeChangeEvent
.Source
= *this;
752 aModeChangeEvent
.NewMode
= mbDesignMode
? OUString( "design" ) : OUString( "alive" );
755 // --- </mutex_lock> ---
756 maModeChangeListeners
.notifyEach( &XModeChangeListener::modeChanged
, aModeChangeEvent
);
761 void SAL_CALL
FmXGridControl::addUpdateListener(const Reference
< XUpdateListener
>& l
)
763 m_aUpdateListeners
.addInterface( l
);
764 if( getPeer().is() && m_aUpdateListeners
.getLength() == 1 )
766 Reference
< XBoundComponent
> xBound(getPeer(), UNO_QUERY
);
767 xBound
->addUpdateListener( &m_aUpdateListeners
);
772 void SAL_CALL
FmXGridControl::removeUpdateListener(const Reference
< XUpdateListener
>& l
)
774 if( getPeer().is() && m_aUpdateListeners
.getLength() == 1 )
776 Reference
< XBoundComponent
> xBound(getPeer(), UNO_QUERY
);
777 xBound
->removeUpdateListener( &m_aUpdateListeners
);
779 m_aUpdateListeners
.removeInterface( l
);
783 sal_Bool SAL_CALL
FmXGridControl::commit()
785 Reference
< XBoundComponent
> xBound(getPeer(), UNO_QUERY
);
787 return xBound
->commit();
794 void SAL_CALL
FmXGridControl::addContainerListener(const Reference
< XContainerListener
>& l
)
796 m_aContainerListeners
.addInterface( l
);
797 if( getPeer().is() && m_aContainerListeners
.getLength() == 1 )
799 Reference
< XContainer
> xContainer(getPeer(), UNO_QUERY
);
800 xContainer
->addContainerListener( &m_aContainerListeners
);
805 void SAL_CALL
FmXGridControl::removeContainerListener(const Reference
< XContainerListener
>& l
)
807 if( getPeer().is() && m_aContainerListeners
.getLength() == 1 )
809 Reference
< XContainer
> xContainer(getPeer(), UNO_QUERY
);
810 xContainer
->removeContainerListener( &m_aContainerListeners
);
812 m_aContainerListeners
.removeInterface( l
);
816 Reference
< css::frame::XDispatch
> SAL_CALL
FmXGridControl::queryDispatch(const css::util::URL
& aURL
, const OUString
& aTargetFrameName
, sal_Int32 nSearchFlags
)
818 Reference
< css::frame::XDispatchProvider
> xPeerProvider(getPeer(), UNO_QUERY
);
819 if (xPeerProvider
.is())
820 return xPeerProvider
->queryDispatch(aURL
, aTargetFrameName
, nSearchFlags
);
822 return Reference
< css::frame::XDispatch
> ();
826 Sequence
< Reference
< css::frame::XDispatch
> > SAL_CALL
FmXGridControl::queryDispatches(const Sequence
< css::frame::DispatchDescriptor
>& aDescripts
)
828 Reference
< css::frame::XDispatchProvider
> xPeerProvider(getPeer(), UNO_QUERY
);
829 if (xPeerProvider
.is())
830 return xPeerProvider
->queryDispatches(aDescripts
);
832 return Sequence
< Reference
< css::frame::XDispatch
> >();
836 void SAL_CALL
FmXGridControl::registerDispatchProviderInterceptor(const Reference
< css::frame::XDispatchProviderInterceptor
>& _xInterceptor
)
838 Reference
< css::frame::XDispatchProviderInterception
> xPeerInterception(getPeer(), UNO_QUERY
);
839 if (xPeerInterception
.is())
840 xPeerInterception
->registerDispatchProviderInterceptor(_xInterceptor
);
844 void SAL_CALL
FmXGridControl::releaseDispatchProviderInterceptor(const Reference
< css::frame::XDispatchProviderInterceptor
>& _xInterceptor
)
846 Reference
< css::frame::XDispatchProviderInterception
> xPeerInterception(getPeer(), UNO_QUERY
);
847 if (xPeerInterception
.is())
848 xPeerInterception
->releaseDispatchProviderInterceptor(_xInterceptor
);
852 void SAL_CALL
FmXGridControl::addGridControlListener( const Reference
< XGridControlListener
>& _listener
)
854 ::osl::MutexGuard
aGuard( GetMutex() );
856 m_aGridControlListeners
.addInterface( _listener
);
857 if ( getPeer().is() && 1 == m_aGridControlListeners
.getLength() )
859 Reference
< XGridControl
> xPeerGrid( getPeer(), UNO_QUERY
);
860 if ( xPeerGrid
.is() )
861 xPeerGrid
->addGridControlListener( &m_aGridControlListeners
);
866 void SAL_CALL
FmXGridControl::removeGridControlListener( const Reference
< XGridControlListener
>& _listener
)
868 ::osl::MutexGuard
aGuard( GetMutex() );
870 if( getPeer().is() && 1 == m_aGridControlListeners
.getLength() )
872 Reference
< XGridControl
> xPeerGrid( getPeer(), UNO_QUERY
);
873 if ( xPeerGrid
.is() )
874 xPeerGrid
->removeGridControlListener( &m_aGridControlListeners
);
877 m_aGridControlListeners
.removeInterface( _listener
);
881 sal_Int16 SAL_CALL
FmXGridControl::getCurrentColumnPosition()
883 Reference
< XGridControl
> xGrid( getPeer(), UNO_QUERY
);
884 return xGrid
.is() ? xGrid
->getCurrentColumnPosition() : -1;
888 void SAL_CALL
FmXGridControl::setCurrentColumnPosition(sal_Int16 nPos
)
890 Reference
< XGridControl
> xGrid( getPeer(), UNO_QUERY
);
893 SolarMutexGuard aGuard
;
894 xGrid
->setCurrentColumnPosition( nPos
);
900 sal_Bool SAL_CALL
FmXGridControl::hasElements()
902 Reference
< XElementAccess
> xPeer(getPeer(), UNO_QUERY
);
903 return xPeer
.is() && xPeer
->hasElements();
907 Type SAL_CALL
FmXGridControl::getElementType( )
909 return cppu::UnoType
<css::awt::XTextComponent
>::get();
912 // XEnumerationAccess
914 Reference
< XEnumeration
> SAL_CALL
FmXGridControl::createEnumeration()
916 Reference
< XEnumerationAccess
> xPeer(getPeer(), UNO_QUERY
);
918 return xPeer
->createEnumeration();
920 return new ::comphelper::OEnumerationByIndex(this);
925 sal_Int32 SAL_CALL
FmXGridControl::getCount()
927 Reference
< XIndexAccess
> xPeer(getPeer(), UNO_QUERY
);
928 return xPeer
.is() ? xPeer
->getCount() : 0;
932 Any SAL_CALL
FmXGridControl::getByIndex(sal_Int32 _nIndex
)
934 Reference
< XIndexAccess
> xPeer(getPeer(), UNO_QUERY
);
936 throw IndexOutOfBoundsException();
938 return xPeer
->getByIndex(_nIndex
);
941 // css::util::XModeSelector
943 void SAL_CALL
FmXGridControl::setMode(const OUString
& Mode
)
945 Reference
< css::util::XModeSelector
> xPeer(getPeer(), UNO_QUERY
);
947 throw NoSupportException();
949 xPeer
->setMode(Mode
);
953 OUString SAL_CALL
FmXGridControl::getMode()
955 Reference
< css::util::XModeSelector
> xPeer(getPeer(), UNO_QUERY
);
956 return xPeer
.is() ? xPeer
->getMode() : OUString();
960 css::uno::Sequence
<OUString
> SAL_CALL
FmXGridControl::getSupportedModes()
962 Reference
< css::util::XModeSelector
> xPeer(getPeer(), UNO_QUERY
);
963 return xPeer
.is() ? xPeer
->getSupportedModes() : css::uno::Sequence
<OUString
>();
967 sal_Bool SAL_CALL
FmXGridControl::supportsMode(const OUString
& Mode
)
969 Reference
< css::util::XModeSelector
> xPeer(getPeer(), UNO_QUERY
);
970 return xPeer
.is() && xPeer
->supportsMode(Mode
);
973 // helper class which prevents that in the peer's header the FmGridListener must be known
974 class FmXGridPeer::GridListenerDelegator
: public FmGridListener
977 FmXGridPeer
* m_pPeer
;
980 explicit GridListenerDelegator( FmXGridPeer
* _pPeer
);
981 virtual ~GridListenerDelegator();
984 virtual void selectionChanged() override
;
985 virtual void columnChanged() override
;
989 FmXGridPeer::GridListenerDelegator::GridListenerDelegator(FmXGridPeer
* _pPeer
)
992 DBG_ASSERT(m_pPeer
, "GridListenerDelegator::GridListenerDelegator");
995 FmXGridPeer::GridListenerDelegator::~GridListenerDelegator()
1000 void FmXGridPeer::GridListenerDelegator::selectionChanged()
1002 m_pPeer
->selectionChanged();
1006 void FmXGridPeer::GridListenerDelegator::columnChanged()
1008 m_pPeer
->columnChanged();
1011 void FmXGridPeer::selectionChanged()
1013 EventObject aSource
;
1014 aSource
.Source
= static_cast< ::cppu::OWeakObject
* >(this);
1015 m_aSelectionListeners
.notifyEach( &XSelectionChangeListener::selectionChanged
, aSource
);
1019 void FmXGridPeer::columnChanged()
1021 EventObject
aEvent( *this );
1022 m_aGridControlListeners
.notifyEach( &XGridControlListener::columnChanged
, aEvent
);
1028 const OUString
getDataModeIdentifier()
1030 return OUString("DataMode");
1033 using namespace fmgridif
;
1036 FmXGridPeer::FmXGridPeer(const Reference
< XComponentContext
>& _rxContext
)
1037 :m_aModifyListeners(m_aMutex
)
1038 ,m_aUpdateListeners(m_aMutex
)
1039 ,m_aContainerListeners(m_aMutex
)
1040 ,m_aSelectionListeners(m_aMutex
)
1041 ,m_aGridControlListeners(m_aMutex
)
1042 ,m_aMode( getDataModeIdentifier() )
1043 ,m_nCursorListening(0)
1044 ,m_bInterceptingDispatch(false)
1045 ,m_pStateCache(nullptr)
1046 ,m_pDispatchers(nullptr)
1047 ,m_pGridListener(nullptr)
1048 ,m_xContext(_rxContext
)
1050 // Create must be called after this constructor
1051 m_pGridListener
= new GridListenerDelegator( this );
1055 VclPtr
<FmGridControl
> FmXGridPeer::imp_CreateControl(vcl::Window
* pParent
, WinBits nStyle
)
1057 return VclPtr
<FmGridControl
>::Create(m_xContext
, pParent
, this, nStyle
);
1061 void FmXGridPeer::Create(vcl::Window
* pParent
, WinBits nStyle
)
1063 VclPtr
<FmGridControl
> pWin
= imp_CreateControl(pParent
, nStyle
);
1064 DBG_ASSERT(pWin
!= nullptr, "FmXGridPeer::Create : imp_CreateControl didn't return a control !");
1066 pWin
->SetStateProvider(LINK(this, FmXGridPeer
, OnQueryGridSlotState
));
1067 pWin
->SetSlotExecutor(LINK(this, FmXGridPeer
, OnExecuteGridSlot
));
1069 // want to hear about row selections
1070 pWin
->setGridListener( m_pGridListener
);
1072 // Init must always be called
1074 pWin
->SetComponentInterface(this);
1080 FmXGridPeer::~FmXGridPeer()
1082 setRowSet(Reference
< XRowSet
> ());
1083 setColumns(Reference
< XIndexContainer
> ());
1085 delete m_pGridListener
;
1090 class theFmXGridPeerImplementationId
: public rtl::Static
< UnoTunnelIdInit
, theFmXGridPeerImplementationId
> {};
1093 const Sequence
< sal_Int8
>& FmXGridPeer::getUnoTunnelImplementationId() throw()
1095 return theFmXGridPeerImplementationId::get().getSeq();
1099 FmXGridPeer
* FmXGridPeer::getImplementation( const Reference
< XInterface
>& _rxIFace
) throw()
1101 FmXGridPeer
* pReturn
= nullptr;
1102 Reference
< XUnoTunnel
> xTunnel(_rxIFace
, UNO_QUERY
);
1104 pReturn
= reinterpret_cast<FmXGridPeer
*>(xTunnel
->getSomething(getUnoTunnelImplementationId()));
1110 sal_Int64 SAL_CALL
FmXGridPeer::getSomething( const Sequence
< sal_Int8
>& _rIdentifier
)
1112 sal_Int64
nReturn(0);
1114 if ( (_rIdentifier
.getLength() == 16)
1115 && (0 == memcmp( getUnoTunnelImplementationId().getConstArray(), _rIdentifier
.getConstArray(), 16 ))
1118 nReturn
= reinterpret_cast<sal_Int64
>(this);
1121 nReturn
= VCLXWindow::getSomething(_rIdentifier
);
1128 void FmXGridPeer::disposing(const EventObject
& e
)
1130 using namespace ::com::sun::star::util
;
1131 bool bKnownSender
= false;
1133 Reference
< XIndexContainer
> xCols( e
.Source
, UNO_QUERY
);
1136 setColumns(Reference
< XIndexContainer
> ());
1137 bKnownSender
= true;
1140 Reference
< XRowSet
> xCursor(e
.Source
, UNO_QUERY
);
1143 setRowSet( m_xCursor
);
1144 m_xCursor
= nullptr;
1145 bKnownSender
= true;
1149 if ( !bKnownSender
&& m_pDispatchers
)
1151 const Sequence
< URL
>& aSupportedURLs
= getSupportedURLs();
1152 const URL
* pSupportedURLs
= aSupportedURLs
.getConstArray();
1153 for ( sal_Int32 i
=0; i
< ( aSupportedURLs
.getLength() ) && !bKnownSender
; ++i
, ++pSupportedURLs
)
1155 if ( m_pDispatchers
[i
] == e
.Source
)
1157 m_pDispatchers
[i
]->removeStatusListener( static_cast< css::frame::XStatusListener
* >( this ), *pSupportedURLs
);
1158 m_pDispatchers
[i
] = nullptr;
1159 m_pStateCache
[i
] = false;
1160 bKnownSender
= true;
1165 if ( !bKnownSender
)
1166 VCLXWindow::disposing(e
);
1170 void FmXGridPeer::addModifyListener(const Reference
< css::util::XModifyListener
>& l
)
1172 m_aModifyListeners
.addInterface( l
);
1176 void FmXGridPeer::removeModifyListener(const Reference
< css::util::XModifyListener
>& l
)
1178 m_aModifyListeners
.removeInterface( l
);
1182 #define LAST_KNOWN_TYPE FormComponentType::PATTERNFIELD
1183 Sequence
< sal_Bool
> SAL_CALL
FmXGridPeer::queryFieldDataType( const Type
& xType
)
1185 // a 'conversion table'
1186 static const bool bCanConvert
[LAST_KNOWN_TYPE
][4] =
1188 { false, false, false, false }, // FormComponentType::CONTROL
1189 { false, false, false, false }, // FormComponentType::COMMANDBUTTON
1190 { false, false, false, false }, // FormComponentType::RADIOBUTTON
1191 { false, false, false, false }, // FormComponentType::IMAGEBUTTON
1192 { false, false, false, true }, // FormComponentType::CHECKBOX
1193 { false, false, false, false }, // FormComponentType::LISTBOX
1194 { false, false, false, false }, // FormComponentType::COMBOBOX
1195 { false, false, false, false }, // FormComponentType::GROUPBOX
1196 { true , false, false, false }, // FormComponentType::TEXTFIELD
1197 { false, false, false, false }, // FormComponentType::FIXEDTEXT
1198 { false, false, false, false }, // FormComponentType::GRIDCONTROL
1199 { false, false, false, false }, // FormComponentType::FILECONTROL
1200 { false, false, false, false }, // FormComponentType::HIDDENCONTROL
1201 { false, false, false, false }, // FormComponentType::IMAGECONTROL
1202 { true , true , true , false }, // FormComponentType::DATEFIELD
1203 { true , true , false, false }, // FormComponentType::TIMEFIELD
1204 { true , true , false, false }, // FormComponentType::NUMERICFIELD
1205 { true , true , false, false }, // FormComponentType::CURRENCYFIELD
1206 { true , false, false, false } // FormComponentType::PATTERNFIELD
1210 sal_Int16 nMapColumn
= -1;
1211 switch (xType
.getTypeClass())
1213 case TypeClass_STRING
: nMapColumn
= 0; break;
1214 case TypeClass_FLOAT
:
1215 case TypeClass_DOUBLE
: nMapColumn
= 1; break;
1216 case TypeClass_SHORT
:
1217 case TypeClass_LONG
:
1218 case TypeClass_UNSIGNED_LONG
:
1219 case TypeClass_UNSIGNED_SHORT
: nMapColumn
= 2; break;
1220 case TypeClass_BOOLEAN
: nMapColumn
= 3; break;
1225 Reference
< XIndexContainer
> xColumns
= getColumns();
1227 VclPtr
< FmGridControl
> pGrid
= GetAs
< FmGridControl
>();
1228 sal_Int32 nColumns
= pGrid
->GetViewColCount();
1230 DbGridColumns aColumns
= pGrid
->GetColumns();
1232 Sequence
<sal_Bool
> aReturnSequence(nColumns
);
1233 sal_Bool
* pReturnArray
= aReturnSequence
.getArray();
1235 bool bRequestedAsAny
= (xType
.getTypeClass() == TypeClass_ANY
);
1238 Reference
< css::sdb::XColumn
> xFieldContent
;
1239 Reference
< XPropertySet
> xCurrentColumn
;
1240 for (sal_Int32 i
=0; i
<nColumns
; ++i
)
1242 if (bRequestedAsAny
)
1244 pReturnArray
[i
] = true;
1248 pReturnArray
[i
] = false;
1250 sal_uInt16 nModelPos
= pGrid
->GetModelColumnPos(pGrid
->GetColumnIdFromViewPos((sal_uInt16
)i
));
1251 DBG_ASSERT(nModelPos
!= (sal_uInt16
)-1, "FmXGridPeer::queryFieldDataType : no model pos !");
1253 pCol
= aColumns
[ nModelPos
];
1254 const DbGridRowRef xRow
= pGrid
->GetSeekRow();
1255 xFieldContent
= (xRow
.is() && xRow
->HasField(pCol
->GetFieldPos())) ? xRow
->GetField(pCol
->GetFieldPos()).getColumn() : Reference
< css::sdb::XColumn
> ();
1256 if (!xFieldContent
.is())
1257 // can't supply anything without a field content
1258 // FS - 07.12.99 - 54391
1261 xColumns
->getByIndex(nModelPos
) >>= xCurrentColumn
;
1262 if (!::comphelper::hasProperty(FM_PROP_CLASSID
, xCurrentColumn
))
1265 sal_Int16 nClassId
= sal_Int16();
1266 xCurrentColumn
->getPropertyValue(FM_PROP_CLASSID
) >>= nClassId
;
1267 if (nClassId
>LAST_KNOWN_TYPE
)
1269 DBG_ASSERT(nClassId
>0, "FmXGridPeer::queryFieldDataType : somebody changed the definition of the FormComponentType enum !");
1271 if (nMapColumn
!= -1)
1272 pReturnArray
[i
] = bCanConvert
[nClassId
-1][nMapColumn
];
1275 return aReturnSequence
;
1279 Sequence
< Any
> SAL_CALL
FmXGridPeer::queryFieldData( sal_Int32 nRow
, const Type
& xType
)
1281 VclPtr
< FmGridControl
> pGrid
= GetAs
< FmGridControl
>();
1282 DBG_ASSERT(pGrid
&& pGrid
->IsOpen(), "FmXGridPeer::queryFieldData : have no valid grid window !");
1283 if (!pGrid
|| !pGrid
->IsOpen())
1284 return Sequence
< Any
>();
1286 // move the control to the specified row
1287 if (!pGrid
->SeekRow(nRow
))
1289 throw IllegalArgumentException();
1292 // don't use GetCurrentRow as this isn't affected by the above SeekRow
1293 // FS - 30.09.99 - 68644
1294 DbGridRowRef xPaintRow
= pGrid
->GetPaintRow();
1295 ENSURE_OR_THROW( xPaintRow
.is(), "invalid paint row" );
1297 // I need the columns of the control for GetFieldText
1298 DbGridColumns aColumns
= pGrid
->GetColumns();
1300 // and through all the columns
1301 sal_Int32 nColumnCount
= pGrid
->GetViewColCount();
1303 Sequence
< Any
> aReturnSequence(nColumnCount
);
1304 Any
* pReturnArray
= aReturnSequence
.getArray();
1306 bool bRequestedAsAny
= (xType
.getTypeClass() == TypeClass_ANY
);
1307 Reference
< css::sdb::XColumn
> xFieldContent
;
1308 for (sal_Int32 i
=0; i
< nColumnCount
; ++i
)
1310 sal_uInt16 nModelPos
= pGrid
->GetModelColumnPos(pGrid
->GetColumnIdFromViewPos((sal_uInt16
)i
));
1311 DBG_ASSERT(nModelPos
!= (sal_uInt16
)-1, "FmXGridPeer::queryFieldData : invalid model pos !");
1313 // don't use GetCurrentFieldValue to determine the field content as this isn't affected by the above SeekRow
1314 // FS - 30.09.99 - 68644
1315 DbGridColumn
* pCol
= aColumns
[ nModelPos
];
1316 xFieldContent
= xPaintRow
->HasField( pCol
->GetFieldPos() )
1317 ? xPaintRow
->GetField( pCol
->GetFieldPos() ).getColumn()
1318 : Reference
< XColumn
> ();
1320 if ( !xFieldContent
.is() )
1323 if (bRequestedAsAny
)
1325 Reference
< XPropertySet
> xFieldSet(xFieldContent
, UNO_QUERY
);
1326 pReturnArray
[i
] = xFieldSet
->getPropertyValue(FM_PROP_VALUE
);
1330 switch (xType
.getTypeClass())
1332 // Strings are dealt with directly by the GetFieldText
1333 case TypeClass_STRING
:
1335 OUString sText
= aColumns
[ nModelPos
]->GetCellText( xPaintRow
.get(), pGrid
->getNumberFormatter() );
1336 pReturnArray
[i
] <<= sText
;
1339 // everything else is requested in the DatabaseVariant
1340 case TypeClass_FLOAT
: pReturnArray
[i
] <<= xFieldContent
->getFloat(); break;
1341 case TypeClass_DOUBLE
: pReturnArray
[i
] <<= xFieldContent
->getDouble(); break;
1342 case TypeClass_SHORT
: pReturnArray
[i
] <<= (sal_Int16
)xFieldContent
->getShort(); break;
1343 case TypeClass_LONG
: pReturnArray
[i
] <<= (sal_Int32
)xFieldContent
->getLong(); break;
1344 case TypeClass_UNSIGNED_SHORT
: pReturnArray
[i
] <<= (sal_uInt16
)xFieldContent
->getShort(); break;
1345 case TypeClass_UNSIGNED_LONG
: pReturnArray
[i
] <<= (sal_uInt32
)xFieldContent
->getLong(); break;
1346 case TypeClass_BOOLEAN
: pReturnArray
[i
] <<= xFieldContent
->getBoolean(); break;
1349 throw IllegalArgumentException();
1354 return aReturnSequence
;
1358 void FmXGridPeer::CellModified()
1361 aEvt
.Source
= static_cast< ::cppu::OWeakObject
* >(this);
1362 m_aModifyListeners
.notifyEach( &XModifyListener::modified
, aEvt
);
1365 // XPropertyChangeListener
1367 void FmXGridPeer::propertyChange(const PropertyChangeEvent
& evt
)
1369 SolarMutexGuard aGuard
;
1370 // want to do a lot of VCL stuff here ...
1371 // this should not be (deadlock) critical, as by definition, every component should release
1372 // any own mutexes before notifying
1374 VclPtr
< FmGridControl
> pGrid
= GetAs
< FmGridControl
>();
1379 if (evt
.PropertyName
== FM_PROP_VALUE
|| m_xCursor
== evt
.Source
)
1380 pGrid
->propertyChange(evt
);
1381 else if (pGrid
&& m_xColumns
.is() && m_xColumns
->hasElements())
1383 // next find which column has changed
1384 css::uno::Reference
<css::uno::XInterface
> xCurrent
;
1387 for ( i
= 0; i
< m_xColumns
->getCount(); i
++)
1389 xCurrent
.set(m_xColumns
->getByIndex(i
), css::uno::UNO_QUERY
);
1390 if (evt
.Source
== xCurrent
)
1394 if (i
>= m_xColumns
->getCount())
1395 // this is valid because we are listening at the cursor, too (RecordCount, -status, edit mode)
1398 sal_uInt16 nId
= pGrid
->GetColumnIdFromModelPos((sal_uInt16
)i
);
1399 bool bInvalidateColumn
= false;
1401 if (evt
.PropertyName
== FM_PROP_LABEL
)
1403 OUString aName
= ::comphelper::getString(evt
.NewValue
);
1404 if (aName
!= pGrid
->GetColumnTitle(nId
))
1405 pGrid
->SetColumnTitle(nId
, aName
);
1407 else if (evt
.PropertyName
== FM_PROP_WIDTH
)
1409 sal_Int32 nWidth
= 0;
1410 if (evt
.NewValue
.getValueType().getTypeClass() == TypeClass_VOID
)
1411 nWidth
= pGrid
->GetDefaultColumnWidth(pGrid
->GetColumnTitle(nId
));
1412 // GetDefaultColumnWidth already considered the zoom factor
1415 sal_Int32 nTest
= 0;
1416 if (evt
.NewValue
>>= nTest
)
1418 nWidth
= pGrid
->LogicToPixel(Point(nTest
,0),MapUnit::Map10thMM
).X();
1419 // take the zoom factor into account
1420 nWidth
= pGrid
->CalcZoom(nWidth
);
1423 if (nWidth
!= (sal_Int32(pGrid
->GetColumnWidth(nId
))))
1425 if (pGrid
->IsEditing())
1427 pGrid
->DeactivateCell();
1428 pGrid
->ActivateCell();
1430 pGrid
->SetColumnWidth(nId
, nWidth
);
1433 else if (evt
.PropertyName
== FM_PROP_HIDDEN
)
1435 DBG_ASSERT(evt
.NewValue
.getValueType().getTypeClass() == TypeClass_BOOLEAN
,
1436 "FmXGridPeer::propertyChange : the property 'hidden' should be of type boolean !");
1437 if (::comphelper::getBOOL(evt
.NewValue
))
1438 pGrid
->HideColumn(nId
);
1440 pGrid
->ShowColumn(nId
);
1442 else if (evt
.PropertyName
== FM_PROP_ALIGN
)
1444 // in design mode it doesn't matter
1445 if (!isDesignMode())
1447 DbGridColumn
* pCol
= pGrid
->GetColumns().at( i
);
1449 pCol
->SetAlignmentFromModel(-1);
1450 bInvalidateColumn
= true;
1453 else if (evt
.PropertyName
== FM_PROP_FORMATKEY
)
1455 if (!isDesignMode())
1456 bInvalidateColumn
= true;
1459 // need to invalidate the affected column ?
1460 if (bInvalidateColumn
)
1462 bool bWasEditing
= pGrid
->IsEditing();
1464 pGrid
->DeactivateCell();
1466 ::tools::Rectangle aColRect
= pGrid
->GetFieldRect(nId
);
1468 aColRect
.Bottom() = pGrid
->GetSizePixel().Height();
1469 pGrid
->Invalidate(aColRect
);
1472 pGrid
->ActivateCell();
1479 void FmXGridPeer::addUpdateListener(const Reference
< XUpdateListener
>& l
)
1481 m_aUpdateListeners
.addInterface(l
);
1485 void FmXGridPeer::removeUpdateListener(const Reference
< XUpdateListener
>& l
)
1487 m_aUpdateListeners
.removeInterface(l
);
1491 sal_Bool
FmXGridPeer::commit()
1493 VclPtr
< FmGridControl
> pGrid
= GetAs
< FmGridControl
>();
1494 if (!m_xCursor
.is() || !pGrid
)
1497 EventObject
aEvt(static_cast< ::cppu::OWeakObject
* >(this));
1498 ::comphelper::OInterfaceIteratorHelper2
aIter(m_aUpdateListeners
);
1499 bool bCancel
= false;
1500 while (aIter
.hasMoreElements() && !bCancel
)
1501 if ( !static_cast< XUpdateListener
* >( aIter
.next() )->approveUpdate( aEvt
) )
1505 bCancel
= !pGrid
->commit();
1508 m_aUpdateListeners
.notifyEach( &XUpdateListener::updated
, aEvt
);
1513 void FmXGridPeer::cursorMoved(const EventObject
& _rEvent
)
1515 VclPtr
< FmGridControl
> pGrid
= GetAs
< FmGridControl
>();
1516 // we are not interested in move to insert row only in the resetted event
1517 // which is fired after positioning an the insert row
1518 if (pGrid
&& pGrid
->IsOpen() && !::comphelper::getBOOL(Reference
< XPropertySet
> (_rEvent
.Source
, UNO_QUERY
)->getPropertyValue(FM_PROP_ISNEW
)))
1519 pGrid
->positioned();
1523 void FmXGridPeer::rowChanged(const EventObject
& /*_rEvent*/)
1525 VclPtr
< FmGridControl
> pGrid
= GetAs
< FmGridControl
>();
1526 if (pGrid
&& pGrid
->IsOpen())
1528 if (m_xCursor
->rowUpdated() && !pGrid
->IsCurrentAppending())
1529 pGrid
->RowModified(pGrid
->GetCurrentPos());
1530 else if (m_xCursor
->rowInserted())
1536 void FmXGridPeer::rowSetChanged(const EventObject
& /*event*/)
1538 // not interested in ...
1539 // (our parent is a form which means we get a loaded or reloaded after this rowSetChanged)
1544 void FmXGridPeer::loaded(const EventObject
& /*rEvent*/)
1546 updateGrid(m_xCursor
);
1550 void FmXGridPeer::unloaded(const EventObject
& /*rEvent*/)
1552 updateGrid( Reference
< XRowSet
> (nullptr) );
1556 void FmXGridPeer::reloading(const EventObject
& /*aEvent*/)
1559 updateGrid( Reference
< XRowSet
> (nullptr) );
1563 void FmXGridPeer::unloading(const EventObject
& /*aEvent*/)
1566 updateGrid( Reference
< XRowSet
> (nullptr) );
1570 void FmXGridPeer::reloaded(const EventObject
& aEvent
)
1573 const sal_Int32 cnt
= m_xColumns
->getCount();
1574 for(sal_Int32 i
=0; i
<cnt
; ++i
)
1576 Reference
< XLoadListener
> xll(m_xColumns
->getByIndex(i
), UNO_QUERY
);
1579 xll
->reloaded(aEvent
);
1583 updateGrid(m_xCursor
);
1588 Reference
< XIndexContainer
> FmXGridPeer::getColumns()
1594 void FmXGridPeer::addColumnListeners(const Reference
< XPropertySet
>& xCol
)
1596 static const OUStringLiteral aPropsListenedTo
[] =
1598 FM_PROP_LABEL
, FM_PROP_WIDTH
, FM_PROP_HIDDEN
, FM_PROP_ALIGN
,
1602 // as not all properties have to be supported by all columns we have to check this
1603 // before adding a listener
1604 Reference
< XPropertySetInfo
> xInfo
= xCol
->getPropertySetInfo();
1605 for (unsigned i
=0; i
<SAL_N_ELEMENTS(aPropsListenedTo
); ++i
)
1607 if ( xInfo
->hasPropertyByName( aPropsListenedTo
[i
] ) )
1609 Property aPropDesc
= xInfo
->getPropertyByName( aPropsListenedTo
[i
] );
1610 if ( 0 != ( aPropDesc
.Attributes
& PropertyAttribute::BOUND
) )
1611 xCol
->addPropertyChangeListener( aPropsListenedTo
[i
], this );
1617 void FmXGridPeer::removeColumnListeners(const Reference
< XPropertySet
>& xCol
)
1619 // the same props as in addColumnListeners ... linux has problems with global static UStrings, so
1620 // we have to do it this way ....
1621 static const OUStringLiteral aPropsListenedTo
[] =
1623 FM_PROP_LABEL
, FM_PROP_WIDTH
, FM_PROP_HIDDEN
, FM_PROP_ALIGN
,
1627 Reference
< XPropertySetInfo
> xInfo
= xCol
->getPropertySetInfo();
1628 for (const auto & i
: aPropsListenedTo
)
1629 if (xInfo
->hasPropertyByName(i
))
1630 xCol
->removePropertyChangeListener(i
, this);
1634 void FmXGridPeer::setColumns(const Reference
< XIndexContainer
>& Columns
)
1636 SolarMutexGuard aGuard
;
1638 VclPtr
< FmGridControl
> pGrid
= GetAs
< FmGridControl
>();
1640 if (m_xColumns
.is())
1642 Reference
< XPropertySet
> xCol
;
1643 for (sal_Int32 i
= 0; i
< m_xColumns
->getCount(); i
++)
1645 xCol
.set(m_xColumns
->getByIndex(i
), css::uno::UNO_QUERY
);
1646 removeColumnListeners(xCol
);
1648 Reference
< XContainer
> xContainer(m_xColumns
, UNO_QUERY
);
1649 xContainer
->removeContainerListener(this);
1651 Reference
< XSelectionSupplier
> xSelSupplier(m_xColumns
, UNO_QUERY
);
1652 xSelSupplier
->removeSelectionChangeListener(this);
1654 Reference
< XReset
> xColumnReset(m_xColumns
, UNO_QUERY
);
1655 if (xColumnReset
.is())
1656 xColumnReset
->removeResetListener(static_cast<XResetListener
*>(this));
1660 Reference
< XContainer
> xContainer(Columns
, UNO_QUERY
);
1661 xContainer
->addContainerListener(this);
1663 Reference
< XSelectionSupplier
> xSelSupplier(Columns
, UNO_QUERY
);
1664 xSelSupplier
->addSelectionChangeListener(this);
1666 Reference
< XPropertySet
> xCol
;
1667 for (sal_Int32 i
= 0; i
< Columns
->getCount(); i
++)
1669 xCol
.set(Columns
->getByIndex(i
), css::uno::UNO_QUERY
);
1670 addColumnListeners(xCol
);
1673 Reference
< XReset
> xColumnReset(Columns
, UNO_QUERY
);
1674 if (xColumnReset
.is())
1675 xColumnReset
->addResetListener(static_cast<XResetListener
*>(this));
1677 m_xColumns
= Columns
;
1680 pGrid
->InitColumnsByModels(m_xColumns
);
1682 if (m_xColumns
.is())
1684 EventObject
aEvt(m_xColumns
);
1685 selectionChanged(aEvt
);
1691 void FmXGridPeer::setDesignMode(sal_Bool bOn
)
1693 if (bOn
!= isDesignMode())
1695 VclPtr
<vcl::Window
> pWin
= GetWindow();
1697 static_cast<FmGridControl
*>(pWin
.get())->SetDesignMode(bOn
);
1701 DisConnectFromDispatcher();
1703 UpdateDispatches(); // will connect if not already connected and just update else
1707 sal_Bool
FmXGridPeer::isDesignMode()
1709 VclPtr
<vcl::Window
> pWin
= GetWindow();
1711 return static_cast<FmGridControl
*>(pWin
.get())->IsDesignMode();
1717 void FmXGridPeer::elementInserted(const ContainerEvent
& evt
)
1719 SolarMutexGuard aGuard
;
1721 VclPtr
< FmGridControl
> pGrid
= GetAs
< FmGridControl
>();
1722 // take handle column into account
1723 if (!pGrid
|| !m_xColumns
.is() || pGrid
->IsInColumnMove() || m_xColumns
->getCount() == ((sal_Int32
)pGrid
->GetModelColCount()))
1726 Reference
< XPropertySet
> xNewColumn(evt
.Element
, css::uno::UNO_QUERY
);
1727 addColumnListeners(xNewColumn
);
1729 OUString aName
= ::comphelper::getString(xNewColumn
->getPropertyValue(FM_PROP_LABEL
));
1730 Any aWidth
= xNewColumn
->getPropertyValue(FM_PROP_WIDTH
);
1731 sal_Int32 nWidth
= 0;
1732 if (aWidth
>>= nWidth
)
1733 nWidth
= pGrid
->LogicToPixel(Point(nWidth
,0),MapUnit::Map10thMM
).X();
1735 pGrid
->AppendColumn(aName
, (sal_uInt16
)nWidth
, (sal_Int16
)::comphelper::getINT32(evt
.Accessor
));
1737 // now set the column
1738 DbGridColumn
* pCol
= pGrid
->GetColumns().at( ::comphelper::getINT32(evt
.Accessor
) );
1739 pCol
->setModel(xNewColumn
);
1741 Any aHidden
= xNewColumn
->getPropertyValue(FM_PROP_HIDDEN
);
1742 if (::comphelper::getBOOL(aHidden
))
1743 pGrid
->HideColumn(pCol
->GetId());
1745 FormControlFactory( m_xContext
).initializeTextFieldLineEnds( xNewColumn
);
1749 void FmXGridPeer::elementReplaced(const ContainerEvent
& evt
)
1751 SolarMutexGuard aGuard
;
1753 VclPtr
< FmGridControl
> pGrid
= GetAs
< FmGridControl
>();
1755 // take handle column into account
1756 if (!pGrid
|| !m_xColumns
.is() || pGrid
->IsInColumnMove())
1759 Reference
< XPropertySet
> xNewColumn(evt
.Element
, css::uno::UNO_QUERY
);
1760 Reference
< XPropertySet
> xOldColumn(
1761 evt
.ReplacedElement
, css::uno::UNO_QUERY
);
1763 bool bWasEditing
= pGrid
->IsEditing();
1765 pGrid
->DeactivateCell();
1767 pGrid
->RemoveColumn(pGrid
->GetColumnIdFromModelPos((sal_uInt16
)::comphelper::getINT32(evt
.Accessor
)));
1769 removeColumnListeners(xOldColumn
);
1770 addColumnListeners(xNewColumn
);
1772 OUString aName
= ::comphelper::getString(xNewColumn
->getPropertyValue(FM_PROP_LABEL
));
1773 Any aWidth
= xNewColumn
->getPropertyValue(FM_PROP_WIDTH
);
1774 sal_Int32 nWidth
= 0;
1775 if (aWidth
>>= nWidth
)
1776 nWidth
= pGrid
->LogicToPixel(Point(nWidth
,0),MapUnit::Map10thMM
).X();
1777 sal_uInt16 nNewId
= pGrid
->AppendColumn(aName
, (sal_uInt16
)nWidth
, (sal_Int16
)::comphelper::getINT32(evt
.Accessor
));
1778 sal_uInt16 nNewPos
= pGrid
->GetModelColumnPos(nNewId
);
1780 // set the model of the new column
1781 DbGridColumn
* pCol
= pGrid
->GetColumns().at( nNewPos
);
1783 // for initializing this grid column, we need the fields of the grid's data source
1784 Reference
< XColumnsSupplier
> xSuppColumns
;
1785 CursorWrapper
* pGridDataSource
= pGrid
->getDataSource();
1786 if ( pGridDataSource
)
1787 xSuppColumns
.set(Reference
< XInterface
>( *pGridDataSource
), css::uno::UNO_QUERY
);
1788 Reference
< XNameAccess
> xColumnsByName
;
1789 if ( xSuppColumns
.is() )
1790 xColumnsByName
= xSuppColumns
->getColumns();
1791 Reference
< XIndexAccess
> xColumnsByIndex( xColumnsByName
, UNO_QUERY
);
1793 if ( xColumnsByIndex
.is() )
1794 FmGridControl::InitColumnByField( pCol
, xNewColumn
, xColumnsByName
, xColumnsByIndex
);
1796 // the simple version, applies when the grid is not yet connected to a data source
1797 pCol
->setModel(xNewColumn
);
1800 pGrid
->ActivateCell();
1804 void FmXGridPeer::elementRemoved(const ContainerEvent
& evt
)
1806 SolarMutexGuard aGuard
;
1808 VclPtr
< FmGridControl
> pGrid
= GetAs
< FmGridControl
>();
1810 // take handle column into account
1811 if (!pGrid
|| !m_xColumns
.is() || pGrid
->IsInColumnMove() || m_xColumns
->getCount() == ((sal_Int32
)pGrid
->GetModelColCount()))
1814 pGrid
->RemoveColumn(pGrid
->GetColumnIdFromModelPos((sal_uInt16
)::comphelper::getINT32(evt
.Accessor
)));
1816 Reference
< XPropertySet
> xOldColumn(evt
.Element
, css::uno::UNO_QUERY
);
1817 removeColumnListeners(xOldColumn
);
1821 void FmXGridPeer::setProperty( const OUString
& PropertyName
, const Any
& Value
)
1823 SolarMutexGuard aGuard
;
1825 VclPtr
< FmGridControl
> pGrid
= GetAs
< FmGridControl
>();
1827 bool bVoid
= !Value
.hasValue();
1829 if ( PropertyName
== FM_PROP_TEXTLINECOLOR
)
1831 ::Color
aTextLineColor( bVoid
? COL_TRANSPARENT
: ::comphelper::getINT32( Value
) );
1834 pGrid
->SetTextLineColor();
1835 pGrid
->GetDataWindow().SetTextLineColor();
1839 pGrid
->SetTextLineColor(aTextLineColor
);
1840 pGrid
->GetDataWindow().SetTextLineColor(aTextLineColor
);
1843 // need to forward this to the columns
1844 DbGridColumns
& rColumns
= const_cast<DbGridColumns
&>(pGrid
->GetColumns());
1845 for (DbGridColumn
* pLoop
: rColumns
)
1847 FmXGridCell
* pXCell
= pLoop
->GetCell();
1851 pXCell
->SetTextLineColor();
1853 pXCell
->SetTextLineColor(aTextLineColor
);
1858 pGrid
->Invalidate();
1860 else if ( PropertyName
== FM_PROP_FONTEMPHASISMARK
)
1862 vcl::Font aGridFont
= pGrid
->GetControlFont();
1863 sal_Int16 nValue
= ::comphelper::getINT16(Value
);
1864 aGridFont
.SetEmphasisMark( (FontEmphasisMark
)nValue
);
1865 pGrid
->SetControlFont( aGridFont
);
1867 else if ( PropertyName
== FM_PROP_FONTRELIEF
)
1869 vcl::Font aGridFont
= pGrid
->GetControlFont();
1870 sal_Int16 nValue
= ::comphelper::getINT16(Value
);
1871 aGridFont
.SetRelief( (FontRelief
)nValue
);
1872 pGrid
->SetControlFont( aGridFont
);
1874 else if ( PropertyName
== FM_PROP_HELPURL
)
1877 OSL_VERIFY( Value
>>= sHelpURL
);
1878 INetURLObject
aHID( sHelpURL
);
1879 if ( aHID
.GetProtocol() == INetProtocol::Hid
)
1880 sHelpURL
= aHID
.GetURLPath();
1881 pGrid
->SetHelpId( OUStringToOString( sHelpURL
, RTL_TEXTENCODING_UTF8
) );
1883 else if ( PropertyName
== FM_PROP_DISPLAYSYNCHRON
)
1885 pGrid
->setDisplaySynchron(::comphelper::getBOOL(Value
));
1887 else if ( PropertyName
== FM_PROP_CURSORCOLOR
)
1890 pGrid
->SetCursorColor(COL_TRANSPARENT
);
1892 pGrid
->SetCursorColor( ::Color(::comphelper::getINT32(Value
)));
1894 pGrid
->Invalidate();
1896 else if ( PropertyName
== FM_PROP_ALWAYSSHOWCURSOR
)
1898 pGrid
->EnablePermanentCursor(::comphelper::getBOOL(Value
));
1900 pGrid
->Invalidate();
1902 else if ( PropertyName
== FM_PROP_FONT
)
1905 pGrid
->SetControlFont( vcl::Font() );
1908 css::awt::FontDescriptor aFont
;
1909 if (Value
>>= aFont
)
1911 vcl::Font aNewVclFont
;
1912 if (aFont
!= ::comphelper::getDefaultFont()) // is this the default
1913 aNewVclFont
= ImplCreateFont( aFont
);
1915 // need to add relief and emphasis (they're stored in a VCL-Font, but not in a FontDescriptor
1916 vcl::Font aOldVclFont
= pGrid
->GetControlFont();
1917 aNewVclFont
.SetRelief( aOldVclFont
.GetRelief() );
1918 aNewVclFont
.SetEmphasisMark( aOldVclFont
.GetEmphasisMark() );
1921 pGrid
->SetControlFont( aNewVclFont
);
1923 // if our row-height property is void (which means "calculate it font-dependent") we have
1924 // to adjust the control's row height
1925 Reference
< XPropertySet
> xModelSet(getColumns(), UNO_QUERY
);
1926 if (xModelSet
.is() && ::comphelper::hasProperty(FM_PROP_ROWHEIGHT
, xModelSet
))
1928 Any aHeight
= xModelSet
->getPropertyValue(FM_PROP_ROWHEIGHT
);
1929 if (!aHeight
.hasValue())
1930 pGrid
->SetDataRowHeight(0);
1936 else if ( PropertyName
== FM_PROP_BACKGROUNDCOLOR
)
1940 pGrid
->SetControlBackground();
1944 ::Color
aColor( ::comphelper::getINT32(Value
) );
1945 pGrid
->SetBackground( aColor
);
1946 pGrid
->SetControlBackground( aColor
);
1949 else if ( PropertyName
== FM_PROP_TEXTCOLOR
)
1953 pGrid
->SetControlForeground();
1957 ::Color
aColor( ::comphelper::getINT32(Value
) );
1958 pGrid
->SetTextColor( aColor
);
1959 pGrid
->SetControlForeground( aColor
);
1962 else if ( PropertyName
== FM_PROP_ROWHEIGHT
)
1964 sal_Int32
nLogHeight(0);
1965 if (Value
>>= nLogHeight
)
1967 sal_Int32 nHeight
= pGrid
->LogicToPixel(Point(0,nLogHeight
),MapUnit::Map10thMM
).Y();
1968 // take the zoom factor into account
1969 nHeight
= pGrid
->CalcZoom(nHeight
);
1970 pGrid
->SetDataRowHeight(nHeight
);
1973 pGrid
->SetDataRowHeight(0);
1975 else if ( PropertyName
== FM_PROP_HASNAVIGATION
)
1977 bool bValue( true );
1978 OSL_VERIFY( Value
>>= bValue
);
1979 pGrid
->EnableNavigationBar( bValue
);
1981 else if ( PropertyName
== FM_PROP_RECORDMARKER
)
1983 bool bValue( true );
1984 OSL_VERIFY( Value
>>= bValue
);
1985 pGrid
->EnableHandle( bValue
);
1987 else if ( PropertyName
== FM_PROP_ENABLED
)
1989 bool bValue( true );
1990 OSL_VERIFY( Value
>>= bValue
);
1992 // In design mode, disable only the data window.
1993 // Else the control cannot be configured anymore.
1995 pGrid
->GetDataWindow().Enable( bValue
);
1997 pGrid
->Enable( bValue
);
2000 VCLXWindow::setProperty( PropertyName
, Value
);
2004 Reference
< XAccessibleContext
> FmXGridPeer::CreateAccessibleContext()
2006 Reference
< XAccessibleContext
> xContext
;
2008 // use the AccessibleContext provided by the VCL window
2009 VclPtr
<vcl::Window
> pGrid
= GetWindow();
2012 Reference
< XAccessible
> xAcc( pGrid
->GetAccessible() );
2014 xContext
= xAcc
->getAccessibleContext();
2015 // TODO: this has a slight conceptual problem:
2017 // We know that the XAccessible and XAccessibleContext implementation of the browse
2018 // box is the same (the class implements both interfaces), which, speaking strictly,
2019 // is bad here (means when a browse box acts as UnoControl): We (the FmXGridPeer) are
2020 // the XAccessible here, and the browse box should be able to provide us an XAccessibleContext,
2021 // but it should _not_ be the XAccessible itself.
2022 // However, as long as no client implementation uses dirty hacks such as querying an
2023 // XAccessibleContext for XAccessible, this should not be a problem.
2026 if ( !xContext
.is() )
2027 xContext
= VCLXWindow::CreateAccessibleContext( );
2033 Any
FmXGridPeer::getProperty( const OUString
& _rPropertyName
)
2038 VclPtr
< FmGridControl
> pGrid
= GetAs
< FmGridControl
>();
2039 vcl::Window
* pDataWindow
= &pGrid
->GetDataWindow();
2041 if ( _rPropertyName
== FM_PROP_NAME
)
2043 vcl::Font aFont
= pDataWindow
->GetControlFont();
2044 aProp
<<= ImplCreateFontDescriptor( aFont
);
2046 else if ( _rPropertyName
== FM_PROP_TEXTCOLOR
)
2048 aProp
<<= (sal_Int32
)pDataWindow
->GetControlForeground().GetColor();
2050 else if ( _rPropertyName
== FM_PROP_BACKGROUNDCOLOR
)
2052 aProp
<<= (sal_Int32
)pDataWindow
->GetControlBackground().GetColor();
2054 else if ( _rPropertyName
== FM_PROP_ROWHEIGHT
)
2056 sal_Int32 nPixelHeight
= pGrid
->GetDataRowHeight();
2057 // take the zoom factor into account
2058 nPixelHeight
= pGrid
->CalcReverseZoom(nPixelHeight
);
2059 aProp
<<= (sal_Int32
)pGrid
->PixelToLogic(Point(0,nPixelHeight
),MapUnit::Map10thMM
).Y();
2061 else if ( _rPropertyName
== FM_PROP_HASNAVIGATION
)
2063 bool bHasNavBar
= pGrid
->HasNavigationBar();
2064 aProp
<<= bHasNavBar
;
2066 else if ( _rPropertyName
== FM_PROP_RECORDMARKER
)
2068 bool bHasHandle
= pGrid
->HasHandle();
2069 aProp
<<= bHasHandle
;
2071 else if ( _rPropertyName
== FM_PROP_ENABLED
)
2073 aProp
<<= pDataWindow
->IsEnabled();
2076 aProp
= VCLXWindow::getProperty( _rPropertyName
);
2082 void FmXGridPeer::dispose()
2085 aEvt
.Source
= static_cast< ::cppu::OWeakObject
* >(this);
2086 m_aModifyListeners
.disposeAndClear(aEvt
);
2087 m_aUpdateListeners
.disposeAndClear(aEvt
);
2088 m_aContainerListeners
.disposeAndClear(aEvt
);
2089 VCLXWindow::dispose();
2091 // release all interceptors
2092 Reference
< XDispatchProviderInterceptor
> xInterceptor( m_xFirstDispatchInterceptor
);
2093 m_xFirstDispatchInterceptor
.clear();
2094 while ( xInterceptor
.is() )
2096 // tell the interceptor it has a new (means no) predecessor
2097 xInterceptor
->setMasterDispatchProvider( nullptr );
2099 // ask for its successor
2100 Reference
< XDispatchProvider
> xSlave
= xInterceptor
->getSlaveDispatchProvider();
2101 // and give it the new (means no) successoert
2102 xInterceptor
->setSlaveDispatchProvider( nullptr );
2104 // start over with the next chain element
2105 xInterceptor
.set(xSlave
, css::uno::UNO_QUERY
);
2108 DisConnectFromDispatcher();
2109 setRowSet(Reference
< XRowSet
> ());
2114 void FmXGridPeer::addContainerListener(const Reference
< XContainerListener
>& l
)
2116 m_aContainerListeners
.addInterface( l
);
2119 void FmXGridPeer::removeContainerListener(const Reference
< XContainerListener
>& l
)
2121 m_aContainerListeners
.removeInterface( l
);
2124 // css::data::XDatabaseCursorSupplier
2126 void FmXGridPeer::startCursorListening()
2128 if (!m_nCursorListening
)
2130 Reference
< XRowSet
> xRowSet(m_xCursor
, UNO_QUERY
);
2132 xRowSet
->addRowSetListener(this);
2134 Reference
< XReset
> xReset(m_xCursor
, UNO_QUERY
);
2136 xReset
->addResetListener(this);
2138 // register all listeners
2139 Reference
< XPropertySet
> xSet(m_xCursor
, UNO_QUERY
);
2142 xSet
->addPropertyChangeListener(FM_PROP_ISMODIFIED
, this);
2143 xSet
->addPropertyChangeListener(FM_PROP_ROWCOUNT
, this);
2146 m_nCursorListening
++;
2150 void FmXGridPeer::stopCursorListening()
2152 if (!--m_nCursorListening
)
2154 Reference
< XRowSet
> xRowSet(m_xCursor
, UNO_QUERY
);
2156 xRowSet
->removeRowSetListener(this);
2158 Reference
< XReset
> xReset(m_xCursor
, UNO_QUERY
);
2160 xReset
->removeResetListener(this);
2162 Reference
< XPropertySet
> xSet(m_xCursor
, UNO_QUERY
);
2165 xSet
->removePropertyChangeListener(FM_PROP_ISMODIFIED
, this);
2166 xSet
->removePropertyChangeListener(FM_PROP_ROWCOUNT
, this);
2172 void FmXGridPeer::updateGrid(const Reference
< XRowSet
>& _rxCursor
)
2174 VclPtr
< FmGridControl
> pGrid
= GetAs
< FmGridControl
>();
2176 pGrid
->setDataSource(_rxCursor
);
2180 Reference
< XRowSet
> FmXGridPeer::getRowSet()
2186 void FmXGridPeer::setRowSet(const Reference
< XRowSet
>& _rDatabaseCursor
)
2188 VclPtr
< FmGridControl
> pGrid
= GetAs
< FmGridControl
>();
2189 if (!pGrid
|| !m_xColumns
.is() || !m_xColumns
->getCount())
2191 // unregister all listeners
2194 Reference
< XLoadable
> xLoadable(m_xCursor
, UNO_QUERY
);
2195 // only if the form is loaded we set the rowset
2198 stopCursorListening();
2199 xLoadable
->removeLoadListener(this);
2203 m_xCursor
= _rDatabaseCursor
;
2207 Reference
< XLoadable
> xLoadable(m_xCursor
, UNO_QUERY
);
2208 // only if the form is loaded we set the rowset
2209 if (xLoadable
.is() && xLoadable
->isLoaded())
2210 pGrid
->setDataSource(m_xCursor
);
2212 pGrid
->setDataSource(Reference
< XRowSet
> ());
2216 startCursorListening();
2217 xLoadable
->addLoadListener(this);
2223 void SAL_CALL
FmXGridPeer::addGridControlListener( const Reference
< XGridControlListener
>& _listener
)
2225 m_aGridControlListeners
.addInterface( _listener
);
2229 void SAL_CALL
FmXGridPeer::removeGridControlListener( const Reference
< XGridControlListener
>& _listener
)
2231 m_aGridControlListeners
.removeInterface( _listener
);
2235 sal_Int16
FmXGridPeer::getCurrentColumnPosition()
2237 VclPtr
< FmGridControl
> pGrid
= GetAs
< FmGridControl
>();
2238 return pGrid
? pGrid
->GetViewColumnPos(pGrid
->GetCurColumnId()) : -1;
2242 void FmXGridPeer::setCurrentColumnPosition(sal_Int16 nPos
)
2244 VclPtr
< FmGridControl
> pGrid
= GetAs
< FmGridControl
>();
2246 pGrid
->GoToColumnId(pGrid
->GetColumnIdFromViewPos(nPos
));
2250 void FmXGridPeer::selectionChanged(const EventObject
& evt
)
2252 SolarMutexGuard aGuard
;
2254 VclPtr
< FmGridControl
> pGrid
= GetAs
< FmGridControl
>();
2257 Reference
< css::view::XSelectionSupplier
> xSelSupplier(evt
.Source
, UNO_QUERY
);
2258 Any aSelection
= xSelSupplier
->getSelection();
2259 DBG_ASSERT(aSelection
.getValueType().getTypeClass() == TypeClass_INTERFACE
, "FmXGridPeer::selectionChanged : invalid selection !");
2260 Reference
< XPropertySet
> xSelection
;
2261 aSelection
>>= xSelection
;
2262 if (xSelection
.is())
2264 Reference
< XPropertySet
> xCol
;
2266 sal_Int32 nColCount
= m_xColumns
->getCount();
2268 for (; i
< nColCount
; ++i
)
2270 m_xColumns
->getByIndex(i
) >>= xCol
;
2271 if ( xCol
== xSelection
)
2273 pGrid
->markColumn(pGrid
->GetColumnIdFromModelPos((sal_uInt16
)i
));
2277 // The columns have to be 1-based for the VCL control.
2278 // If necessary, pass on the selection to the VCL control
2279 if ( i
!= pGrid
->GetSelectedColumn() )
2280 { // (if this does not take effect, the selectionChanged was implicitly triggered by the control itself)
2281 if ( i
< nColCount
)
2283 pGrid
->SelectColumnPos(pGrid
->GetViewColumnPos(pGrid
->GetColumnIdFromModelPos( (sal_uInt16
)i
)) + 1);
2284 // SelectColumnPos has led to an implicit ActivateCell again
2285 if (pGrid
->IsEditing())
2286 pGrid
->DeactivateCell();
2289 pGrid
->SetNoSelection();
2293 pGrid
->markColumn(USHRT_MAX
);
2299 sal_Bool
FmXGridPeer::hasElements()
2301 return getCount() != 0;
2305 Type SAL_CALL
FmXGridPeer::getElementType( )
2307 return cppu::UnoType
<css::awt::XControl
>::get();
2310 // XEnumerationAccess
2312 Reference
< XEnumeration
> FmXGridPeer::createEnumeration()
2314 return new ::comphelper::OEnumerationByIndex(this);
2319 sal_Int32
FmXGridPeer::getCount()
2321 VclPtr
< FmGridControl
> pGrid
= GetAs
< FmGridControl
>();
2323 return pGrid
->GetViewColCount();
2329 Any
FmXGridPeer::getByIndex(sal_Int32 _nIndex
)
2331 VclPtr
< FmGridControl
> pGrid
= GetAs
< FmGridControl
>();
2333 _nIndex
>= getCount() || !pGrid
)
2334 throw IndexOutOfBoundsException();
2338 sal_uInt16 nId
= pGrid
->GetColumnIdFromViewPos((sal_uInt16
)_nIndex
);
2339 // get the list position
2340 sal_uInt16 nPos
= pGrid
->GetModelColumnPos(nId
);
2342 if ( nPos
== GRID_COLUMN_NOT_FOUND
)
2345 DbGridColumn
* pCol
= pGrid
->GetColumns().at( nPos
);
2346 Reference
< css::awt::XControl
> xControl(pCol
->GetCell());
2347 aElement
<<= xControl
;
2352 // css::util::XModeSelector
2354 void FmXGridPeer::setMode(const OUString
& Mode
)
2356 if (!supportsMode(Mode
))
2357 throw NoSupportException();
2359 if (Mode
== m_aMode
)
2364 VclPtr
< FmGridControl
> pGrid
= GetAs
< FmGridControl
>();
2365 if ( Mode
== "FilterMode" )
2366 pGrid
->SetFilterMode(true);
2369 pGrid
->SetFilterMode(false);
2370 pGrid
->setDataSource(m_xCursor
);
2375 OUString
FmXGridPeer::getMode()
2381 css::uno::Sequence
<OUString
> FmXGridPeer::getSupportedModes()
2383 static css::uno::Sequence
<OUString
> aModes
;
2384 if (!aModes
.getLength())
2387 OUString
* pModes
= aModes
.getArray();
2388 pModes
[0] = "DataMode";
2389 pModes
[1] = "FilterMode";
2395 sal_Bool
FmXGridPeer::supportsMode(const OUString
& Mode
)
2397 css::uno::Sequence
<OUString
> aModes(getSupportedModes());
2398 const OUString
* pModes
= aModes
.getConstArray();
2399 for (sal_Int32 i
= aModes
.getLength(); i
> 0; )
2401 if (pModes
[--i
] == Mode
)
2408 void FmXGridPeer::columnVisible(DbGridColumn
* pColumn
)
2410 VclPtr
< FmGridControl
> pGrid
= GetAs
< FmGridControl
>();
2412 sal_Int32 _nIndex
= pGrid
->GetModelColumnPos(pColumn
->GetId());
2413 Reference
< css::awt::XControl
> xControl(pColumn
->GetCell());
2414 ContainerEvent aEvt
;
2415 aEvt
.Source
= static_cast<XContainer
*>(this);
2416 aEvt
.Accessor
<<= _nIndex
;
2417 aEvt
.Element
<<= xControl
;
2419 m_aContainerListeners
.notifyEach( &XContainerListener::elementInserted
, aEvt
);
2423 void FmXGridPeer::columnHidden(DbGridColumn
* pColumn
)
2425 VclPtr
< FmGridControl
> pGrid
= GetAs
< FmGridControl
>();
2427 sal_Int32 _nIndex
= pGrid
->GetModelColumnPos(pColumn
->GetId());
2428 Reference
< css::awt::XControl
> xControl(pColumn
->GetCell());
2429 ContainerEvent aEvt
;
2430 aEvt
.Source
= static_cast<XContainer
*>(this);
2431 aEvt
.Accessor
<<= _nIndex
;
2432 aEvt
.Element
<<= xControl
;
2434 m_aContainerListeners
.notifyEach( &XContainerListener::elementRemoved
, aEvt
);
2438 void FmXGridPeer::draw( sal_Int32 x
, sal_Int32 y
)
2440 VclPtr
< FmGridControl
> pGrid
= GetAs
< FmGridControl
>();
2441 EditBrowseBoxFlags nOldFlags
= pGrid
->GetBrowserFlags();
2442 pGrid
->SetBrowserFlags(nOldFlags
| EditBrowseBoxFlags::NO_HANDLE_COLUMN_CONTENT
);
2444 VCLXWindow::draw(x
, y
);
2446 pGrid
->SetBrowserFlags(nOldFlags
);
2450 Reference
< css::frame::XDispatch
> FmXGridPeer::queryDispatch(const css::util::URL
& aURL
, const OUString
& aTargetFrameName
, sal_Int32 nSearchFlags
)
2452 Reference
< css::frame::XDispatch
> xResult
;
2454 // first ask our interceptor chain
2455 if (m_xFirstDispatchInterceptor
.is() && !m_bInterceptingDispatch
)
2457 m_bInterceptingDispatch
= true;
2458 // safety against recursion : as we are master of the first chain element and slave of the last one we would
2459 // have an infinite loop without this if no dispatcher can fulfill the request
2460 xResult
= m_xFirstDispatchInterceptor
->queryDispatch(aURL
, aTargetFrameName
, nSearchFlags
);
2461 m_bInterceptingDispatch
= false;
2464 // then ask ourself : we don't have any dispatches
2469 Sequence
< Reference
< css::frame::XDispatch
> > FmXGridPeer::queryDispatches(const Sequence
< css::frame::DispatchDescriptor
>& aDescripts
)
2471 if (m_xFirstDispatchInterceptor
.is())
2472 return m_xFirstDispatchInterceptor
->queryDispatches(aDescripts
);
2474 // then ask ourself : we don't have any dispatches
2475 return Sequence
< Reference
< css::frame::XDispatch
> >();
2479 void FmXGridPeer::registerDispatchProviderInterceptor(const Reference
< css::frame::XDispatchProviderInterceptor
>& _xInterceptor
)
2481 if (_xInterceptor
.is())
2483 if (m_xFirstDispatchInterceptor
.is())
2485 Reference
< css::frame::XDispatchProvider
> xFirstProvider(m_xFirstDispatchInterceptor
, UNO_QUERY
);
2486 // there is already an interceptor; the new one will become its master
2487 _xInterceptor
->setSlaveDispatchProvider(xFirstProvider
);
2488 m_xFirstDispatchInterceptor
->setMasterDispatchProvider(xFirstProvider
);
2492 // it is the first interceptor; set ourself as slave
2493 _xInterceptor
->setSlaveDispatchProvider(static_cast<css::frame::XDispatchProvider
*>(this));
2496 // we are the master of the chain's first interceptor
2497 m_xFirstDispatchInterceptor
= _xInterceptor
;
2498 m_xFirstDispatchInterceptor
->setMasterDispatchProvider(static_cast<css::frame::XDispatchProvider
*>(this));
2500 // we have a new interceptor and we're alive ?
2501 if (!isDesignMode())
2502 // -> check for new dispatchers
2508 void FmXGridPeer::releaseDispatchProviderInterceptor(const Reference
< css::frame::XDispatchProviderInterceptor
>& _xInterceptor
)
2510 if (!_xInterceptor
.is())
2513 Reference
< css::frame::XDispatchProviderInterceptor
> xChainWalk(m_xFirstDispatchInterceptor
);
2515 if (m_xFirstDispatchInterceptor
== _xInterceptor
)
2516 { // our chain will have a new first element
2517 Reference
< css::frame::XDispatchProviderInterceptor
> xSlave(m_xFirstDispatchInterceptor
->getSlaveDispatchProvider(), UNO_QUERY
);
2518 m_xFirstDispatchInterceptor
= xSlave
;
2520 // do this before removing the interceptor from the chain as we won't know it's slave afterwards)
2522 while (xChainWalk
.is())
2524 // walk along the chain of interceptors and look for the interceptor that has to be removed
2525 Reference
< css::frame::XDispatchProviderInterceptor
> xSlave(xChainWalk
->getSlaveDispatchProvider(), UNO_QUERY
);
2527 if (xChainWalk
== _xInterceptor
)
2529 // old master may be an interceptor too
2530 Reference
< css::frame::XDispatchProviderInterceptor
> xMaster(xChainWalk
->getMasterDispatchProvider(), UNO_QUERY
);
2532 // unchain the interceptor that has to be removed
2533 xChainWalk
->setSlaveDispatchProvider(Reference
< css::frame::XDispatchProvider
> ());
2534 xChainWalk
->setMasterDispatchProvider(Reference
< css::frame::XDispatchProvider
> ());
2536 // reconnect the chain
2540 xMaster
->setSlaveDispatchProvider(Reference
< css::frame::XDispatchProvider
>::query(xSlave
));
2542 // it's the first interceptor of the chain, set ourself as slave
2543 xMaster
->setSlaveDispatchProvider(static_cast<css::frame::XDispatchProvider
*>(this));
2547 // the chain's first element was removed, set ourself as new master of the second one
2549 xSlave
->setMasterDispatchProvider(static_cast<css::frame::XDispatchProvider
*>(this));
2553 xChainWalk
= xSlave
;
2555 // our interceptor chain has changed and we're alive ?
2556 if (!isDesignMode())
2557 // -> check the dispatchers
2562 void FmXGridPeer::statusChanged(const css::frame::FeatureStateEvent
& Event
)
2564 DBG_ASSERT(m_pStateCache
, "FmXGridPeer::statusChanged : invalid call !");
2565 DBG_ASSERT(m_pDispatchers
, "FmXGridPeer::statusChanged : invalid call !");
2567 Sequence
< css::util::URL
>& aUrls
= getSupportedURLs();
2568 const css::util::URL
* pUrls
= aUrls
.getConstArray();
2570 const std::vector
<DbGridControlNavigationBarState
>& aSlots
= getSupportedGridSlots();
2573 for (i
=0; i
<aUrls
.getLength(); ++i
, ++pUrls
)
2575 if (pUrls
->Main
== Event
.FeatureURL
.Main
)
2577 DBG_ASSERT(m_pDispatchers
[i
] == Event
.Source
, "FmXGridPeer::statusChanged : the event source is a little bit suspect !");
2578 m_pStateCache
[i
] = Event
.IsEnabled
;
2579 VclPtr
< FmGridControl
> pGrid
= GetAs
< FmGridControl
>();
2580 if (aSlots
[i
] != DbGridControlNavigationBarState::Undo
)
2581 pGrid
->GetNavigationBar().InvalidateState(aSlots
[i
]);
2585 DBG_ASSERT(i
<aUrls
.getLength(), "FmXGridPeer::statusChanged : got a call for an unknown url !");
2589 sal_Bool
FmXGridPeer::approveReset(const EventObject
& /*rEvent*/)
2595 sal_Bool SAL_CALL
FmXGridPeer::select( const Any
& _rSelection
)
2597 Sequence
< Any
> aBookmarks
;
2598 if ( !( _rSelection
>>= aBookmarks
) )
2599 throw IllegalArgumentException();
2601 return GetAs
< FmGridControl
>()->selectBookmarks(aBookmarks
);
2604 // speaking strictly, we would have to adjust our model, as our ColumnSelection may have changed.
2605 // Our model is a XSelectionSupplier, too, it handles the selection of single columns.
2606 // This is somewhat strange, as selection should be a view (not a model) aspect.
2607 // So for a clean solution, we should handle column selection ourself, and the model shouldn't
2608 // deal with selection at all.
2612 Any SAL_CALL
FmXGridPeer::getSelection( )
2614 VclPtr
< FmGridControl
> pVclControl
= GetAs
< FmGridControl
>();
2615 Sequence
< Any
> aSelectionBookmarks
= pVclControl
->getSelectionBookmarks();
2616 return makeAny(aSelectionBookmarks
);
2620 void SAL_CALL
FmXGridPeer::addSelectionChangeListener( const Reference
< XSelectionChangeListener
>& _rxListener
)
2622 m_aSelectionListeners
.addInterface( _rxListener
);
2626 void SAL_CALL
FmXGridPeer::removeSelectionChangeListener( const Reference
< XSelectionChangeListener
>& _rxListener
)
2628 m_aSelectionListeners
.removeInterface( _rxListener
);
2632 void FmXGridPeer::resetted(const EventObject
& rEvent
)
2634 if (m_xColumns
== rEvent
.Source
)
2635 { // my model was reset -> refresh the grid content
2636 SolarMutexGuard aGuard
;
2637 VclPtr
< FmGridControl
> pGrid
= GetAs
< FmGridControl
>();
2640 pGrid
->resetCurrentRow();
2642 // if the cursor fired a reset event we seem to be on the insert row
2643 else if (m_xCursor
== rEvent
.Source
)
2645 SolarMutexGuard aGuard
;
2646 VclPtr
< FmGridControl
> pGrid
= GetAs
< FmGridControl
>();
2647 if (pGrid
&& pGrid
->IsOpen())
2648 pGrid
->positioned();
2653 const std::vector
<DbGridControlNavigationBarState
>& FmXGridPeer::getSupportedGridSlots()
2655 static const std::vector
<DbGridControlNavigationBarState
> aSupported
{
2656 DbGridControlNavigationBarState::First
,
2657 DbGridControlNavigationBarState::Prev
,
2658 DbGridControlNavigationBarState::Next
,
2659 DbGridControlNavigationBarState::Last
,
2660 DbGridControlNavigationBarState::New
,
2661 DbGridControlNavigationBarState::Undo
2667 Sequence
< css::util::URL
>& FmXGridPeer::getSupportedURLs()
2669 static Sequence
< css::util::URL
> aSupported
;
2670 if (aSupported
.getLength() == 0)
2672 static const char* sSupported
[] = {
2673 FMURL_RECORD_MOVEFIRST
,
2674 FMURL_RECORD_MOVEPREV
,
2675 FMURL_RECORD_MOVENEXT
,
2676 FMURL_RECORD_MOVELAST
,
2677 FMURL_RECORD_MOVETONEW
,
2680 aSupported
.realloc(SAL_N_ELEMENTS(sSupported
));
2681 css::util::URL
* pSupported
= aSupported
.getArray();
2683 for ( sal_Int32 i
= 0; i
< aSupported
.getLength(); ++i
, ++pSupported
)
2684 pSupported
->Complete
= OUString::createFromAscii(sSupported
[i
]);
2686 // let an css::util::URL-transformer normalize the URLs
2687 Reference
< css::util::XURLTransformer
> xTransformer(
2688 util::URLTransformer::create(::comphelper::getProcessComponentContext()) );
2689 pSupported
= aSupported
.getArray();
2690 for (sal_Int32 i
=0; i
<aSupported
.getLength(); ++i
)
2691 xTransformer
->parseStrict(pSupported
[i
]);
2698 void FmXGridPeer::UpdateDispatches()
2701 { // we don't have any dispatchers yet -> do the initial connect
2702 ConnectToDispatcher();
2706 sal_uInt16 nDispatchersGot
= 0;
2707 const Sequence
< css::util::URL
>& aSupportedURLs
= getSupportedURLs();
2708 const css::util::URL
* pSupportedURLs
= aSupportedURLs
.getConstArray();
2709 Reference
< css::frame::XDispatch
> xNewDispatch
;
2710 for (sal_Int32 i
=0; i
<aSupportedURLs
.getLength(); ++i
, ++pSupportedURLs
)
2712 xNewDispatch
= queryDispatch(*pSupportedURLs
, OUString(), 0);
2713 if (xNewDispatch
!= m_pDispatchers
[i
])
2715 if (m_pDispatchers
[i
].is())
2716 m_pDispatchers
[i
]->removeStatusListener(static_cast<css::frame::XStatusListener
*>(this), *pSupportedURLs
);
2717 m_pDispatchers
[i
] = xNewDispatch
;
2718 if (m_pDispatchers
[i
].is())
2719 m_pDispatchers
[i
]->addStatusListener(static_cast<css::frame::XStatusListener
*>(this), *pSupportedURLs
);
2721 if (m_pDispatchers
[i
].is())
2725 if (!nDispatchersGot
)
2727 delete[] m_pStateCache
;
2728 delete[] m_pDispatchers
;
2729 m_pStateCache
= nullptr;
2730 m_pDispatchers
= nullptr;
2735 void FmXGridPeer::ConnectToDispatcher()
2737 DBG_ASSERT((m_pStateCache
!= nullptr) == (m_pDispatchers
!= nullptr), "FmXGridPeer::ConnectToDispatcher : inconsistent !");
2739 { // already connected -> just do an update
2744 const Sequence
< css::util::URL
>& aSupportedURLs
= getSupportedURLs();
2746 // _before_ adding the status listeners (as the add should result in a statusChanged-call) !
2747 m_pStateCache
= new bool[aSupportedURLs
.getLength()];
2748 m_pDispatchers
= new Reference
< css::frame::XDispatch
> [aSupportedURLs
.getLength()];
2750 sal_uInt16 nDispatchersGot
= 0;
2751 const css::util::URL
* pSupportedURLs
= aSupportedURLs
.getConstArray();
2752 for (sal_Int32 i
=0; i
<aSupportedURLs
.getLength(); ++i
, ++pSupportedURLs
)
2754 m_pStateCache
[i
] = false;
2755 m_pDispatchers
[i
] = queryDispatch(*pSupportedURLs
, OUString(), 0);
2756 if (m_pDispatchers
[i
].is())
2758 m_pDispatchers
[i
]->addStatusListener(static_cast<css::frame::XStatusListener
*>(this), *pSupportedURLs
);
2763 if (!nDispatchersGot
)
2765 delete[] m_pStateCache
;
2766 delete[] m_pDispatchers
;
2767 m_pStateCache
= nullptr;
2768 m_pDispatchers
= nullptr;
2773 void FmXGridPeer::DisConnectFromDispatcher()
2775 if (!m_pStateCache
|| !m_pDispatchers
)
2777 // we're not connected
2779 const Sequence
< css::util::URL
>& aSupportedURLs
= getSupportedURLs();
2780 const css::util::URL
* pSupportedURLs
= aSupportedURLs
.getConstArray();
2781 for (sal_Int32 i
=0; i
<aSupportedURLs
.getLength(); ++i
, ++pSupportedURLs
)
2783 if (m_pDispatchers
[i
].is())
2784 m_pDispatchers
[i
]->removeStatusListener(static_cast<css::frame::XStatusListener
*>(this), *pSupportedURLs
);
2787 delete[] m_pStateCache
;
2788 delete[] m_pDispatchers
;
2789 m_pStateCache
= nullptr;
2790 m_pDispatchers
= nullptr;
2794 IMPL_LINK(FmXGridPeer
, OnQueryGridSlotState
, DbGridControlNavigationBarState
, nSlot
, int)
2797 return -1; // unspecified
2799 // search the given slot with our supported sequence
2800 const std::vector
<DbGridControlNavigationBarState
>& aSupported
= getSupportedGridSlots();
2801 for (size_t i
=0; i
<aSupported
.size(); ++i
)
2803 if (aSupported
[i
] == nSlot
)
2805 if (!m_pDispatchers
[i
].is())
2806 return -1; // nothing known about this slot
2808 return m_pStateCache
[i
] ? 1 : 0;
2816 IMPL_LINK(FmXGridPeer
, OnExecuteGridSlot
, DbGridControlNavigationBarState
, nSlot
, bool)
2818 if (!m_pDispatchers
)
2819 return false; // not handled
2821 Sequence
< css::util::URL
>& aUrls
= getSupportedURLs();
2822 const css::util::URL
* pUrls
= aUrls
.getConstArray();
2824 const std::vector
<DbGridControlNavigationBarState
>& aSlots
= getSupportedGridSlots();
2826 DBG_ASSERT((sal_Int32
)aSlots
.size() == aUrls
.getLength(), "FmXGridPeer::OnExecuteGridSlot : inconsistent data returned by getSupportedURLs/getSupportedGridSlots!");
2828 for (size_t i
=0; i
<aSlots
.size(); ++i
, ++pUrls
)
2830 if (aSlots
[i
] == nSlot
)
2832 if (m_pDispatchers
[i
].is())
2834 // commit any changes done so far, if it's not the undoRecord URL
2835 if ( pUrls
->Complete
== FMURL_RECORD_UNDO
|| commit() )
2836 m_pDispatchers
[i
]->dispatch(*pUrls
, Sequence
< PropertyValue
>());
2838 return true; // handled
2843 return false; // not handled
2846 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */