Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
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/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
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 .
18 : */
19 :
20 :
21 : #include "svx/fmgridif.hxx"
22 : #include "fmprop.hrc"
23 : #include "fmservs.hxx"
24 : #include "svx/fmtools.hxx"
25 : #include "fmurl.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>
32 :
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>
45 :
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>
58 :
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;
70 :
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;
78 :
79 :
80 :
81 0 : ::com::sun::star::awt::FontDescriptor ImplCreateFontDescriptor( const vcl::Font& rFont )
82 : {
83 0 : ::com::sun::star::awt::FontDescriptor aFD;
84 0 : aFD.Name = rFont.GetName();
85 0 : aFD.StyleName = rFont.GetStyleName();
86 0 : aFD.Height = (sal_Int16)rFont.GetSize().Height();
87 0 : aFD.Width = (sal_Int16)rFont.GetSize().Width();
88 0 : aFD.Family = (sal_Int16)rFont.GetFamily();
89 0 : aFD.CharSet = rFont.GetCharSet();
90 0 : aFD.Pitch = (sal_Int16)rFont.GetPitch();
91 0 : aFD.CharacterWidth = VCLUnoHelper::ConvertFontWidth( rFont.GetWidthType() );
92 0 : aFD.Weight= VCLUnoHelper::ConvertFontWeight( rFont.GetWeight() );
93 0 : aFD.Slant = VCLUnoHelper::ConvertFontSlant( rFont.GetItalic() );
94 0 : aFD.Underline = (sal_Int16)rFont.GetUnderline();
95 0 : aFD.Strikeout = (sal_Int16)rFont.GetStrikeout();
96 0 : aFD.Orientation = rFont.GetOrientation();
97 0 : aFD.Kerning = rFont.IsKerning();
98 0 : aFD.WordLineMode = rFont.IsWordLineMode();
99 0 : aFD.Type = 0; // ??? => Nur an Metric...
100 0 : return aFD;
101 : }
102 :
103 :
104 89 : vcl::Font ImplCreateFont( const ::com::sun::star::awt::FontDescriptor& rDescr )
105 : {
106 89 : vcl::Font aFont;
107 89 : aFont.SetName( rDescr.Name );
108 89 : aFont.SetStyleName( rDescr.StyleName );
109 89 : aFont.SetSize( ::Size( rDescr.Width, rDescr.Height ) );
110 89 : aFont.SetFamily( (FontFamily)rDescr.Family );
111 89 : aFont.SetCharSet( (rtl_TextEncoding)rDescr.CharSet );
112 89 : aFont.SetPitch( (FontPitch)rDescr.Pitch );
113 89 : aFont.SetWidthType( VCLUnoHelper::ConvertFontWidth( rDescr.CharacterWidth ) );
114 89 : aFont.SetWeight( VCLUnoHelper::ConvertFontWeight( rDescr.Weight ) );
115 89 : aFont.SetItalic( (FontItalic)rDescr.Slant );
116 89 : aFont.SetUnderline( (::FontUnderline)rDescr.Underline );
117 89 : aFont.SetStrikeout( (::FontStrikeout)rDescr.Strikeout );
118 89 : aFont.SetOrientation( (sal_Int16)rDescr.Orientation );
119 89 : aFont.SetKerning( rDescr.Kerning );
120 89 : aFont.SetWordLineMode( rDescr.WordLineMode );
121 89 : return aFont;
122 : }
123 :
124 22 : FmXModifyMultiplexer::FmXModifyMultiplexer( ::cppu::OWeakObject& rSource, ::osl::Mutex& _rMutex )
125 : :OWeakSubObject( rSource )
126 22 : ,OInterfaceContainerHelper( _rMutex )
127 : {
128 22 : }
129 :
130 :
131 0 : Any SAL_CALL FmXModifyMultiplexer::queryInterface(const Type& _rType) throw (RuntimeException, std::exception)
132 : {
133 0 : Any aReturn;
134 0 : aReturn = ::cppu::queryInterface(_rType,
135 : static_cast< ::com::sun::star::util::XModifyListener*>(this),
136 : static_cast< XEventListener*>(this)
137 0 : );
138 :
139 0 : if (!aReturn.hasValue())
140 0 : aReturn = OWeakSubObject::queryInterface( _rType );
141 :
142 0 : return aReturn;
143 : }
144 :
145 :
146 0 : void FmXModifyMultiplexer::disposing(const EventObject& ) throw( RuntimeException, std::exception )
147 : {
148 0 : }
149 :
150 :
151 0 : void FmXModifyMultiplexer::modified(const EventObject& e) throw( RuntimeException, std::exception )
152 : {
153 0 : EventObject aMulti( e);
154 0 : aMulti.Source = &m_rParent;
155 0 : notifyEach( &XModifyListener::modified, aMulti );
156 0 : }
157 :
158 22 : FmXUpdateMultiplexer::FmXUpdateMultiplexer( ::cppu::OWeakObject& rSource, ::osl::Mutex& _rMutex )
159 : :OWeakSubObject( rSource )
160 22 : ,OInterfaceContainerHelper( _rMutex )
161 : {
162 22 : }
163 :
164 :
165 0 : Any SAL_CALL FmXUpdateMultiplexer::queryInterface(const Type& _rType) throw (RuntimeException, std::exception)
166 : {
167 0 : Any aReturn;
168 0 : aReturn = ::cppu::queryInterface(_rType,
169 : static_cast< XUpdateListener*>(this),
170 : static_cast< XEventListener*>(this)
171 0 : );
172 :
173 0 : if (!aReturn.hasValue())
174 0 : aReturn = OWeakSubObject::queryInterface( _rType );
175 :
176 0 : return aReturn;
177 : }
178 :
179 :
180 0 : void FmXUpdateMultiplexer::disposing(const EventObject& ) throw( RuntimeException, std::exception )
181 : {
182 0 : }
183 :
184 :
185 0 : sal_Bool FmXUpdateMultiplexer::approveUpdate(const EventObject &e) throw( RuntimeException, std::exception )
186 : {
187 0 : EventObject aMulti( e );
188 0 : aMulti.Source = &m_rParent;
189 :
190 0 : bool bResult = true;
191 0 : if (getLength())
192 : {
193 0 : ::cppu::OInterfaceIteratorHelper aIter(*this);
194 0 : while ( bResult && aIter.hasMoreElements() )
195 0 : bResult = static_cast< XUpdateListener* >( aIter.next() )->approveUpdate( aMulti );
196 : }
197 :
198 0 : return bResult;
199 : }
200 :
201 :
202 0 : void FmXUpdateMultiplexer::updated(const EventObject &e) throw( RuntimeException, std::exception )
203 : {
204 0 : EventObject aMulti( e );
205 0 : aMulti.Source = &m_rParent;
206 0 : notifyEach( &XUpdateListener::updated, aMulti );
207 0 : }
208 :
209 22 : FmXSelectionMultiplexer::FmXSelectionMultiplexer( ::cppu::OWeakObject& rSource, ::osl::Mutex& _rMutex )
210 : :OWeakSubObject( rSource )
211 22 : ,OInterfaceContainerHelper( _rMutex )
212 : {
213 22 : }
214 :
215 :
216 0 : Any SAL_CALL FmXSelectionMultiplexer::queryInterface(const Type& _rType) throw (RuntimeException, std::exception)
217 : {
218 0 : Any aReturn;
219 0 : aReturn = ::cppu::queryInterface(_rType,
220 : static_cast< XSelectionChangeListener*>(this),
221 : static_cast< XEventListener*>(this)
222 0 : );
223 :
224 0 : if (!aReturn.hasValue())
225 0 : aReturn = OWeakSubObject::queryInterface( _rType );
226 :
227 0 : return aReturn;
228 : }
229 :
230 :
231 0 : void FmXSelectionMultiplexer::disposing(const EventObject& ) throw( RuntimeException, std::exception )
232 : {
233 0 : }
234 :
235 :
236 0 : void SAL_CALL FmXSelectionMultiplexer::selectionChanged( const EventObject& _rEvent ) throw (RuntimeException, std::exception)
237 : {
238 0 : EventObject aMulti(_rEvent);
239 0 : aMulti.Source = &m_rParent;
240 0 : notifyEach( &XSelectionChangeListener::selectionChanged, aMulti );
241 0 : }
242 :
243 22 : FmXContainerMultiplexer::FmXContainerMultiplexer( ::cppu::OWeakObject& rSource, ::osl::Mutex& _rMutex )
244 : :OWeakSubObject( rSource )
245 22 : ,OInterfaceContainerHelper( _rMutex )
246 : {
247 22 : }
248 :
249 :
250 0 : Any SAL_CALL FmXContainerMultiplexer::queryInterface(const Type& _rType) throw (RuntimeException, std::exception)
251 : {
252 0 : Any aReturn;
253 0 : aReturn = ::cppu::queryInterface(_rType,
254 : static_cast< XContainerListener*>(this),
255 : static_cast< XEventListener*>(this)
256 0 : );
257 :
258 0 : if (!aReturn.hasValue())
259 0 : aReturn = OWeakSubObject::queryInterface( _rType );
260 :
261 0 : return aReturn;
262 : }
263 :
264 :
265 0 : void FmXContainerMultiplexer::disposing(const EventObject& ) throw( RuntimeException, std::exception )
266 : {
267 0 : }
268 :
269 0 : void FmXContainerMultiplexer::elementInserted(const ContainerEvent& e) throw( RuntimeException, std::exception )
270 : {
271 0 : ContainerEvent aMulti( e );
272 0 : aMulti.Source = &m_rParent;
273 0 : notifyEach( &XContainerListener::elementInserted, aMulti );
274 0 : }
275 :
276 :
277 0 : void FmXContainerMultiplexer::elementRemoved(const ContainerEvent& e) throw( RuntimeException, std::exception )
278 : {
279 0 : ContainerEvent aMulti( e );
280 0 : aMulti.Source = &m_rParent;
281 0 : notifyEach( &XContainerListener::elementRemoved, aMulti );
282 0 : }
283 :
284 :
285 :
286 0 : void FmXContainerMultiplexer::elementReplaced(const ContainerEvent& e) throw( RuntimeException, std::exception )
287 : {
288 0 : ContainerEvent aMulti( e );
289 0 : aMulti.Source = &m_rParent;
290 0 : notifyEach( &XContainerListener::elementReplaced, aMulti );
291 0 : }
292 :
293 22 : FmXGridControlMultiplexer::FmXGridControlMultiplexer( ::cppu::OWeakObject& rSource, ::osl::Mutex& _rMutex )
294 : :OWeakSubObject( rSource )
295 22 : ,OInterfaceContainerHelper( _rMutex )
296 : {
297 22 : }
298 :
299 :
300 0 : Any SAL_CALL FmXGridControlMultiplexer::queryInterface(const Type& _rType) throw (RuntimeException, std::exception)
301 : {
302 0 : Any aReturn;
303 0 : aReturn = ::cppu::queryInterface( _rType,
304 : static_cast< XGridControlListener*>(this)
305 0 : );
306 :
307 0 : if (!aReturn.hasValue())
308 0 : aReturn = OWeakSubObject::queryInterface( _rType );
309 :
310 0 : return aReturn;
311 : }
312 :
313 :
314 0 : void FmXGridControlMultiplexer::disposing( const EventObject& ) throw( RuntimeException, std::exception )
315 : {
316 0 : }
317 :
318 :
319 0 : void SAL_CALL FmXGridControlMultiplexer::columnChanged( const EventObject& _event ) throw (RuntimeException, std::exception)
320 : {
321 0 : EventObject aForwardedEvent( _event );
322 0 : aForwardedEvent.Source = &m_rParent;
323 0 : notifyEach( &XGridControlListener::columnChanged, aForwardedEvent );
324 0 : }
325 :
326 :
327 : //= FmXGridControl
328 :
329 :
330 :
331 0 : Reference< XInterface > SAL_CALL FmXGridControl_NewInstance_Impl(const Reference< XMultiServiceFactory>& _rxFactory)
332 : throw (css::uno::Exception)
333 : {
334 0 : return *(new FmXGridControl( comphelper::getComponentContext(_rxFactory) ));
335 : }
336 :
337 22 : FmXGridControl::FmXGridControl(const Reference< XComponentContext >& _rxContext)
338 : :UnoControl()
339 22 : ,m_aModifyListeners(*this, GetMutex())
340 22 : ,m_aUpdateListeners(*this, GetMutex())
341 22 : ,m_aContainerListeners(*this, GetMutex())
342 22 : ,m_aSelectionListeners(*this, GetMutex())
343 22 : ,m_aGridControlListeners(*this, GetMutex())
344 : ,m_nPeerCreationLevel(0)
345 : ,m_bInDraw(false)
346 132 : ,m_xContext(_rxContext)
347 : {
348 22 : }
349 :
350 :
351 22 : FmXGridControl::~FmXGridControl()
352 : {
353 22 : }
354 :
355 :
356 814 : Any SAL_CALL FmXGridControl::queryAggregation(const Type& _rType) throw (RuntimeException, std::exception)
357 : {
358 814 : Any aReturn = FmXGridControl_BASE::queryInterface(_rType);
359 :
360 814 : if (!aReturn.hasValue())
361 717 : aReturn = UnoControl::queryAggregation( _rType );
362 814 : return aReturn;
363 : }
364 :
365 :
366 0 : Sequence< Type> SAL_CALL FmXGridControl::getTypes( ) throw(RuntimeException, std::exception)
367 : {
368 0 : return comphelper::concatSequences(UnoControl::getTypes(),FmXGridControl_BASE::getTypes());
369 : }
370 :
371 :
372 0 : Sequence<sal_Int8> SAL_CALL FmXGridControl::getImplementationId( ) throw(RuntimeException, std::exception)
373 : {
374 0 : return css::uno::Sequence<sal_Int8>();
375 : }
376 :
377 : // XServiceInfo
378 0 : sal_Bool SAL_CALL FmXGridControl::supportsService(const OUString& ServiceName) throw(std::exception)
379 : {
380 0 : return cppu::supportsService(this, ServiceName);
381 : }
382 :
383 0 : OUString SAL_CALL FmXGridControl::getImplementationName() throw(std::exception)
384 : {
385 0 : return OUString("com.sun.star.form.FmXGridControl");
386 : }
387 :
388 0 : ::comphelper::StringSequence SAL_CALL FmXGridControl::getSupportedServiceNames() throw(std::exception)
389 : {
390 0 : Sequence< OUString > aServiceNames(2);
391 0 : aServiceNames[0] = FM_SUN_CONTROL_GRIDCONTROL;
392 0 : aServiceNames[1] = "com.sun.star.awt.UnoControl";
393 0 : return aServiceNames;
394 : }
395 :
396 :
397 24 : void SAL_CALL FmXGridControl::dispose() throw( RuntimeException, std::exception )
398 : {
399 24 : SolarMutexGuard aGuard;
400 :
401 48 : EventObject aEvt;
402 24 : aEvt.Source = static_cast< ::cppu::OWeakObject* >(this);
403 24 : m_aModifyListeners.disposeAndClear(aEvt);
404 24 : m_aUpdateListeners.disposeAndClear(aEvt);
405 24 : m_aContainerListeners.disposeAndClear(aEvt);
406 :
407 48 : UnoControl::dispose();
408 24 : }
409 :
410 :
411 0 : OUString FmXGridControl::GetComponentServiceName()
412 : {
413 0 : OUString aName("DBGrid");
414 0 : return aName;
415 : }
416 :
417 :
418 46 : sal_Bool SAL_CALL FmXGridControl::setModel(const Reference< ::com::sun::star::awt::XControlModel >& rModel) throw( RuntimeException, std::exception )
419 : {
420 46 : SolarMutexGuard aGuard;
421 :
422 46 : if (!UnoControl::setModel(rModel))
423 24 : return sal_False;
424 :
425 44 : Reference< XGridPeer > xGridPeer(getPeer(), UNO_QUERY);
426 22 : if (xGridPeer.is())
427 : {
428 0 : Reference< XIndexContainer > xCols(mxModel, UNO_QUERY);
429 0 : xGridPeer->setColumns(xCols);
430 : }
431 68 : return sal_True;
432 : }
433 :
434 :
435 0 : FmXGridPeer* FmXGridControl::imp_CreatePeer(vcl::Window* pParent)
436 : {
437 0 : FmXGridPeer* pReturn = new FmXGridPeer(m_xContext);
438 :
439 : // translate properties into WinBits
440 0 : WinBits nStyle = WB_TABSTOP;
441 0 : Reference< XPropertySet > xModelSet(getModel(), UNO_QUERY);
442 0 : if (xModelSet.is())
443 : {
444 : try
445 : {
446 0 : if (::comphelper::getINT16(xModelSet->getPropertyValue(FM_PROP_BORDER)))
447 0 : nStyle |= WB_BORDER;
448 : }
449 0 : catch(const Exception&)
450 : {
451 : OSL_FAIL("Can not get style");
452 : }
453 : }
454 :
455 0 : pReturn->Create(pParent, nStyle);
456 0 : return pReturn;
457 : }
458 :
459 :
460 41 : 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 )
461 : {
462 41 : if ( !mxModel.is() )
463 0 : throw DisposedException( OUString(), *this );
464 :
465 : DBG_ASSERT(/*(0 == m_nPeerCreationLevel) && */!mbCreatingPeer, "FmXGridControl::createPeer : recursion!");
466 : // I think this should never assert, now that we're using the base class' mbCreatingPeer in addition to
467 : // our own m_nPeerCreationLevel
468 : // But I'm not sure as I don't _fully_ understand the underlying toolkit implementations ....
469 : // (if this asserts, we still need m_nPeerCreationLevel. If not, we could omit it ....)
470 : // 14.05.2001 - 86836 - frank.schoenheit@germany.sun.com
471 :
472 : // TODO: why the hell this whole class does not use any mutex?
473 :
474 41 : if (!getPeer().is())
475 : {
476 41 : mbCreatingPeer = true;
477 : // mbCreatingPeer is virtually the same as m_nPeerCreationLevel, but it's the base class' method
478 : // to prevent recursion.
479 :
480 41 : vcl::Window* pParentWin = NULL;
481 41 : if (rParentPeer.is())
482 : {
483 41 : VCLXWindow* pParent = VCLXWindow::GetImplementation(rParentPeer);
484 41 : if (pParent)
485 41 : pParentWin = pParent->GetWindow();
486 : }
487 :
488 41 : FmXGridPeer* pPeer = imp_CreatePeer(pParentWin);
489 : DBG_ASSERT(pPeer != NULL, "FmXGridControl::createPeer : imp_CreatePeer didn't return a peer !");
490 41 : setPeer( pPeer );
491 :
492 : // reading the properties from the model
493 : // ++m_nPeerCreationLevel;
494 41 : updateFromModel();
495 :
496 : // consider the following ugly scenario: updateFromModel leads to a propertiesChanges on the Control,
497 : // which determines, dat a "critical" property has changed (e.g. "Border") and therefore starts a new
498 : // Peer, which lands again here in createPeerm we also start a second FmXGridPeer and initialise it.
499 : // Then we exit from the first incarnation's updateFromModel and continue working with the pPeer,
500 : // that is in fact now already obsolete (as another peer is being started in the second incarnation).
501 : // Therefore the effort with the PeerCreationLevel, which ensures that we really use the Peer
502 : // created at the deepest level, but first initialise it in the top-level.
503 : // if (--m_nPeerCreationLevel == 0)
504 : {
505 : DBG_ASSERT(getPeer().is(), "FmXGridControl::createPeer : something went wrong ... no top level peer !");
506 41 : pPeer = FmXGridPeer::getImplementation(getPeer());
507 :
508 41 : setPosSize( maComponentInfos.nX, maComponentInfos.nY, maComponentInfos.nWidth, maComponentInfos.nHeight, ::com::sun::star::awt::PosSize::POSSIZE );
509 :
510 41 : Reference< XIndexContainer > xColumns(getModel(), UNO_QUERY);
511 41 : if (xColumns.is())
512 41 : pPeer->setColumns(xColumns);
513 :
514 41 : if (maComponentInfos.bVisible)
515 41 : pPeer->setVisible(sal_True);
516 :
517 41 : if (!maComponentInfos.bEnable)
518 0 : pPeer->setEnable(sal_False);
519 :
520 41 : if (maWindowListeners.getLength())
521 19 : pPeer->addWindowListener( &maWindowListeners );
522 :
523 41 : if (maFocusListeners.getLength())
524 0 : pPeer->addFocusListener( &maFocusListeners );
525 :
526 41 : if (maKeyListeners.getLength())
527 0 : pPeer->addKeyListener( &maKeyListeners );
528 :
529 41 : if (maMouseListeners.getLength())
530 0 : pPeer->addMouseListener( &maMouseListeners );
531 :
532 41 : if (maMouseMotionListeners.getLength())
533 0 : pPeer->addMouseMotionListener( &maMouseMotionListeners );
534 :
535 41 : if (maPaintListeners.getLength())
536 0 : pPeer->addPaintListener( &maPaintListeners );
537 :
538 41 : if (m_aModifyListeners.getLength())
539 0 : pPeer->addModifyListener( &m_aModifyListeners );
540 :
541 41 : if (m_aUpdateListeners.getLength())
542 0 : pPeer->addUpdateListener( &m_aUpdateListeners );
543 :
544 41 : if (m_aContainerListeners.getLength())
545 0 : pPeer->addContainerListener( &m_aContainerListeners );
546 :
547 : // forward the design mode
548 41 : bool bForceAlivePeer = m_bInDraw && !maComponentInfos.bVisible;
549 : // (we force an alive-mode peer if we're in "draw", cause in this case the peer will be used for drawing in
550 : // foreign devices. We ensure this with the visibility check as an living peer is assumed to be noncritical
551 : // only if invisible)
552 82 : Any aOldCursorBookmark;
553 41 : if (!mbDesignMode || bForceAlivePeer)
554 : {
555 0 : Reference< XFormComponent > xComp(getModel(), UNO_QUERY);
556 0 : if (xComp.is())
557 : {
558 0 : Reference< XRowSet > xForm(xComp->getParent(), UNO_QUERY);
559 : // is the form alive?
560 : // we can see that if the form contains columns
561 0 : Reference< ::com::sun::star::sdbcx::XColumnsSupplier > xColumnsSupplier(xForm, UNO_QUERY);
562 0 : if (xColumnsSupplier.is())
563 : {
564 0 : if (Reference< XIndexAccess > (xColumnsSupplier->getColumns(),UNO_QUERY)->getCount())
565 : {
566 : // we get only a new bookmark if the resultset is not forwardonly
567 0 : if (::comphelper::getINT32(Reference< XPropertySet > (xForm, UNO_QUERY)->getPropertyValue(FM_PROP_RESULTSET_TYPE)) != ResultSetType::FORWARD_ONLY)
568 : {
569 : // as the FmGridControl touches the data source it is connected to we have to remember the current
570 : // cursor position (and restore afterwards)
571 : // OJ: but only when we stand on a valid row
572 0 : Reference< XResultSet > xResultSet(xForm, UNO_QUERY);
573 0 : if ( !xResultSet->isBeforeFirst() && !xResultSet->isAfterLast() )
574 : {
575 : try
576 : {
577 0 : aOldCursorBookmark = Reference< ::com::sun::star::sdbcx::XRowLocate > (xForm, UNO_QUERY)->getBookmark();
578 : }
579 0 : catch( const Exception& e )
580 : {
581 : DBG_UNHANDLED_EXCEPTION();
582 : (void)e;
583 : }
584 0 : }
585 : }
586 : }
587 : }
588 0 : pPeer->setRowSet(xForm);
589 0 : }
590 : }
591 41 : pPeer->setDesignMode(mbDesignMode && !bForceAlivePeer);
592 :
593 : try
594 : {
595 41 : if (aOldCursorBookmark.hasValue())
596 : { // we have a valid bookmark, so we have to restore the cursor's position
597 0 : Reference< XFormComponent > xComp(getModel(), UNO_QUERY);
598 0 : Reference< ::com::sun::star::sdbcx::XRowLocate > xLocate(xComp->getParent(), UNO_QUERY);
599 0 : xLocate->moveToBookmark(aOldCursorBookmark);
600 : }
601 : }
602 0 : catch( const Exception& e )
603 : {
604 : DBG_UNHANDLED_EXCEPTION();
605 : (void)e;
606 : }
607 :
608 82 : Reference< ::com::sun::star::awt::XView > xPeerView(getPeer(), UNO_QUERY);
609 41 : xPeerView->setZoom( maComponentInfos.nZoomX, maComponentInfos.nZoomY );
610 82 : xPeerView->setGraphics( mxGraphics );
611 : }
612 41 : mbCreatingPeer = false;
613 : }
614 41 : }
615 :
616 :
617 2 : void FmXGridControl::addModifyListener(const Reference< ::com::sun::star::util::XModifyListener >& l) throw( RuntimeException, std::exception )
618 : {
619 2 : m_aModifyListeners.addInterface( l );
620 2 : if( getPeer().is() && m_aModifyListeners.getLength() == 1 )
621 : {
622 2 : Reference< ::com::sun::star::util::XModifyBroadcaster > xGrid(getPeer(), UNO_QUERY);
623 2 : xGrid->addModifyListener( &m_aModifyListeners);
624 : }
625 2 : }
626 :
627 :
628 0 : sal_Bool SAL_CALL FmXGridControl::select( const Any& _rSelection ) throw (IllegalArgumentException, RuntimeException, std::exception)
629 : {
630 0 : SolarMutexGuard aGuard;
631 0 : Reference< XSelectionSupplier > xPeer(getPeer(), UNO_QUERY);
632 0 : return xPeer->select(_rSelection);
633 : }
634 :
635 :
636 0 : Any SAL_CALL FmXGridControl::getSelection( ) throw (RuntimeException, std::exception)
637 : {
638 0 : SolarMutexGuard aGuard;
639 0 : Reference< XSelectionSupplier > xPeer(getPeer(), UNO_QUERY);
640 0 : return xPeer->getSelection();
641 : }
642 :
643 :
644 0 : void SAL_CALL FmXGridControl::addSelectionChangeListener( const Reference< XSelectionChangeListener >& _rxListener ) throw (RuntimeException, std::exception)
645 : {
646 0 : m_aSelectionListeners.addInterface( _rxListener );
647 0 : if( getPeer().is() && 1 == m_aSelectionListeners.getLength() )
648 : {
649 0 : Reference< XSelectionSupplier > xGrid(getPeer(), UNO_QUERY);
650 0 : xGrid->addSelectionChangeListener( &m_aSelectionListeners);
651 : }
652 0 : }
653 :
654 :
655 0 : void SAL_CALL FmXGridControl::removeSelectionChangeListener( const Reference< XSelectionChangeListener >& _rxListener ) throw (RuntimeException, std::exception)
656 : {
657 0 : if( getPeer().is() && 1 == m_aSelectionListeners.getLength() )
658 : {
659 0 : Reference< XSelectionSupplier > xGrid(getPeer(), UNO_QUERY);
660 0 : xGrid->removeSelectionChangeListener( &m_aSelectionListeners);
661 : }
662 0 : m_aSelectionListeners.removeInterface( _rxListener );
663 0 : }
664 :
665 :
666 0 : Sequence< sal_Bool > SAL_CALL FmXGridControl::queryFieldDataType( const Type& xType ) throw(RuntimeException, std::exception)
667 : {
668 0 : if (getPeer().is())
669 : {
670 0 : Reference< XGridFieldDataSupplier > xPeerSupplier(getPeer(), UNO_QUERY);
671 0 : if (xPeerSupplier.is())
672 0 : return xPeerSupplier->queryFieldDataType(xType);
673 : }
674 :
675 0 : return Sequence<sal_Bool>();
676 : }
677 :
678 :
679 0 : Sequence< Any > SAL_CALL FmXGridControl::queryFieldData( sal_Int32 nRow, const Type& xType ) throw(RuntimeException, std::exception)
680 : {
681 0 : if (getPeer().is())
682 : {
683 0 : Reference< XGridFieldDataSupplier > xPeerSupplier(getPeer(), UNO_QUERY);
684 0 : if (xPeerSupplier.is())
685 0 : return xPeerSupplier->queryFieldData(nRow, xType);
686 : }
687 :
688 0 : return Sequence< Any>();
689 : }
690 :
691 :
692 2 : void SAL_CALL FmXGridControl::removeModifyListener(const Reference< ::com::sun::star::util::XModifyListener >& l) throw( RuntimeException, std::exception )
693 : {
694 2 : if( getPeer().is() && m_aModifyListeners.getLength() == 1 )
695 : {
696 2 : Reference< ::com::sun::star::util::XModifyBroadcaster > xGrid(getPeer(), UNO_QUERY);
697 2 : xGrid->removeModifyListener( &m_aModifyListeners);
698 : }
699 2 : m_aModifyListeners.removeInterface( l );
700 2 : }
701 :
702 :
703 21 : void SAL_CALL FmXGridControl::draw( sal_Int32 x, sal_Int32 y ) throw( RuntimeException, std::exception )
704 : {
705 21 : SolarMutexGuard aGuard;
706 21 : m_bInDraw = true;
707 21 : UnoControl::draw(x, y);
708 21 : m_bInDraw = false;
709 21 : }
710 :
711 :
712 26 : void SAL_CALL FmXGridControl::setDesignMode(sal_Bool bOn) throw( RuntimeException, std::exception )
713 : {
714 26 : ::com::sun::star::util::ModeChangeEvent aModeChangeEvent;
715 :
716 : // --- <mutex_lock> ---
717 : {
718 26 : SolarMutexGuard aGuard;
719 :
720 52 : Reference< XRowSetSupplier > xGrid(getPeer(), UNO_QUERY);
721 :
722 26 : if (xGrid.is() && (bool(bOn) != mbDesignMode || (!bOn && !xGrid->getRowSet().is())))
723 : {
724 2 : if (bOn)
725 : {
726 0 : xGrid->setRowSet(Reference< XRowSet > ());
727 : }
728 : else
729 : {
730 2 : Reference< XFormComponent > xComp(getModel(), UNO_QUERY);
731 2 : if (xComp.is())
732 : {
733 2 : Reference< XRowSet > xForm(xComp->getParent(), UNO_QUERY);
734 2 : xGrid->setRowSet(xForm);
735 2 : }
736 : }
737 :
738 2 : mbDesignMode = bOn;
739 :
740 2 : Reference< XVclWindowPeer > xVclWindowPeer( getPeer(), UNO_QUERY );
741 2 : if (xVclWindowPeer.is())
742 2 : xVclWindowPeer->setDesignMode(bOn);
743 : }
744 26 : mbDesignMode = bOn;
745 :
746 : // dispose our current AccessibleContext, if we have one
747 : // (changing the design mode implies having a new implementation for this context,
748 : // so the old one must be declared DEFUNC)
749 : DisposeAccessibleContext(
750 26 : Reference<XComponent>(maAccessibleContext, UNO_QUERY));
751 26 : maAccessibleContext.clear();
752 :
753 : // prepare firing an event
754 26 : aModeChangeEvent.Source = *this;
755 52 : aModeChangeEvent.NewMode = mbDesignMode ? OUString( "design" ) : OUString( "alive" );
756 : }
757 :
758 : // --- </mutex_lock> ---
759 26 : maModeChangeListeners.notifyEach( &XModeChangeListener::modeChanged, aModeChangeEvent );
760 26 : }
761 :
762 : // XBoundComponent
763 :
764 0 : void SAL_CALL FmXGridControl::addUpdateListener(const Reference< XUpdateListener >& l) throw( RuntimeException, std::exception )
765 : {
766 0 : m_aUpdateListeners.addInterface( l );
767 0 : if( getPeer().is() && m_aUpdateListeners.getLength() == 1 )
768 : {
769 0 : Reference< XBoundComponent > xBound(getPeer(), UNO_QUERY);
770 0 : xBound->addUpdateListener( &m_aUpdateListeners);
771 : }
772 0 : }
773 :
774 :
775 0 : void SAL_CALL FmXGridControl::removeUpdateListener(const Reference< XUpdateListener >& l) throw( RuntimeException, std::exception )
776 : {
777 0 : if( getPeer().is() && m_aUpdateListeners.getLength() == 1 )
778 : {
779 0 : Reference< XBoundComponent > xBound(getPeer(), UNO_QUERY);
780 0 : xBound->removeUpdateListener( &m_aUpdateListeners);
781 : }
782 0 : m_aUpdateListeners.removeInterface( l );
783 0 : }
784 :
785 :
786 0 : sal_Bool SAL_CALL FmXGridControl::commit() throw( RuntimeException, std::exception )
787 : {
788 0 : Reference< XBoundComponent > xBound(getPeer(), UNO_QUERY);
789 0 : if (xBound.is())
790 0 : return xBound->commit();
791 : else
792 0 : return sal_True;
793 : }
794 :
795 : // XContainer
796 :
797 0 : void SAL_CALL FmXGridControl::addContainerListener(const Reference< XContainerListener >& l) throw( RuntimeException, std::exception )
798 : {
799 0 : m_aContainerListeners.addInterface( l );
800 0 : if( getPeer().is() && m_aContainerListeners.getLength() == 1 )
801 : {
802 0 : Reference< XContainer > xContainer(getPeer(), UNO_QUERY);
803 0 : xContainer->addContainerListener( &m_aContainerListeners);
804 : }
805 0 : }
806 :
807 :
808 0 : void SAL_CALL FmXGridControl::removeContainerListener(const Reference< XContainerListener >& l) throw( RuntimeException, std::exception )
809 : {
810 0 : if( getPeer().is() && m_aContainerListeners.getLength() == 1 )
811 : {
812 0 : Reference< XContainer > xContainer(getPeer(), UNO_QUERY);
813 0 : xContainer->removeContainerListener( &m_aContainerListeners);
814 : }
815 0 : m_aContainerListeners.removeInterface( l );
816 0 : }
817 :
818 :
819 0 : 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 )
820 : {
821 0 : Reference< ::com::sun::star::frame::XDispatchProvider > xPeerProvider(getPeer(), UNO_QUERY);
822 0 : if (xPeerProvider.is())
823 0 : return xPeerProvider->queryDispatch(aURL, aTargetFrameName, nSearchFlags);
824 : else
825 0 : return Reference< ::com::sun::star::frame::XDispatch > ();
826 : }
827 :
828 :
829 0 : Sequence< Reference< ::com::sun::star::frame::XDispatch > > SAL_CALL FmXGridControl::queryDispatches(const Sequence< ::com::sun::star::frame::DispatchDescriptor>& aDescripts) throw( RuntimeException, std::exception )
830 : {
831 0 : Reference< ::com::sun::star::frame::XDispatchProvider > xPeerProvider(getPeer(), UNO_QUERY);
832 0 : if (xPeerProvider.is())
833 0 : return xPeerProvider->queryDispatches(aDescripts);
834 : else
835 0 : return Sequence< Reference< ::com::sun::star::frame::XDispatch > >();
836 : }
837 :
838 :
839 2 : void SAL_CALL FmXGridControl::registerDispatchProviderInterceptor(const Reference< ::com::sun::star::frame::XDispatchProviderInterceptor >& _xInterceptor) throw( RuntimeException, std::exception )
840 : {
841 2 : Reference< ::com::sun::star::frame::XDispatchProviderInterception > xPeerInterception(getPeer(), UNO_QUERY);
842 2 : if (xPeerInterception.is())
843 2 : xPeerInterception->registerDispatchProviderInterceptor(_xInterceptor);
844 2 : }
845 :
846 :
847 2 : void SAL_CALL FmXGridControl::releaseDispatchProviderInterceptor(const Reference< ::com::sun::star::frame::XDispatchProviderInterceptor >& _xInterceptor) throw( RuntimeException, std::exception )
848 : {
849 2 : Reference< ::com::sun::star::frame::XDispatchProviderInterception > xPeerInterception(getPeer(), UNO_QUERY);
850 2 : if (xPeerInterception.is())
851 2 : xPeerInterception->releaseDispatchProviderInterceptor(_xInterceptor);
852 2 : }
853 :
854 :
855 0 : void SAL_CALL FmXGridControl::addGridControlListener( const Reference< XGridControlListener >& _listener ) throw( RuntimeException, std::exception )
856 : {
857 0 : ::osl::MutexGuard aGuard( GetMutex() );
858 :
859 0 : m_aGridControlListeners.addInterface( _listener );
860 0 : if ( getPeer().is() && 1 == m_aGridControlListeners.getLength() )
861 : {
862 0 : Reference< XGridControl > xPeerGrid( getPeer(), UNO_QUERY );
863 0 : if ( xPeerGrid.is() )
864 0 : xPeerGrid->addGridControlListener( &m_aGridControlListeners );
865 0 : }
866 0 : }
867 :
868 :
869 0 : void SAL_CALL FmXGridControl::removeGridControlListener( const Reference< XGridControlListener >& _listener ) throw( RuntimeException, std::exception )
870 : {
871 0 : ::osl::MutexGuard aGuard( GetMutex() );
872 :
873 0 : if( getPeer().is() && 1 == m_aGridControlListeners.getLength() )
874 : {
875 0 : Reference< XGridControl > xPeerGrid( getPeer(), UNO_QUERY );
876 0 : if ( xPeerGrid.is() )
877 0 : xPeerGrid->removeGridControlListener( &m_aGridControlListeners );
878 : }
879 :
880 0 : m_aGridControlListeners.removeInterface( _listener );
881 0 : }
882 :
883 :
884 33 : sal_Int16 SAL_CALL FmXGridControl::getCurrentColumnPosition() throw( RuntimeException, std::exception )
885 : {
886 33 : Reference< XGridControl > xGrid( getPeer(), UNO_QUERY );
887 33 : return xGrid.is() ? xGrid->getCurrentColumnPosition() : -1;
888 : }
889 :
890 :
891 0 : void SAL_CALL FmXGridControl::setCurrentColumnPosition(sal_Int16 nPos) throw( RuntimeException, std::exception )
892 : {
893 0 : Reference< XGridControl > xGrid( getPeer(), UNO_QUERY );
894 0 : if ( xGrid.is() )
895 : {
896 0 : SolarMutexGuard aGuard;
897 0 : xGrid->setCurrentColumnPosition( nPos );
898 0 : }
899 0 : }
900 :
901 : // XElementAccess
902 :
903 0 : sal_Bool SAL_CALL FmXGridControl::hasElements() throw( RuntimeException, std::exception )
904 : {
905 0 : Reference< XElementAccess > xPeer(getPeer(), UNO_QUERY);
906 0 : return xPeer.is() ? xPeer->hasElements() : 0;
907 : }
908 :
909 :
910 0 : Type SAL_CALL FmXGridControl::getElementType( ) throw(RuntimeException, std::exception)
911 : {
912 0 : return cppu::UnoType<com::sun::star::awt::XTextComponent>::get();
913 : }
914 :
915 : // XEnumerationAccess
916 :
917 0 : Reference< XEnumeration > SAL_CALL FmXGridControl::createEnumeration() throw( RuntimeException, std::exception )
918 : {
919 0 : Reference< XEnumerationAccess > xPeer(getPeer(), UNO_QUERY);
920 0 : if (xPeer.is())
921 0 : return xPeer->createEnumeration();
922 : else
923 0 : return new ::comphelper::OEnumerationByIndex(this);
924 : }
925 :
926 : // XIndexAccess
927 :
928 0 : sal_Int32 SAL_CALL FmXGridControl::getCount() throw( RuntimeException, std::exception )
929 : {
930 0 : Reference< XIndexAccess > xPeer(getPeer(), UNO_QUERY);
931 0 : return xPeer.is() ? xPeer->getCount() : 0;
932 : }
933 :
934 :
935 0 : Any SAL_CALL FmXGridControl::getByIndex(sal_Int32 _nIndex) throw( IndexOutOfBoundsException, WrappedTargetException, RuntimeException, std::exception )
936 : {
937 0 : Reference< XIndexAccess > xPeer(getPeer(), UNO_QUERY);
938 0 : if (!xPeer.is())
939 0 : throw IndexOutOfBoundsException();
940 :
941 0 : return xPeer->getByIndex(_nIndex);
942 : }
943 :
944 : // ::com::sun::star::util::XModeSelector
945 :
946 0 : void SAL_CALL FmXGridControl::setMode(const OUString& Mode) throw( NoSupportException, RuntimeException, std::exception )
947 : {
948 0 : Reference< ::com::sun::star::util::XModeSelector > xPeer(getPeer(), UNO_QUERY);
949 0 : if (!xPeer.is())
950 0 : throw NoSupportException();
951 :
952 0 : xPeer->setMode(Mode);
953 0 : }
954 :
955 :
956 0 : OUString SAL_CALL FmXGridControl::getMode() throw( RuntimeException, std::exception )
957 : {
958 0 : Reference< ::com::sun::star::util::XModeSelector > xPeer(getPeer(), UNO_QUERY);
959 0 : return xPeer.is() ? xPeer->getMode() : OUString();
960 : }
961 :
962 :
963 0 : ::comphelper::StringSequence SAL_CALL FmXGridControl::getSupportedModes() throw( RuntimeException, std::exception )
964 : {
965 0 : Reference< ::com::sun::star::util::XModeSelector > xPeer(getPeer(), UNO_QUERY);
966 0 : return xPeer.is() ? xPeer->getSupportedModes() : ::comphelper::StringSequence();
967 : }
968 :
969 :
970 0 : sal_Bool SAL_CALL FmXGridControl::supportsMode(const OUString& Mode) throw( RuntimeException, std::exception )
971 : {
972 0 : Reference< ::com::sun::star::util::XModeSelector > xPeer(getPeer(), UNO_QUERY);
973 0 : return xPeer.is() ? xPeer->supportsMode(Mode) : sal_False;
974 : }
975 :
976 : // helper class which prevents that in the peer's header the FmGridListener must be known
977 : class FmXGridPeer::GridListenerDelegator : public FmGridListener
978 : {
979 : protected:
980 : FmXGridPeer* m_pPeer;
981 :
982 : public:
983 : GridListenerDelegator( FmXGridPeer* _pPeer );
984 : virtual ~GridListenerDelegator();
985 :
986 : protected:
987 : virtual void selectionChanged() SAL_OVERRIDE;
988 : virtual void columnChanged() SAL_OVERRIDE;
989 : };
990 :
991 :
992 41 : FmXGridPeer::GridListenerDelegator::GridListenerDelegator(FmXGridPeer* _pPeer)
993 41 : :m_pPeer(_pPeer)
994 : {
995 : DBG_ASSERT(m_pPeer, "GridListenerDelegator::GridListenerDelegator");
996 41 : }
997 :
998 82 : FmXGridPeer::GridListenerDelegator::~GridListenerDelegator()
999 : {
1000 82 : }
1001 :
1002 :
1003 0 : void FmXGridPeer::GridListenerDelegator::selectionChanged()
1004 : {
1005 0 : m_pPeer->selectionChanged();
1006 0 : }
1007 :
1008 :
1009 0 : void FmXGridPeer::GridListenerDelegator::columnChanged()
1010 : {
1011 0 : m_pPeer->columnChanged();
1012 0 : }
1013 :
1014 0 : Sequence< Type> SAL_CALL FmXGridPeer::getTypes( ) throw(RuntimeException, std::exception)
1015 : {
1016 0 : return comphelper::concatSequences( VCLXWindow::getTypes(), FmXGridPeer_BASE::getTypes() );
1017 : }
1018 :
1019 :
1020 0 : Sequence<sal_Int8> SAL_CALL FmXGridPeer::getImplementationId( ) throw(RuntimeException, std::exception)
1021 : {
1022 0 : return css::uno::Sequence<sal_Int8>();
1023 : }
1024 :
1025 :
1026 2063 : Any SAL_CALL FmXGridPeer::queryInterface(const Type& _rType) throw (RuntimeException, std::exception)
1027 : {
1028 2063 : Any aReturn = FmXGridPeer_BASE::queryInterface(_rType);
1029 :
1030 2063 : if (!aReturn.hasValue())
1031 1561 : aReturn = VCLXWindow::queryInterface( _rType );
1032 :
1033 2063 : return aReturn;
1034 : }
1035 :
1036 :
1037 0 : void FmXGridPeer::selectionChanged()
1038 : {
1039 0 : EventObject aSource;
1040 0 : aSource.Source = static_cast< ::cppu::OWeakObject* >(this);
1041 0 : m_aSelectionListeners.notifyEach( &XSelectionChangeListener::selectionChanged, aSource);
1042 0 : }
1043 :
1044 :
1045 0 : void FmXGridPeer::columnChanged()
1046 : {
1047 0 : EventObject aEvent( *this );
1048 0 : m_aGridControlListeners.notifyEach( &XGridControlListener::columnChanged, aEvent );
1049 0 : }
1050 :
1051 :
1052 : namespace fmgridif
1053 : {
1054 41 : const OUString getDataModeIdentifier()
1055 : {
1056 41 : return OUString("DataMode");
1057 : }
1058 : }
1059 : using namespace fmgridif;
1060 :
1061 :
1062 41 : FmXGridPeer::FmXGridPeer(const Reference< XComponentContext >& _rxContext)
1063 : :m_aModifyListeners(m_aMutex)
1064 : ,m_aUpdateListeners(m_aMutex)
1065 : ,m_aContainerListeners(m_aMutex)
1066 : ,m_aSelectionListeners(m_aMutex)
1067 : ,m_aGridControlListeners(m_aMutex)
1068 : ,m_aMode( getDataModeIdentifier() )
1069 : ,m_nCursorListening(0)
1070 : ,m_bInterceptingDispatch(false)
1071 : ,m_pStateCache(NULL)
1072 : ,m_pDispatchers(NULL)
1073 : ,m_pGridListener(NULL)
1074 41 : ,m_xContext(_rxContext)
1075 : {
1076 : // Create must be called after this constructure
1077 41 : m_pGridListener = new GridListenerDelegator( this );
1078 41 : }
1079 :
1080 :
1081 0 : FmGridControl* FmXGridPeer::imp_CreateControl(vcl::Window* pParent, WinBits nStyle)
1082 : {
1083 0 : return new FmGridControl(m_xContext, pParent, this, nStyle);
1084 : }
1085 :
1086 :
1087 41 : void FmXGridPeer::Create(vcl::Window* pParent, WinBits nStyle)
1088 : {
1089 41 : FmGridControl* pWin = imp_CreateControl(pParent, nStyle);
1090 : DBG_ASSERT(pWin != NULL, "FmXGridPeer::Create : imp_CreateControl didn't return a control !");
1091 :
1092 41 : pWin->SetStateProvider(LINK(this, FmXGridPeer, OnQueryGridSlotState));
1093 41 : pWin->SetSlotExecutor(LINK(this, FmXGridPeer, OnExecuteGridSlot));
1094 :
1095 : // want to hear about row selections
1096 41 : pWin->setGridListener( m_pGridListener );
1097 :
1098 : // Init must always be called
1099 41 : pWin->Init();
1100 41 : pWin->SetComponentInterface(this);
1101 :
1102 41 : getSupportedURLs();
1103 41 : }
1104 :
1105 :
1106 82 : FmXGridPeer::~FmXGridPeer()
1107 : {
1108 41 : setRowSet(Reference< XRowSet > ());
1109 41 : setColumns(Reference< XIndexContainer > ());
1110 :
1111 41 : delete m_pGridListener;
1112 41 : }
1113 :
1114 : namespace
1115 : {
1116 : class theFmXGridPeerImplementationId : public rtl::Static< UnoTunnelIdInit, theFmXGridPeerImplementationId > {};
1117 : }
1118 :
1119 510 : const Sequence< sal_Int8 >& FmXGridPeer::getUnoTunnelImplementationId() throw()
1120 : {
1121 510 : return theFmXGridPeerImplementationId::get().getSeq();
1122 : }
1123 :
1124 :
1125 41 : FmXGridPeer* FmXGridPeer::getImplementation( const Reference< XInterface >& _rxIFace ) throw()
1126 : {
1127 41 : FmXGridPeer* pReturn = NULL;
1128 41 : Reference< XUnoTunnel > xTunnel(_rxIFace, UNO_QUERY);
1129 41 : if (xTunnel.is())
1130 41 : pReturn = reinterpret_cast<FmXGridPeer*>(xTunnel->getSomething(getUnoTunnelImplementationId()));
1131 :
1132 41 : return pReturn;
1133 : }
1134 :
1135 :
1136 469 : sal_Int64 SAL_CALL FmXGridPeer::getSomething( const Sequence< sal_Int8 >& _rIdentifier ) throw(RuntimeException, std::exception)
1137 : {
1138 469 : sal_Int64 nReturn(0);
1139 :
1140 938 : if ( (_rIdentifier.getLength() == 16)
1141 469 : && (0 == memcmp( getUnoTunnelImplementationId().getConstArray(), _rIdentifier.getConstArray(), 16 ))
1142 : )
1143 : {
1144 41 : nReturn = reinterpret_cast<sal_Int64>(this);
1145 : }
1146 : else
1147 428 : nReturn = VCLXWindow::getSomething(_rIdentifier);
1148 :
1149 469 : return nReturn;
1150 : }
1151 :
1152 : // XEventListener
1153 :
1154 283 : void FmXGridPeer::disposing(const EventObject& e) throw( RuntimeException, std::exception )
1155 : {
1156 : using namespace ::com::sun::star::util;
1157 283 : bool bKnownSender = false;
1158 :
1159 283 : Reference< XIndexContainer > xCols( e.Source, UNO_QUERY );
1160 283 : if ( xCols.is() )
1161 : {
1162 49 : setColumns(Reference< XIndexContainer > ());
1163 49 : bKnownSender = true;
1164 : }
1165 :
1166 566 : Reference< XRowSet > xCursor(e.Source, UNO_QUERY);
1167 283 : if (xCursor.is())
1168 : {
1169 10 : setRowSet( m_xCursor );
1170 10 : m_xCursor = NULL;
1171 10 : bKnownSender = true;
1172 : }
1173 :
1174 :
1175 283 : if ( !bKnownSender && m_pDispatchers )
1176 : {
1177 2 : const Sequence< URL>& aSupportedURLs = getSupportedURLs();
1178 2 : const URL* pSupportedURLs = aSupportedURLs.getConstArray();
1179 14 : for ( sal_uInt16 i=0; i < ( aSupportedURLs.getLength() ) && !bKnownSender; ++i, ++pSupportedURLs )
1180 : {
1181 12 : if ( m_pDispatchers[i] == e.Source )
1182 : {
1183 2 : m_pDispatchers[i]->removeStatusListener( static_cast< ::com::sun::star::frame::XStatusListener* >( this ), *pSupportedURLs );
1184 2 : m_pDispatchers[i] = NULL;
1185 2 : m_pStateCache[i] = false;
1186 2 : bKnownSender = true;
1187 : }
1188 : }
1189 : }
1190 :
1191 283 : if ( !bKnownSender )
1192 515 : VCLXWindow::disposing(e);
1193 283 : }
1194 :
1195 :
1196 2 : void FmXGridPeer::addModifyListener(const Reference< ::com::sun::star::util::XModifyListener >& l) throw( RuntimeException, std::exception )
1197 : {
1198 2 : m_aModifyListeners.addInterface( l );
1199 2 : }
1200 :
1201 :
1202 2 : void FmXGridPeer::removeModifyListener(const Reference< ::com::sun::star::util::XModifyListener >& l) throw( RuntimeException, std::exception )
1203 : {
1204 2 : m_aModifyListeners.removeInterface( l );
1205 2 : }
1206 :
1207 :
1208 : #define LAST_KNOWN_TYPE FormComponentType::PATTERNFIELD
1209 0 : Sequence< sal_Bool > SAL_CALL FmXGridPeer::queryFieldDataType( const Type& xType ) throw(RuntimeException, std::exception)
1210 : {
1211 : // eine 'Konvertierungstabelle'
1212 : static const sal_Bool bCanConvert[LAST_KNOWN_TYPE][4] =
1213 : {
1214 : { sal_False, sal_False, sal_False, sal_False }, // FormComponentType::CONTROL
1215 : { sal_False, sal_False, sal_False, sal_False }, // FormComponentType::COMMANDBUTTON
1216 : { sal_False, sal_False, sal_False, sal_False }, // FormComponentType::RADIOBUTTON
1217 : { sal_False, sal_False, sal_False, sal_False }, // FormComponentType::IMAGEBUTTON
1218 : { sal_False, sal_False, sal_False, sal_True }, // FormComponentType::CHECKBOX
1219 : { sal_False, sal_False, sal_False, sal_False }, // FormComponentType::LISTBOX
1220 : { sal_False, sal_False, sal_False, sal_False }, // FormComponentType::COMBOBOX
1221 : { sal_False, sal_False, sal_False, sal_False }, // FormComponentType::GROUPBOX
1222 : { sal_True , sal_False, sal_False, sal_False }, // FormComponentType::TEXTFIELD
1223 : { sal_False, sal_False, sal_False, sal_False }, // FormComponentType::FIXEDTEXT
1224 : { sal_False, sal_False, sal_False, sal_False }, // FormComponentType::GRIDCONTROL
1225 : { sal_False, sal_False, sal_False, sal_False }, // FormComponentType::FILECONTROL
1226 : { sal_False, sal_False, sal_False, sal_False }, // FormComponentType::HIDDENCONTROL
1227 : { sal_False, sal_False, sal_False, sal_False }, // FormComponentType::IMAGECONTROL
1228 : { sal_True , sal_True , sal_True , sal_False }, // FormComponentType::DATEFIELD
1229 : { sal_True , sal_True , sal_False, sal_False }, // FormComponentType::TIMEFIELD
1230 : { sal_True , sal_True , sal_False, sal_False }, // FormComponentType::NUMERICFIELD
1231 : { sal_True , sal_True , sal_False, sal_False }, // FormComponentType::CURRENCYFIELD
1232 : { sal_True , sal_False, sal_False, sal_False } // FormComponentType::PATTERNFIELD
1233 : };
1234 :
1235 :
1236 0 : sal_Int16 nMapColumn = -1;
1237 0 : switch (xType.getTypeClass())
1238 : {
1239 0 : case TypeClass_STRING : nMapColumn = 0; break;
1240 : case TypeClass_FLOAT:
1241 0 : case TypeClass_DOUBLE : nMapColumn = 1; break;
1242 : case TypeClass_SHORT:
1243 : case TypeClass_LONG:
1244 : case TypeClass_UNSIGNED_LONG:
1245 0 : case TypeClass_UNSIGNED_SHORT : nMapColumn = 2; break;
1246 0 : case TypeClass_BOOLEAN : nMapColumn = 3; break;
1247 : default:
1248 0 : break;
1249 : }
1250 :
1251 0 : Reference< XIndexContainer > xColumns = getColumns();
1252 :
1253 0 : FmGridControl* pGrid = static_cast<FmGridControl*>(GetWindow());
1254 0 : sal_Int32 nColumns = pGrid->GetViewColCount();
1255 :
1256 0 : DbGridColumns aColumns = pGrid->GetColumns();
1257 :
1258 0 : Sequence<sal_Bool> aReturnSequence(nColumns);
1259 0 : sal_Bool* pReturnArray = aReturnSequence.getArray();
1260 :
1261 0 : bool bRequestedAsAny = (xType.getTypeClass() == TypeClass_ANY);
1262 :
1263 : DbGridColumn* pCol;
1264 0 : Reference< ::com::sun::star::sdb::XColumn > xFieldContent;
1265 0 : Reference< XPropertySet > xCurrentColumn;
1266 0 : for (sal_Int32 i=0; i<nColumns; ++i)
1267 : {
1268 0 : if (bRequestedAsAny)
1269 : {
1270 0 : pReturnArray[i] = sal_True;
1271 0 : continue;
1272 : }
1273 :
1274 0 : pReturnArray[i] = sal_False;
1275 :
1276 0 : sal_uInt16 nModelPos = pGrid->GetModelColumnPos(pGrid->GetColumnIdFromViewPos((sal_uInt16)i));
1277 : DBG_ASSERT(nModelPos != (sal_uInt16)-1, "FmXGridPeer::queryFieldDataType : no model pos !");
1278 :
1279 0 : pCol = aColumns[ nModelPos ];
1280 0 : const DbGridRowRef xRow = pGrid->GetSeekRow();
1281 0 : xFieldContent = (xRow.Is() && xRow->HasField(pCol->GetFieldPos())) ? xRow->GetField(pCol->GetFieldPos()).getColumn() : Reference< ::com::sun::star::sdb::XColumn > ();
1282 0 : if (!xFieldContent.is())
1283 : // can't supply anything without a field content
1284 : // FS - 07.12.99 - 54391
1285 0 : continue;
1286 :
1287 0 : xColumns->getByIndex(nModelPos) >>= xCurrentColumn;
1288 0 : if (!::comphelper::hasProperty(FM_PROP_CLASSID, xCurrentColumn))
1289 0 : continue;
1290 :
1291 0 : sal_Int16 nClassId = sal_Int16();
1292 0 : xCurrentColumn->getPropertyValue(FM_PROP_CLASSID) >>= nClassId;
1293 0 : if (nClassId>LAST_KNOWN_TYPE)
1294 0 : continue;
1295 : DBG_ASSERT(nClassId>0, "FmXGridPeer::queryFieldDataType : somebody changed the definition of the FormComponentType enum !");
1296 :
1297 0 : if (nMapColumn != -1)
1298 0 : pReturnArray[i] = bCanConvert[nClassId-1][nMapColumn];
1299 0 : }
1300 :
1301 0 : return aReturnSequence;
1302 : }
1303 :
1304 :
1305 0 : Sequence< Any > SAL_CALL FmXGridPeer::queryFieldData( sal_Int32 nRow, const Type& xType ) throw(RuntimeException, std::exception)
1306 : {
1307 0 : FmGridControl* pGrid = static_cast<FmGridControl*>(GetWindow());
1308 : DBG_ASSERT(pGrid && pGrid->IsOpen(), "FmXGridPeer::queryFieldData : have no valid grid window !");
1309 0 : if (!pGrid || !pGrid->IsOpen())
1310 0 : return Sequence< Any>();
1311 :
1312 : // das Control zur angegebenen Row fahren
1313 0 : if (!pGrid->SeekRow(nRow))
1314 : {
1315 0 : throw IllegalArgumentException();
1316 : }
1317 :
1318 : // don't use GetCurrentRow as this isn't affected by the above SeekRow
1319 : // FS - 30.09.99 - 68644
1320 0 : DbGridRowRef xPaintRow = pGrid->GetPaintRow();
1321 0 : ENSURE_OR_THROW( xPaintRow.Is(), "invalid paint row" );
1322 :
1323 : // I need the columns of the control for GetFieldText
1324 0 : DbGridColumns aColumns = pGrid->GetColumns();
1325 :
1326 : // und durch alle Spalten durch
1327 0 : sal_Int32 nColumnCount = pGrid->GetViewColCount();
1328 :
1329 0 : Sequence< Any> aReturnSequence(nColumnCount);
1330 0 : Any* pReturnArray = aReturnSequence.getArray();
1331 :
1332 0 : bool bRequestedAsAny = (xType.getTypeClass() == TypeClass_ANY);
1333 0 : Reference< ::com::sun::star::sdb::XColumn > xFieldContent;
1334 : DbGridColumn* pCol;
1335 0 : for (sal_Int32 i=0; i < nColumnCount; ++i)
1336 : {
1337 0 : sal_uInt16 nModelPos = pGrid->GetModelColumnPos(pGrid->GetColumnIdFromViewPos((sal_uInt16)i));
1338 : DBG_ASSERT(nModelPos != (sal_uInt16)-1, "FmXGridPeer::queryFieldData : invalid model pos !");
1339 :
1340 : // don't use GetCurrentFieldValue to determine the field content as this isn't affected by the above SeekRow
1341 : // FS - 30.09.99 - 68644
1342 0 : pCol = aColumns[ nModelPos ];
1343 0 : xFieldContent = xPaintRow->HasField( pCol->GetFieldPos() )
1344 0 : ? xPaintRow->GetField( pCol->GetFieldPos() ).getColumn()
1345 0 : : Reference< XColumn > ();
1346 :
1347 0 : if ( !xFieldContent.is() )
1348 0 : continue;
1349 :
1350 0 : if (bRequestedAsAny)
1351 : {
1352 0 : Reference< XPropertySet > xFieldSet(xFieldContent, UNO_QUERY);
1353 0 : pReturnArray[i] = xFieldSet->getPropertyValue(FM_PROP_VALUE);
1354 : }
1355 : else
1356 : {
1357 0 : switch (xType.getTypeClass())
1358 : {
1359 : // Strings are dealt with directly by the GetFieldText
1360 : case TypeClass_STRING :
1361 : {
1362 0 : OUString sText = aColumns[ nModelPos ]->GetCellText( xPaintRow, pGrid->getNumberFormatter() );
1363 0 : pReturnArray[i] <<= sText;
1364 : }
1365 0 : break;
1366 : // everything else is requested in the DatabaseVariant
1367 0 : case TypeClass_FLOAT : pReturnArray[i] <<= xFieldContent->getFloat(); break;
1368 0 : case TypeClass_DOUBLE : pReturnArray[i] <<= xFieldContent->getDouble(); break;
1369 0 : case TypeClass_SHORT : pReturnArray[i] <<= (sal_Int16)xFieldContent->getShort(); break;
1370 0 : case TypeClass_LONG : pReturnArray[i] <<= (sal_Int32)xFieldContent->getLong(); break;
1371 0 : case TypeClass_UNSIGNED_SHORT : pReturnArray[i] <<= (sal_uInt16)xFieldContent->getShort(); break;
1372 0 : case TypeClass_UNSIGNED_LONG : pReturnArray[i] <<= (sal_uInt32)xFieldContent->getLong(); break;
1373 0 : case TypeClass_BOOLEAN : ::comphelper::setBOOL(pReturnArray[i],xFieldContent->getBoolean()); break;
1374 : default:
1375 : {
1376 0 : throw IllegalArgumentException();
1377 : }
1378 : }
1379 : }
1380 : }
1381 0 : return aReturnSequence;
1382 : }
1383 :
1384 :
1385 0 : void FmXGridPeer::CellModified()
1386 : {
1387 0 : EventObject aEvt;
1388 0 : aEvt.Source = static_cast< ::cppu::OWeakObject* >(this);
1389 0 : m_aModifyListeners.notifyEach( &XModifyListener::modified, aEvt );
1390 0 : }
1391 :
1392 : // XPropertyChangeListener
1393 :
1394 0 : void FmXGridPeer::propertyChange(const PropertyChangeEvent& evt) throw( RuntimeException, std::exception )
1395 : {
1396 0 : SolarMutexGuard aGuard;
1397 : // want to do a lot of VCL stuff here ...
1398 : // this should not be (deadlock) critical, as by definition, every component should release
1399 : // any own mutexes before notifying
1400 :
1401 0 : FmGridControl* pGrid = static_cast<FmGridControl*>( GetWindow() );
1402 0 : if (!pGrid)
1403 0 : return;
1404 :
1405 : // Database event
1406 0 : Reference< XRowSet > xCursor(evt.Source, UNO_QUERY);
1407 0 : if (evt.PropertyName == FM_PROP_VALUE || m_xCursor == evt.Source)
1408 0 : pGrid->propertyChange(evt);
1409 0 : else if (pGrid && m_xColumns.is() && m_xColumns->hasElements())
1410 : {
1411 : // next find which column has changed
1412 0 : ::comphelper::InterfaceRef xCurrent;
1413 : sal_Int32 i;
1414 :
1415 0 : for ( i = 0; i < m_xColumns->getCount(); i++)
1416 : {
1417 0 : xCurrent.set(m_xColumns->getByIndex(i), css::uno::UNO_QUERY);
1418 0 : if (evt.Source == xCurrent)
1419 0 : break;
1420 : }
1421 :
1422 0 : if (i >= m_xColumns->getCount())
1423 : // this is valid because we are listening at the cursor, too (RecordCount, -status, edit mode)
1424 0 : return;
1425 :
1426 0 : sal_uInt16 nId = pGrid->GetColumnIdFromModelPos((sal_uInt16)i);
1427 0 : bool bInvalidateColumn = false;
1428 :
1429 0 : if (evt.PropertyName == FM_PROP_LABEL)
1430 : {
1431 0 : OUString aName = ::comphelper::getString(evt.NewValue);
1432 0 : if (aName != pGrid->GetColumnTitle(nId))
1433 0 : pGrid->SetColumnTitle(nId, aName);
1434 : }
1435 0 : else if (evt.PropertyName == FM_PROP_WIDTH)
1436 : {
1437 0 : sal_Int32 nWidth = 0;
1438 0 : if (evt.NewValue.getValueType().getTypeClass() == TypeClass_VOID)
1439 0 : nWidth = pGrid->GetDefaultColumnWidth(pGrid->GetColumnTitle(nId));
1440 : // GetDefaultColumnWidth already considered the zoom factor
1441 : else
1442 : {
1443 0 : sal_Int32 nTest = 0;
1444 0 : if (evt.NewValue >>= nTest)
1445 : {
1446 0 : nWidth = pGrid->LogicToPixel(Point(nTest,0),MAP_10TH_MM).X();
1447 : // take the zoom factor into account
1448 0 : nWidth = pGrid->CalcZoom(nWidth);
1449 : }
1450 : }
1451 0 : if (nWidth != (sal_Int32(pGrid->GetColumnWidth(nId))))
1452 : {
1453 0 : if (pGrid->IsEditing())
1454 : {
1455 0 : pGrid->DeactivateCell();
1456 0 : pGrid->ActivateCell();
1457 : }
1458 0 : pGrid->SetColumnWidth(nId, nWidth);
1459 : }
1460 : }
1461 0 : else if (evt.PropertyName == FM_PROP_HIDDEN)
1462 : {
1463 : DBG_ASSERT(evt.NewValue.getValueType().getTypeClass() == TypeClass_BOOLEAN,
1464 : "FmXGridPeer::propertyChange : the property 'hidden' should be of type boolean !");
1465 0 : if (::comphelper::getBOOL(evt.NewValue))
1466 0 : pGrid->HideColumn(nId);
1467 : else
1468 0 : pGrid->ShowColumn(nId);
1469 : }
1470 0 : else if (evt.PropertyName == FM_PROP_ALIGN)
1471 : {
1472 : // in design mode it doesn't matter
1473 0 : if (!isDesignMode())
1474 : {
1475 0 : DbGridColumn* pCol = pGrid->GetColumns().at( i );
1476 :
1477 0 : pCol->SetAlignmentFromModel(-1);
1478 0 : bInvalidateColumn = true;
1479 : }
1480 : }
1481 0 : else if (evt.PropertyName == FM_PROP_FORMATKEY)
1482 : {
1483 0 : if (!isDesignMode())
1484 0 : bInvalidateColumn = true;
1485 : }
1486 :
1487 : // need to invalidate the affected column ?
1488 0 : if (bInvalidateColumn)
1489 : {
1490 0 : bool bWasEditing = pGrid->IsEditing();
1491 0 : if (bWasEditing)
1492 0 : pGrid->DeactivateCell();
1493 :
1494 0 : ::Rectangle aColRect = pGrid->GetFieldRect(nId);
1495 0 : aColRect.Top() = 0;
1496 0 : aColRect.Bottom() = pGrid->GetSizePixel().Height();
1497 0 : pGrid->Invalidate(aColRect);
1498 :
1499 0 : if (bWasEditing)
1500 0 : pGrid->ActivateCell();
1501 0 : }
1502 0 : }
1503 : }
1504 :
1505 : // XBoundComponent
1506 :
1507 0 : void FmXGridPeer::addUpdateListener(const Reference< XUpdateListener >& l) throw( RuntimeException, std::exception )
1508 : {
1509 0 : m_aUpdateListeners.addInterface(l);
1510 0 : }
1511 :
1512 :
1513 0 : void FmXGridPeer::removeUpdateListener(const Reference< XUpdateListener >& l) throw( RuntimeException, std::exception )
1514 : {
1515 0 : m_aUpdateListeners.removeInterface(l);
1516 0 : }
1517 :
1518 :
1519 0 : sal_Bool FmXGridPeer::commit() throw( RuntimeException, std::exception )
1520 : {
1521 0 : FmGridControl* pGrid = static_cast<FmGridControl*>( GetWindow() );
1522 0 : if (!m_xCursor.is() || !pGrid)
1523 0 : return sal_True;
1524 :
1525 0 : EventObject aEvt(static_cast< ::cppu::OWeakObject* >(this));
1526 0 : ::cppu::OInterfaceIteratorHelper aIter(m_aUpdateListeners);
1527 0 : bool bCancel = false;
1528 0 : while (aIter.hasMoreElements() && !bCancel)
1529 0 : if ( !static_cast< XUpdateListener* >( aIter.next() )->approveUpdate( aEvt ) )
1530 0 : bCancel = true;
1531 :
1532 0 : if (!bCancel)
1533 0 : bCancel = !pGrid->commit();
1534 :
1535 0 : if (!bCancel)
1536 0 : m_aUpdateListeners.notifyEach( &XUpdateListener::updated, aEvt );
1537 0 : return !bCancel;
1538 : }
1539 :
1540 :
1541 :
1542 0 : void FmXGridPeer::cursorMoved(const EventObject& _rEvent) throw( RuntimeException, std::exception )
1543 : {
1544 0 : FmGridControl* pGrid = static_cast<FmGridControl*>( GetWindow() );
1545 : // we are not interested in move to insert row only in the resetted event
1546 : // which is fired after positioning an the insert row
1547 0 : if (pGrid && pGrid->IsOpen() && !::comphelper::getBOOL(Reference< XPropertySet > (_rEvent.Source, UNO_QUERY)->getPropertyValue(FM_PROP_ISNEW)))
1548 0 : pGrid->positioned(_rEvent);
1549 0 : }
1550 :
1551 :
1552 0 : void FmXGridPeer::rowChanged(const EventObject& _rEvent) throw( RuntimeException, std::exception )
1553 : {
1554 0 : FmGridControl* pGrid = static_cast<FmGridControl*>( GetWindow() );
1555 0 : if (pGrid && pGrid->IsOpen())
1556 : {
1557 0 : if (m_xCursor->rowUpdated() && !pGrid->IsCurrentAppending())
1558 0 : pGrid->RowModified(pGrid->GetCurrentPos());
1559 0 : else if (m_xCursor->rowInserted())
1560 0 : pGrid->inserted(_rEvent);
1561 : }
1562 0 : }
1563 :
1564 :
1565 0 : void FmXGridPeer::rowSetChanged(const EventObject& /*event*/) throw( RuntimeException, std::exception )
1566 : {
1567 : // not interested in ...
1568 : // (our parent is a form which means we get a loaded or reloaded after this rowSetChanged)
1569 0 : }
1570 :
1571 : // XLoadListener
1572 :
1573 0 : void FmXGridPeer::loaded(const EventObject& /*rEvent*/) throw( RuntimeException, std::exception )
1574 : {
1575 0 : updateGrid(m_xCursor);
1576 0 : }
1577 :
1578 :
1579 2 : void FmXGridPeer::unloaded(const EventObject& /*rEvent*/) throw( RuntimeException, std::exception )
1580 : {
1581 2 : updateGrid( Reference< XRowSet > (NULL) );
1582 2 : }
1583 :
1584 :
1585 0 : void FmXGridPeer::reloading(const EventObject& /*aEvent*/) throw( RuntimeException, std::exception )
1586 : {
1587 : // empty the grid
1588 0 : updateGrid( Reference< XRowSet > (NULL) );
1589 0 : }
1590 :
1591 :
1592 2 : void FmXGridPeer::unloading(const EventObject& /*aEvent*/) throw( RuntimeException, std::exception )
1593 : {
1594 : // empty the grid
1595 2 : updateGrid( Reference< XRowSet > (NULL) );
1596 2 : }
1597 :
1598 :
1599 0 : void FmXGridPeer::reloaded(const EventObject& /*aEvent*/) throw( RuntimeException, std::exception )
1600 : {
1601 0 : updateGrid(m_xCursor);
1602 0 : }
1603 :
1604 : // XGridPeer
1605 :
1606 134 : Reference< XIndexContainer > FmXGridPeer::getColumns() throw( RuntimeException, std::exception )
1607 : {
1608 134 : return m_xColumns;
1609 : }
1610 :
1611 :
1612 140 : void FmXGridPeer::addColumnListeners(const Reference< XPropertySet >& xCol)
1613 : {
1614 : static const OUString aPropsListenedTo[] =
1615 : {
1616 : OUString(FM_PROP_LABEL), OUString(FM_PROP_WIDTH), OUString(FM_PROP_HIDDEN), OUString(FM_PROP_ALIGN), OUString(FM_PROP_FORMATKEY)
1617 144 : };
1618 :
1619 : // as not all properties have to be supported by all columns we have to check this
1620 : // before adding a listener
1621 140 : Reference< XPropertySetInfo > xInfo = xCol->getPropertySetInfo();
1622 280 : Property aPropDesc;
1623 140 : const OUString* pProps = aPropsListenedTo;
1624 140 : const OUString* pPropsEnd = pProps + sizeof( aPropsListenedTo ) / sizeof( aPropsListenedTo[ 0 ] );
1625 840 : for (; pProps != pPropsEnd; ++pProps)
1626 : {
1627 700 : if ( xInfo->hasPropertyByName( *pProps ) )
1628 : {
1629 619 : aPropDesc = xInfo->getPropertyByName( *pProps );
1630 619 : if ( 0 != ( aPropDesc.Attributes & PropertyAttribute::BOUND ) )
1631 588 : xCol->addPropertyChangeListener( *pProps, this );
1632 : }
1633 140 : }
1634 140 : }
1635 :
1636 :
1637 82 : void FmXGridPeer::removeColumnListeners(const Reference< XPropertySet >& xCol)
1638 : {
1639 : // the same props as in addColumnListeners ... linux has problems with global static UStrings, so
1640 : // we have to do it this way ....
1641 : static OUString aPropsListenedTo[] =
1642 : {
1643 : OUString(FM_PROP_LABEL), OUString(FM_PROP_WIDTH), OUString(FM_PROP_HIDDEN), OUString(FM_PROP_ALIGN), OUString(FM_PROP_FORMATKEY)
1644 86 : };
1645 :
1646 82 : Reference< XPropertySetInfo > xInfo = xCol->getPropertySetInfo();
1647 492 : for (sal_uInt16 i=0; i<sizeof(aPropsListenedTo)/sizeof(aPropsListenedTo[0]); ++i)
1648 410 : if (xInfo->hasPropertyByName(aPropsListenedTo[i]))
1649 440 : xCol->removePropertyChangeListener(aPropsListenedTo[i], this);
1650 82 : }
1651 :
1652 :
1653 131 : void FmXGridPeer::setColumns(const Reference< XIndexContainer >& Columns) throw( RuntimeException, std::exception )
1654 : {
1655 131 : SolarMutexGuard aGuard;
1656 :
1657 131 : FmGridControl* pGrid = static_cast< FmGridControl* >( GetWindow() );
1658 :
1659 131 : if (m_xColumns.is())
1660 : {
1661 41 : Reference< XPropertySet > xCol;
1662 103 : for (sal_Int32 i = 0; i < m_xColumns->getCount(); i++)
1663 : {
1664 62 : xCol.set(m_xColumns->getByIndex(i), css::uno::UNO_QUERY);
1665 62 : removeColumnListeners(xCol);
1666 : }
1667 82 : Reference< XContainer > xContainer(m_xColumns, UNO_QUERY);
1668 41 : xContainer->removeContainerListener(this);
1669 :
1670 82 : Reference< XSelectionSupplier > xSelSupplier(m_xColumns, UNO_QUERY);
1671 41 : xSelSupplier->removeSelectionChangeListener(this);
1672 :
1673 82 : Reference< XReset > xColumnReset(m_xColumns, UNO_QUERY);
1674 41 : if (xColumnReset.is())
1675 82 : xColumnReset->removeResetListener((XResetListener*)this);
1676 : }
1677 131 : if (Columns.is())
1678 : {
1679 41 : Reference< XContainer > xContainer(Columns, UNO_QUERY);
1680 41 : xContainer->addContainerListener(this);
1681 :
1682 82 : Reference< XSelectionSupplier > xSelSupplier(Columns, UNO_QUERY);
1683 41 : xSelSupplier->addSelectionChangeListener(this);
1684 :
1685 82 : Reference< XPropertySet > xCol;
1686 79 : for (sal_Int32 i = 0; i < Columns->getCount(); i++)
1687 : {
1688 38 : xCol.set(Columns->getByIndex(i), css::uno::UNO_QUERY);
1689 38 : addColumnListeners(xCol);
1690 : }
1691 :
1692 82 : Reference< XReset > xColumnReset(Columns, UNO_QUERY);
1693 41 : if (xColumnReset.is())
1694 82 : xColumnReset->addResetListener((XResetListener*)this);
1695 : }
1696 131 : m_xColumns = Columns;
1697 131 : if (pGrid)
1698 : {
1699 45 : pGrid->InitColumnsByModels(m_xColumns);
1700 :
1701 45 : if (m_xColumns.is())
1702 : {
1703 41 : EventObject aEvt(m_xColumns);
1704 41 : selectionChanged(aEvt);
1705 : }
1706 131 : }
1707 131 : }
1708 :
1709 :
1710 64 : void FmXGridPeer::setDesignMode(sal_Bool bOn) throw( RuntimeException, std::exception )
1711 : {
1712 64 : if (bOn != isDesignMode())
1713 : {
1714 43 : vcl::Window* pWin = GetWindow();
1715 43 : if (pWin)
1716 43 : static_cast<FmGridControl*>(pWin)->SetDesignMode(bOn);
1717 : }
1718 :
1719 64 : if (bOn)
1720 62 : DisConnectFromDispatcher();
1721 : else
1722 2 : UpdateDispatches(); // will connect if not already connected and just update else
1723 64 : }
1724 :
1725 :
1726 284 : sal_Bool FmXGridPeer::isDesignMode() throw( RuntimeException, std::exception )
1727 : {
1728 284 : vcl::Window* pWin = GetWindow();
1729 284 : if (pWin)
1730 284 : return static_cast<FmGridControl*>(pWin)->IsDesignMode();
1731 : else
1732 0 : return sal_False;
1733 : }
1734 :
1735 :
1736 90 : void FmXGridPeer::elementInserted(const ContainerEvent& evt) throw( RuntimeException, std::exception )
1737 : {
1738 90 : SolarMutexGuard aGuard;
1739 :
1740 90 : FmGridControl* pGrid = static_cast<FmGridControl*>(GetWindow());
1741 : // Handle Column beruecksichtigen
1742 90 : if (!pGrid || !m_xColumns.is() || pGrid->IsInColumnMove() || m_xColumns->getCount() == ((sal_Int32)pGrid->GetModelColCount()))
1743 90 : return;
1744 :
1745 180 : Reference< XPropertySet > xSet(evt.Element, css::uno::UNO_QUERY);
1746 90 : addColumnListeners(xSet);
1747 :
1748 180 : Reference< XPropertySet > xNewColumn(xSet);
1749 180 : OUString aName = ::comphelper::getString(xNewColumn->getPropertyValue(FM_PROP_LABEL));
1750 180 : Any aWidth = xNewColumn->getPropertyValue(FM_PROP_WIDTH);
1751 90 : sal_Int32 nWidth = 0;
1752 90 : if (aWidth >>= nWidth)
1753 20 : nWidth = pGrid->LogicToPixel(Point(nWidth,0),MAP_10TH_MM).X();
1754 :
1755 90 : pGrid->AppendColumn(aName, (sal_uInt16)nWidth, (sal_Int16)::comphelper::getINT32(evt.Accessor));
1756 :
1757 : // jetzt die Spalte setzen
1758 90 : DbGridColumn* pCol = pGrid->GetColumns().at( ::comphelper::getINT32(evt.Accessor) );
1759 90 : pCol->setModel(xNewColumn);
1760 :
1761 180 : Any aHidden = xNewColumn->getPropertyValue(FM_PROP_HIDDEN);
1762 90 : if (::comphelper::getBOOL(aHidden))
1763 0 : pGrid->HideColumn(pCol->GetId());
1764 :
1765 180 : FormControlFactory( m_xContext ).initializeTextFieldLineEnds( xNewColumn );
1766 : }
1767 :
1768 :
1769 12 : void FmXGridPeer::elementReplaced(const ContainerEvent& evt) throw( RuntimeException, std::exception )
1770 : {
1771 12 : SolarMutexGuard aGuard;
1772 :
1773 12 : FmGridControl* pGrid = static_cast<FmGridControl*>( GetWindow() );
1774 :
1775 : // Handle Column beruecksichtigen
1776 12 : if (!pGrid || !m_xColumns.is() || pGrid->IsInColumnMove())
1777 12 : return;
1778 :
1779 24 : Reference< XPropertySet > xNewColumn(evt.Element, css::uno::UNO_QUERY);
1780 : Reference< XPropertySet > xOldColumn(
1781 24 : evt.ReplacedElement, css::uno::UNO_QUERY);
1782 :
1783 12 : bool bWasEditing = pGrid->IsEditing();
1784 12 : if (bWasEditing)
1785 0 : pGrid->DeactivateCell();
1786 :
1787 12 : pGrid->RemoveColumn(pGrid->GetColumnIdFromModelPos((sal_uInt16)::comphelper::getINT32(evt.Accessor)));
1788 :
1789 12 : removeColumnListeners(xOldColumn);
1790 12 : addColumnListeners(xNewColumn);
1791 :
1792 24 : OUString aName = ::comphelper::getString(xNewColumn->getPropertyValue(FM_PROP_LABEL));
1793 24 : Any aWidth = xNewColumn->getPropertyValue(FM_PROP_WIDTH);
1794 12 : sal_Int32 nWidth = 0;
1795 12 : if (aWidth >>= nWidth)
1796 0 : nWidth = pGrid->LogicToPixel(Point(nWidth,0),MAP_10TH_MM).X();
1797 12 : sal_uInt16 nNewId = pGrid->AppendColumn(aName, (sal_uInt16)nWidth, (sal_Int16)::comphelper::getINT32(evt.Accessor));
1798 12 : sal_uInt16 nNewPos = pGrid->GetModelColumnPos(nNewId);
1799 :
1800 : // set the model of the new column
1801 12 : DbGridColumn* pCol = pGrid->GetColumns().at( nNewPos );
1802 :
1803 : // for initializong this grid column, we need the fields of the grid's data source
1804 24 : Reference< XColumnsSupplier > xSuppColumns;
1805 12 : CursorWrapper* pGridDataSource = pGrid->getDataSource();
1806 12 : if ( pGridDataSource )
1807 0 : xSuppColumns.set(Reference< XInterface >( *pGridDataSource ), css::uno::UNO_QUERY);
1808 24 : Reference< XNameAccess > xColumnsByName;
1809 12 : if ( xSuppColumns.is() )
1810 0 : xColumnsByName = xSuppColumns->getColumns();
1811 24 : Reference< XIndexAccess > xColumnsByIndex( xColumnsByName, UNO_QUERY );
1812 :
1813 12 : if ( xColumnsByIndex.is() )
1814 0 : pGrid->InitColumnByField( pCol, xNewColumn, xColumnsByName, xColumnsByIndex );
1815 : else
1816 : // the simple version, applies when the grid is not yet connected to a data source
1817 12 : pCol->setModel(xNewColumn);
1818 :
1819 12 : if (bWasEditing)
1820 12 : pGrid->ActivateCell();
1821 : }
1822 :
1823 :
1824 8 : void FmXGridPeer::elementRemoved(const ContainerEvent& evt) throw( RuntimeException, std::exception )
1825 : {
1826 8 : SolarMutexGuard aGuard;
1827 :
1828 8 : FmGridControl* pGrid = static_cast<FmGridControl*>(GetWindow());
1829 :
1830 : // Handle Column beruecksichtigen
1831 8 : if (!pGrid || !m_xColumns.is() || pGrid->IsInColumnMove() || m_xColumns->getCount() == ((sal_Int32)pGrid->GetModelColCount()))
1832 8 : return;
1833 :
1834 8 : pGrid->RemoveColumn(pGrid->GetColumnIdFromModelPos((sal_uInt16)::comphelper::getINT32(evt.Accessor)));
1835 :
1836 16 : Reference< XPropertySet > xOldColumn(evt.Element, css::uno::UNO_QUERY);
1837 16 : removeColumnListeners(xOldColumn);
1838 : }
1839 :
1840 :
1841 1804 : void FmXGridPeer::setProperty( const OUString& PropertyName, const Any& Value) throw( RuntimeException, std::exception )
1842 : {
1843 1804 : SolarMutexGuard aGuard;
1844 :
1845 1804 : FmGridControl* pGrid = static_cast<FmGridControl*>( GetWindow() );
1846 :
1847 1804 : bool bVoid = !Value.hasValue();
1848 :
1849 1804 : if ( PropertyName == FM_PROP_TEXTLINECOLOR )
1850 : {
1851 41 : ::Color aTextLineColor( bVoid ? COL_TRANSPARENT : ::comphelper::getINT32( Value ) );
1852 41 : if (bVoid)
1853 : {
1854 41 : pGrid->SetTextLineColor();
1855 41 : pGrid->GetDataWindow().SetTextLineColor();
1856 : }
1857 : else
1858 : {
1859 0 : pGrid->SetTextLineColor(aTextLineColor);
1860 0 : pGrid->GetDataWindow().SetTextLineColor(aTextLineColor);
1861 : }
1862 :
1863 : // need to forward this to the columns
1864 41 : DbGridColumns& rColumns = const_cast<DbGridColumns&>(pGrid->GetColumns());
1865 41 : for ( size_t i = 0, n = rColumns.size(); i < n; ++i )
1866 : {
1867 0 : DbGridColumn* pLoop = rColumns[ i ];
1868 0 : FmXGridCell* pXCell = pLoop->GetCell();
1869 0 : if (pXCell)
1870 : {
1871 0 : if (bVoid)
1872 0 : pXCell->SetTextLineColor();
1873 : else
1874 0 : pXCell->SetTextLineColor(aTextLineColor);
1875 : }
1876 : }
1877 :
1878 41 : if (isDesignMode())
1879 0 : pGrid->Invalidate();
1880 : }
1881 1763 : else if ( PropertyName == FM_PROP_FONTEMPHASISMARK )
1882 : {
1883 47 : vcl::Font aGridFont = pGrid->GetControlFont();
1884 47 : sal_Int16 nValue = ::comphelper::getINT16(Value);
1885 47 : aGridFont.SetEmphasisMark( nValue );
1886 47 : pGrid->SetControlFont( aGridFont );
1887 : }
1888 1716 : else if ( PropertyName == FM_PROP_FONTRELIEF )
1889 : {
1890 47 : vcl::Font aGridFont = pGrid->GetControlFont();
1891 47 : sal_Int16 nValue = ::comphelper::getINT16(Value);
1892 47 : aGridFont.SetRelief( (FontRelief)nValue );
1893 47 : pGrid->SetControlFont( aGridFont );
1894 : }
1895 1669 : else if ( PropertyName == FM_PROP_HELPURL )
1896 : {
1897 47 : OUString sHelpURL;
1898 47 : OSL_VERIFY( Value >>= sHelpURL );
1899 94 : INetURLObject aHID( sHelpURL );
1900 47 : if ( aHID.GetProtocol() == INET_PROT_HID )
1901 0 : sHelpURL = aHID.GetURLPath();
1902 94 : pGrid->SetHelpId( OUStringToOString( sHelpURL, RTL_TEXTENCODING_UTF8 ) );
1903 : }
1904 1622 : else if ( PropertyName == FM_PROP_DISPLAYSYNCHRON )
1905 : {
1906 55 : pGrid->setDisplaySynchron(::comphelper::getBOOL(Value));
1907 : }
1908 1567 : else if ( PropertyName == FM_PROP_CURSORCOLOR )
1909 : {
1910 41 : if (bVoid)
1911 41 : pGrid->SetCursorColor(COL_TRANSPARENT);
1912 : else
1913 0 : pGrid->SetCursorColor( ::Color(::comphelper::getINT32(Value)));
1914 41 : if (isDesignMode())
1915 0 : pGrid->Invalidate();
1916 : }
1917 1526 : else if ( PropertyName == FM_PROP_ALWAYSSHOWCURSOR )
1918 : {
1919 55 : pGrid->EnablePermanentCursor(::comphelper::getBOOL(Value));
1920 55 : if (isDesignMode())
1921 14 : pGrid->Invalidate();
1922 : }
1923 1471 : else if ( PropertyName == FM_PROP_FONT )
1924 : {
1925 91 : if ( bVoid )
1926 0 : pGrid->SetControlFont( vcl::Font() );
1927 : else
1928 : {
1929 91 : ::com::sun::star::awt::FontDescriptor aFont;
1930 91 : if (Value >>= aFont)
1931 : {
1932 91 : vcl::Font aNewVclFont;
1933 91 : if (::comphelper::operator!=(aFont, ::comphelper::getDefaultFont())) // ist das der Default
1934 89 : aNewVclFont = ImplCreateFont( aFont );
1935 :
1936 : // need to add relief and emphasis (they're stored in a VCL-Font, but not in a FontDescriptor
1937 182 : vcl::Font aOldVclFont = pGrid->GetControlFont();
1938 91 : aNewVclFont.SetRelief( aOldVclFont.GetRelief() );
1939 91 : aNewVclFont.SetEmphasisMark( aOldVclFont.GetEmphasisMark() );
1940 :
1941 : // now set it ...
1942 91 : pGrid->SetControlFont( aNewVclFont );
1943 :
1944 : // if our row-height property is void (which means "calculate it font-dependent") we have
1945 : // to adjust the control's row height
1946 182 : Reference< XPropertySet > xModelSet(getColumns(), UNO_QUERY);
1947 91 : if (xModelSet.is() && ::comphelper::hasProperty(FM_PROP_ROWHEIGHT, xModelSet))
1948 : {
1949 50 : Any aHeight = xModelSet->getPropertyValue(FM_PROP_ROWHEIGHT);
1950 50 : if (!aHeight.hasValue())
1951 50 : pGrid->SetDataRowHeight(0);
1952 91 : }
1953 :
1954 91 : }
1955 : }
1956 : }
1957 1380 : else if ( PropertyName == FM_PROP_BACKGROUNDCOLOR )
1958 : {
1959 41 : if ( bVoid )
1960 : {
1961 41 : pGrid->SetControlBackground();
1962 : }
1963 : else
1964 : {
1965 0 : ::Color aColor( ::comphelper::getINT32(Value) );
1966 0 : pGrid->SetBackground( aColor );
1967 0 : pGrid->SetControlBackground( aColor );
1968 : }
1969 : }
1970 1339 : else if ( PropertyName == FM_PROP_TEXTCOLOR )
1971 : {
1972 41 : if ( bVoid )
1973 : {
1974 41 : pGrid->SetControlForeground();
1975 : }
1976 : else
1977 : {
1978 0 : ::Color aColor( ::comphelper::getINT32(Value) );
1979 0 : pGrid->SetTextColor( aColor );
1980 0 : pGrid->SetControlForeground( aColor );
1981 : }
1982 : }
1983 1298 : else if ( PropertyName == FM_PROP_ROWHEIGHT )
1984 : {
1985 41 : sal_Int32 nLogHeight(0);
1986 41 : if (Value >>= nLogHeight)
1987 : {
1988 0 : sal_Int32 nHeight = pGrid->LogicToPixel(Point(0,nLogHeight),MAP_10TH_MM).Y();
1989 : // take the zoom factor into account
1990 0 : nHeight = pGrid->CalcZoom(nHeight);
1991 0 : pGrid->SetDataRowHeight(nHeight);
1992 : }
1993 41 : else if (bVoid)
1994 41 : pGrid->SetDataRowHeight(0);
1995 : }
1996 1257 : else if ( PropertyName == FM_PROP_HASNAVIGATION )
1997 : {
1998 55 : bool bValue( true );
1999 55 : OSL_VERIFY( Value >>= bValue );
2000 55 : pGrid->EnableNavigationBar( bValue );
2001 : }
2002 1202 : else if ( PropertyName == FM_PROP_RECORDMARKER )
2003 : {
2004 55 : bool bValue( true );
2005 55 : OSL_VERIFY( Value >>= bValue );
2006 55 : pGrid->EnableHandle( bValue );
2007 : }
2008 1147 : else if ( PropertyName == FM_PROP_ENABLED )
2009 : {
2010 58 : bool bValue( true );
2011 58 : OSL_VERIFY( Value >>= bValue );
2012 :
2013 : // In design mode, disable only the data window.
2014 : // Else the control cannot be configured anymore.
2015 58 : if (isDesignMode())
2016 17 : pGrid->GetDataWindow().Enable( bValue );
2017 : else
2018 41 : pGrid->Enable( bValue );
2019 : }
2020 : else
2021 1089 : VCLXWindow::setProperty( PropertyName, Value );
2022 1804 : }
2023 :
2024 :
2025 0 : Reference< XAccessibleContext > FmXGridPeer::CreateAccessibleContext()
2026 : {
2027 0 : Reference< XAccessibleContext > xContext;
2028 :
2029 : // use the AccessibleContext provided by the VCL window
2030 0 : vcl::Window* pGrid = GetWindow();
2031 0 : if ( pGrid )
2032 : {
2033 0 : Reference< XAccessible > xAcc( pGrid->GetAccessible( true ) );
2034 0 : if ( xAcc.is() )
2035 0 : xContext = xAcc->getAccessibleContext();
2036 : // TODO: this has a slight conceptual problem:
2037 :
2038 : // We know that the XAccessible and XAccessibleContext implementation of the browse
2039 : // box is the same (the class implements both interfaces), which, speaking strictly,
2040 : // is bad here (means when a browse box acts as UnoControl): We (the FmXGridPeer) are
2041 : // the XAccessible here, and the browse box should be able to provide us an XAccessibleContext,
2042 : // but it should _not_ be the XAccessible itself.
2043 : // However, as long as no client implementation uses dirty hacks such as querying an
2044 : // XAccessibleContext for XAccessible, this should not be a problem.
2045 : }
2046 :
2047 0 : if ( !xContext.is() )
2048 0 : xContext = VCLXWindow::CreateAccessibleContext( );
2049 :
2050 0 : return xContext;
2051 : }
2052 :
2053 :
2054 0 : Any FmXGridPeer::getProperty( const OUString& _rPropertyName ) throw( RuntimeException, std::exception )
2055 : {
2056 0 : Any aProp;
2057 0 : if (GetWindow())
2058 : {
2059 0 : FmGridControl* pGrid = static_cast<FmGridControl*>(GetWindow());
2060 0 : vcl::Window* pDataWindow = &pGrid->GetDataWindow();
2061 :
2062 0 : if ( _rPropertyName == FM_PROP_NAME )
2063 : {
2064 0 : vcl::Font aFont = pDataWindow->GetControlFont();
2065 0 : aProp <<= ImplCreateFontDescriptor( aFont );
2066 : }
2067 0 : else if ( _rPropertyName == FM_PROP_TEXTCOLOR )
2068 : {
2069 0 : aProp <<= (sal_Int32)pDataWindow->GetControlForeground().GetColor();
2070 : }
2071 0 : else if ( _rPropertyName == FM_PROP_BACKGROUNDCOLOR )
2072 : {
2073 0 : aProp <<= (sal_Int32)pDataWindow->GetControlBackground().GetColor();
2074 : }
2075 0 : else if ( _rPropertyName == FM_PROP_ROWHEIGHT )
2076 : {
2077 0 : sal_Int32 nPixelHeight = pGrid->GetDataRowHeight();
2078 : // take the zoom factor into account
2079 0 : nPixelHeight = pGrid->CalcReverseZoom(nPixelHeight);
2080 0 : aProp <<= (sal_Int32)pGrid->PixelToLogic(Point(0,nPixelHeight),MAP_10TH_MM).Y();
2081 : }
2082 0 : else if ( _rPropertyName == FM_PROP_HASNAVIGATION )
2083 : {
2084 0 : bool bHasNavBar = pGrid->HasNavigationBar();
2085 0 : aProp <<= bHasNavBar;
2086 : }
2087 0 : else if ( _rPropertyName == FM_PROP_RECORDMARKER )
2088 : {
2089 0 : bool bHasHandle = pGrid->HasHandle();
2090 0 : aProp <<= bHasHandle;
2091 : }
2092 0 : else if ( _rPropertyName == FM_PROP_ENABLED )
2093 : {
2094 0 : aProp <<= pDataWindow->IsEnabled();
2095 : }
2096 : else
2097 0 : aProp = VCLXWindow::getProperty( _rPropertyName );
2098 : }
2099 0 : return aProp;
2100 : }
2101 :
2102 :
2103 82 : void FmXGridPeer::dispose() throw( RuntimeException, std::exception )
2104 : {
2105 82 : EventObject aEvt;
2106 82 : aEvt.Source = static_cast< ::cppu::OWeakObject* >(this);
2107 82 : m_aModifyListeners.disposeAndClear(aEvt);
2108 82 : m_aUpdateListeners.disposeAndClear(aEvt);
2109 82 : m_aContainerListeners.disposeAndClear(aEvt);
2110 82 : VCLXWindow::dispose();
2111 :
2112 : // release all interceptors
2113 164 : Reference< XDispatchProviderInterceptor > xInterceptor( m_xFirstDispatchInterceptor );
2114 82 : m_xFirstDispatchInterceptor.clear();
2115 164 : while ( xInterceptor.is() )
2116 : {
2117 : // tell the interceptor it has a new (means no) predecessor
2118 0 : xInterceptor->setMasterDispatchProvider( NULL );
2119 :
2120 : // ask for it's successor
2121 0 : Reference< XDispatchProvider > xSlave = xInterceptor->getSlaveDispatchProvider();
2122 : // and give it the new (means no) successoert
2123 0 : xInterceptor->setSlaveDispatchProvider( NULL );
2124 :
2125 : // start over with the next chain element
2126 0 : xInterceptor.set(xSlave, css::uno::UNO_QUERY);
2127 0 : }
2128 :
2129 82 : DisConnectFromDispatcher();
2130 164 : setRowSet(Reference< XRowSet > ());
2131 82 : }
2132 :
2133 : // XContainer
2134 :
2135 0 : void FmXGridPeer::addContainerListener(const Reference< XContainerListener >& l) throw( RuntimeException, std::exception )
2136 : {
2137 0 : m_aContainerListeners.addInterface( l );
2138 0 : }
2139 :
2140 0 : void FmXGridPeer::removeContainerListener(const Reference< XContainerListener >& l) throw( RuntimeException, std::exception )
2141 : {
2142 0 : m_aContainerListeners.removeInterface( l );
2143 0 : }
2144 :
2145 : // ::com::sun::star::data::XDatabaseCursorSupplier
2146 :
2147 4 : void FmXGridPeer::startCursorListening()
2148 : {
2149 4 : if (!m_nCursorListening)
2150 : {
2151 2 : Reference< XRowSet > xRowSet(m_xCursor, UNO_QUERY);
2152 2 : if (xRowSet.is())
2153 2 : xRowSet->addRowSetListener(this);
2154 :
2155 4 : Reference< XReset > xReset(m_xCursor, UNO_QUERY);
2156 2 : if (xReset.is())
2157 2 : xReset->addResetListener(this);
2158 :
2159 : // register all listeners
2160 4 : Reference< XPropertySet > xSet(m_xCursor, UNO_QUERY);
2161 2 : if (xSet.is())
2162 : {
2163 2 : xSet->addPropertyChangeListener(FM_PROP_ISMODIFIED, this);
2164 2 : xSet->addPropertyChangeListener(FM_PROP_ROWCOUNT, this);
2165 2 : }
2166 : }
2167 4 : m_nCursorListening++;
2168 4 : }
2169 :
2170 :
2171 2 : void FmXGridPeer::stopCursorListening()
2172 : {
2173 2 : if (!--m_nCursorListening)
2174 : {
2175 0 : Reference< XRowSet > xRowSet(m_xCursor, UNO_QUERY);
2176 0 : if (xRowSet.is())
2177 0 : xRowSet->removeRowSetListener(this);
2178 :
2179 0 : Reference< XReset > xReset(m_xCursor, UNO_QUERY);
2180 0 : if (xReset.is())
2181 0 : xReset->removeResetListener(this);
2182 :
2183 0 : Reference< XPropertySet > xSet(m_xCursor, UNO_QUERY);
2184 0 : if (xSet.is())
2185 : {
2186 0 : xSet->removePropertyChangeListener(FM_PROP_ISMODIFIED, this);
2187 0 : xSet->removePropertyChangeListener(FM_PROP_ROWCOUNT, this);
2188 0 : }
2189 : }
2190 2 : }
2191 :
2192 :
2193 4 : void FmXGridPeer::updateGrid(const Reference< XRowSet >& _rxCursor)
2194 : {
2195 4 : FmGridControl* pGrid = static_cast<FmGridControl*>(GetWindow());
2196 4 : if (pGrid)
2197 4 : pGrid->setDataSource(_rxCursor);
2198 4 : }
2199 :
2200 :
2201 0 : Reference< XRowSet > FmXGridPeer::getRowSet() throw( RuntimeException, std::exception )
2202 : {
2203 0 : return m_xCursor;
2204 : }
2205 :
2206 :
2207 135 : void FmXGridPeer::setRowSet(const Reference< XRowSet >& _rDatabaseCursor) throw( RuntimeException, std::exception )
2208 : {
2209 135 : FmGridControl* pGrid = static_cast<FmGridControl*>(GetWindow());
2210 135 : if (!pGrid || !m_xColumns.is() || !m_xColumns->getCount())
2211 268 : return;
2212 : // unregister all listeners
2213 2 : if (m_xCursor.is())
2214 : {
2215 0 : Reference< XLoadable > xLoadable(m_xCursor, UNO_QUERY);
2216 : // only if the form is loaded we set the rowset
2217 0 : if (xLoadable.is())
2218 : {
2219 0 : stopCursorListening();
2220 0 : xLoadable->removeLoadListener(this);
2221 0 : }
2222 : }
2223 :
2224 2 : m_xCursor = _rDatabaseCursor;
2225 :
2226 2 : if (pGrid)
2227 : {
2228 2 : Reference< XLoadable > xLoadable(m_xCursor, UNO_QUERY);
2229 : // only if the form is loaded we set the rowset
2230 2 : if (xLoadable.is() && xLoadable->isLoaded())
2231 2 : pGrid->setDataSource(m_xCursor);
2232 : else
2233 0 : pGrid->setDataSource(Reference< XRowSet > ());
2234 :
2235 2 : if (xLoadable.is())
2236 : {
2237 2 : startCursorListening();
2238 2 : xLoadable->addLoadListener(this);
2239 2 : }
2240 : }
2241 : }
2242 :
2243 :
2244 0 : void SAL_CALL FmXGridPeer::addGridControlListener( const Reference< XGridControlListener >& _listener ) throw( RuntimeException, std::exception )
2245 : {
2246 0 : m_aGridControlListeners.addInterface( _listener );
2247 0 : }
2248 :
2249 :
2250 0 : void SAL_CALL FmXGridPeer::removeGridControlListener( const Reference< XGridControlListener >& _listener ) throw( RuntimeException, std::exception )
2251 : {
2252 0 : m_aGridControlListeners.removeInterface( _listener );
2253 0 : }
2254 :
2255 :
2256 33 : sal_Int16 FmXGridPeer::getCurrentColumnPosition() throw( RuntimeException, std::exception )
2257 : {
2258 33 : FmGridControl* pGrid = static_cast<FmGridControl*>( GetWindow() );
2259 33 : return pGrid ? pGrid->GetViewColumnPos(pGrid->GetCurColumnId()) : -1;
2260 : }
2261 :
2262 :
2263 0 : void FmXGridPeer::setCurrentColumnPosition(sal_Int16 nPos) throw( RuntimeException, std::exception )
2264 : {
2265 0 : FmGridControl* pGrid = static_cast<FmGridControl*>( GetWindow() );
2266 0 : if (pGrid)
2267 0 : pGrid->GoToColumnId(pGrid->GetColumnIdFromViewPos(nPos));
2268 0 : }
2269 :
2270 :
2271 41 : void FmXGridPeer::selectionChanged(const EventObject& evt) throw( RuntimeException, std::exception )
2272 : {
2273 41 : SolarMutexGuard aGuard;
2274 :
2275 41 : FmGridControl* pGrid = static_cast<FmGridControl*>( GetWindow() );
2276 41 : if (pGrid)
2277 : {
2278 41 : Reference< ::com::sun::star::view::XSelectionSupplier > xSelSupplier(evt.Source, UNO_QUERY);
2279 82 : Any aSelection = xSelSupplier->getSelection();
2280 : DBG_ASSERT(aSelection.getValueType().getTypeClass() == TypeClass_INTERFACE, "FmXGridPeer::selectionChanged : invalid selection !");
2281 82 : Reference< XPropertySet > xSelection;
2282 41 : aSelection >>= xSelection;
2283 41 : if (xSelection.is())
2284 : {
2285 0 : Reference< XPropertySet > xCol;
2286 0 : sal_Int32 i = 0;
2287 0 : sal_Int32 nColCount = m_xColumns->getCount();
2288 :
2289 0 : for (; i < nColCount; ++i)
2290 : {
2291 0 : m_xColumns->getByIndex(i) >>= xCol;
2292 0 : if ( xCol == xSelection )
2293 : {
2294 0 : pGrid->markColumn(pGrid->GetColumnIdFromModelPos((sal_uInt16)i));
2295 0 : break;
2296 : }
2297 : }
2298 : // The columns have to be 1-based for the VCL control.
2299 : // If necessary, pass on the selection to the VCL control
2300 0 : if ( i != pGrid->GetSelectedColumn() )
2301 : { // (wenn das nicht greift, wurde das selectionChanged implizit von dem Control selber ausgeloest
2302 : // if this does not ?hold?catch?, the selectionChanged is cleared by the Control itself
2303 0 : if ( i < nColCount )
2304 : {
2305 0 : pGrid->SelectColumnPos(pGrid->GetViewColumnPos(pGrid->GetColumnIdFromModelPos( (sal_uInt16)i )) + 1, true);
2306 : // SelectColumnPos has led to an implicit ActivateCell again
2307 0 : if (pGrid->IsEditing())
2308 0 : pGrid->DeactivateCell();
2309 : }
2310 : else
2311 0 : pGrid->SetNoSelection();
2312 0 : }
2313 : }
2314 : else
2315 82 : pGrid->markColumn(USHRT_MAX);
2316 41 : }
2317 41 : }
2318 :
2319 : // XElementAccess
2320 :
2321 0 : sal_Bool FmXGridPeer::hasElements() throw( RuntimeException, std::exception )
2322 : {
2323 0 : return getCount() != 0;
2324 : }
2325 :
2326 :
2327 0 : Type SAL_CALL FmXGridPeer::getElementType( ) throw(RuntimeException, std::exception)
2328 : {
2329 0 : return cppu::UnoType<com::sun::star::awt::XControl>::get();
2330 : }
2331 :
2332 : // XEnumerationAccess
2333 :
2334 0 : Reference< XEnumeration > FmXGridPeer::createEnumeration() throw( RuntimeException, std::exception )
2335 : {
2336 0 : return new ::comphelper::OEnumerationByIndex(this);
2337 : }
2338 :
2339 : // XIndexAccess
2340 :
2341 0 : sal_Int32 FmXGridPeer::getCount() throw( RuntimeException, std::exception )
2342 : {
2343 0 : FmGridControl* pGrid = static_cast<FmGridControl*>( GetWindow() );
2344 0 : if (pGrid)
2345 0 : return pGrid->GetViewColCount();
2346 : else
2347 0 : return 0;
2348 : }
2349 :
2350 :
2351 0 : Any FmXGridPeer::getByIndex(sal_Int32 _nIndex) throw( IndexOutOfBoundsException, WrappedTargetException, RuntimeException, std::exception )
2352 : {
2353 0 : FmGridControl* pGrid = static_cast<FmGridControl*>( GetWindow() );
2354 0 : if (_nIndex < 0 ||
2355 0 : _nIndex >= getCount() || !pGrid)
2356 0 : throw IndexOutOfBoundsException();
2357 :
2358 0 : Any aElement;
2359 : // get the columnid
2360 0 : sal_uInt16 nId = pGrid->GetColumnIdFromViewPos((sal_uInt16)_nIndex);
2361 : // get the list position
2362 0 : sal_uInt16 nPos = pGrid->GetModelColumnPos(nId);
2363 :
2364 0 : if ( nPos == GRID_COLUMN_NOT_FOUND )
2365 0 : return aElement;
2366 :
2367 0 : DbGridColumn* pCol = pGrid->GetColumns().at( nPos );
2368 0 : Reference< ::com::sun::star::awt::XControl > xControl(pCol->GetCell());
2369 0 : aElement <<= xControl;
2370 :
2371 0 : return aElement;
2372 : }
2373 :
2374 : // ::com::sun::star::util::XModeSelector
2375 :
2376 0 : void FmXGridPeer::setMode(const OUString& Mode) throw( NoSupportException, RuntimeException, std::exception )
2377 : {
2378 0 : if (!supportsMode(Mode))
2379 0 : throw NoSupportException();
2380 :
2381 0 : if (Mode == m_aMode)
2382 0 : return;
2383 :
2384 0 : m_aMode = Mode;
2385 :
2386 0 : FmGridControl* pGrid = static_cast<FmGridControl*>(GetWindow());
2387 0 : if ( Mode == "FilterMode" )
2388 0 : pGrid->SetFilterMode(true);
2389 : else
2390 : {
2391 0 : pGrid->SetFilterMode(false);
2392 0 : pGrid->setDataSource(m_xCursor);
2393 : }
2394 : }
2395 :
2396 :
2397 0 : OUString FmXGridPeer::getMode() throw( RuntimeException, std::exception )
2398 : {
2399 0 : return m_aMode;
2400 : }
2401 :
2402 :
2403 0 : ::comphelper::StringSequence FmXGridPeer::getSupportedModes() throw( RuntimeException, std::exception )
2404 : {
2405 0 : static ::comphelper::StringSequence aModes;
2406 0 : if (!aModes.getLength())
2407 : {
2408 0 : aModes.realloc(2);
2409 0 : OUString* pModes = aModes.getArray();
2410 0 : pModes[0] = "DataMode";
2411 0 : pModes[1] = "FilterMode";
2412 : }
2413 0 : return aModes;
2414 : }
2415 :
2416 :
2417 0 : sal_Bool FmXGridPeer::supportsMode(const OUString& Mode) throw( RuntimeException, std::exception )
2418 : {
2419 0 : ::comphelper::StringSequence aModes(getSupportedModes());
2420 0 : const OUString* pModes = aModes.getConstArray();
2421 0 : for (sal_Int32 i = aModes.getLength(); i > 0; )
2422 : {
2423 0 : if (pModes[--i] == Mode)
2424 0 : return sal_True;
2425 : }
2426 0 : return sal_False;
2427 : }
2428 :
2429 :
2430 0 : void FmXGridPeer::columnVisible(DbGridColumn* pColumn)
2431 : {
2432 0 : FmGridControl* pGrid = static_cast<FmGridControl*>( GetWindow() );
2433 :
2434 0 : sal_Int32 _nIndex = pGrid->GetModelColumnPos(pColumn->GetId());
2435 0 : Reference< ::com::sun::star::awt::XControl > xControl(pColumn->GetCell());
2436 0 : ContainerEvent aEvt;
2437 0 : aEvt.Source = (XContainer*)this;
2438 0 : aEvt.Accessor <<= _nIndex;
2439 0 : aEvt.Element <<= xControl;
2440 :
2441 0 : m_aContainerListeners.notifyEach( &XContainerListener::elementInserted, aEvt );
2442 0 : }
2443 :
2444 :
2445 0 : void FmXGridPeer::columnHidden(DbGridColumn* pColumn)
2446 : {
2447 0 : FmGridControl* pGrid = static_cast<FmGridControl*>( GetWindow() );
2448 :
2449 0 : sal_Int32 _nIndex = pGrid->GetModelColumnPos(pColumn->GetId());
2450 0 : Reference< ::com::sun::star::awt::XControl > xControl(pColumn->GetCell());
2451 0 : ContainerEvent aEvt;
2452 0 : aEvt.Source = (XContainer*)this;
2453 0 : aEvt.Accessor <<= _nIndex;
2454 0 : aEvt.Element <<= xControl;
2455 :
2456 0 : m_aContainerListeners.notifyEach( &XContainerListener::elementRemoved, aEvt );
2457 0 : }
2458 :
2459 :
2460 21 : void FmXGridPeer::draw( sal_Int32 x, sal_Int32 y ) throw( RuntimeException, std::exception )
2461 : {
2462 21 : FmGridControl* pGrid = static_cast<FmGridControl*>(GetWindow());
2463 21 : sal_Int32 nOldFlags = pGrid->GetBrowserFlags();
2464 21 : pGrid->SetBrowserFlags(nOldFlags | EBBF_NOROWPICTURE);
2465 :
2466 21 : VCLXWindow::draw(x, y);
2467 :
2468 21 : pGrid->SetBrowserFlags(nOldFlags);
2469 21 : }
2470 :
2471 :
2472 42 : 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 )
2473 : {
2474 42 : Reference< ::com::sun::star::frame::XDispatch > xResult;
2475 :
2476 : // first ask our interceptor chain
2477 42 : if (m_xFirstDispatchInterceptor.is() && !m_bInterceptingDispatch)
2478 : {
2479 16 : m_bInterceptingDispatch = true;
2480 : // safety against recursion : as we are master of the first chain element and slave of the last one we would
2481 : // have an infinite loop without this if no dispatcher can fullfill the request
2482 16 : xResult = m_xFirstDispatchInterceptor->queryDispatch(aURL, aTargetFrameName, nSearchFlags);
2483 16 : m_bInterceptingDispatch = false;
2484 : }
2485 :
2486 : // then ask ourself : we don't have any dispatches
2487 42 : return xResult;
2488 : }
2489 :
2490 :
2491 0 : Sequence< Reference< ::com::sun::star::frame::XDispatch > > FmXGridPeer::queryDispatches(const Sequence< ::com::sun::star::frame::DispatchDescriptor>& aDescripts) throw( RuntimeException, std::exception )
2492 : {
2493 0 : if (m_xFirstDispatchInterceptor.is())
2494 0 : return m_xFirstDispatchInterceptor->queryDispatches(aDescripts);
2495 :
2496 : // then ask ourself : we don't have any dispatches
2497 0 : return Sequence< Reference< ::com::sun::star::frame::XDispatch > >();
2498 : }
2499 :
2500 :
2501 2 : void FmXGridPeer::registerDispatchProviderInterceptor(const Reference< ::com::sun::star::frame::XDispatchProviderInterceptor >& _xInterceptor) throw( RuntimeException, std::exception )
2502 : {
2503 2 : if (_xInterceptor.is())
2504 : {
2505 2 : if (m_xFirstDispatchInterceptor.is())
2506 : {
2507 0 : Reference< ::com::sun::star::frame::XDispatchProvider > xFirstProvider(m_xFirstDispatchInterceptor, UNO_QUERY);
2508 : // there is already an interceptor; the new one will become its master
2509 0 : _xInterceptor->setSlaveDispatchProvider(xFirstProvider);
2510 0 : m_xFirstDispatchInterceptor->setMasterDispatchProvider(xFirstProvider);
2511 : }
2512 : else
2513 : {
2514 : // it is the first interceptor; set ourself as slave
2515 2 : _xInterceptor->setSlaveDispatchProvider((::com::sun::star::frame::XDispatchProvider*)this);
2516 : }
2517 :
2518 : // we are the master of the chain's first interceptor
2519 2 : m_xFirstDispatchInterceptor = _xInterceptor;
2520 2 : m_xFirstDispatchInterceptor->setMasterDispatchProvider((::com::sun::star::frame::XDispatchProvider*)this);
2521 :
2522 : // we have a new interceptor and we're alive ?
2523 2 : if (!isDesignMode())
2524 : // -> check for new dispatchers
2525 0 : UpdateDispatches();
2526 : }
2527 2 : }
2528 :
2529 :
2530 2 : void FmXGridPeer::releaseDispatchProviderInterceptor(const Reference< ::com::sun::star::frame::XDispatchProviderInterceptor >& _xInterceptor) throw( RuntimeException, std::exception )
2531 : {
2532 2 : if (!_xInterceptor.is())
2533 2 : return;
2534 :
2535 2 : Reference< ::com::sun::star::frame::XDispatchProviderInterceptor > xChainWalk(m_xFirstDispatchInterceptor);
2536 :
2537 2 : if (m_xFirstDispatchInterceptor == _xInterceptor)
2538 : { // our chain will have a new first element
2539 2 : Reference< ::com::sun::star::frame::XDispatchProviderInterceptor > xSlave(m_xFirstDispatchInterceptor->getSlaveDispatchProvider(), UNO_QUERY);
2540 2 : m_xFirstDispatchInterceptor = xSlave;
2541 : }
2542 : // do this before removing the interceptor from the chain as we won't know it's slave afterwards)
2543 :
2544 6 : while (xChainWalk.is())
2545 : {
2546 : // walk along the chain of interceptors and look for the interceptor that has to be removed
2547 2 : Reference< ::com::sun::star::frame::XDispatchProviderInterceptor > xSlave(xChainWalk->getSlaveDispatchProvider(), UNO_QUERY);
2548 :
2549 2 : if (xChainWalk == _xInterceptor)
2550 : {
2551 : // old master may be an interceptor too
2552 2 : Reference< ::com::sun::star::frame::XDispatchProviderInterceptor > xMaster(xChainWalk->getMasterDispatchProvider(), UNO_QUERY);
2553 :
2554 : // unchain the interceptor that has to be removed
2555 2 : xChainWalk->setSlaveDispatchProvider(Reference< ::com::sun::star::frame::XDispatchProvider > ());
2556 2 : xChainWalk->setMasterDispatchProvider(Reference< ::com::sun::star::frame::XDispatchProvider > ());
2557 :
2558 : // reconnect the chain
2559 2 : if (xMaster.is())
2560 : {
2561 0 : if (xSlave.is())
2562 0 : xMaster->setSlaveDispatchProvider(Reference< ::com::sun::star::frame::XDispatchProvider >::query(xSlave));
2563 : else
2564 : // it's the first interceptor of the chain, set ourself as slave
2565 0 : xMaster->setSlaveDispatchProvider((::com::sun::star::frame::XDispatchProvider*)this);
2566 : }
2567 : else
2568 : {
2569 : // the chain's first element was removed, set ourself as new master of the second one
2570 2 : if (xSlave.is())
2571 0 : xSlave->setMasterDispatchProvider((::com::sun::star::frame::XDispatchProvider*)this);
2572 2 : }
2573 : }
2574 :
2575 2 : xChainWalk = xSlave;
2576 2 : }
2577 : // our interceptor chain has changed and we're alive ?
2578 2 : if (!isDesignMode())
2579 : // -> check the dispatchers
2580 2 : UpdateDispatches();
2581 : }
2582 :
2583 :
2584 20 : void FmXGridPeer::statusChanged(const ::com::sun::star::frame::FeatureStateEvent& Event) throw( RuntimeException, std::exception )
2585 : {
2586 : DBG_ASSERT(m_pStateCache, "FmXGridPeer::statusChanged : invalid call !");
2587 : DBG_ASSERT(m_pDispatchers, "FmXGridPeer::statusChanged : invalid call !");
2588 :
2589 20 : Sequence< ::com::sun::star::util::URL>& aUrls = getSupportedURLs();
2590 20 : const ::com::sun::star::util::URL* pUrls = aUrls.getConstArray();
2591 :
2592 20 : Sequence<sal_uInt16> aSlots = getSupportedGridSlots();
2593 20 : const sal_uInt16* pSlots = aSlots.getConstArray();
2594 :
2595 : sal_uInt16 i;
2596 120 : for (i=0; i<aUrls.getLength(); ++i, ++pUrls, ++pSlots)
2597 : {
2598 120 : if (pUrls->Main == Event.FeatureURL.Main)
2599 : {
2600 : DBG_ASSERT(m_pDispatchers[i] == Event.Source, "FmXGridPeer::statusChanged : the event source is a little bit suspect !");
2601 20 : m_pStateCache[i] = Event.IsEnabled;
2602 20 : FmGridControl* pGrid = static_cast<FmGridControl*>( GetWindow() );
2603 20 : if (*pSlots != SID_FM_RECORD_UNDO)
2604 0 : pGrid->GetNavigationBar().InvalidateState(*pSlots);
2605 20 : break;
2606 : }
2607 : }
2608 20 : DBG_ASSERT(i<aUrls.getLength(), "FmXGridPeer::statusChanged : got a call for an unknown url !");
2609 20 : }
2610 :
2611 :
2612 4 : sal_Bool FmXGridPeer::approveReset(const EventObject& /*rEvent*/) throw( RuntimeException, std::exception )
2613 : {
2614 4 : return sal_True;
2615 : }
2616 :
2617 :
2618 0 : sal_Bool SAL_CALL FmXGridPeer::select( const Any& _rSelection ) throw (IllegalArgumentException, RuntimeException, std::exception)
2619 : {
2620 0 : Sequence< Any > aBookmarks;
2621 0 : if ( !( _rSelection >>= aBookmarks ) )
2622 0 : throw IllegalArgumentException();
2623 :
2624 0 : FmGridControl* pVclControl = static_cast<FmGridControl*>(GetWindow());
2625 0 : return pVclControl->selectBookmarks(aBookmarks);
2626 :
2627 : // TODO:
2628 : // speaking strictly, we would have to adjust our model, as our ColumnSelection may have changed.
2629 : // Our model is a XSelectionSupplier, too, it handles the selection of single columns.
2630 : // This is somewhat strange, as selection should be a view (not a model) aspect.
2631 : // So for a clean solution, we should handle column selection ourself, and the model shouldn't
2632 : // deal with selection at all.
2633 : }
2634 :
2635 :
2636 0 : Any SAL_CALL FmXGridPeer::getSelection( ) throw (RuntimeException, std::exception)
2637 : {
2638 0 : FmGridControl* pVclControl = static_cast<FmGridControl*>(GetWindow());
2639 0 : Sequence< Any > aSelectionBookmarks = pVclControl->getSelectionBookmarks();
2640 0 : return makeAny(aSelectionBookmarks);
2641 : }
2642 :
2643 :
2644 0 : void SAL_CALL FmXGridPeer::addSelectionChangeListener( const Reference< XSelectionChangeListener >& _rxListener ) throw (RuntimeException, std::exception)
2645 : {
2646 0 : m_aSelectionListeners.addInterface( _rxListener );
2647 0 : }
2648 :
2649 :
2650 0 : void SAL_CALL FmXGridPeer::removeSelectionChangeListener( const Reference< XSelectionChangeListener >& _rxListener ) throw (RuntimeException, std::exception)
2651 : {
2652 0 : m_aSelectionListeners.removeInterface( _rxListener );
2653 0 : }
2654 :
2655 :
2656 4 : void FmXGridPeer::resetted(const EventObject& rEvent) throw( RuntimeException, std::exception )
2657 : {
2658 4 : if (m_xColumns == rEvent.Source)
2659 : { // my model was reset -> refresh the grid content
2660 4 : FmGridControl* pGrid = static_cast<FmGridControl*>(GetWindow());
2661 4 : if (!pGrid)
2662 4 : return;
2663 4 : SolarMutexGuard aGuard;
2664 4 : pGrid->resetCurrentRow();
2665 : }
2666 : // if the cursor fired a reset event we seem to be on the insert row
2667 0 : else if (m_xCursor == rEvent.Source)
2668 : {
2669 0 : SolarMutexGuard aGuard;
2670 0 : FmGridControl* pGrid = static_cast<FmGridControl*>(GetWindow());
2671 0 : if (pGrid && pGrid->IsOpen())
2672 0 : pGrid->positioned(rEvent);
2673 : }
2674 : }
2675 :
2676 :
2677 20 : Sequence<sal_uInt16>& FmXGridPeer::getSupportedGridSlots()
2678 : {
2679 20 : static Sequence<sal_uInt16> aSupported;
2680 20 : if (aSupported.getLength() == 0)
2681 : {
2682 : sal_uInt16 nSupported[] = {
2683 : DbGridControl::NavigationBar::RECORD_FIRST,
2684 : DbGridControl::NavigationBar::RECORD_PREV,
2685 : DbGridControl::NavigationBar::RECORD_NEXT,
2686 : DbGridControl::NavigationBar::RECORD_LAST,
2687 : DbGridControl::NavigationBar::RECORD_NEW,
2688 : SID_FM_RECORD_UNDO
2689 2 : };
2690 2 : aSupported.realloc(sizeof(nSupported)/sizeof(nSupported[0]));
2691 2 : sal_uInt16* pSupported = aSupported.getArray();
2692 14 : for (sal_uInt16 i=0; i<aSupported.getLength(); ++i, ++pSupported)
2693 12 : *pSupported = nSupported[i];
2694 : }
2695 20 : return aSupported;
2696 : }
2697 :
2698 :
2699 67 : Sequence< ::com::sun::star::util::URL>& FmXGridPeer::getSupportedURLs()
2700 : {
2701 67 : static Sequence< ::com::sun::star::util::URL> aSupported;
2702 67 : if (aSupported.getLength() == 0)
2703 : {
2704 : static const OUString sSupported[] = {
2705 : FMURL_RECORD_MOVEFIRST,
2706 : FMURL_RECORD_MOVEPREV,
2707 : FMURL_RECORD_MOVENEXT,
2708 : FMURL_RECORD_MOVELAST,
2709 : FMURL_RECORD_MOVETONEW,
2710 : FMURL_RECORD_UNDO
2711 8 : };
2712 4 : aSupported.realloc(sizeof(sSupported)/sizeof(sSupported[0]));
2713 4 : ::com::sun::star::util::URL* pSupported = aSupported.getArray();
2714 : sal_uInt16 i;
2715 :
2716 28 : for ( i = 0; i < aSupported.getLength(); ++i, ++pSupported)
2717 24 : pSupported->Complete = sSupported[i];
2718 :
2719 : // let an ::com::sun::star::util::URL-transformer normalize the URLs
2720 : Reference< ::com::sun::star::util::XURLTransformer > xTransformer(
2721 4 : util::URLTransformer::create(::comphelper::getProcessComponentContext()) );
2722 4 : pSupported = aSupported.getArray();
2723 28 : for (i=0; i<aSupported.getLength(); ++i)
2724 28 : xTransformer->parseStrict(pSupported[i]);
2725 : }
2726 :
2727 67 : return aSupported;
2728 : }
2729 :
2730 :
2731 4 : void FmXGridPeer::UpdateDispatches()
2732 : {
2733 4 : if (!m_pStateCache)
2734 : { // we don't have any dispatchers yet -> do the initial connect
2735 2 : ConnectToDispatcher();
2736 6 : return;
2737 : }
2738 :
2739 2 : sal_uInt16 nDispatchersGot = 0;
2740 2 : const Sequence< ::com::sun::star::util::URL>& aSupportedURLs = getSupportedURLs();
2741 2 : const ::com::sun::star::util::URL* pSupportedURLs = aSupportedURLs.getConstArray();
2742 2 : Reference< ::com::sun::star::frame::XDispatch > xNewDispatch;
2743 14 : for (sal_uInt16 i=0; i<aSupportedURLs.getLength(); ++i, ++pSupportedURLs)
2744 : {
2745 12 : xNewDispatch = queryDispatch(*pSupportedURLs, OUString(), 0);
2746 12 : if (xNewDispatch != m_pDispatchers[i])
2747 : {
2748 0 : if (m_pDispatchers[i].is())
2749 0 : m_pDispatchers[i]->removeStatusListener((::com::sun::star::frame::XStatusListener*)this, *pSupportedURLs);
2750 0 : m_pDispatchers[i] = xNewDispatch;
2751 0 : if (m_pDispatchers[i].is())
2752 0 : m_pDispatchers[i]->addStatusListener((::com::sun::star::frame::XStatusListener*)this, *pSupportedURLs);
2753 : }
2754 12 : if (m_pDispatchers[i].is())
2755 0 : ++nDispatchersGot;
2756 : }
2757 :
2758 2 : if (!nDispatchersGot)
2759 : {
2760 2 : delete[] m_pStateCache;
2761 2 : delete[] m_pDispatchers;
2762 2 : m_pStateCache = NULL;
2763 2 : m_pDispatchers = NULL;
2764 2 : }
2765 : }
2766 :
2767 :
2768 2 : void FmXGridPeer::ConnectToDispatcher()
2769 : {
2770 : DBG_ASSERT((m_pStateCache != NULL) == (m_pDispatchers != NULL), "FmXGridPeer::ConnectToDispatcher : inconsistent !");
2771 2 : if (m_pStateCache)
2772 : { // already connected -> just do an update
2773 0 : UpdateDispatches();
2774 2 : return;
2775 : }
2776 :
2777 2 : const Sequence< ::com::sun::star::util::URL>& aSupportedURLs = getSupportedURLs();
2778 :
2779 : // _before_ adding the status listeners (as the add should result in a statusChanged-call) !
2780 2 : m_pStateCache = new bool[aSupportedURLs.getLength()];
2781 2 : m_pDispatchers = new Reference< ::com::sun::star::frame::XDispatch > [aSupportedURLs.getLength()];
2782 :
2783 2 : sal_uInt16 nDispatchersGot = 0;
2784 2 : const ::com::sun::star::util::URL* pSupportedURLs = aSupportedURLs.getConstArray();
2785 14 : for (sal_uInt16 i=0; i<aSupportedURLs.getLength(); ++i, ++pSupportedURLs)
2786 : {
2787 12 : m_pStateCache[i] = false;
2788 12 : m_pDispatchers[i] = queryDispatch(*pSupportedURLs, OUString(), 0);
2789 12 : if (m_pDispatchers[i].is())
2790 : {
2791 2 : m_pDispatchers[i]->addStatusListener((::com::sun::star::frame::XStatusListener*)this, *pSupportedURLs);
2792 2 : ++nDispatchersGot;
2793 : }
2794 : }
2795 :
2796 2 : if (!nDispatchersGot)
2797 : {
2798 0 : delete[] m_pStateCache;
2799 0 : delete[] m_pDispatchers;
2800 0 : m_pStateCache = NULL;
2801 0 : m_pDispatchers = NULL;
2802 : }
2803 : }
2804 :
2805 :
2806 144 : void FmXGridPeer::DisConnectFromDispatcher()
2807 : {
2808 144 : if (!m_pStateCache || !m_pDispatchers)
2809 288 : return;
2810 : // we're not connected
2811 :
2812 0 : const Sequence< ::com::sun::star::util::URL>& aSupportedURLs = getSupportedURLs();
2813 0 : const ::com::sun::star::util::URL* pSupportedURLs = aSupportedURLs.getConstArray();
2814 0 : for (sal_uInt16 i=0; i<aSupportedURLs.getLength(); ++i, ++pSupportedURLs)
2815 : {
2816 0 : if (m_pDispatchers[i].is())
2817 0 : m_pDispatchers[i]->removeStatusListener((::com::sun::star::frame::XStatusListener*)this, *pSupportedURLs);
2818 : }
2819 :
2820 0 : delete[] m_pStateCache;
2821 0 : delete[] m_pDispatchers;
2822 0 : m_pStateCache = NULL;
2823 0 : m_pDispatchers = NULL;
2824 : }
2825 :
2826 :
2827 36 : IMPL_LINK(FmXGridPeer, OnQueryGridSlotState, void*, pSlot)
2828 : {
2829 18 : if (!m_pStateCache)
2830 18 : return -1; // unspecified
2831 :
2832 0 : sal_uInt16 nSlot = (sal_uInt16)reinterpret_cast<sal_uIntPtr>(pSlot);
2833 :
2834 : // search the given slot with our supported sequence
2835 0 : Sequence<sal_uInt16>& aSupported = getSupportedGridSlots();
2836 0 : const sal_uInt16* pSlots = aSupported.getConstArray();
2837 0 : for (sal_uInt16 i=0; i<aSupported.getLength(); ++i)
2838 : {
2839 0 : if (pSlots[i] == nSlot)
2840 : {
2841 0 : if (!m_pDispatchers[i].is())
2842 0 : return -1; // nothing known about this slot
2843 : else
2844 0 : return m_pStateCache[i] ? 1 : 0;
2845 : }
2846 : }
2847 :
2848 0 : return -1;
2849 : }
2850 :
2851 :
2852 0 : IMPL_LINK(FmXGridPeer, OnExecuteGridSlot, void*, pSlot)
2853 : {
2854 0 : if (!m_pDispatchers)
2855 0 : return 0; // not handled
2856 :
2857 0 : Sequence< ::com::sun::star::util::URL>& aUrls = getSupportedURLs();
2858 0 : const ::com::sun::star::util::URL* pUrls = aUrls.getConstArray();
2859 :
2860 0 : Sequence<sal_uInt16> aSlots = getSupportedGridSlots();
2861 0 : const sal_uInt16* pSlots = aSlots.getConstArray();
2862 :
2863 : DBG_ASSERT(aSlots.getLength() == aUrls.getLength(), "FmXGridPeer::OnExecuteGridSlot : inconstent data returned by getSupportedURLs/getSupportedGridSlots !");
2864 :
2865 0 : sal_uInt16 nSlot = (sal_uInt16)reinterpret_cast<sal_uIntPtr>(pSlot);
2866 0 : for (sal_uInt16 i=0; i<aSlots.getLength(); ++i, ++pUrls, ++pSlots)
2867 : {
2868 0 : if (*pSlots == nSlot)
2869 : {
2870 0 : if (m_pDispatchers[i].is())
2871 : {
2872 : // commit any changes done so far, if it's not the undoRecord URL
2873 0 : if ( pUrls->Complete == FMURL_RECORD_UNDO || commit() )
2874 0 : m_pDispatchers[i]->dispatch(*pUrls, Sequence< PropertyValue>());
2875 :
2876 0 : return 1; // handled
2877 : }
2878 : }
2879 : }
2880 :
2881 0 : return 0; // not handled
2882 651 : }
2883 :
2884 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|