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/sdbc/ResultSetType.hpp>
40 #include <com/sun/star/sdbcx/XColumnsSupplier.hpp>
41 #include <com/sun/star/util/URLTransformer.hpp>
42 #include <com/sun/star/util/XURLTransformer.hpp>
43 #include <com/sun/star/view/XSelectionSupplier.hpp>
44 #include <com/sun/star/sdbcx/XRowLocate.hpp>
46 #include <comphelper/container.hxx>
47 #include <comphelper/enumhelper.hxx>
48 #include <comphelper/processfactory.hxx>
49 #include <comphelper/property.hxx>
50 #include <comphelper/sequence.hxx>
51 #include <comphelper/servicehelper.hxx>
52 #include <comphelper/types.hxx>
53 #include <cppuhelper/supportsservice.hxx>
54 #include <cppuhelper/typeprovider.hxx>
55 #include <toolkit/helper/vclunohelper.hxx>
56 #include <tools/diagnose_ex.h>
57 #include <sal/macros.h>
59 using namespace ::svxform
;
60 using namespace ::com::sun::star::container
;
61 using namespace ::com::sun::star::sdb
;
62 using namespace ::com::sun::star::sdbc
;
63 using namespace ::com::sun::star::uno
;
64 using namespace ::com::sun::star::view
;
65 using namespace ::com::sun::star::beans
;
66 using namespace ::com::sun::star::lang
;
67 using namespace ::com::sun::star::form
;
68 using namespace ::com::sun::star::util
;
69 using namespace ::com::sun::star
;
71 using ::com::sun::star::sdbcx::XColumnsSupplier
;
72 using ::com::sun::star::frame::XDispatchProviderInterceptor
;
73 using ::com::sun::star::frame::XDispatchProvider
;
74 using ::com::sun::star::accessibility::XAccessible
;
75 using ::com::sun::star::accessibility::XAccessibleContext
;
76 using ::com::sun::star::sdb::XRowSetSupplier
;
77 using ::com::sun::star::awt::XVclWindowPeer
;
81 ::com::sun::star::awt::FontDescriptor
ImplCreateFontDescriptor( const Font
& rFont
)
83 ::com::sun::star::awt::FontDescriptor aFD
;
84 aFD
.Name
= rFont
.GetName();
85 aFD
.StyleName
= rFont
.GetStyleName();
86 aFD
.Height
= (sal_Int16
)rFont
.GetSize().Height();
87 aFD
.Width
= (sal_Int16
)rFont
.GetSize().Width();
88 aFD
.Family
= (sal_Int16
)rFont
.GetFamily();
89 aFD
.CharSet
= rFont
.GetCharSet();
90 aFD
.Pitch
= (sal_Int16
)rFont
.GetPitch();
91 aFD
.CharacterWidth
= VCLUnoHelper::ConvertFontWidth( rFont
.GetWidthType() );
92 aFD
.Weight
= VCLUnoHelper::ConvertFontWeight( rFont
.GetWeight() );
93 aFD
.Slant
= (::com::sun::star::awt::FontSlant
)rFont
.GetItalic();
94 aFD
.Underline
= (sal_Int16
)rFont
.GetUnderline();
95 aFD
.Strikeout
= (sal_Int16
)rFont
.GetStrikeout();
96 aFD
.Orientation
= rFont
.GetOrientation();
97 aFD
.Kerning
= rFont
.IsKerning();
98 aFD
.WordLineMode
= rFont
.IsWordLineMode();
99 aFD
.Type
= 0; // ??? => Nur an Metric...
104 Font
ImplCreateFont( const ::com::sun::star::awt::FontDescriptor
& rDescr
)
107 aFont
.SetName( rDescr
.Name
);
108 aFont
.SetStyleName( rDescr
.StyleName
);
109 aFont
.SetSize( ::Size( rDescr
.Width
, rDescr
.Height
) );
110 aFont
.SetFamily( (FontFamily
)rDescr
.Family
);
111 aFont
.SetCharSet( (rtl_TextEncoding
)rDescr
.CharSet
);
112 aFont
.SetPitch( (FontPitch
)rDescr
.Pitch
);
113 aFont
.SetWidthType( VCLUnoHelper::ConvertFontWidth( rDescr
.CharacterWidth
) );
114 aFont
.SetWeight( VCLUnoHelper::ConvertFontWeight( rDescr
.Weight
) );
115 aFont
.SetItalic( (FontItalic
)rDescr
.Slant
);
116 aFont
.SetUnderline( (::FontUnderline
)rDescr
.Underline
);
117 aFont
.SetStrikeout( (::FontStrikeout
)rDescr
.Strikeout
);
118 aFont
.SetOrientation( (sal_Int16
)rDescr
.Orientation
);
119 aFont
.SetKerning( rDescr
.Kerning
);
120 aFont
.SetWordLineMode( rDescr
.WordLineMode
);
125 //= FmXModifyMultiplexer
128 FmXModifyMultiplexer::FmXModifyMultiplexer( ::cppu::OWeakObject
& rSource
, ::osl::Mutex
& _rMutex
)
129 :OWeakSubObject( rSource
)
130 ,OInterfaceContainerHelper( _rMutex
)
135 Any SAL_CALL
FmXModifyMultiplexer::queryInterface(const Type
& _rType
) throw (RuntimeException
, std::exception
)
138 aReturn
= ::cppu::queryInterface(_rType
,
139 static_cast< ::com::sun::star::util::XModifyListener
*>(this),
140 static_cast< XEventListener
*>(this)
143 if (!aReturn
.hasValue())
144 aReturn
= OWeakSubObject::queryInterface( _rType
);
150 void FmXModifyMultiplexer::disposing(const EventObject
& ) throw( RuntimeException
, std::exception
)
155 void FmXModifyMultiplexer::modified(const EventObject
& e
) throw( RuntimeException
, std::exception
)
157 EventObject
aMulti( e
);
158 aMulti
.Source
= &m_rParent
;
159 notifyEach( &XModifyListener::modified
, aMulti
);
163 //= FmXUpdateMultiplexer
166 FmXUpdateMultiplexer::FmXUpdateMultiplexer( ::cppu::OWeakObject
& rSource
, ::osl::Mutex
& _rMutex
)
167 :OWeakSubObject( rSource
)
168 ,OInterfaceContainerHelper( _rMutex
)
173 Any SAL_CALL
FmXUpdateMultiplexer::queryInterface(const Type
& _rType
) throw (RuntimeException
, std::exception
)
176 aReturn
= ::cppu::queryInterface(_rType
,
177 static_cast< XUpdateListener
*>(this),
178 static_cast< XEventListener
*>(this)
181 if (!aReturn
.hasValue())
182 aReturn
= OWeakSubObject::queryInterface( _rType
);
188 void FmXUpdateMultiplexer::disposing(const EventObject
& ) throw( RuntimeException
, std::exception
)
193 sal_Bool
FmXUpdateMultiplexer::approveUpdate(const EventObject
&e
) throw( RuntimeException
, std::exception
)
195 EventObject
aMulti( e
);
196 aMulti
.Source
= &m_rParent
;
201 ::cppu::OInterfaceIteratorHelper
aIter(*this);
202 while ( bResult
&& aIter
.hasMoreElements() )
203 bResult
= static_cast< XUpdateListener
* >( aIter
.next() )->approveUpdate( aMulti
);
210 void FmXUpdateMultiplexer::updated(const EventObject
&e
) throw( RuntimeException
, std::exception
)
212 EventObject
aMulti( e
);
213 aMulti
.Source
= &m_rParent
;
214 notifyEach( &XUpdateListener::updated
, aMulti
);
219 //= FmXSelectionMultiplexer
222 FmXSelectionMultiplexer::FmXSelectionMultiplexer( ::cppu::OWeakObject
& rSource
, ::osl::Mutex
& _rMutex
)
223 :OWeakSubObject( rSource
)
224 ,OInterfaceContainerHelper( _rMutex
)
229 Any SAL_CALL
FmXSelectionMultiplexer::queryInterface(const Type
& _rType
) throw (RuntimeException
, std::exception
)
232 aReturn
= ::cppu::queryInterface(_rType
,
233 static_cast< XSelectionChangeListener
*>(this),
234 static_cast< XEventListener
*>(this)
237 if (!aReturn
.hasValue())
238 aReturn
= OWeakSubObject::queryInterface( _rType
);
244 void FmXSelectionMultiplexer::disposing(const EventObject
& ) throw( RuntimeException
, std::exception
)
249 void SAL_CALL
FmXSelectionMultiplexer::selectionChanged( const EventObject
& _rEvent
) throw (RuntimeException
, std::exception
)
251 EventObject
aMulti(_rEvent
);
252 aMulti
.Source
= &m_rParent
;
253 notifyEach( &XSelectionChangeListener::selectionChanged
, aMulti
);
257 //= FmXContainerMultiplexer
260 FmXContainerMultiplexer::FmXContainerMultiplexer( ::cppu::OWeakObject
& rSource
, ::osl::Mutex
& _rMutex
)
261 :OWeakSubObject( rSource
)
262 ,OInterfaceContainerHelper( _rMutex
)
267 Any SAL_CALL
FmXContainerMultiplexer::queryInterface(const Type
& _rType
) throw (RuntimeException
, std::exception
)
270 aReturn
= ::cppu::queryInterface(_rType
,
271 static_cast< XContainerListener
*>(this),
272 static_cast< XEventListener
*>(this)
275 if (!aReturn
.hasValue())
276 aReturn
= OWeakSubObject::queryInterface( _rType
);
282 void FmXContainerMultiplexer::disposing(const EventObject
& ) throw( RuntimeException
, std::exception
)
286 void FmXContainerMultiplexer::elementInserted(const ContainerEvent
& e
) throw( RuntimeException
, std::exception
)
288 ContainerEvent
aMulti( e
);
289 aMulti
.Source
= &m_rParent
;
290 notifyEach( &XContainerListener::elementInserted
, aMulti
);
294 void FmXContainerMultiplexer::elementRemoved(const ContainerEvent
& e
) throw( RuntimeException
, std::exception
)
296 ContainerEvent
aMulti( e
);
297 aMulti
.Source
= &m_rParent
;
298 notifyEach( &XContainerListener::elementRemoved
, aMulti
);
303 void FmXContainerMultiplexer::elementReplaced(const ContainerEvent
& e
) throw( RuntimeException
, std::exception
)
305 ContainerEvent
aMulti( e
);
306 aMulti
.Source
= &m_rParent
;
307 notifyEach( &XContainerListener::elementReplaced
, aMulti
);
311 //= FmXGridControlMultiplexer
314 FmXGridControlMultiplexer::FmXGridControlMultiplexer( ::cppu::OWeakObject
& rSource
, ::osl::Mutex
& _rMutex
)
315 :OWeakSubObject( rSource
)
316 ,OInterfaceContainerHelper( _rMutex
)
321 Any SAL_CALL
FmXGridControlMultiplexer::queryInterface(const Type
& _rType
) throw (RuntimeException
, std::exception
)
324 aReturn
= ::cppu::queryInterface( _rType
,
325 static_cast< XGridControlListener
*>(this)
328 if (!aReturn
.hasValue())
329 aReturn
= OWeakSubObject::queryInterface( _rType
);
335 void FmXGridControlMultiplexer::disposing( const EventObject
& ) throw( RuntimeException
, std::exception
)
340 void SAL_CALL
FmXGridControlMultiplexer::columnChanged( const EventObject
& _event
) throw (RuntimeException
, std::exception
)
342 EventObject
aForwardedEvent( _event
);
343 aForwardedEvent
.Source
= &m_rParent
;
344 notifyEach( &XGridControlListener::columnChanged
, aForwardedEvent
);
352 Reference
< XInterface
> SAL_CALL
FmXGridControl_NewInstance_Impl(const Reference
< XMultiServiceFactory
>& _rxFactory
)
353 throw (css::uno::Exception
)
355 return *(new FmXGridControl( comphelper::getComponentContext(_rxFactory
) ));
358 FmXGridControl::FmXGridControl(const Reference
< XComponentContext
>& _rxContext
)
360 ,m_aModifyListeners(*this, GetMutex())
361 ,m_aUpdateListeners(*this, GetMutex())
362 ,m_aContainerListeners(*this, GetMutex())
363 ,m_aSelectionListeners(*this, GetMutex())
364 ,m_aGridControlListeners(*this, GetMutex())
365 ,m_nPeerCreationLevel(0)
367 ,m_xContext(_rxContext
)
372 FmXGridControl::~FmXGridControl()
377 Any SAL_CALL
FmXGridControl::queryAggregation(const Type
& _rType
) throw (RuntimeException
, std::exception
)
379 Any aReturn
= FmXGridControl_BASE::queryInterface(_rType
);
381 if (!aReturn
.hasValue())
382 aReturn
= UnoControl::queryAggregation( _rType
);
387 Sequence
< Type
> SAL_CALL
FmXGridControl::getTypes( ) throw(RuntimeException
, std::exception
)
389 return comphelper::concatSequences(UnoControl::getTypes(),FmXGridControl_BASE::getTypes());
393 Sequence
<sal_Int8
> SAL_CALL
FmXGridControl::getImplementationId( ) throw(RuntimeException
, std::exception
)
395 return css::uno::Sequence
<sal_Int8
>();
399 sal_Bool SAL_CALL
FmXGridControl::supportsService(const OUString
& ServiceName
) throw(std::exception
)
401 return cppu::supportsService(this, ServiceName
);
404 OUString SAL_CALL
FmXGridControl::getImplementationName() throw(std::exception
)
406 return OUString("com.sun.star.form.FmXGridControl");
409 ::comphelper::StringSequence SAL_CALL
FmXGridControl::getSupportedServiceNames() throw(std::exception
)
411 Sequence
< OUString
> aServiceNames(2);
412 aServiceNames
[0] = FM_SUN_CONTROL_GRIDCONTROL
;
413 aServiceNames
[1] = "com.sun.star.awt.UnoControl";
414 return aServiceNames
;
418 void SAL_CALL
FmXGridControl::dispose() throw( RuntimeException
, std::exception
)
420 SolarMutexGuard aGuard
;
423 aEvt
.Source
= static_cast< ::cppu::OWeakObject
* >(this);
424 m_aModifyListeners
.disposeAndClear(aEvt
);
425 m_aUpdateListeners
.disposeAndClear(aEvt
);
426 m_aContainerListeners
.disposeAndClear(aEvt
);
428 UnoControl::dispose();
432 OUString
FmXGridControl::GetComponentServiceName()
434 OUString
aName("DBGrid");
439 sal_Bool SAL_CALL
FmXGridControl::setModel(const Reference
< ::com::sun::star::awt::XControlModel
>& rModel
) throw( RuntimeException
, std::exception
)
441 SolarMutexGuard aGuard
;
443 if (!UnoControl::setModel(rModel
))
446 Reference
< XGridPeer
> xGridPeer(getPeer(), UNO_QUERY
);
449 Reference
< XIndexContainer
> xCols(mxModel
, UNO_QUERY
);
450 xGridPeer
->setColumns(xCols
);
456 FmXGridPeer
* FmXGridControl::imp_CreatePeer(Window
* pParent
)
458 FmXGridPeer
* pReturn
= new FmXGridPeer(m_xContext
);
460 // translate properties into WinBits
461 WinBits nStyle
= WB_TABSTOP
;
462 Reference
< XPropertySet
> xModelSet(getModel(), UNO_QUERY
);
467 if (::comphelper::getINT16(xModelSet
->getPropertyValue(FM_PROP_BORDER
)))
470 catch(const Exception
&)
472 OSL_FAIL("Can not get style");
476 pReturn
->Create(pParent
, nStyle
);
481 void SAL_CALL
FmXGridControl::createPeer(const Reference
< ::com::sun::star::awt::XToolkit
>& /*rToolkit*/, const Reference
< ::com::sun::star::awt::XWindowPeer
>& rParentPeer
) throw( RuntimeException
, std::exception
)
484 throw DisposedException( OUString(), *this );
486 DBG_ASSERT(/*(0 == m_nPeerCreationLevel) && */!mbCreatingPeer
, "FmXGridControl::createPeer : recursion!");
487 // I think this should never assert, now that we're using the base class' mbCreatingPeer in addition to
488 // our own m_nPeerCreationLevel
489 // But I'm not sure as I don't _fully_ understand the underlying toolkit implementations ....
490 // (if this asserts, we still need m_nPeerCreationLevel. If not, we could omit it ....)
491 // 14.05.2001 - 86836 - frank.schoenheit@germany.sun.com
493 // TODO: why the hell this whole class does not use any mutex?
497 mbCreatingPeer
= true;
498 // mbCreatingPeer is virtually the same as m_nPeerCreationLevel, but it's the base class' method
499 // to prevent recursion.
501 Window
* pParentWin
= NULL
;
502 if (rParentPeer
.is())
504 VCLXWindow
* pParent
= VCLXWindow::GetImplementation(rParentPeer
);
506 pParentWin
= pParent
->GetWindow();
509 FmXGridPeer
* pPeer
= imp_CreatePeer(pParentWin
);
510 DBG_ASSERT(pPeer
!= NULL
, "FmXGridControl::createPeer : imp_CreatePeer didn't return a peer !");
513 // reading the properties from the model
514 // ++m_nPeerCreationLevel;
517 // consider the following ugly scenario: updateFromModel leads to a propertiesChanges on the Control,
518 // which determines, dat a "critical" property has changed (e.g. "Border") and therefore starts a new
519 // Peer, which lands again here in createPeerm we also start a second FmXGridPeer and initialise it.
520 // Then we exit from the first incarnation's updateFromModel and continue working with the pPeer,
521 // that is in fact now already obsolete (as another peer is being started in the second incarnation).
522 // Therefore the effort with the PeerCreationLevel, which ensures that we really use the Peer
523 // created at the deepest level, but first initialise it in the top-level.
524 // if (--m_nPeerCreationLevel == 0)
526 DBG_ASSERT(getPeer().is(), "FmXGridControl::createPeer : something went wrong ... no top level peer !");
527 pPeer
= FmXGridPeer::getImplementation(getPeer());
529 setPosSize( maComponentInfos
.nX
, maComponentInfos
.nY
, maComponentInfos
.nWidth
, maComponentInfos
.nHeight
, ::com::sun::star::awt::PosSize::POSSIZE
);
531 Reference
< XIndexContainer
> xColumns(getModel(), UNO_QUERY
);
533 pPeer
->setColumns(xColumns
);
535 if (maComponentInfos
.bVisible
)
536 pPeer
->setVisible(sal_True
);
538 if (!maComponentInfos
.bEnable
)
539 pPeer
->setEnable(sal_False
);
541 if (maWindowListeners
.getLength())
542 pPeer
->addWindowListener( &maWindowListeners
);
544 if (maFocusListeners
.getLength())
545 pPeer
->addFocusListener( &maFocusListeners
);
547 if (maKeyListeners
.getLength())
548 pPeer
->addKeyListener( &maKeyListeners
);
550 if (maMouseListeners
.getLength())
551 pPeer
->addMouseListener( &maMouseListeners
);
553 if (maMouseMotionListeners
.getLength())
554 pPeer
->addMouseMotionListener( &maMouseMotionListeners
);
556 if (maPaintListeners
.getLength())
557 pPeer
->addPaintListener( &maPaintListeners
);
559 if (m_aModifyListeners
.getLength())
560 pPeer
->addModifyListener( &m_aModifyListeners
);
562 if (m_aUpdateListeners
.getLength())
563 pPeer
->addUpdateListener( &m_aUpdateListeners
);
565 if (m_aContainerListeners
.getLength())
566 pPeer
->addContainerListener( &m_aContainerListeners
);
568 // forward the design mode
569 bool bForceAlivePeer
= m_bInDraw
&& !maComponentInfos
.bVisible
;
570 // (we force an alive-mode peer if we're in "draw", cause in this case the peer will be used for drawing in
571 // foreign devices. We ensure this with the visibility check as an living peer is assumed to be noncritical
572 // only if invisible)
573 Any aOldCursorBookmark
;
574 if (!mbDesignMode
|| bForceAlivePeer
)
576 Reference
< XFormComponent
> xComp(getModel(), UNO_QUERY
);
579 Reference
< XRowSet
> xForm(xComp
->getParent(), UNO_QUERY
);
580 // is the form alive?
581 // we can see that if the form contains columns
582 Reference
< ::com::sun::star::sdbcx::XColumnsSupplier
> xColumnsSupplier(xForm
, UNO_QUERY
);
583 if (xColumnsSupplier
.is())
585 if (Reference
< XIndexAccess
> (xColumnsSupplier
->getColumns(),UNO_QUERY
)->getCount())
587 // we get only a new bookmark if the resultset is not forwardonly
588 if (::comphelper::getINT32(Reference
< XPropertySet
> (xForm
, UNO_QUERY
)->getPropertyValue(FM_PROP_RESULTSET_TYPE
)) != ResultSetType::FORWARD_ONLY
)
590 // as the FmGridControl touches the data source it is connected to we have to remember the current
591 // cursor position (and restore afterwards)
592 // OJ: but only when we stand on a valid row
593 Reference
< XResultSet
> xResultSet(xForm
, UNO_QUERY
);
594 if ( !xResultSet
->isBeforeFirst() && !xResultSet
->isAfterLast() )
598 aOldCursorBookmark
= Reference
< ::com::sun::star::sdbcx::XRowLocate
> (xForm
, UNO_QUERY
)->getBookmark();
600 catch( const Exception
& e
)
602 DBG_UNHANDLED_EXCEPTION();
609 pPeer
->setRowSet(xForm
);
612 pPeer
->setDesignMode(mbDesignMode
&& !bForceAlivePeer
);
616 if (aOldCursorBookmark
.hasValue())
617 { // we have a valid bookmark, so we have to restore the cursor's position
618 Reference
< XFormComponent
> xComp(getModel(), UNO_QUERY
);
619 Reference
< ::com::sun::star::sdbcx::XRowLocate
> xLocate(xComp
->getParent(), UNO_QUERY
);
620 xLocate
->moveToBookmark(aOldCursorBookmark
);
623 catch( const Exception
& e
)
625 DBG_UNHANDLED_EXCEPTION();
629 Reference
< ::com::sun::star::awt::XView
> xPeerView(getPeer(), UNO_QUERY
);
630 xPeerView
->setZoom( maComponentInfos
.nZoomX
, maComponentInfos
.nZoomY
);
631 xPeerView
->setGraphics( mxGraphics
);
633 mbCreatingPeer
= false;
638 void FmXGridControl::addModifyListener(const Reference
< ::com::sun::star::util::XModifyListener
>& l
) throw( RuntimeException
, std::exception
)
640 m_aModifyListeners
.addInterface( l
);
641 if( getPeer().is() && m_aModifyListeners
.getLength() == 1 )
643 Reference
< ::com::sun::star::util::XModifyBroadcaster
> xGrid(getPeer(), UNO_QUERY
);
644 xGrid
->addModifyListener( &m_aModifyListeners
);
649 sal_Bool SAL_CALL
FmXGridControl::select( const Any
& _rSelection
) throw (IllegalArgumentException
, RuntimeException
, std::exception
)
651 SolarMutexGuard aGuard
;
652 Reference
< XSelectionSupplier
> xPeer(getPeer(), UNO_QUERY
);
653 return xPeer
->select(_rSelection
);
657 Any SAL_CALL
FmXGridControl::getSelection( ) throw (RuntimeException
, std::exception
)
659 SolarMutexGuard aGuard
;
660 Reference
< XSelectionSupplier
> xPeer(getPeer(), UNO_QUERY
);
661 return xPeer
->getSelection();
665 void SAL_CALL
FmXGridControl::addSelectionChangeListener( const Reference
< XSelectionChangeListener
>& _rxListener
) throw (RuntimeException
, std::exception
)
667 m_aSelectionListeners
.addInterface( _rxListener
);
668 if( getPeer().is() && 1 == m_aSelectionListeners
.getLength() )
670 Reference
< XSelectionSupplier
> xGrid(getPeer(), UNO_QUERY
);
671 xGrid
->addSelectionChangeListener( &m_aSelectionListeners
);
676 void SAL_CALL
FmXGridControl::removeSelectionChangeListener( const Reference
< XSelectionChangeListener
>& _rxListener
) throw (RuntimeException
, std::exception
)
678 if( getPeer().is() && 1 == m_aSelectionListeners
.getLength() )
680 Reference
< XSelectionSupplier
> xGrid(getPeer(), UNO_QUERY
);
681 xGrid
->removeSelectionChangeListener( &m_aSelectionListeners
);
683 m_aSelectionListeners
.removeInterface( _rxListener
);
687 Sequence
< sal_Bool
> SAL_CALL
FmXGridControl::queryFieldDataType( const Type
& xType
) throw(RuntimeException
, std::exception
)
691 Reference
< XGridFieldDataSupplier
> xPeerSupplier(getPeer(), UNO_QUERY
);
692 if (xPeerSupplier
.is())
693 return xPeerSupplier
->queryFieldDataType(xType
);
696 return Sequence
<sal_Bool
>();
700 Sequence
< Any
> SAL_CALL
FmXGridControl::queryFieldData( sal_Int32 nRow
, const Type
& xType
) throw(RuntimeException
, std::exception
)
704 Reference
< XGridFieldDataSupplier
> xPeerSupplier(getPeer(), UNO_QUERY
);
705 if (xPeerSupplier
.is())
706 return xPeerSupplier
->queryFieldData(nRow
, xType
);
709 return Sequence
< Any
>();
713 void SAL_CALL
FmXGridControl::removeModifyListener(const Reference
< ::com::sun::star::util::XModifyListener
>& l
) throw( RuntimeException
, std::exception
)
715 if( getPeer().is() && m_aModifyListeners
.getLength() == 1 )
717 Reference
< ::com::sun::star::util::XModifyBroadcaster
> xGrid(getPeer(), UNO_QUERY
);
718 xGrid
->removeModifyListener( &m_aModifyListeners
);
720 m_aModifyListeners
.removeInterface( l
);
724 void SAL_CALL
FmXGridControl::draw( sal_Int32 x
, sal_Int32 y
) throw( RuntimeException
, std::exception
)
726 SolarMutexGuard aGuard
;
728 UnoControl::draw(x
, y
);
733 void SAL_CALL
FmXGridControl::setDesignMode(sal_Bool bOn
) throw( RuntimeException
, std::exception
)
735 ::com::sun::star::util::ModeChangeEvent aModeChangeEvent
;
737 // --- <mutex_lock> ---
739 SolarMutexGuard aGuard
;
741 Reference
< XRowSetSupplier
> xGrid(getPeer(), UNO_QUERY
);
743 if (xGrid
.is() && (bool(bOn
) != mbDesignMode
|| (!bOn
&& !xGrid
->getRowSet().is())))
747 xGrid
->setRowSet(Reference
< XRowSet
> ());
751 Reference
< XFormComponent
> xComp(getModel(), UNO_QUERY
);
754 Reference
< XRowSet
> xForm(xComp
->getParent(), UNO_QUERY
);
755 xGrid
->setRowSet(xForm
);
761 Reference
< XVclWindowPeer
> xVclWindowPeer( getPeer(), UNO_QUERY
);
762 if (xVclWindowPeer
.is())
763 xVclWindowPeer
->setDesignMode(bOn
);
767 // dispose our current AccessibleContext, if we have one
768 // (changing the design mode implies having a new implementation for this context,
769 // so the old one must be declared DEFUNC)
770 DisposeAccessibleContext(
771 Reference
<XComponent
>(maAccessibleContext
, UNO_QUERY
));
772 maAccessibleContext
.clear();
774 // prepare firing an event
775 aModeChangeEvent
.Source
= *this;
776 aModeChangeEvent
.NewMode
= mbDesignMode
? OUString( "design" ) : OUString( "alive" );
779 // --- </mutex_lock> ---
780 maModeChangeListeners
.notifyEach( &XModeChangeListener::modeChanged
, aModeChangeEvent
);
785 void SAL_CALL
FmXGridControl::addUpdateListener(const Reference
< XUpdateListener
>& l
) throw( RuntimeException
, std::exception
)
787 m_aUpdateListeners
.addInterface( l
);
788 if( getPeer().is() && m_aUpdateListeners
.getLength() == 1 )
790 Reference
< XBoundComponent
> xBound(getPeer(), UNO_QUERY
);
791 xBound
->addUpdateListener( &m_aUpdateListeners
);
796 void SAL_CALL
FmXGridControl::removeUpdateListener(const Reference
< XUpdateListener
>& l
) throw( RuntimeException
, std::exception
)
798 if( getPeer().is() && m_aUpdateListeners
.getLength() == 1 )
800 Reference
< XBoundComponent
> xBound(getPeer(), UNO_QUERY
);
801 xBound
->removeUpdateListener( &m_aUpdateListeners
);
803 m_aUpdateListeners
.removeInterface( l
);
807 sal_Bool SAL_CALL
FmXGridControl::commit() throw( RuntimeException
, std::exception
)
809 Reference
< XBoundComponent
> xBound(getPeer(), UNO_QUERY
);
811 return xBound
->commit();
818 void SAL_CALL
FmXGridControl::addContainerListener(const Reference
< XContainerListener
>& l
) throw( RuntimeException
, std::exception
)
820 m_aContainerListeners
.addInterface( l
);
821 if( getPeer().is() && m_aContainerListeners
.getLength() == 1 )
823 Reference
< XContainer
> xContainer(getPeer(), UNO_QUERY
);
824 xContainer
->addContainerListener( &m_aContainerListeners
);
829 void SAL_CALL
FmXGridControl::removeContainerListener(const Reference
< XContainerListener
>& l
) throw( RuntimeException
, std::exception
)
831 if( getPeer().is() && m_aContainerListeners
.getLength() == 1 )
833 Reference
< XContainer
> xContainer(getPeer(), UNO_QUERY
);
834 xContainer
->removeContainerListener( &m_aContainerListeners
);
836 m_aContainerListeners
.removeInterface( l
);
840 Reference
< ::com::sun::star::frame::XDispatch
> SAL_CALL
FmXGridControl::queryDispatch(const ::com::sun::star::util::URL
& aURL
, const OUString
& aTargetFrameName
, sal_Int32 nSearchFlags
) throw( RuntimeException
, std::exception
)
842 Reference
< ::com::sun::star::frame::XDispatchProvider
> xPeerProvider(getPeer(), UNO_QUERY
);
843 if (xPeerProvider
.is())
844 return xPeerProvider
->queryDispatch(aURL
, aTargetFrameName
, nSearchFlags
);
846 return Reference
< ::com::sun::star::frame::XDispatch
> ();
850 Sequence
< Reference
< ::com::sun::star::frame::XDispatch
> > SAL_CALL
FmXGridControl::queryDispatches(const Sequence
< ::com::sun::star::frame::DispatchDescriptor
>& aDescripts
) throw( RuntimeException
, std::exception
)
852 Reference
< ::com::sun::star::frame::XDispatchProvider
> xPeerProvider(getPeer(), UNO_QUERY
);
853 if (xPeerProvider
.is())
854 return xPeerProvider
->queryDispatches(aDescripts
);
856 return Sequence
< Reference
< ::com::sun::star::frame::XDispatch
> >();
860 void SAL_CALL
FmXGridControl::registerDispatchProviderInterceptor(const Reference
< ::com::sun::star::frame::XDispatchProviderInterceptor
>& _xInterceptor
) throw( RuntimeException
, std::exception
)
862 Reference
< ::com::sun::star::frame::XDispatchProviderInterception
> xPeerInterception(getPeer(), UNO_QUERY
);
863 if (xPeerInterception
.is())
864 xPeerInterception
->registerDispatchProviderInterceptor(_xInterceptor
);
868 void SAL_CALL
FmXGridControl::releaseDispatchProviderInterceptor(const Reference
< ::com::sun::star::frame::XDispatchProviderInterceptor
>& _xInterceptor
) throw( RuntimeException
, std::exception
)
870 Reference
< ::com::sun::star::frame::XDispatchProviderInterception
> xPeerInterception(getPeer(), UNO_QUERY
);
871 if (xPeerInterception
.is())
872 xPeerInterception
->releaseDispatchProviderInterceptor(_xInterceptor
);
876 void SAL_CALL
FmXGridControl::addGridControlListener( const Reference
< XGridControlListener
>& _listener
) throw( RuntimeException
, std::exception
)
878 ::osl::MutexGuard
aGuard( GetMutex() );
880 m_aGridControlListeners
.addInterface( _listener
);
881 if ( getPeer().is() && 1 == m_aGridControlListeners
.getLength() )
883 Reference
< XGridControl
> xPeerGrid( getPeer(), UNO_QUERY
);
884 if ( xPeerGrid
.is() )
885 xPeerGrid
->addGridControlListener( &m_aGridControlListeners
);
890 void SAL_CALL
FmXGridControl::removeGridControlListener( const Reference
< XGridControlListener
>& _listener
) throw( RuntimeException
, std::exception
)
892 ::osl::MutexGuard
aGuard( GetMutex() );
894 if( getPeer().is() && 1 == m_aGridControlListeners
.getLength() )
896 Reference
< XGridControl
> xPeerGrid( getPeer(), UNO_QUERY
);
897 if ( xPeerGrid
.is() )
898 xPeerGrid
->removeGridControlListener( &m_aGridControlListeners
);
901 m_aGridControlListeners
.removeInterface( _listener
);
905 sal_Int16 SAL_CALL
FmXGridControl::getCurrentColumnPosition() throw( RuntimeException
, std::exception
)
907 Reference
< XGridControl
> xGrid( getPeer(), UNO_QUERY
);
908 return xGrid
.is() ? xGrid
->getCurrentColumnPosition() : -1;
912 void SAL_CALL
FmXGridControl::setCurrentColumnPosition(sal_Int16 nPos
) throw( RuntimeException
, std::exception
)
914 Reference
< XGridControl
> xGrid( getPeer(), UNO_QUERY
);
917 SolarMutexGuard aGuard
;
918 xGrid
->setCurrentColumnPosition( nPos
);
924 sal_Bool SAL_CALL
FmXGridControl::hasElements() throw( RuntimeException
, std::exception
)
926 Reference
< XElementAccess
> xPeer(getPeer(), UNO_QUERY
);
927 return xPeer
.is() ? xPeer
->hasElements() : 0;
931 Type SAL_CALL
FmXGridControl::getElementType( ) throw(RuntimeException
, std::exception
)
933 return cppu::UnoType
<com::sun::star::awt::XTextComponent
>::get();
936 // XEnumerationAccess
938 Reference
< XEnumeration
> SAL_CALL
FmXGridControl::createEnumeration() throw( RuntimeException
, std::exception
)
940 Reference
< XEnumerationAccess
> xPeer(getPeer(), UNO_QUERY
);
942 return xPeer
->createEnumeration();
944 return new ::comphelper::OEnumerationByIndex(this);
949 sal_Int32 SAL_CALL
FmXGridControl::getCount() throw( RuntimeException
, std::exception
)
951 Reference
< XIndexAccess
> xPeer(getPeer(), UNO_QUERY
);
952 return xPeer
.is() ? xPeer
->getCount() : 0;
956 Any SAL_CALL
FmXGridControl::getByIndex(sal_Int32 _nIndex
) throw( IndexOutOfBoundsException
, WrappedTargetException
, RuntimeException
, std::exception
)
958 Reference
< XIndexAccess
> xPeer(getPeer(), UNO_QUERY
);
960 throw IndexOutOfBoundsException();
962 return xPeer
->getByIndex(_nIndex
);
965 // ::com::sun::star::util::XModeSelector
967 void SAL_CALL
FmXGridControl::setMode(const OUString
& Mode
) throw( NoSupportException
, RuntimeException
, std::exception
)
969 Reference
< ::com::sun::star::util::XModeSelector
> xPeer(getPeer(), UNO_QUERY
);
971 throw NoSupportException();
973 xPeer
->setMode(Mode
);
977 OUString SAL_CALL
FmXGridControl::getMode() throw( RuntimeException
, std::exception
)
979 Reference
< ::com::sun::star::util::XModeSelector
> xPeer(getPeer(), UNO_QUERY
);
980 return xPeer
.is() ? xPeer
->getMode() : OUString();
984 ::comphelper::StringSequence SAL_CALL
FmXGridControl::getSupportedModes() throw( RuntimeException
, std::exception
)
986 Reference
< ::com::sun::star::util::XModeSelector
> xPeer(getPeer(), UNO_QUERY
);
987 return xPeer
.is() ? xPeer
->getSupportedModes() : ::comphelper::StringSequence();
991 sal_Bool SAL_CALL
FmXGridControl::supportsMode(const OUString
& Mode
) throw( RuntimeException
, std::exception
)
993 Reference
< ::com::sun::star::util::XModeSelector
> xPeer(getPeer(), UNO_QUERY
);
994 return xPeer
.is() ? xPeer
->supportsMode(Mode
) : sal_False
;
1000 // helper class which prevents that in the peer's header the FmGridListener must be known
1001 class FmXGridPeer::GridListenerDelegator
: public FmGridListener
1004 FmXGridPeer
* m_pPeer
;
1007 GridListenerDelegator( FmXGridPeer
* _pPeer
);
1008 virtual ~GridListenerDelegator();
1011 virtual void selectionChanged() SAL_OVERRIDE
;
1012 virtual void columnChanged() SAL_OVERRIDE
;
1016 FmXGridPeer::GridListenerDelegator::GridListenerDelegator(FmXGridPeer
* _pPeer
)
1019 DBG_ASSERT(m_pPeer
, "GridListenerDelegator::GridListenerDelegator");
1022 FmXGridPeer::GridListenerDelegator::~GridListenerDelegator()
1027 void FmXGridPeer::GridListenerDelegator::selectionChanged()
1029 m_pPeer
->selectionChanged();
1033 void FmXGridPeer::GridListenerDelegator::columnChanged()
1035 m_pPeer
->columnChanged();
1038 Sequence
< Type
> SAL_CALL
FmXGridPeer::getTypes( ) throw(RuntimeException
, std::exception
)
1040 return comphelper::concatSequences( VCLXWindow::getTypes(), FmXGridPeer_BASE::getTypes() );
1044 Sequence
<sal_Int8
> SAL_CALL
FmXGridPeer::getImplementationId( ) throw(RuntimeException
, std::exception
)
1046 return css::uno::Sequence
<sal_Int8
>();
1050 Any SAL_CALL
FmXGridPeer::queryInterface(const Type
& _rType
) throw (RuntimeException
, std::exception
)
1052 Any aReturn
= FmXGridPeer_BASE::queryInterface(_rType
);
1054 if (!aReturn
.hasValue())
1055 aReturn
= VCLXWindow::queryInterface( _rType
);
1061 void FmXGridPeer::selectionChanged()
1063 EventObject aSource
;
1064 aSource
.Source
= static_cast< ::cppu::OWeakObject
* >(this);
1065 m_aSelectionListeners
.notifyEach( &XSelectionChangeListener::selectionChanged
, aSource
);
1069 void FmXGridPeer::columnChanged()
1071 EventObject
aEvent( *this );
1072 m_aGridControlListeners
.notifyEach( &XGridControlListener::columnChanged
, aEvent
);
1078 const OUString
getDataModeIdentifier()
1080 return OUString("DataMode");
1083 using namespace fmgridif
;
1086 FmXGridPeer::FmXGridPeer(const Reference
< XComponentContext
>& _rxContext
)
1087 :m_aModifyListeners(m_aMutex
)
1088 ,m_aUpdateListeners(m_aMutex
)
1089 ,m_aContainerListeners(m_aMutex
)
1090 ,m_aSelectionListeners(m_aMutex
)
1091 ,m_aGridControlListeners(m_aMutex
)
1092 ,m_aMode( getDataModeIdentifier() )
1093 ,m_nCursorListening(0)
1094 ,m_bInterceptingDispatch(false)
1095 ,m_pStateCache(NULL
)
1096 ,m_pDispatchers(NULL
)
1097 ,m_pGridListener(NULL
)
1098 ,m_xContext(_rxContext
)
1100 // Create must be called after this constructure
1101 m_pGridListener
= new GridListenerDelegator( this );
1105 FmGridControl
* FmXGridPeer::imp_CreateControl(Window
* pParent
, WinBits nStyle
)
1107 return new FmGridControl(m_xContext
, pParent
, this, nStyle
);
1111 void FmXGridPeer::Create(Window
* pParent
, WinBits nStyle
)
1113 FmGridControl
* pWin
= imp_CreateControl(pParent
, nStyle
);
1114 DBG_ASSERT(pWin
!= NULL
, "FmXGridPeer::Create : imp_CreateControl didn't return a control !");
1116 pWin
->SetStateProvider(LINK(this, FmXGridPeer
, OnQueryGridSlotState
));
1117 pWin
->SetSlotExecutor(LINK(this, FmXGridPeer
, OnExecuteGridSlot
));
1119 // want to hear about row selections
1120 pWin
->setGridListener( m_pGridListener
);
1122 // Init must always be called
1124 pWin
->SetComponentInterface(this);
1130 FmXGridPeer::~FmXGridPeer()
1132 setRowSet(Reference
< XRowSet
> ());
1133 setColumns(Reference
< XIndexContainer
> ());
1135 delete m_pGridListener
;
1140 class theFmXGridPeerImplementationId
: public rtl::Static
< UnoTunnelIdInit
, theFmXGridPeerImplementationId
> {};
1143 const Sequence
< sal_Int8
>& FmXGridPeer::getUnoTunnelImplementationId() throw()
1145 return theFmXGridPeerImplementationId::get().getSeq();
1149 FmXGridPeer
* FmXGridPeer::getImplementation( const Reference
< XInterface
>& _rxIFace
) throw()
1151 FmXGridPeer
* pReturn
= NULL
;
1152 Reference
< XUnoTunnel
> xTunnel(_rxIFace
, UNO_QUERY
);
1154 pReturn
= reinterpret_cast<FmXGridPeer
*>(xTunnel
->getSomething(getUnoTunnelImplementationId()));
1160 sal_Int64 SAL_CALL
FmXGridPeer::getSomething( const Sequence
< sal_Int8
>& _rIdentifier
) throw(RuntimeException
, std::exception
)
1162 sal_Int64
nReturn(0);
1164 if ( (_rIdentifier
.getLength() == 16)
1165 && (0 == memcmp( getUnoTunnelImplementationId().getConstArray(), _rIdentifier
.getConstArray(), 16 ))
1168 nReturn
= reinterpret_cast<sal_Int64
>(this);
1171 nReturn
= VCLXWindow::getSomething(_rIdentifier
);
1178 void FmXGridPeer::disposing(const EventObject
& e
) throw( RuntimeException
, std::exception
)
1180 using namespace ::com::sun::star::util
;
1181 bool bKnownSender
= false;
1183 Reference
< XIndexContainer
> xCols( e
.Source
, UNO_QUERY
);
1186 setColumns(Reference
< XIndexContainer
> ());
1187 bKnownSender
= true;
1190 Reference
< XRowSet
> xCursor(e
.Source
, UNO_QUERY
);
1193 setRowSet( m_xCursor
);
1195 bKnownSender
= true;
1199 if ( !bKnownSender
&& m_pDispatchers
)
1201 const Sequence
< URL
>& aSupportedURLs
= getSupportedURLs();
1202 const URL
* pSupportedURLs
= aSupportedURLs
.getConstArray();
1203 for ( sal_uInt16 i
=0; i
< ( aSupportedURLs
.getLength() ) && !bKnownSender
; ++i
, ++pSupportedURLs
)
1205 if ( m_pDispatchers
[i
] == e
.Source
)
1207 m_pDispatchers
[i
]->removeStatusListener( static_cast< ::com::sun::star::frame::XStatusListener
* >( this ), *pSupportedURLs
);
1208 m_pDispatchers
[i
] = NULL
;
1209 m_pStateCache
[i
] = false;
1210 bKnownSender
= true;
1215 if ( !bKnownSender
)
1216 VCLXWindow::disposing(e
);
1220 void FmXGridPeer::addModifyListener(const Reference
< ::com::sun::star::util::XModifyListener
>& l
) throw( RuntimeException
, std::exception
)
1222 m_aModifyListeners
.addInterface( l
);
1226 void FmXGridPeer::removeModifyListener(const Reference
< ::com::sun::star::util::XModifyListener
>& l
) throw( RuntimeException
, std::exception
)
1228 m_aModifyListeners
.removeInterface( l
);
1232 #define LAST_KNOWN_TYPE FormComponentType::PATTERNFIELD
1233 Sequence
< sal_Bool
> SAL_CALL
FmXGridPeer::queryFieldDataType( const Type
& xType
) throw(RuntimeException
, std::exception
)
1235 // eine 'Konvertierungstabelle'
1236 static const sal_Bool bCanConvert
[LAST_KNOWN_TYPE
][4] =
1238 { sal_False
, sal_False
, sal_False
, sal_False
}, // FormComponentType::CONTROL
1239 { sal_False
, sal_False
, sal_False
, sal_False
}, // FormComponentType::COMMANDBUTTON
1240 { sal_False
, sal_False
, sal_False
, sal_False
}, // FormComponentType::RADIOBUTTON
1241 { sal_False
, sal_False
, sal_False
, sal_False
}, // FormComponentType::IMAGEBUTTON
1242 { sal_False
, sal_False
, sal_False
, sal_True
}, // FormComponentType::CHECKBOX
1243 { sal_False
, sal_False
, sal_False
, sal_False
}, // FormComponentType::LISTBOX
1244 { sal_False
, sal_False
, sal_False
, sal_False
}, // FormComponentType::COMBOBOX
1245 { sal_False
, sal_False
, sal_False
, sal_False
}, // FormComponentType::GROUPBOX
1246 { sal_True
, sal_False
, sal_False
, sal_False
}, // FormComponentType::TEXTFIELD
1247 { sal_False
, sal_False
, sal_False
, sal_False
}, // FormComponentType::FIXEDTEXT
1248 { sal_False
, sal_False
, sal_False
, sal_False
}, // FormComponentType::GRIDCONTROL
1249 { sal_False
, sal_False
, sal_False
, sal_False
}, // FormComponentType::FILECONTROL
1250 { sal_False
, sal_False
, sal_False
, sal_False
}, // FormComponentType::HIDDENCONTROL
1251 { sal_False
, sal_False
, sal_False
, sal_False
}, // FormComponentType::IMAGECONTROL
1252 { sal_True
, sal_True
, sal_True
, sal_False
}, // FormComponentType::DATEFIELD
1253 { sal_True
, sal_True
, sal_False
, sal_False
}, // FormComponentType::TIMEFIELD
1254 { sal_True
, sal_True
, sal_False
, sal_False
}, // FormComponentType::NUMERICFIELD
1255 { sal_True
, sal_True
, sal_False
, sal_False
}, // FormComponentType::CURRENCYFIELD
1256 { sal_True
, sal_False
, sal_False
, sal_False
} // FormComponentType::PATTERNFIELD
1260 sal_Int16 nMapColumn
= -1;
1261 switch (xType
.getTypeClass())
1263 case TypeClass_STRING
: nMapColumn
= 0; break;
1264 case TypeClass_FLOAT
:
1265 case TypeClass_DOUBLE
: nMapColumn
= 1; break;
1266 case TypeClass_SHORT
:
1267 case TypeClass_LONG
:
1268 case TypeClass_UNSIGNED_LONG
:
1269 case TypeClass_UNSIGNED_SHORT
: nMapColumn
= 2; break;
1270 case TypeClass_BOOLEAN
: nMapColumn
= 3; break;
1275 Reference
< XIndexContainer
> xColumns
= getColumns();
1277 FmGridControl
* pGrid
= (FmGridControl
*) GetWindow();
1278 sal_Int32 nColumns
= pGrid
->GetViewColCount();
1280 DbGridColumns aColumns
= pGrid
->GetColumns();
1282 Sequence
<sal_Bool
> aReturnSequence(nColumns
);
1283 sal_Bool
* pReturnArray
= aReturnSequence
.getArray();
1285 bool bRequestedAsAny
= (xType
.getTypeClass() == TypeClass_ANY
);
1288 Reference
< ::com::sun::star::sdb::XColumn
> xFieldContent
;
1289 Reference
< XPropertySet
> xCurrentColumn
;
1290 for (sal_Int32 i
=0; i
<nColumns
; ++i
)
1292 if (bRequestedAsAny
)
1294 pReturnArray
[i
] = sal_True
;
1298 pReturnArray
[i
] = sal_False
;
1300 sal_uInt16 nModelPos
= pGrid
->GetModelColumnPos(pGrid
->GetColumnIdFromViewPos((sal_uInt16
)i
));
1301 DBG_ASSERT(nModelPos
!= (sal_uInt16
)-1, "FmXGridPeer::queryFieldDataType : no model pos !");
1303 pCol
= aColumns
[ nModelPos
];
1304 const DbGridRowRef xRow
= pGrid
->GetSeekRow();
1305 xFieldContent
= (xRow
.Is() && xRow
->HasField(pCol
->GetFieldPos())) ? xRow
->GetField(pCol
->GetFieldPos()).getColumn() : Reference
< ::com::sun::star::sdb::XColumn
> ();
1306 if (!xFieldContent
.is())
1307 // can't supply anything without a field content
1308 // FS - 07.12.99 - 54391
1311 xColumns
->getByIndex(nModelPos
) >>= xCurrentColumn
;
1312 if (!::comphelper::hasProperty(FM_PROP_CLASSID
, xCurrentColumn
))
1315 sal_Int16 nClassId
= sal_Int16();
1316 xCurrentColumn
->getPropertyValue(FM_PROP_CLASSID
) >>= nClassId
;
1317 if (nClassId
>LAST_KNOWN_TYPE
)
1319 DBG_ASSERT(nClassId
>0, "FmXGridPeer::queryFieldDataType : somebody changed the definition of the FormComponentType enum !");
1321 if (nMapColumn
!= -1)
1322 pReturnArray
[i
] = bCanConvert
[nClassId
-1][nMapColumn
];
1325 return aReturnSequence
;
1329 Sequence
< Any
> SAL_CALL
FmXGridPeer::queryFieldData( sal_Int32 nRow
, const Type
& xType
) throw(RuntimeException
, std::exception
)
1331 FmGridControl
* pGrid
= (FmGridControl
*) GetWindow();
1332 DBG_ASSERT(pGrid
&& pGrid
->IsOpen(), "FmXGridPeer::queryFieldData : have no valid grid window !");
1333 if (!pGrid
|| !pGrid
->IsOpen())
1334 return Sequence
< Any
>();
1336 // das Control zur angegebenen Row fahren
1337 if (!pGrid
->SeekRow(nRow
))
1339 throw IllegalArgumentException();
1342 // don't use GetCurrentRow as this isn't affected by the above SeekRow
1343 // FS - 30.09.99 - 68644
1344 DbGridRowRef xPaintRow
= pGrid
->GetPaintRow();
1345 ENSURE_OR_THROW( xPaintRow
.Is(), "invalid paint row" );
1347 // I need the columns of the control for GetFieldText
1348 DbGridColumns aColumns
= pGrid
->GetColumns();
1350 // und durch alle Spalten durch
1351 sal_Int32 nColumnCount
= pGrid
->GetViewColCount();
1353 Sequence
< Any
> aReturnSequence(nColumnCount
);
1354 Any
* pReturnArray
= aReturnSequence
.getArray();
1356 bool bRequestedAsAny
= (xType
.getTypeClass() == TypeClass_ANY
);
1357 Reference
< ::com::sun::star::sdb::XColumn
> xFieldContent
;
1359 for (sal_Int32 i
=0; i
< nColumnCount
; ++i
)
1361 sal_uInt16 nModelPos
= pGrid
->GetModelColumnPos(pGrid
->GetColumnIdFromViewPos((sal_uInt16
)i
));
1362 DBG_ASSERT(nModelPos
!= (sal_uInt16
)-1, "FmXGridPeer::queryFieldData : invalid model pos !");
1364 // don't use GetCurrentFieldValue to determine the field content as this isn't affected by the above SeekRow
1365 // FS - 30.09.99 - 68644
1366 pCol
= aColumns
[ nModelPos
];
1367 xFieldContent
= xPaintRow
->HasField( pCol
->GetFieldPos() )
1368 ? xPaintRow
->GetField( pCol
->GetFieldPos() ).getColumn()
1369 : Reference
< XColumn
> ();
1371 if ( !xFieldContent
.is() )
1374 if (bRequestedAsAny
)
1376 Reference
< XPropertySet
> xFieldSet(xFieldContent
, UNO_QUERY
);
1377 pReturnArray
[i
] = xFieldSet
->getPropertyValue(FM_PROP_VALUE
);
1381 switch (xType
.getTypeClass())
1383 // Strings are dealt with directly by the GetFieldText
1384 case TypeClass_STRING
:
1386 OUString sText
= aColumns
[ nModelPos
]->GetCellText( xPaintRow
, pGrid
->getNumberFormatter() );
1387 pReturnArray
[i
] <<= sText
;
1390 // everything else is requested in the DatabaseVariant
1391 case TypeClass_FLOAT
: pReturnArray
[i
] <<= xFieldContent
->getFloat(); break;
1392 case TypeClass_DOUBLE
: pReturnArray
[i
] <<= xFieldContent
->getDouble(); break;
1393 case TypeClass_SHORT
: pReturnArray
[i
] <<= (sal_Int16
)xFieldContent
->getShort(); break;
1394 case TypeClass_LONG
: pReturnArray
[i
] <<= (sal_Int32
)xFieldContent
->getLong(); break;
1395 case TypeClass_UNSIGNED_SHORT
: pReturnArray
[i
] <<= (sal_uInt16
)xFieldContent
->getShort(); break;
1396 case TypeClass_UNSIGNED_LONG
: pReturnArray
[i
] <<= (sal_uInt32
)xFieldContent
->getLong(); break;
1397 case TypeClass_BOOLEAN
: ::comphelper::setBOOL(pReturnArray
[i
],xFieldContent
->getBoolean()); break;
1400 throw IllegalArgumentException();
1405 return aReturnSequence
;
1409 void FmXGridPeer::CellModified()
1412 aEvt
.Source
= static_cast< ::cppu::OWeakObject
* >(this);
1413 m_aModifyListeners
.notifyEach( &XModifyListener::modified
, aEvt
);
1416 // XPropertyChangeListener
1418 void FmXGridPeer::propertyChange(const PropertyChangeEvent
& evt
) throw( RuntimeException
, std::exception
)
1420 SolarMutexGuard aGuard
;
1421 // want to do a lot of VCL stuff here ...
1422 // this should not be (deadlock) critical, as by definition, every component should release
1423 // any own mutexes before notifying
1425 FmGridControl
* pGrid
= (FmGridControl
*) GetWindow();
1430 Reference
< XRowSet
> xCursor(evt
.Source
, UNO_QUERY
);
1431 if (evt
.PropertyName
== FM_PROP_VALUE
|| m_xCursor
== evt
.Source
)
1432 pGrid
->propertyChange(evt
);
1433 else if (pGrid
&& m_xColumns
.is() && m_xColumns
->hasElements())
1435 // next find which column has changed
1436 ::comphelper::InterfaceRef xCurrent
;
1439 for ( i
= 0; i
< m_xColumns
->getCount(); i
++)
1441 xCurrent
.set(m_xColumns
->getByIndex(i
), css::uno::UNO_QUERY
);
1442 if (evt
.Source
== xCurrent
)
1446 if (i
>= m_xColumns
->getCount())
1447 // this is valid because we are listening at the cursor, too (RecordCount, -status, edit mode)
1450 sal_uInt16 nId
= pGrid
->GetColumnIdFromModelPos((sal_uInt16
)i
);
1451 bool bInvalidateColumn
= false;
1453 if (evt
.PropertyName
== FM_PROP_LABEL
)
1455 OUString aName
= ::comphelper::getString(evt
.NewValue
);
1456 if (aName
!= pGrid
->GetColumnTitle(nId
))
1457 pGrid
->SetColumnTitle(nId
, aName
);
1459 else if (evt
.PropertyName
== FM_PROP_WIDTH
)
1461 sal_Int32 nWidth
= 0;
1462 if (evt
.NewValue
.getValueType().getTypeClass() == TypeClass_VOID
)
1463 nWidth
= pGrid
->GetDefaultColumnWidth(pGrid
->GetColumnTitle(nId
));
1464 // GetDefaultColumnWidth already considered the zoom factor
1467 sal_Int32 nTest
= 0;
1468 if (evt
.NewValue
>>= nTest
)
1470 nWidth
= pGrid
->LogicToPixel(Point(nTest
,0),MAP_10TH_MM
).X();
1471 // take the zoom factor into account
1472 nWidth
= pGrid
->CalcZoom(nWidth
);
1475 if (nWidth
!= (sal_Int32(pGrid
->GetColumnWidth(nId
))))
1477 if (pGrid
->IsEditing())
1479 pGrid
->DeactivateCell();
1480 pGrid
->ActivateCell();
1482 pGrid
->SetColumnWidth(nId
, nWidth
);
1485 else if (evt
.PropertyName
== FM_PROP_HIDDEN
)
1487 DBG_ASSERT(evt
.NewValue
.getValueType().getTypeClass() == TypeClass_BOOLEAN
,
1488 "FmXGridPeer::propertyChange : the property 'hidden' should be of type boolean !");
1489 if (::comphelper::getBOOL(evt
.NewValue
))
1490 pGrid
->HideColumn(nId
);
1492 pGrid
->ShowColumn(nId
);
1494 else if (evt
.PropertyName
== FM_PROP_ALIGN
)
1496 // in design mode it doesn't matter
1497 if (!isDesignMode())
1499 DbGridColumn
* pCol
= pGrid
->GetColumns().at( i
);
1501 pCol
->SetAlignmentFromModel(-1);
1502 bInvalidateColumn
= true;
1505 else if (evt
.PropertyName
== FM_PROP_FORMATKEY
)
1507 if (!isDesignMode())
1508 bInvalidateColumn
= true;
1511 // need to invalidate the affected column ?
1512 if (bInvalidateColumn
)
1514 bool bWasEditing
= pGrid
->IsEditing();
1516 pGrid
->DeactivateCell();
1518 ::Rectangle aColRect
= pGrid
->GetFieldRect(nId
);
1520 aColRect
.Bottom() = pGrid
->GetSizePixel().Height();
1521 pGrid
->Invalidate(aColRect
);
1524 pGrid
->ActivateCell();
1531 void FmXGridPeer::addUpdateListener(const Reference
< XUpdateListener
>& l
) throw( RuntimeException
, std::exception
)
1533 m_aUpdateListeners
.addInterface(l
);
1537 void FmXGridPeer::removeUpdateListener(const Reference
< XUpdateListener
>& l
) throw( RuntimeException
, std::exception
)
1539 m_aUpdateListeners
.removeInterface(l
);
1543 sal_Bool
FmXGridPeer::commit() throw( RuntimeException
, std::exception
)
1545 FmGridControl
* pGrid
= (FmGridControl
*) GetWindow();
1546 if (!m_xCursor
.is() || !pGrid
)
1549 EventObject
aEvt(static_cast< ::cppu::OWeakObject
* >(this));
1550 ::cppu::OInterfaceIteratorHelper
aIter(m_aUpdateListeners
);
1551 bool bCancel
= false;
1552 while (aIter
.hasMoreElements() && !bCancel
)
1553 if ( !static_cast< XUpdateListener
* >( aIter
.next() )->approveUpdate( aEvt
) )
1557 bCancel
= !pGrid
->commit();
1560 m_aUpdateListeners
.notifyEach( &XUpdateListener::updated
, aEvt
);
1566 void FmXGridPeer::cursorMoved(const EventObject
& _rEvent
) throw( RuntimeException
, std::exception
)
1568 FmGridControl
* pGrid
= (FmGridControl
*) GetWindow();
1569 // we are not interested in move to insert row only in the resetted event
1570 // which is fired after positioning an the insert row
1571 if (pGrid
&& pGrid
->IsOpen() && !::comphelper::getBOOL(Reference
< XPropertySet
> (_rEvent
.Source
, UNO_QUERY
)->getPropertyValue(FM_PROP_ISNEW
)))
1572 pGrid
->positioned(_rEvent
);
1576 void FmXGridPeer::rowChanged(const EventObject
& _rEvent
) throw( RuntimeException
, std::exception
)
1578 FmGridControl
* pGrid
= (FmGridControl
*) GetWindow();
1579 if (pGrid
&& pGrid
->IsOpen())
1581 if (m_xCursor
->rowUpdated() && !pGrid
->IsCurrentAppending())
1582 pGrid
->RowModified(pGrid
->GetCurrentPos());
1583 else if (m_xCursor
->rowInserted())
1584 pGrid
->inserted(_rEvent
);
1589 void FmXGridPeer::rowSetChanged(const EventObject
& /*event*/) throw( RuntimeException
, std::exception
)
1591 // not interested in ...
1592 // (our parent is a form which means we get a loaded or reloaded after this rowSetChanged)
1597 void FmXGridPeer::loaded(const EventObject
& /*rEvent*/) throw( RuntimeException
, std::exception
)
1599 updateGrid(m_xCursor
);
1603 void FmXGridPeer::unloaded(const EventObject
& /*rEvent*/) throw( RuntimeException
, std::exception
)
1605 updateGrid( Reference
< XRowSet
> (NULL
) );
1609 void FmXGridPeer::reloading(const EventObject
& /*aEvent*/) throw( RuntimeException
, std::exception
)
1612 updateGrid( Reference
< XRowSet
> (NULL
) );
1616 void FmXGridPeer::unloading(const EventObject
& /*aEvent*/) throw( RuntimeException
, std::exception
)
1619 updateGrid( Reference
< XRowSet
> (NULL
) );
1623 void FmXGridPeer::reloaded(const EventObject
& /*aEvent*/) throw( RuntimeException
, std::exception
)
1625 updateGrid(m_xCursor
);
1630 Reference
< XIndexContainer
> FmXGridPeer::getColumns() throw( RuntimeException
, std::exception
)
1636 void FmXGridPeer::addColumnListeners(const Reference
< XPropertySet
>& xCol
)
1638 static const OUString aPropsListenedTo
[] =
1640 OUString(FM_PROP_LABEL
), OUString(FM_PROP_WIDTH
), OUString(FM_PROP_HIDDEN
), OUString(FM_PROP_ALIGN
), OUString(FM_PROP_FORMATKEY
)
1643 // as not all properties have to be supported by all columns we have to check this
1644 // before adding a listener
1645 Reference
< XPropertySetInfo
> xInfo
= xCol
->getPropertySetInfo();
1647 const OUString
* pProps
= aPropsListenedTo
;
1648 const OUString
* pPropsEnd
= pProps
+ sizeof( aPropsListenedTo
) / sizeof( aPropsListenedTo
[ 0 ] );
1649 for (; pProps
!= pPropsEnd
; ++pProps
)
1651 if ( xInfo
->hasPropertyByName( *pProps
) )
1653 aPropDesc
= xInfo
->getPropertyByName( *pProps
);
1654 if ( 0 != ( aPropDesc
.Attributes
& PropertyAttribute::BOUND
) )
1655 xCol
->addPropertyChangeListener( *pProps
, this );
1661 void FmXGridPeer::removeColumnListeners(const Reference
< XPropertySet
>& xCol
)
1663 // the same props as in addColumnListeners ... linux has problems with global static UStrings, so
1664 // we have to do it this way ....
1665 static OUString aPropsListenedTo
[] =
1667 OUString(FM_PROP_LABEL
), OUString(FM_PROP_WIDTH
), OUString(FM_PROP_HIDDEN
), OUString(FM_PROP_ALIGN
), OUString(FM_PROP_FORMATKEY
)
1670 Reference
< XPropertySetInfo
> xInfo
= xCol
->getPropertySetInfo();
1671 for (sal_uInt16 i
=0; i
<sizeof(aPropsListenedTo
)/sizeof(aPropsListenedTo
[0]); ++i
)
1672 if (xInfo
->hasPropertyByName(aPropsListenedTo
[i
]))
1673 xCol
->removePropertyChangeListener(aPropsListenedTo
[i
], this);
1677 void FmXGridPeer::setColumns(const Reference
< XIndexContainer
>& Columns
) throw( RuntimeException
, std::exception
)
1679 SolarMutexGuard aGuard
;
1681 FmGridControl
* pGrid
= static_cast< FmGridControl
* >( GetWindow() );
1683 if (m_xColumns
.is())
1685 Reference
< XPropertySet
> xCol
;
1686 for (sal_Int32 i
= 0; i
< m_xColumns
->getCount(); i
++)
1688 xCol
.set(m_xColumns
->getByIndex(i
), css::uno::UNO_QUERY
);
1689 removeColumnListeners(xCol
);
1691 Reference
< XContainer
> xContainer(m_xColumns
, UNO_QUERY
);
1692 xContainer
->removeContainerListener(this);
1694 Reference
< XSelectionSupplier
> xSelSupplier(m_xColumns
, UNO_QUERY
);
1695 xSelSupplier
->removeSelectionChangeListener(this);
1697 Reference
< XReset
> xColumnReset(m_xColumns
, UNO_QUERY
);
1698 if (xColumnReset
.is())
1699 xColumnReset
->removeResetListener((XResetListener
*)this);
1703 Reference
< XContainer
> xContainer(Columns
, UNO_QUERY
);
1704 xContainer
->addContainerListener(this);
1706 Reference
< XSelectionSupplier
> xSelSupplier(Columns
, UNO_QUERY
);
1707 xSelSupplier
->addSelectionChangeListener(this);
1709 Reference
< XPropertySet
> xCol
;
1710 for (sal_Int32 i
= 0; i
< Columns
->getCount(); i
++)
1712 xCol
.set(Columns
->getByIndex(i
), css::uno::UNO_QUERY
);
1713 addColumnListeners(xCol
);
1716 Reference
< XReset
> xColumnReset(Columns
, UNO_QUERY
);
1717 if (xColumnReset
.is())
1718 xColumnReset
->addResetListener((XResetListener
*)this);
1720 m_xColumns
= Columns
;
1723 pGrid
->InitColumnsByModels(m_xColumns
);
1725 if (m_xColumns
.is())
1727 EventObject
aEvt(m_xColumns
);
1728 selectionChanged(aEvt
);
1734 void FmXGridPeer::setDesignMode(sal_Bool bOn
) throw( RuntimeException
, std::exception
)
1736 if (bOn
!= isDesignMode())
1738 Window
* pWin
= GetWindow();
1740 ((FmGridControl
*) pWin
)->SetDesignMode(bOn
);
1744 DisConnectFromDispatcher();
1746 UpdateDispatches(); // will connect if not already connected and just update else
1750 sal_Bool
FmXGridPeer::isDesignMode() throw( RuntimeException
, std::exception
)
1752 Window
* pWin
= GetWindow();
1754 return ((FmGridControl
*) pWin
)->IsDesignMode();
1760 void FmXGridPeer::elementInserted(const ContainerEvent
& evt
) throw( RuntimeException
, std::exception
)
1762 SolarMutexGuard aGuard
;
1764 FmGridControl
* pGrid
= (FmGridControl
*) GetWindow();
1765 // Handle Column beruecksichtigen
1766 if (!pGrid
|| !m_xColumns
.is() || pGrid
->IsInColumnMove() || m_xColumns
->getCount() == ((sal_Int32
)pGrid
->GetModelColCount()))
1769 Reference
< XPropertySet
> xSet(evt
.Element
, css::uno::UNO_QUERY
);
1770 addColumnListeners(xSet
);
1772 Reference
< XPropertySet
> xNewColumn(xSet
);
1773 OUString aName
= ::comphelper::getString(xNewColumn
->getPropertyValue(FM_PROP_LABEL
));
1774 Any aWidth
= xNewColumn
->getPropertyValue(FM_PROP_WIDTH
);
1775 sal_Int32 nWidth
= 0;
1776 if (aWidth
>>= nWidth
)
1777 nWidth
= pGrid
->LogicToPixel(Point(nWidth
,0),MAP_10TH_MM
).X();
1779 pGrid
->AppendColumn(aName
, (sal_uInt16
)nWidth
, (sal_Int16
)::comphelper::getINT32(evt
.Accessor
));
1781 // jetzt die Spalte setzen
1782 DbGridColumn
* pCol
= pGrid
->GetColumns().at( ::comphelper::getINT32(evt
.Accessor
) );
1783 pCol
->setModel(xNewColumn
);
1785 Any aHidden
= xNewColumn
->getPropertyValue(FM_PROP_HIDDEN
);
1786 if (::comphelper::getBOOL(aHidden
))
1787 pGrid
->HideColumn(pCol
->GetId());
1789 FormControlFactory( m_xContext
).initializeTextFieldLineEnds( xNewColumn
);
1793 void FmXGridPeer::elementReplaced(const ContainerEvent
& evt
) throw( RuntimeException
, std::exception
)
1795 SolarMutexGuard aGuard
;
1797 FmGridControl
* pGrid
= (FmGridControl
*) GetWindow();
1799 // Handle Column beruecksichtigen
1800 if (!pGrid
|| !m_xColumns
.is() || pGrid
->IsInColumnMove())
1803 Reference
< XPropertySet
> xNewColumn(evt
.Element
, css::uno::UNO_QUERY
);
1804 Reference
< XPropertySet
> xOldColumn(
1805 evt
.ReplacedElement
, css::uno::UNO_QUERY
);
1807 bool bWasEditing
= pGrid
->IsEditing();
1809 pGrid
->DeactivateCell();
1811 pGrid
->RemoveColumn(pGrid
->GetColumnIdFromModelPos((sal_uInt16
)::comphelper::getINT32(evt
.Accessor
)));
1813 removeColumnListeners(xOldColumn
);
1814 addColumnListeners(xNewColumn
);
1816 OUString aName
= ::comphelper::getString(xNewColumn
->getPropertyValue(FM_PROP_LABEL
));
1817 Any aWidth
= xNewColumn
->getPropertyValue(FM_PROP_WIDTH
);
1818 sal_Int32 nWidth
= 0;
1819 if (aWidth
>>= nWidth
)
1820 nWidth
= pGrid
->LogicToPixel(Point(nWidth
,0),MAP_10TH_MM
).X();
1821 sal_uInt16 nNewId
= pGrid
->AppendColumn(aName
, (sal_uInt16
)nWidth
, (sal_Int16
)::comphelper::getINT32(evt
.Accessor
));
1822 sal_uInt16 nNewPos
= pGrid
->GetModelColumnPos(nNewId
);
1824 // set the model of the new column
1825 DbGridColumn
* pCol
= pGrid
->GetColumns().at( nNewPos
);
1827 // for initializong this grid column, we need the fields of the grid's data source
1828 Reference
< XColumnsSupplier
> xSuppColumns
;
1829 CursorWrapper
* pGridDataSource
= pGrid
->getDataSource();
1830 if ( pGridDataSource
)
1831 xSuppColumns
= xSuppColumns
.query( (Reference
< XInterface
>)( *pGridDataSource
) );
1832 Reference
< XNameAccess
> xColumnsByName
;
1833 if ( xSuppColumns
.is() )
1834 xColumnsByName
= xSuppColumns
->getColumns();
1835 Reference
< XIndexAccess
> xColumnsByIndex( xColumnsByName
, UNO_QUERY
);
1837 if ( xColumnsByIndex
.is() )
1838 pGrid
->InitColumnByField( pCol
, xNewColumn
, xColumnsByName
, xColumnsByIndex
);
1840 // the simple version, applies when the grid is not yet connected to a data source
1841 pCol
->setModel(xNewColumn
);
1844 pGrid
->ActivateCell();
1848 void FmXGridPeer::elementRemoved(const ContainerEvent
& evt
) throw( RuntimeException
, std::exception
)
1850 SolarMutexGuard aGuard
;
1852 FmGridControl
* pGrid
= (FmGridControl
*) GetWindow();
1854 // Handle Column beruecksichtigen
1855 if (!pGrid
|| !m_xColumns
.is() || pGrid
->IsInColumnMove() || m_xColumns
->getCount() == ((sal_Int32
)pGrid
->GetModelColCount()))
1858 pGrid
->RemoveColumn(pGrid
->GetColumnIdFromModelPos((sal_uInt16
)::comphelper::getINT32(evt
.Accessor
)));
1860 Reference
< XPropertySet
> xOldColumn(evt
.Element
, css::uno::UNO_QUERY
);
1861 removeColumnListeners(xOldColumn
);
1865 void FmXGridPeer::setProperty( const OUString
& PropertyName
, const Any
& Value
) throw( RuntimeException
, std::exception
)
1867 SolarMutexGuard aGuard
;
1869 FmGridControl
* pGrid
= (FmGridControl
*) GetWindow();
1871 bool bVoid
= !Value
.hasValue();
1873 if ( PropertyName
== FM_PROP_TEXTLINECOLOR
)
1875 ::Color
aTextLineColor( bVoid
? COL_TRANSPARENT
: ::comphelper::getINT32( Value
) );
1878 pGrid
->SetTextLineColor();
1879 pGrid
->GetDataWindow().SetTextLineColor();
1883 pGrid
->SetTextLineColor(aTextLineColor
);
1884 pGrid
->GetDataWindow().SetTextLineColor(aTextLineColor
);
1887 // need to forward this to the columns
1888 DbGridColumns
& rColumns
= const_cast<DbGridColumns
&>(pGrid
->GetColumns());
1889 for ( size_t i
= 0, n
= rColumns
.size(); i
< n
; ++i
)
1891 DbGridColumn
* pLoop
= rColumns
[ i
];
1892 FmXGridCell
* pXCell
= pLoop
->GetCell();
1896 pXCell
->SetTextLineColor();
1898 pXCell
->SetTextLineColor(aTextLineColor
);
1903 pGrid
->Invalidate();
1905 else if ( PropertyName
== FM_PROP_FONTEMPHASISMARK
)
1907 Font aGridFont
= pGrid
->GetControlFont();
1908 sal_Int16 nValue
= ::comphelper::getINT16(Value
);
1909 aGridFont
.SetEmphasisMark( nValue
);
1910 pGrid
->SetControlFont( aGridFont
);
1912 else if ( PropertyName
== FM_PROP_FONTRELIEF
)
1914 Font aGridFont
= pGrid
->GetControlFont();
1915 sal_Int16 nValue
= ::comphelper::getINT16(Value
);
1916 aGridFont
.SetRelief( (FontRelief
)nValue
);
1917 pGrid
->SetControlFont( aGridFont
);
1919 else if ( PropertyName
== FM_PROP_HELPURL
)
1922 OSL_VERIFY( Value
>>= sHelpURL
);
1923 INetURLObject
aHID( sHelpURL
);
1924 if ( aHID
.GetProtocol() == INET_PROT_HID
)
1925 sHelpURL
= aHID
.GetURLPath();
1926 pGrid
->SetHelpId( OUStringToOString( sHelpURL
, RTL_TEXTENCODING_UTF8
) );
1928 else if ( PropertyName
== FM_PROP_DISPLAYSYNCHRON
)
1930 pGrid
->setDisplaySynchron(::comphelper::getBOOL(Value
));
1932 else if ( PropertyName
== FM_PROP_CURSORCOLOR
)
1935 pGrid
->SetCursorColor(COL_TRANSPARENT
);
1937 pGrid
->SetCursorColor( ::Color(::comphelper::getINT32(Value
)));
1939 pGrid
->Invalidate();
1941 else if ( PropertyName
== FM_PROP_ALWAYSSHOWCURSOR
)
1943 pGrid
->EnablePermanentCursor(::comphelper::getBOOL(Value
));
1945 pGrid
->Invalidate();
1947 else if ( PropertyName
== FM_PROP_FONT
)
1950 pGrid
->SetControlFont( Font() );
1953 ::com::sun::star::awt::FontDescriptor aFont
;
1954 if (Value
>>= aFont
)
1957 if (::comphelper::operator!=(aFont
, ::comphelper::getDefaultFont())) // ist das der Default
1958 aNewVclFont
= ImplCreateFont( aFont
);
1960 // need to add relief and emphasis (they're stored in a VCL-Font, but not in a FontDescriptor
1961 Font aOldVclFont
= pGrid
->GetControlFont();
1962 aNewVclFont
.SetRelief( aOldVclFont
.GetRelief() );
1963 aNewVclFont
.SetEmphasisMark( aOldVclFont
.GetEmphasisMark() );
1966 pGrid
->SetControlFont( aNewVclFont
);
1968 // if our row-height property is void (which means "calculate it font-dependent") we have
1969 // to adjust the control's row height
1970 Reference
< XPropertySet
> xModelSet(getColumns(), UNO_QUERY
);
1971 if (xModelSet
.is() && ::comphelper::hasProperty(FM_PROP_ROWHEIGHT
, xModelSet
))
1973 Any aHeight
= xModelSet
->getPropertyValue(FM_PROP_ROWHEIGHT
);
1974 if (!aHeight
.hasValue())
1975 pGrid
->SetDataRowHeight(0);
1981 else if ( PropertyName
== FM_PROP_BACKGROUNDCOLOR
)
1985 pGrid
->SetControlBackground();
1989 ::Color
aColor( ::comphelper::getINT32(Value
) );
1990 pGrid
->SetBackground( aColor
);
1991 pGrid
->SetControlBackground( aColor
);
1994 else if ( PropertyName
== FM_PROP_TEXTCOLOR
)
1998 pGrid
->SetControlForeground();
2002 ::Color
aColor( ::comphelper::getINT32(Value
) );
2003 pGrid
->SetTextColor( aColor
);
2004 pGrid
->SetControlForeground( aColor
);
2007 else if ( PropertyName
== FM_PROP_ROWHEIGHT
)
2009 sal_Int32
nLogHeight(0);
2010 if (Value
>>= nLogHeight
)
2012 sal_Int32 nHeight
= pGrid
->LogicToPixel(Point(0,nLogHeight
),MAP_10TH_MM
).Y();
2013 // take the zoom factor into account
2014 nHeight
= pGrid
->CalcZoom(nHeight
);
2015 pGrid
->SetDataRowHeight(nHeight
);
2018 pGrid
->SetDataRowHeight(0);
2020 else if ( PropertyName
== FM_PROP_HASNAVIGATION
)
2022 bool bValue( true );
2023 OSL_VERIFY( Value
>>= bValue
);
2024 pGrid
->EnableNavigationBar( bValue
);
2026 else if ( PropertyName
== FM_PROP_RECORDMARKER
)
2028 bool bValue( true );
2029 OSL_VERIFY( Value
>>= bValue
);
2030 pGrid
->EnableHandle( bValue
);
2032 else if ( PropertyName
== FM_PROP_ENABLED
)
2034 bool bValue( true );
2035 OSL_VERIFY( Value
>>= bValue
);
2037 // In design mode, disable only the data window.
2038 // Else the control cannot be configured anymore.
2040 pGrid
->GetDataWindow().Enable( bValue
);
2042 pGrid
->Enable( bValue
);
2045 VCLXWindow::setProperty( PropertyName
, Value
);
2049 Reference
< XAccessibleContext
> FmXGridPeer::CreateAccessibleContext()
2051 Reference
< XAccessibleContext
> xContext
;
2053 // use the AccessibleContext provided by the VCL window
2054 Window
* pGrid
= GetWindow();
2057 Reference
< XAccessible
> xAcc( pGrid
->GetAccessible( true ) );
2059 xContext
= xAcc
->getAccessibleContext();
2060 // TODO: this has a slight conceptual problem:
2062 // We know that the XAccessible and XAccessibleContext implementation of the browse
2063 // box is the same (the class implements both interfaces), which, speaking strictly,
2064 // is bad here (means when a browse box acts as UnoControl): We (the FmXGridPeer) are
2065 // the XAccessible here, and the browse box should be able to provide us an XAccessibleContext,
2066 // but it should _not_ be the XAccessible itself.
2067 // However, as long as no client implementation uses dirty hacks such as querying an
2068 // XAccessibleContext for XAccessible, this should not be a problem.
2071 if ( !xContext
.is() )
2072 xContext
= VCLXWindow::CreateAccessibleContext( );
2078 Any
FmXGridPeer::getProperty( const OUString
& _rPropertyName
) throw( RuntimeException
, std::exception
)
2083 FmGridControl
* pGrid
= (FmGridControl
*) GetWindow();
2084 Window
* pDataWindow
= &pGrid
->GetDataWindow();
2086 if ( _rPropertyName
== FM_PROP_NAME
)
2088 Font aFont
= pDataWindow
->GetControlFont();
2089 aProp
<<= ImplCreateFontDescriptor( aFont
);
2091 else if ( _rPropertyName
== FM_PROP_TEXTCOLOR
)
2093 aProp
<<= (sal_Int32
)pDataWindow
->GetControlForeground().GetColor();
2095 else if ( _rPropertyName
== FM_PROP_BACKGROUNDCOLOR
)
2097 aProp
<<= (sal_Int32
)pDataWindow
->GetControlBackground().GetColor();
2099 else if ( _rPropertyName
== FM_PROP_ROWHEIGHT
)
2101 sal_Int32 nPixelHeight
= pGrid
->GetDataRowHeight();
2102 // take the zoom factor into account
2103 nPixelHeight
= pGrid
->CalcReverseZoom(nPixelHeight
);
2104 aProp
<<= (sal_Int32
)pGrid
->PixelToLogic(Point(0,nPixelHeight
),MAP_10TH_MM
).Y();
2106 else if ( _rPropertyName
== FM_PROP_HASNAVIGATION
)
2108 bool bHasNavBar
= pGrid
->HasNavigationBar();
2109 aProp
<<= bHasNavBar
;
2111 else if ( _rPropertyName
== FM_PROP_RECORDMARKER
)
2113 bool bHasHandle
= pGrid
->HasHandle();
2114 aProp
<<= bHasHandle
;
2116 else if ( _rPropertyName
== FM_PROP_ENABLED
)
2118 aProp
<<= pDataWindow
->IsEnabled();
2121 aProp
= VCLXWindow::getProperty( _rPropertyName
);
2127 void FmXGridPeer::dispose() throw( RuntimeException
, std::exception
)
2130 aEvt
.Source
= static_cast< ::cppu::OWeakObject
* >(this);
2131 m_aModifyListeners
.disposeAndClear(aEvt
);
2132 m_aUpdateListeners
.disposeAndClear(aEvt
);
2133 m_aContainerListeners
.disposeAndClear(aEvt
);
2134 VCLXWindow::dispose();
2136 // release all interceptors
2137 Reference
< XDispatchProviderInterceptor
> xInterceptor( m_xFirstDispatchInterceptor
);
2138 m_xFirstDispatchInterceptor
.clear();
2139 while ( xInterceptor
.is() )
2141 // tell the interceptor it has a new (means no) predecessor
2142 xInterceptor
->setMasterDispatchProvider( NULL
);
2144 // ask for it's successor
2145 Reference
< XDispatchProvider
> xSlave
= xInterceptor
->getSlaveDispatchProvider();
2146 // and give it the new (means no) successoert
2147 xInterceptor
->setSlaveDispatchProvider( NULL
);
2149 // start over with the next chain element
2150 xInterceptor
= xInterceptor
.query( xSlave
);
2153 DisConnectFromDispatcher();
2154 setRowSet(Reference
< XRowSet
> ());
2159 void FmXGridPeer::addContainerListener(const Reference
< XContainerListener
>& l
) throw( RuntimeException
, std::exception
)
2161 m_aContainerListeners
.addInterface( l
);
2164 void FmXGridPeer::removeContainerListener(const Reference
< XContainerListener
>& l
) throw( RuntimeException
, std::exception
)
2166 m_aContainerListeners
.removeInterface( l
);
2169 // ::com::sun::star::data::XDatabaseCursorSupplier
2171 void FmXGridPeer::startCursorListening()
2173 if (!m_nCursorListening
)
2175 Reference
< XRowSet
> xRowSet(m_xCursor
, UNO_QUERY
);
2177 xRowSet
->addRowSetListener(this);
2179 Reference
< XReset
> xReset(m_xCursor
, UNO_QUERY
);
2181 xReset
->addResetListener(this);
2183 // register all listeners
2184 Reference
< XPropertySet
> xSet(m_xCursor
, UNO_QUERY
);
2187 xSet
->addPropertyChangeListener(FM_PROP_ISMODIFIED
, this);
2188 xSet
->addPropertyChangeListener(FM_PROP_ROWCOUNT
, this);
2191 m_nCursorListening
++;
2195 void FmXGridPeer::stopCursorListening()
2197 if (!--m_nCursorListening
)
2199 Reference
< XRowSet
> xRowSet(m_xCursor
, UNO_QUERY
);
2201 xRowSet
->removeRowSetListener(this);
2203 Reference
< XReset
> xReset(m_xCursor
, UNO_QUERY
);
2205 xReset
->removeResetListener(this);
2207 Reference
< XPropertySet
> xSet(m_xCursor
, UNO_QUERY
);
2210 xSet
->removePropertyChangeListener(FM_PROP_ISMODIFIED
, this);
2211 xSet
->removePropertyChangeListener(FM_PROP_ROWCOUNT
, this);
2217 void FmXGridPeer::updateGrid(const Reference
< XRowSet
>& _rxCursor
)
2219 FmGridControl
* pGrid
= (FmGridControl
*)GetWindow();
2221 pGrid
->setDataSource(_rxCursor
);
2225 Reference
< XRowSet
> FmXGridPeer::getRowSet() throw( RuntimeException
, std::exception
)
2231 void FmXGridPeer::setRowSet(const Reference
< XRowSet
>& _rDatabaseCursor
) throw( RuntimeException
, std::exception
)
2233 FmGridControl
* pGrid
= (FmGridControl
*) GetWindow();
2234 if (!pGrid
|| !m_xColumns
.is() || !m_xColumns
->getCount())
2236 // unregister all listeners
2239 Reference
< XLoadable
> xLoadable(m_xCursor
, UNO_QUERY
);
2240 // only if the form is loaded we set the rowset
2243 stopCursorListening();
2244 xLoadable
->removeLoadListener(this);
2248 m_xCursor
= _rDatabaseCursor
;
2252 Reference
< XLoadable
> xLoadable(m_xCursor
, UNO_QUERY
);
2253 // only if the form is loaded we set the rowset
2254 if (xLoadable
.is() && xLoadable
->isLoaded())
2255 pGrid
->setDataSource(m_xCursor
);
2257 pGrid
->setDataSource(Reference
< XRowSet
> ());
2261 startCursorListening();
2262 xLoadable
->addLoadListener(this);
2268 void SAL_CALL
FmXGridPeer::addGridControlListener( const Reference
< XGridControlListener
>& _listener
) throw( RuntimeException
, std::exception
)
2270 m_aGridControlListeners
.addInterface( _listener
);
2274 void SAL_CALL
FmXGridPeer::removeGridControlListener( const Reference
< XGridControlListener
>& _listener
) throw( RuntimeException
, std::exception
)
2276 m_aGridControlListeners
.removeInterface( _listener
);
2280 sal_Int16
FmXGridPeer::getCurrentColumnPosition() throw( RuntimeException
, std::exception
)
2282 FmGridControl
* pGrid
= (FmGridControl
*) GetWindow();
2283 return pGrid
? pGrid
->GetViewColumnPos(pGrid
->GetCurColumnId()) : -1;
2287 void FmXGridPeer::setCurrentColumnPosition(sal_Int16 nPos
) throw( RuntimeException
, std::exception
)
2289 FmGridControl
* pGrid
= (FmGridControl
*) GetWindow();
2291 pGrid
->GoToColumnId(pGrid
->GetColumnIdFromViewPos(nPos
));
2295 void FmXGridPeer::selectionChanged(const EventObject
& evt
) throw( RuntimeException
, std::exception
)
2297 SolarMutexGuard aGuard
;
2299 FmGridControl
* pGrid
= (FmGridControl
*) GetWindow();
2302 Reference
< ::com::sun::star::view::XSelectionSupplier
> xSelSupplier(evt
.Source
, UNO_QUERY
);
2303 Any aSelection
= xSelSupplier
->getSelection();
2304 DBG_ASSERT(aSelection
.getValueType().getTypeClass() == TypeClass_INTERFACE
, "FmXGridPeer::selectionChanged : invalid selection !");
2305 Reference
< XPropertySet
> xSelection
;
2306 aSelection
>>= xSelection
;
2307 if (xSelection
.is())
2309 Reference
< XPropertySet
> xCol
;
2311 sal_Int32 nColCount
= m_xColumns
->getCount();
2313 for (; i
< nColCount
; ++i
)
2315 m_xColumns
->getByIndex(i
) >>= xCol
;
2316 if ( xCol
== xSelection
)
2318 pGrid
->markColumn(pGrid
->GetColumnIdFromModelPos((sal_uInt16
)i
));
2322 // The columns have to be 1-based for the VCL control.
2323 // If necessary, pass on the selection to the VCL control
2324 if ( i
!= pGrid
->GetSelectedColumn() )
2325 { // (wenn das nicht greift, wurde das selectionChanged implizit von dem Control selber ausgeloest
2326 // if this does not ?hold?catch?, the selectionChanged is cleared by the Control itself
2327 if ( i
< nColCount
)
2329 pGrid
->SelectColumnPos(pGrid
->GetViewColumnPos(pGrid
->GetColumnIdFromModelPos( (sal_uInt16
)i
)) + 1, true);
2330 // SelectColumnPos has led to an implicit ActivateCell again
2331 if (pGrid
->IsEditing())
2332 pGrid
->DeactivateCell();
2335 pGrid
->SetNoSelection();
2339 pGrid
->markColumn(USHRT_MAX
);
2345 sal_Bool
FmXGridPeer::hasElements() throw( RuntimeException
, std::exception
)
2347 return getCount() != 0;
2351 Type SAL_CALL
FmXGridPeer::getElementType( ) throw(RuntimeException
, std::exception
)
2353 return cppu::UnoType
<com::sun::star::awt::XControl
>::get();
2356 // XEnumerationAccess
2358 Reference
< XEnumeration
> FmXGridPeer::createEnumeration() throw( RuntimeException
, std::exception
)
2360 return new ::comphelper::OEnumerationByIndex(this);
2365 sal_Int32
FmXGridPeer::getCount() throw( RuntimeException
, std::exception
)
2367 FmGridControl
* pGrid
= (FmGridControl
*) GetWindow();
2369 return pGrid
->GetViewColCount();
2375 Any
FmXGridPeer::getByIndex(sal_Int32 _nIndex
) throw( IndexOutOfBoundsException
, WrappedTargetException
, RuntimeException
, std::exception
)
2377 FmGridControl
* pGrid
= (FmGridControl
*) GetWindow();
2379 _nIndex
>= getCount() || !pGrid
)
2380 throw IndexOutOfBoundsException();
2384 sal_uInt16 nId
= pGrid
->GetColumnIdFromViewPos((sal_uInt16
)_nIndex
);
2385 // get the list position
2386 sal_uInt16 nPos
= pGrid
->GetModelColumnPos(nId
);
2388 if ( nPos
== GRID_COLUMN_NOT_FOUND
)
2391 DbGridColumn
* pCol
= pGrid
->GetColumns().at( nPos
);
2392 Reference
< ::com::sun::star::awt::XControl
> xControl(pCol
->GetCell());
2393 aElement
<<= xControl
;
2398 // ::com::sun::star::util::XModeSelector
2400 void FmXGridPeer::setMode(const OUString
& Mode
) throw( NoSupportException
, RuntimeException
, std::exception
)
2402 if (!supportsMode(Mode
))
2403 throw NoSupportException();
2405 if (Mode
== m_aMode
)
2410 FmGridControl
* pGrid
= (FmGridControl
*) GetWindow();
2411 if ( Mode
== "FilterMode" )
2412 pGrid
->SetFilterMode(true);
2415 pGrid
->SetFilterMode(false);
2416 pGrid
->setDataSource(m_xCursor
);
2421 OUString
FmXGridPeer::getMode() throw( RuntimeException
, std::exception
)
2427 ::comphelper::StringSequence
FmXGridPeer::getSupportedModes() throw( RuntimeException
, std::exception
)
2429 static ::comphelper::StringSequence aModes
;
2430 if (!aModes
.getLength())
2433 OUString
* pModes
= aModes
.getArray();
2434 pModes
[0] = "DataMode";
2435 pModes
[1] = "FilterMode";
2441 sal_Bool
FmXGridPeer::supportsMode(const OUString
& Mode
) throw( RuntimeException
, std::exception
)
2443 ::comphelper::StringSequence
aModes(getSupportedModes());
2444 const OUString
* pModes
= aModes
.getConstArray();
2445 for (sal_Int32 i
= aModes
.getLength(); i
> 0; )
2447 if (pModes
[--i
] == Mode
)
2454 void FmXGridPeer::columnVisible(DbGridColumn
* pColumn
)
2456 FmGridControl
* pGrid
= (FmGridControl
*) GetWindow();
2458 sal_Int32 _nIndex
= pGrid
->GetModelColumnPos(pColumn
->GetId());
2459 Reference
< ::com::sun::star::awt::XControl
> xControl(pColumn
->GetCell());
2460 ContainerEvent aEvt
;
2461 aEvt
.Source
= (XContainer
*)this;
2462 aEvt
.Accessor
<<= _nIndex
;
2463 aEvt
.Element
<<= xControl
;
2465 m_aContainerListeners
.notifyEach( &XContainerListener::elementInserted
, aEvt
);
2469 void FmXGridPeer::columnHidden(DbGridColumn
* pColumn
)
2471 FmGridControl
* pGrid
= (FmGridControl
*) GetWindow();
2473 sal_Int32 _nIndex
= pGrid
->GetModelColumnPos(pColumn
->GetId());
2474 Reference
< ::com::sun::star::awt::XControl
> xControl(pColumn
->GetCell());
2475 ContainerEvent aEvt
;
2476 aEvt
.Source
= (XContainer
*)this;
2477 aEvt
.Accessor
<<= _nIndex
;
2478 aEvt
.Element
<<= xControl
;
2480 m_aContainerListeners
.notifyEach( &XContainerListener::elementRemoved
, aEvt
);
2484 void FmXGridPeer::draw( sal_Int32 x
, sal_Int32 y
) throw( RuntimeException
, std::exception
)
2486 FmGridControl
* pGrid
= (FmGridControl
*) GetWindow();
2487 sal_Int32 nOldFlags
= pGrid
->GetBrowserFlags();
2488 pGrid
->SetBrowserFlags(nOldFlags
| EBBF_NOROWPICTURE
);
2490 VCLXWindow::draw(x
, y
);
2492 pGrid
->SetBrowserFlags(nOldFlags
);
2496 Reference
< ::com::sun::star::frame::XDispatch
> FmXGridPeer::queryDispatch(const ::com::sun::star::util::URL
& aURL
, const OUString
& aTargetFrameName
, sal_Int32 nSearchFlags
) throw( RuntimeException
, std::exception
)
2498 Reference
< ::com::sun::star::frame::XDispatch
> xResult
;
2500 // first ask our interceptor chain
2501 if (m_xFirstDispatchInterceptor
.is() && !m_bInterceptingDispatch
)
2503 m_bInterceptingDispatch
= true;
2504 // safety against recursion : as we are master of the first chain element and slave of the last one we would
2505 // have an infinite loop without this if no dispatcher can fullfill the request
2506 xResult
= m_xFirstDispatchInterceptor
->queryDispatch(aURL
, aTargetFrameName
, nSearchFlags
);
2507 m_bInterceptingDispatch
= false;
2510 // then ask ourself : we don't have any dispatches
2515 Sequence
< Reference
< ::com::sun::star::frame::XDispatch
> > FmXGridPeer::queryDispatches(const Sequence
< ::com::sun::star::frame::DispatchDescriptor
>& aDescripts
) throw( RuntimeException
, std::exception
)
2517 if (m_xFirstDispatchInterceptor
.is())
2518 return m_xFirstDispatchInterceptor
->queryDispatches(aDescripts
);
2520 // then ask ourself : we don't have any dispatches
2521 return Sequence
< Reference
< ::com::sun::star::frame::XDispatch
> >();
2525 void FmXGridPeer::registerDispatchProviderInterceptor(const Reference
< ::com::sun::star::frame::XDispatchProviderInterceptor
>& _xInterceptor
) throw( RuntimeException
, std::exception
)
2527 if (_xInterceptor
.is())
2529 if (m_xFirstDispatchInterceptor
.is())
2531 Reference
< ::com::sun::star::frame::XDispatchProvider
> xFirstProvider(m_xFirstDispatchInterceptor
, UNO_QUERY
);
2532 // there is already an interceptor; the new one will become its master
2533 _xInterceptor
->setSlaveDispatchProvider(xFirstProvider
);
2534 m_xFirstDispatchInterceptor
->setMasterDispatchProvider(xFirstProvider
);
2538 // it is the first interceptor; set ourself as slave
2539 _xInterceptor
->setSlaveDispatchProvider((::com::sun::star::frame::XDispatchProvider
*)this);
2542 // we are the master of the chain's first interceptor
2543 m_xFirstDispatchInterceptor
= _xInterceptor
;
2544 m_xFirstDispatchInterceptor
->setMasterDispatchProvider((::com::sun::star::frame::XDispatchProvider
*)this);
2546 // we have a new interceptor and we're alive ?
2547 if (!isDesignMode())
2548 // -> check for new dispatchers
2554 void FmXGridPeer::releaseDispatchProviderInterceptor(const Reference
< ::com::sun::star::frame::XDispatchProviderInterceptor
>& _xInterceptor
) throw( RuntimeException
, std::exception
)
2556 if (!_xInterceptor
.is())
2559 Reference
< ::com::sun::star::frame::XDispatchProviderInterceptor
> xChainWalk(m_xFirstDispatchInterceptor
);
2561 if (m_xFirstDispatchInterceptor
== _xInterceptor
)
2562 { // our chain will have a new first element
2563 Reference
< ::com::sun::star::frame::XDispatchProviderInterceptor
> xSlave(m_xFirstDispatchInterceptor
->getSlaveDispatchProvider(), UNO_QUERY
);
2564 m_xFirstDispatchInterceptor
= xSlave
;
2566 // do this before removing the interceptor from the chain as we won't know it's slave afterwards)
2568 while (xChainWalk
.is())
2570 // walk along the chain of interceptors and look for the interceptor that has to be removed
2571 Reference
< ::com::sun::star::frame::XDispatchProviderInterceptor
> xSlave(xChainWalk
->getSlaveDispatchProvider(), UNO_QUERY
);
2573 if (xChainWalk
== _xInterceptor
)
2575 // old master may be an interceptor too
2576 Reference
< ::com::sun::star::frame::XDispatchProviderInterceptor
> xMaster(xChainWalk
->getMasterDispatchProvider(), UNO_QUERY
);
2578 // unchain the interceptor that has to be removed
2579 xChainWalk
->setSlaveDispatchProvider(Reference
< ::com::sun::star::frame::XDispatchProvider
> ());
2580 xChainWalk
->setMasterDispatchProvider(Reference
< ::com::sun::star::frame::XDispatchProvider
> ());
2582 // reconnect the chain
2586 xMaster
->setSlaveDispatchProvider(Reference
< ::com::sun::star::frame::XDispatchProvider
>::query(xSlave
));
2588 // it's the first interceptor of the chain, set ourself as slave
2589 xMaster
->setSlaveDispatchProvider((::com::sun::star::frame::XDispatchProvider
*)this);
2593 // the chain's first element was removed, set ourself as new master of the second one
2595 xSlave
->setMasterDispatchProvider((::com::sun::star::frame::XDispatchProvider
*)this);
2599 xChainWalk
= xSlave
;
2601 // our interceptor chain has changed and we're alive ?
2602 if (!isDesignMode())
2603 // -> check the dispatchers
2608 void FmXGridPeer::statusChanged(const ::com::sun::star::frame::FeatureStateEvent
& Event
) throw( RuntimeException
, std::exception
)
2610 DBG_ASSERT(m_pStateCache
, "FmXGridPeer::statusChanged : invalid call !");
2611 DBG_ASSERT(m_pDispatchers
, "FmXGridPeer::statusChanged : invalid call !");
2613 Sequence
< ::com::sun::star::util::URL
>& aUrls
= getSupportedURLs();
2614 const ::com::sun::star::util::URL
* pUrls
= aUrls
.getConstArray();
2616 Sequence
<sal_uInt16
> aSlots
= getSupportedGridSlots();
2617 const sal_uInt16
* pSlots
= aSlots
.getConstArray();
2620 for (i
=0; i
<aUrls
.getLength(); ++i
, ++pUrls
, ++pSlots
)
2622 if (pUrls
->Main
== Event
.FeatureURL
.Main
)
2624 DBG_ASSERT(m_pDispatchers
[i
] == Event
.Source
, "FmXGridPeer::statusChanged : the event source is a little bit suspect !");
2625 m_pStateCache
[i
] = Event
.IsEnabled
;
2626 FmGridControl
* pGrid
= (FmGridControl
*) GetWindow();
2627 if (*pSlots
!= SID_FM_RECORD_UNDO
)
2628 pGrid
->GetNavigationBar().InvalidateState(*pSlots
);
2632 DBG_ASSERT(i
<aUrls
.getLength(), "FmXGridPeer::statusChanged : got a call for an unknown url !");
2636 sal_Bool
FmXGridPeer::approveReset(const EventObject
& /*rEvent*/) throw( RuntimeException
, std::exception
)
2642 sal_Bool SAL_CALL
FmXGridPeer::select( const Any
& _rSelection
) throw (IllegalArgumentException
, RuntimeException
, std::exception
)
2644 Sequence
< Any
> aBookmarks
;
2645 if ( !( _rSelection
>>= aBookmarks
) )
2646 throw IllegalArgumentException();
2648 FmGridControl
* pVclControl
= static_cast<FmGridControl
*>(GetWindow());
2649 return pVclControl
->selectBookmarks(aBookmarks
);
2652 // speaking strictly, we would have to adjust our model, as our ColumnSelection may have changed.
2653 // Our model is a XSelectionSupplier, too, it handles the selection of single columns.
2654 // This is somewhat strange, as selection should be a view (not a model) aspect.
2655 // So for a clean solution, we should handle column selection ourself, and the model shouldn't
2656 // deal with selection at all.
2660 Any SAL_CALL
FmXGridPeer::getSelection( ) throw (RuntimeException
, std::exception
)
2662 FmGridControl
* pVclControl
= static_cast<FmGridControl
*>(GetWindow());
2663 Sequence
< Any
> aSelectionBookmarks
= pVclControl
->getSelectionBookmarks();
2664 return makeAny(aSelectionBookmarks
);
2668 void SAL_CALL
FmXGridPeer::addSelectionChangeListener( const Reference
< XSelectionChangeListener
>& _rxListener
) throw (RuntimeException
, std::exception
)
2670 m_aSelectionListeners
.addInterface( _rxListener
);
2674 void SAL_CALL
FmXGridPeer::removeSelectionChangeListener( const Reference
< XSelectionChangeListener
>& _rxListener
) throw (RuntimeException
, std::exception
)
2676 m_aSelectionListeners
.removeInterface( _rxListener
);
2680 void FmXGridPeer::resetted(const EventObject
& rEvent
) throw( RuntimeException
, std::exception
)
2682 if (m_xColumns
== rEvent
.Source
)
2683 { // my model was reset -> refresh the grid content
2684 FmGridControl
* pGrid
= (FmGridControl
*)GetWindow();
2687 SolarMutexGuard aGuard
;
2688 pGrid
->resetCurrentRow();
2690 // if the cursor fired a reset event we seem to be on the insert row
2691 else if (m_xCursor
== rEvent
.Source
)
2693 SolarMutexGuard aGuard
;
2694 FmGridControl
* pGrid
= (FmGridControl
*) GetWindow();
2695 if (pGrid
&& pGrid
->IsOpen())
2696 pGrid
->positioned(rEvent
);
2701 Sequence
<sal_uInt16
>& FmXGridPeer::getSupportedGridSlots()
2703 static Sequence
<sal_uInt16
> aSupported
;
2704 if (aSupported
.getLength() == 0)
2706 sal_uInt16 nSupported
[] = {
2707 DbGridControl::NavigationBar::RECORD_FIRST
,
2708 DbGridControl::NavigationBar::RECORD_PREV
,
2709 DbGridControl::NavigationBar::RECORD_NEXT
,
2710 DbGridControl::NavigationBar::RECORD_LAST
,
2711 DbGridControl::NavigationBar::RECORD_NEW
,
2714 aSupported
.realloc(sizeof(nSupported
)/sizeof(nSupported
[0]));
2715 sal_uInt16
* pSupported
= aSupported
.getArray();
2716 for (sal_uInt16 i
=0; i
<aSupported
.getLength(); ++i
, ++pSupported
)
2717 *pSupported
= nSupported
[i
];
2723 Sequence
< ::com::sun::star::util::URL
>& FmXGridPeer::getSupportedURLs()
2725 static Sequence
< ::com::sun::star::util::URL
> aSupported
;
2726 if (aSupported
.getLength() == 0)
2728 static const OUString sSupported
[] = {
2729 FMURL_RECORD_MOVEFIRST
,
2730 FMURL_RECORD_MOVEPREV
,
2731 FMURL_RECORD_MOVENEXT
,
2732 FMURL_RECORD_MOVELAST
,
2733 FMURL_RECORD_MOVETONEW
,
2736 aSupported
.realloc(sizeof(sSupported
)/sizeof(sSupported
[0]));
2737 ::com::sun::star::util::URL
* pSupported
= aSupported
.getArray();
2740 for ( i
= 0; i
< aSupported
.getLength(); ++i
, ++pSupported
)
2741 pSupported
->Complete
= sSupported
[i
];
2743 // let an ::com::sun::star::util::URL-transformer normalize the URLs
2744 Reference
< ::com::sun::star::util::XURLTransformer
> xTransformer(
2745 util::URLTransformer::create(::comphelper::getProcessComponentContext()) );
2746 pSupported
= aSupported
.getArray();
2747 for (i
=0; i
<aSupported
.getLength(); ++i
)
2748 xTransformer
->parseStrict(pSupported
[i
]);
2755 void FmXGridPeer::UpdateDispatches()
2758 { // we don't have any dispatchers yet -> do the initial connect
2759 ConnectToDispatcher();
2763 sal_uInt16 nDispatchersGot
= 0;
2764 const Sequence
< ::com::sun::star::util::URL
>& aSupportedURLs
= getSupportedURLs();
2765 const ::com::sun::star::util::URL
* pSupportedURLs
= aSupportedURLs
.getConstArray();
2766 Reference
< ::com::sun::star::frame::XDispatch
> xNewDispatch
;
2767 for (sal_uInt16 i
=0; i
<aSupportedURLs
.getLength(); ++i
, ++pSupportedURLs
)
2769 xNewDispatch
= queryDispatch(*pSupportedURLs
, OUString(), 0);
2770 if (xNewDispatch
!= m_pDispatchers
[i
])
2772 if (m_pDispatchers
[i
].is())
2773 m_pDispatchers
[i
]->removeStatusListener((::com::sun::star::frame::XStatusListener
*)this, *pSupportedURLs
);
2774 m_pDispatchers
[i
] = xNewDispatch
;
2775 if (m_pDispatchers
[i
].is())
2776 m_pDispatchers
[i
]->addStatusListener((::com::sun::star::frame::XStatusListener
*)this, *pSupportedURLs
);
2778 if (m_pDispatchers
[i
].is())
2782 if (!nDispatchersGot
)
2784 delete[] m_pStateCache
;
2785 delete[] m_pDispatchers
;
2786 m_pStateCache
= NULL
;
2787 m_pDispatchers
= NULL
;
2792 void FmXGridPeer::ConnectToDispatcher()
2794 DBG_ASSERT((m_pStateCache
!= NULL
) == (m_pDispatchers
!= NULL
), "FmXGridPeer::ConnectToDispatcher : inconsistent !");
2796 { // already connected -> just do an update
2801 const Sequence
< ::com::sun::star::util::URL
>& aSupportedURLs
= getSupportedURLs();
2803 // _before_ adding the status listeners (as the add should result in a statusChanged-call) !
2804 m_pStateCache
= new bool[aSupportedURLs
.getLength()];
2805 m_pDispatchers
= new Reference
< ::com::sun::star::frame::XDispatch
> [aSupportedURLs
.getLength()];
2807 sal_uInt16 nDispatchersGot
= 0;
2808 const ::com::sun::star::util::URL
* pSupportedURLs
= aSupportedURLs
.getConstArray();
2809 for (sal_uInt16 i
=0; i
<aSupportedURLs
.getLength(); ++i
, ++pSupportedURLs
)
2811 m_pStateCache
[i
] = false;
2812 m_pDispatchers
[i
] = queryDispatch(*pSupportedURLs
, OUString(), 0);
2813 if (m_pDispatchers
[i
].is())
2815 m_pDispatchers
[i
]->addStatusListener((::com::sun::star::frame::XStatusListener
*)this, *pSupportedURLs
);
2820 if (!nDispatchersGot
)
2822 delete[] m_pStateCache
;
2823 delete[] m_pDispatchers
;
2824 m_pStateCache
= NULL
;
2825 m_pDispatchers
= NULL
;
2830 void FmXGridPeer::DisConnectFromDispatcher()
2832 if (!m_pStateCache
|| !m_pDispatchers
)
2834 // we're not connected
2836 const Sequence
< ::com::sun::star::util::URL
>& aSupportedURLs
= getSupportedURLs();
2837 const ::com::sun::star::util::URL
* pSupportedURLs
= aSupportedURLs
.getConstArray();
2838 for (sal_uInt16 i
=0; i
<aSupportedURLs
.getLength(); ++i
, ++pSupportedURLs
)
2840 if (m_pDispatchers
[i
].is())
2841 m_pDispatchers
[i
]->removeStatusListener((::com::sun::star::frame::XStatusListener
*)this, *pSupportedURLs
);
2844 delete[] m_pStateCache
;
2845 delete[] m_pDispatchers
;
2846 m_pStateCache
= NULL
;
2847 m_pDispatchers
= NULL
;
2851 IMPL_LINK(FmXGridPeer
, OnQueryGridSlotState
, void*, pSlot
)
2854 return -1; // unspecified
2856 sal_uInt16 nSlot
= (sal_uInt16
)(sal_uIntPtr
)pSlot
;
2858 // search the given slot with our supported sequence
2859 Sequence
<sal_uInt16
>& aSupported
= getSupportedGridSlots();
2860 const sal_uInt16
* pSlots
= aSupported
.getConstArray();
2861 for (sal_uInt16 i
=0; i
<aSupported
.getLength(); ++i
)
2863 if (pSlots
[i
] == nSlot
)
2865 if (!m_pDispatchers
[i
].is())
2866 return -1; // nothing known about this slot
2868 return m_pStateCache
[i
] ? 1 : 0;
2876 IMPL_LINK(FmXGridPeer
, OnExecuteGridSlot
, void*, pSlot
)
2878 if (!m_pDispatchers
)
2879 return 0; // not handled
2881 Sequence
< ::com::sun::star::util::URL
>& aUrls
= getSupportedURLs();
2882 const ::com::sun::star::util::URL
* pUrls
= aUrls
.getConstArray();
2884 Sequence
<sal_uInt16
> aSlots
= getSupportedGridSlots();
2885 const sal_uInt16
* pSlots
= aSlots
.getConstArray();
2887 DBG_ASSERT(aSlots
.getLength() == aUrls
.getLength(), "FmXGridPeer::OnExecuteGridSlot : inconstent data returned by getSupportedURLs/getSupportedGridSlots !");
2889 sal_uInt16 nSlot
= (sal_uInt16
)(sal_uIntPtr
)pSlot
;
2890 for (sal_uInt16 i
=0; i
<aSlots
.getLength(); ++i
, ++pUrls
, ++pSlots
)
2892 if (*pSlots
== nSlot
)
2894 if (m_pDispatchers
[i
].is())
2896 // commit any changes done so far, if it's not the undoRecord URL
2897 if ( pUrls
->Complete
== FMURL_RECORD_UNDO
|| commit() )
2898 m_pDispatchers
[i
]->dispatch(*pUrls
, Sequence
< PropertyValue
>());
2900 return 1; // handled
2905 return 0; // not handled
2908 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */