bump product version to 5.0.4.1
[LibreOffice.git] / forms / source / component / Grid.cxx
blob6b7409240dc649df9f96b8b3cadfea6bf6456c4d
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <config_features.h>
22 #include "Columns.hxx"
23 #include "findpos.hxx"
24 #include "Grid.hxx"
25 #include "property.hrc"
26 #include "property.hxx"
27 #include "services.hxx"
28 #include <com/sun/star/form/FormComponentType.hpp>
29 #include <com/sun/star/form/XForm.hpp>
30 #include <com/sun/star/form/XLoadable.hpp>
31 #include <com/sun/star/text/WritingMode2.hpp>
32 #include <comphelper/basicio.hxx>
33 #include <comphelper/container.hxx>
34 #include <comphelper/processfactory.hxx>
35 #include <cppuhelper/queryinterface.hxx>
36 #include <toolkit/helper/vclunohelper.hxx>
37 #include <vcl/svapp.hxx>
39 using namespace ::com::sun::star::uno;
41 namespace frm
43 using namespace ::com::sun::star;
44 using namespace ::com::sun::star::uno;
45 using namespace ::com::sun::star::sdb;
46 using namespace ::com::sun::star::sdbc;
47 using namespace ::com::sun::star::sdbcx;
48 using namespace ::com::sun::star::beans;
49 using namespace ::com::sun::star::container;
50 using namespace ::com::sun::star::form;
51 using namespace ::com::sun::star::awt;
52 using namespace ::com::sun::star::io;
53 using namespace ::com::sun::star::lang;
54 using namespace ::com::sun::star::util;
55 using namespace ::com::sun::star::view;
56 namespace WritingMode2 = ::com::sun::star::text::WritingMode2;
57 const sal_uInt16 ROWHEIGHT = 0x0001;
58 const sal_uInt16 FONTTYPE = 0x0002;
59 const sal_uInt16 FONTSIZE = 0x0004;
60 const sal_uInt16 FONTATTRIBS = 0x0008;
61 const sal_uInt16 TABSTOP = 0x0010;
62 const sal_uInt16 TEXTCOLOR = 0x0020;
63 const sal_uInt16 FONTDESCRIPTOR = 0x0040;
64 const sal_uInt16 RECORDMARKER = 0x0080;
65 const sal_uInt16 BACKGROUNDCOLOR = 0x0100;
67 OGridControlModel::OGridControlModel(const Reference<XComponentContext>& _rxFactory)
68 :OControlModel(_rxFactory, OUString())
69 ,OInterfaceContainer(_rxFactory, m_aMutex, cppu::UnoType<XPropertySet>::get())
70 ,OErrorBroadcaster( OComponentHelper::rBHelper )
71 ,FontControlModel( false )
72 ,m_aSelectListeners(m_aMutex)
73 ,m_aResetListeners(m_aMutex)
74 ,m_aRowSetChangeListeners(m_aMutex)
75 ,m_aDefaultControl( FRM_SUN_CONTROL_GRIDCONTROL )
76 ,m_nBorder(1)
77 ,m_nWritingMode( WritingMode2::CONTEXT )
78 ,m_nContextWritingMode( WritingMode2::CONTEXT )
79 ,m_bEnableVisible(true)
80 ,m_bEnable(true)
81 ,m_bNavigation(true)
82 ,m_bRecordMarker(true)
83 ,m_bPrintable(true)
84 ,m_bAlwaysShowCursor(false)
85 ,m_bDisplaySynchron(true)
87 m_nClassId = FormComponentType::GRIDCONTROL;
90 OGridControlModel::OGridControlModel( const OGridControlModel* _pOriginal, const Reference< XComponentContext >& _rxFactory )
91 :OControlModel( _pOriginal, _rxFactory )
92 ,OInterfaceContainer( _rxFactory, m_aMutex, cppu::UnoType<XPropertySet>::get() )
93 ,OErrorBroadcaster( OComponentHelper::rBHelper )
94 ,FontControlModel( _pOriginal )
95 ,m_aSelectListeners( m_aMutex )
96 ,m_aResetListeners( m_aMutex )
97 ,m_aRowSetChangeListeners( m_aMutex )
99 m_aDefaultControl = _pOriginal->m_aDefaultControl;
100 m_bEnable = _pOriginal->m_bEnable;
101 m_bEnableVisible = _pOriginal->m_bEnableVisible;
102 m_bNavigation = _pOriginal->m_bNavigation;
103 m_nBorder = _pOriginal->m_nBorder;
104 m_nWritingMode = _pOriginal->m_nWritingMode;
105 m_nContextWritingMode = _pOriginal->m_nContextWritingMode;
106 m_bRecordMarker = _pOriginal->m_bRecordMarker;
107 m_bPrintable = _pOriginal->m_bPrintable;
108 m_bAlwaysShowCursor = _pOriginal->m_bAlwaysShowCursor;
109 m_bDisplaySynchron = _pOriginal->m_bDisplaySynchron;
110 // clone the columns
111 cloneColumns( _pOriginal );
112 // TODO: clone the events?
115 OGridControlModel::~OGridControlModel()
117 if (!OComponentHelper::rBHelper.bDisposed)
119 acquire();
120 dispose();
124 // XCloneable
125 Reference< XCloneable > SAL_CALL OGridControlModel::createClone( ) throw (RuntimeException, std::exception)
127 OGridControlModel* pClone = new OGridControlModel( this, getContext() );
128 osl_atomic_increment( &pClone->m_refCount );
129 pClone->OControlModel::clonedFrom( this );
130 // do not call OInterfaceContainer::clonedFrom, it would clone the elements aka columns, which is
131 // already done in the ctor
132 //pClone->OInterfaceContainer::clonedFrom( *this );
133 osl_atomic_decrement( &pClone->m_refCount );
134 return static_cast< XCloneable* >( static_cast< OControlModel* >( pClone ) );
137 void OGridControlModel::cloneColumns( const OGridControlModel* _pOriginalContainer )
141 Reference< XCloneable > xColCloneable;
142 const OInterfaceArray::const_iterator pColumnStart = _pOriginalContainer->m_aItems.begin();
143 const OInterfaceArray::const_iterator pColumnEnd = _pOriginalContainer->m_aItems.end();
144 for ( OInterfaceArray::const_iterator pColumn = pColumnStart; pColumn != pColumnEnd; ++pColumn )
146 // ask the col for a factory for the clone
147 xColCloneable.set(*pColumn, css::uno::UNO_QUERY);
148 DBG_ASSERT( xColCloneable.is(), "OGridControlModel::cloneColumns: column is not cloneable!" );
149 if ( xColCloneable.is() )
151 // create a clone of the column
152 Reference< XCloneable > xColClone( xColCloneable->createClone() );
153 DBG_ASSERT( xColClone.is(), "OGridControlModel::cloneColumns: invalid column clone!" );
154 if ( xColClone.is() )
156 // insert this clone into our own container
157 insertByIndex( pColumn - pColumnStart, xColClone->queryInterface( m_aElementType ) );
162 catch( const Exception& )
164 OSL_FAIL( "OGridControlModel::cloneColumns: caught an exception while cloning the columns!" );
168 // XServiceInfo
169 StringSequence OGridControlModel::getSupportedServiceNames() throw(RuntimeException, std::exception)
171 StringSequence aSupported = OControlModel::getSupportedServiceNames();
172 aSupported.realloc(aSupported.getLength() + 4);
173 aSupported[aSupported.getLength()-4] = "com.sun.star.awt.UnoControlModel";
174 aSupported[aSupported.getLength()-3] = FRM_SUN_COMPONENT_GRIDCONTROL;
175 aSupported[aSupported.getLength()-2] = FRM_COMPONENT_GRID;
176 aSupported[aSupported.getLength()-1] = FRM_COMPONENT_GRIDCONTROL;
177 return aSupported;
179 Any SAL_CALL OGridControlModel::queryAggregation( const Type& _rType ) throw (RuntimeException, std::exception)
181 Any aReturn = OGridControlModel_BASE::queryInterface(_rType);
182 if ( !aReturn.hasValue() )
184 aReturn = OControlModel::queryAggregation( _rType );
185 if ( !aReturn.hasValue() )
187 aReturn = OInterfaceContainer::queryInterface( _rType );
188 if ( !aReturn.hasValue() )
189 aReturn = OErrorBroadcaster::queryInterface( _rType );
192 return aReturn;
195 #if HAVE_FEATURE_DBCONNECTIVITY
197 // XSQLErrorListener
198 void SAL_CALL OGridControlModel::errorOccured( const SQLErrorEvent& _rEvent ) throw (RuntimeException, std::exception)
200 // forward the errors which happened to my columns to my own listeners
201 onError( _rEvent );
203 #endif
205 // XRowSetSupplier
206 Reference< XRowSet > SAL_CALL OGridControlModel::getRowSet( ) throw (RuntimeException, std::exception)
208 return Reference< XRowSet >( getParent(), UNO_QUERY );
211 void SAL_CALL OGridControlModel::setRowSet( const Reference< XRowSet >& /*_rxDataSource*/ ) throw (RuntimeException, std::exception)
213 OSL_FAIL( "OGridControlModel::setRowSet: not supported!" );
216 void SAL_CALL OGridControlModel::addRowSetChangeListener( const Reference< XRowSetChangeListener >& i_Listener ) throw (RuntimeException, std::exception)
218 if ( i_Listener.is() )
219 m_aRowSetChangeListeners.addInterface( i_Listener );
222 void SAL_CALL OGridControlModel::removeRowSetChangeListener( const Reference< XRowSetChangeListener >& i_Listener ) throw (RuntimeException, std::exception)
224 m_aRowSetChangeListeners.removeInterface( i_Listener );
227 // XChild
228 void SAL_CALL OGridControlModel::setParent( const InterfaceRef& i_Parent ) throw(NoSupportException, RuntimeException, std::exception)
230 ::osl::ClearableMutexGuard aGuard( m_aMutex );
231 if ( i_Parent == getParent() )
232 return;
233 OControlModel::setParent( i_Parent );
234 EventObject aEvent( *this );
235 aGuard.clear();
236 m_aRowSetChangeListeners.notifyEach( &XRowSetChangeListener::onRowSetChanged, aEvent );
238 Sequence< Type > SAL_CALL OGridControlModel::getTypes( ) throw(RuntimeException, std::exception)
240 return concatSequences(
241 concatSequences(
242 OControlModel::getTypes(),
243 OInterfaceContainer::getTypes(),
244 OErrorBroadcaster::getTypes()
246 OGridControlModel_BASE::getTypes()
250 // OComponentHelper
251 void OGridControlModel::disposing()
253 OControlModel::disposing();
254 OErrorBroadcaster::disposing();
255 OInterfaceContainer::disposing();
256 setParent(NULL);
257 EventObject aEvt(static_cast<XWeak*>(this));
258 m_aSelectListeners.disposeAndClear(aEvt);
259 m_aResetListeners.disposeAndClear(aEvt);
260 m_aRowSetChangeListeners.disposeAndClear(aEvt);
263 // XEventListener
264 void OGridControlModel::disposing(const EventObject& _rEvent) throw( RuntimeException, std::exception )
266 OControlModel::disposing( _rEvent );
267 OInterfaceContainer::disposing( _rEvent );
270 // XSelectionSupplier
271 sal_Bool SAL_CALL OGridControlModel::select(const Any& rElement) throw(IllegalArgumentException, RuntimeException, std::exception)
273 ::osl::ClearableMutexGuard aGuard( m_aMutex );
274 Reference<XPropertySet> xSel;
275 if (rElement.hasValue())
277 xSel.set(rElement, css::uno::UNO_QUERY);
278 if (!xSel.is())
280 throw IllegalArgumentException();
283 InterfaceRef xMe = static_cast<XWeak*>(this);
284 if (xSel.is())
286 Reference<XChild> xAsChild(xSel, UNO_QUERY);
287 if (!xAsChild.is() || (xAsChild->getParent() != xMe))
289 throw IllegalArgumentException();
292 if ( xSel != m_xSelection )
294 m_xSelection = xSel;
295 aGuard.clear();
296 m_aSelectListeners.notifyEach( &XSelectionChangeListener::selectionChanged, EventObject( *this ) );
297 return sal_True;
299 return sal_False;
301 Any SAL_CALL OGridControlModel::getSelection() throw(RuntimeException, std::exception)
303 return makeAny(m_xSelection);
306 void OGridControlModel::addSelectionChangeListener(const Reference< XSelectionChangeListener >& _rxListener) throw( RuntimeException, std::exception )
308 m_aSelectListeners.addInterface(_rxListener);
311 void OGridControlModel::removeSelectionChangeListener(const Reference< XSelectionChangeListener >& _rxListener) throw( RuntimeException, std::exception )
313 m_aSelectListeners.removeInterface(_rxListener);
316 // XGridColumnFactory
317 Reference<XPropertySet> SAL_CALL OGridControlModel::createColumn(const OUString& ColumnType) throw ( :: com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException, std::exception)
319 SolarMutexGuard g;
320 const Sequence< OUString >& rColumnTypes = frm::getColumnTypes();
321 return createColumn( ::detail::findPos( ColumnType, rColumnTypes ) );
323 Reference<XPropertySet> OGridControlModel::createColumn(sal_Int32 nTypeId) const
325 Reference<XPropertySet> xReturn;
326 switch (nTypeId)
328 case TYPE_CHECKBOX: xReturn = new CheckBoxColumn( getContext() ); break;
329 case TYPE_COMBOBOX: xReturn = new ComboBoxColumn( getContext() ); break;
330 case TYPE_CURRENCYFIELD: xReturn = new CurrencyFieldColumn( getContext() ); break;
331 case TYPE_DATEFIELD: xReturn = new DateFieldColumn( getContext() ); break;
332 case TYPE_LISTBOX: xReturn = new ListBoxColumn( getContext() ); break;
333 case TYPE_NUMERICFIELD: xReturn = new NumericFieldColumn( getContext() ); break;
334 case TYPE_PATTERNFIELD: xReturn = new PatternFieldColumn( getContext() ); break;
335 case TYPE_TEXTFIELD: xReturn = new TextFieldColumn( getContext() ); break;
336 case TYPE_TIMEFIELD: xReturn = new TimeFieldColumn( getContext() ); break;
337 case TYPE_FORMATTEDFIELD: xReturn = new FormattedFieldColumn( getContext() ); break;
338 default:
339 OSL_FAIL("OGridControlModel::createColumn: Unknown Column");
340 break;
342 return xReturn;
344 StringSequence SAL_CALL OGridControlModel::getColumnTypes() throw ( ::com::sun::star::uno::RuntimeException, std::exception)
346 return frm::getColumnTypes();
349 // XReset
350 void SAL_CALL OGridControlModel::reset() throw ( ::com::sun::star::uno::RuntimeException, std::exception)
352 ::cppu::OInterfaceIteratorHelper aIter(m_aResetListeners);
353 EventObject aEvt(static_cast<XWeak*>(this));
354 bool bContinue = true;
355 while (aIter.hasMoreElements() && bContinue)
356 bContinue = static_cast<XResetListener*>(aIter.next())->approveReset(aEvt);
357 if (bContinue)
359 _reset();
360 m_aResetListeners.notifyEach( &XResetListener::resetted, aEvt );
363 void SAL_CALL OGridControlModel::addResetListener(const Reference<XResetListener>& _rxListener) throw ( ::com::sun::star::uno::RuntimeException, std::exception)
365 m_aResetListeners.addInterface(_rxListener);
367 void SAL_CALL OGridControlModel::removeResetListener(const Reference<XResetListener>& _rxListener) throw ( ::com::sun::star::uno::RuntimeException, std::exception)
369 m_aResetListeners.removeInterface(_rxListener);
371 void OGridControlModel::_reset()
373 Reference<XReset> xReset;
374 sal_Int32 nCount = getCount();
375 for (sal_Int32 nIndex=0; nIndex < nCount; nIndex++)
377 getByIndex( nIndex ) >>= xReset;
378 if (xReset.is())
379 xReset->reset();
383 // XPropertySet
384 void OGridControlModel::describeFixedProperties( Sequence< Property >& _rProps ) const
386 BEGIN_DESCRIBE_BASE_PROPERTIES( 37 )
387 DECL_PROP1(NAME, OUString, BOUND);
388 DECL_PROP2(CLASSID, sal_Int16, READONLY, TRANSIENT);
389 DECL_PROP1(TAG, OUString, BOUND);
390 DECL_PROP1(TABINDEX, sal_Int16, BOUND);
391 DECL_PROP3(TABSTOP, sal_Bool, BOUND, MAYBEDEFAULT, MAYBEVOID);
392 DECL_PROP2(HASNAVIGATION, sal_Bool, BOUND, MAYBEDEFAULT);
393 DECL_PROP1(ENABLED, sal_Bool, BOUND);
394 DECL_PROP2(ENABLEVISIBLE, sal_Bool, BOUND, MAYBEDEFAULT);
395 DECL_PROP1(BORDER, sal_Int16, BOUND);
396 DECL_PROP2(BORDERCOLOR, sal_Int16, BOUND, MAYBEVOID);
397 DECL_PROP1(DEFAULTCONTROL, OUString, BOUND);
398 DECL_PROP3(TEXTCOLOR, sal_Int32, BOUND, MAYBEDEFAULT, MAYBEVOID);
399 DECL_PROP3(BACKGROUNDCOLOR, sal_Int32, BOUND, MAYBEDEFAULT, MAYBEVOID);
400 DECL_PROP2(FONT, FontDescriptor, BOUND, MAYBEDEFAULT);
401 DECL_PROP3(ROWHEIGHT, sal_Int32, BOUND, MAYBEDEFAULT, MAYBEVOID);
402 DECL_PROP1(HELPTEXT, OUString, BOUND);
403 DECL_PROP1(FONT_NAME, OUString, MAYBEDEFAULT);
404 DECL_PROP1(FONT_STYLENAME, OUString, MAYBEDEFAULT);
405 DECL_PROP1(FONT_FAMILY, sal_Int16, MAYBEDEFAULT);
406 DECL_PROP1(FONT_CHARSET, sal_Int16, MAYBEDEFAULT);
407 DECL_PROP1(FONT_HEIGHT, float, MAYBEDEFAULT);
408 DECL_PROP1(FONT_WEIGHT, float, MAYBEDEFAULT);
409 DECL_PROP1(FONT_SLANT, sal_Int16, MAYBEDEFAULT);
410 DECL_PROP1(FONT_UNDERLINE, sal_Int16, MAYBEDEFAULT);
411 DECL_BOOL_PROP1(FONT_WORDLINEMODE, MAYBEDEFAULT);
412 DECL_PROP3(TEXTLINECOLOR, sal_Int32, BOUND, MAYBEDEFAULT, MAYBEVOID);
413 DECL_PROP2(FONTEMPHASISMARK, sal_Int16, BOUND, MAYBEDEFAULT);
414 DECL_PROP2(FONTRELIEF, sal_Int16, BOUND, MAYBEDEFAULT);
415 DECL_PROP1(FONT_STRIKEOUT, sal_Int16, MAYBEDEFAULT);
416 DECL_PROP2(RECORDMARKER, sal_Bool, BOUND, MAYBEDEFAULT );
417 DECL_PROP2(PRINTABLE, sal_Bool, BOUND, MAYBEDEFAULT );
418 DECL_PROP4(CURSORCOLOR, sal_Int32, BOUND, MAYBEDEFAULT, MAYBEVOID , TRANSIENT);
419 DECL_PROP3(ALWAYSSHOWCURSOR, sal_Bool, BOUND, MAYBEDEFAULT, TRANSIENT);
420 DECL_PROP3(DISPLAYSYNCHRON, sal_Bool, BOUND, MAYBEDEFAULT, TRANSIENT);
421 DECL_PROP2(HELPURL, OUString, BOUND, MAYBEDEFAULT);
422 DECL_PROP2(WRITING_MODE, sal_Int16, BOUND, MAYBEDEFAULT);
423 DECL_PROP3(CONTEXT_WRITING_MODE,sal_Int16, BOUND, MAYBEDEFAULT, TRANSIENT);
424 END_DESCRIBE_PROPERTIES();
426 void OGridControlModel::getFastPropertyValue(Any& rValue, sal_Int32 nHandle ) const
428 switch (nHandle)
430 case PROPERTY_ID_CONTEXT_WRITING_MODE:
431 rValue <<= m_nContextWritingMode;
432 break;
433 case PROPERTY_ID_WRITING_MODE:
434 rValue <<= m_nWritingMode;
435 break;
436 case PROPERTY_ID_HELPTEXT:
437 rValue <<= m_sHelpText;
438 break;
439 case PROPERTY_ID_HELPURL:
440 rValue <<= m_sHelpURL;
441 break;
442 case PROPERTY_ID_DISPLAYSYNCHRON:
443 setBOOL(rValue, m_bDisplaySynchron);
444 break;
445 case PROPERTY_ID_ALWAYSSHOWCURSOR:
446 setBOOL(rValue, m_bAlwaysShowCursor);
447 break;
448 case PROPERTY_ID_CURSORCOLOR:
449 rValue = m_aCursorColor;
450 break;
451 case PROPERTY_ID_PRINTABLE:
452 setBOOL(rValue, m_bPrintable);
453 break;
454 case PROPERTY_ID_TABSTOP:
455 rValue = m_aTabStop;
456 break;
457 case PROPERTY_ID_HASNAVIGATION:
458 setBOOL(rValue, m_bNavigation);
459 break;
460 case PROPERTY_ID_RECORDMARKER:
461 setBOOL(rValue, m_bRecordMarker);
462 break;
463 case PROPERTY_ID_ENABLED:
464 setBOOL(rValue, m_bEnable);
465 break;
466 case PROPERTY_ID_ENABLEVISIBLE:
467 setBOOL(rValue, m_bEnableVisible);
468 break;
469 case PROPERTY_ID_BORDER:
470 rValue <<= (sal_Int16)m_nBorder;
471 break;
472 case PROPERTY_ID_BORDERCOLOR:
473 rValue <<= m_aBorderColor;
474 break;
475 case PROPERTY_ID_DEFAULTCONTROL:
476 rValue <<= m_aDefaultControl;
477 break;
478 case PROPERTY_ID_BACKGROUNDCOLOR:
479 rValue = m_aBackgroundColor;
480 break;
481 case PROPERTY_ID_ROWHEIGHT:
482 rValue = m_aRowHeight;
483 break;
484 default:
485 if ( isFontRelatedProperty( nHandle ) )
486 FontControlModel::getFastPropertyValue( rValue, nHandle );
487 else
488 OControlModel::getFastPropertyValue( rValue, nHandle );
491 sal_Bool OGridControlModel::convertFastPropertyValue( Any& rConvertedValue, Any& rOldValue,
492 sal_Int32 nHandle, const Any& rValue )throw( IllegalArgumentException )
494 bool bModified(false);
495 switch (nHandle)
497 case PROPERTY_ID_CONTEXT_WRITING_MODE:
498 bModified = tryPropertyValue( rConvertedValue, rOldValue, rValue, m_nContextWritingMode );
499 break;
500 case PROPERTY_ID_WRITING_MODE:
501 bModified = tryPropertyValue( rConvertedValue, rOldValue, rValue, m_nWritingMode );
502 break;
503 case PROPERTY_ID_HELPTEXT:
504 bModified = tryPropertyValue(rConvertedValue, rOldValue, rValue, m_sHelpText);
505 break;
506 case PROPERTY_ID_HELPURL:
507 bModified = tryPropertyValue(rConvertedValue, rOldValue, rValue, m_sHelpURL);
508 break;
509 case PROPERTY_ID_DISPLAYSYNCHRON:
510 bModified = tryPropertyValue(rConvertedValue, rOldValue, rValue, m_bDisplaySynchron);
511 break;
512 case PROPERTY_ID_ALWAYSSHOWCURSOR:
513 bModified = tryPropertyValue(rConvertedValue, rOldValue, rValue, m_bAlwaysShowCursor);
514 break;
515 case PROPERTY_ID_CURSORCOLOR:
516 if (!rValue.hasValue() || !m_aCursorColor.hasValue())
518 if (rValue.hasValue() && (TypeClass_LONG != rValue.getValueType().getTypeClass()))
520 throw IllegalArgumentException();
522 rOldValue = m_aCursorColor;
523 rConvertedValue = rValue;
524 bModified = (rOldValue.getValue() != rConvertedValue.getValue());
526 else
527 bModified = tryPropertyValue(rConvertedValue, rOldValue, rValue, getINT32(m_aCursorColor));
528 break;
529 case PROPERTY_ID_PRINTABLE:
530 bModified = tryPropertyValue(rConvertedValue, rOldValue, rValue, m_bPrintable);
531 break;
532 case PROPERTY_ID_TABSTOP:
533 bModified = tryPropertyValue(rConvertedValue, rOldValue, rValue, m_aTabStop, cppu::UnoType<bool>::get());
534 break;
535 case PROPERTY_ID_HASNAVIGATION:
536 bModified = tryPropertyValue(rConvertedValue, rOldValue, rValue, m_bNavigation);
537 break;
538 case PROPERTY_ID_RECORDMARKER:
539 bModified = tryPropertyValue(rConvertedValue, rOldValue, rValue, m_bRecordMarker);
540 break;
541 case PROPERTY_ID_ENABLED:
542 bModified = tryPropertyValue(rConvertedValue, rOldValue, rValue, m_bEnable);
543 break;
544 case PROPERTY_ID_ENABLEVISIBLE:
545 bModified = tryPropertyValue(rConvertedValue, rOldValue, rValue, m_bEnableVisible);
546 break;
547 case PROPERTY_ID_BORDER:
548 bModified = tryPropertyValue(rConvertedValue, rOldValue, rValue, m_nBorder);
549 break;
550 case PROPERTY_ID_BORDERCOLOR:
551 bModified = tryPropertyValue(rConvertedValue, rOldValue, rValue, m_aBorderColor, cppu::UnoType<sal_Int32>::get());
552 break;
553 case PROPERTY_ID_DEFAULTCONTROL:
554 bModified = tryPropertyValue(rConvertedValue, rOldValue, rValue, m_aDefaultControl);
555 break;
556 case PROPERTY_ID_BACKGROUNDCOLOR:
557 bModified = tryPropertyValue(rConvertedValue, rOldValue, rValue, m_aBackgroundColor, cppu::UnoType<sal_Int32>::get());
558 break;
559 case PROPERTY_ID_ROWHEIGHT:
561 bModified = tryPropertyValue(rConvertedValue, rOldValue, rValue, m_aRowHeight, cppu::UnoType<sal_Int32>::get());
562 sal_Int32 nNewVal( 0 );
563 if ( ( rConvertedValue >>= nNewVal ) && ( nNewVal <= 0 ) )
565 rConvertedValue.clear();
566 bModified = m_aRowHeight.hasValue();
569 break;
570 default:
571 if ( isFontRelatedProperty( nHandle ) )
572 bModified = FontControlModel::convertFastPropertyValue( rConvertedValue, rOldValue, nHandle, rValue );
573 else
574 bModified = OControlModel::convertFastPropertyValue( rConvertedValue, rOldValue, nHandle, rValue);
576 return bModified;
578 void OGridControlModel::setFastPropertyValue_NoBroadcast( sal_Int32 nHandle, const Any& rValue ) throw ( ::com::sun::star::uno::Exception, std::exception)
580 switch (nHandle)
582 case PROPERTY_ID_CONTEXT_WRITING_MODE:
583 rValue >>= m_nContextWritingMode;
584 break;
585 case PROPERTY_ID_WRITING_MODE:
586 rValue >>= m_nWritingMode;
587 break;
588 case PROPERTY_ID_HELPTEXT:
589 rValue >>= m_sHelpText;
590 break;
591 case PROPERTY_ID_HELPURL:
592 rValue >>= m_sHelpURL;
593 break;
594 case PROPERTY_ID_DISPLAYSYNCHRON:
595 m_bDisplaySynchron = getBOOL(rValue);
596 break;
597 case PROPERTY_ID_ALWAYSSHOWCURSOR:
598 m_bAlwaysShowCursor = getBOOL(rValue);
599 break;
600 case PROPERTY_ID_CURSORCOLOR:
601 m_aCursorColor = rValue;
602 break;
603 case PROPERTY_ID_PRINTABLE:
604 m_bPrintable = getBOOL(rValue);
605 break;
606 case PROPERTY_ID_TABSTOP:
607 m_aTabStop = rValue;
608 break;
609 case PROPERTY_ID_HASNAVIGATION:
610 m_bNavigation = getBOOL(rValue);
611 break;
612 case PROPERTY_ID_ENABLED:
613 m_bEnable = getBOOL(rValue);
614 break;
615 case PROPERTY_ID_ENABLEVISIBLE:
616 m_bEnableVisible = getBOOL(rValue);
617 break;
618 case PROPERTY_ID_RECORDMARKER:
619 m_bRecordMarker = getBOOL(rValue);
620 break;
621 case PROPERTY_ID_BORDER:
622 rValue >>= m_nBorder;
623 break;
624 case PROPERTY_ID_BORDERCOLOR:
625 m_aBorderColor = rValue;
626 break;
627 case PROPERTY_ID_DEFAULTCONTROL:
628 rValue >>= m_aDefaultControl;
629 break;
630 case PROPERTY_ID_BACKGROUNDCOLOR:
631 m_aBackgroundColor = rValue;
632 break;
633 case PROPERTY_ID_ROWHEIGHT:
634 m_aRowHeight = rValue;
635 break;
636 default:
637 if ( isFontRelatedProperty( nHandle ) )
639 FontControlModel::setFastPropertyValue_NoBroadcast_impl(
640 *this, &OGridControlModel::setDependentFastPropertyValue,
641 nHandle, rValue);
643 else
644 OControlModel::setFastPropertyValue_NoBroadcast( nHandle, rValue );
648 //XPropertyState
649 Any OGridControlModel::getPropertyDefaultByHandle( sal_Int32 nHandle ) const
651 Any aReturn;
652 switch (nHandle)
654 case PROPERTY_ID_CONTEXT_WRITING_MODE:
655 case PROPERTY_ID_WRITING_MODE:
656 aReturn <<= WritingMode2::CONTEXT;
657 break;
658 case PROPERTY_ID_DEFAULTCONTROL:
659 aReturn <<= OUString( STARDIV_ONE_FORM_CONTROL_GRID );
660 break;
661 case PROPERTY_ID_PRINTABLE:
662 case PROPERTY_ID_HASNAVIGATION:
663 case PROPERTY_ID_RECORDMARKER:
664 case PROPERTY_ID_DISPLAYSYNCHRON:
665 case PROPERTY_ID_ENABLED:
666 case PROPERTY_ID_ENABLEVISIBLE:
667 aReturn = makeBoolAny(true);
668 break;
669 case PROPERTY_ID_ALWAYSSHOWCURSOR:
670 aReturn = makeBoolAny(false);
671 break;
672 case PROPERTY_ID_HELPURL:
673 case PROPERTY_ID_HELPTEXT:
674 aReturn <<= OUString();
675 break;
676 case PROPERTY_ID_BORDER:
677 aReturn <<= (sal_Int16)1;
678 break;
679 case PROPERTY_ID_BORDERCOLOR:
680 case PROPERTY_ID_TABSTOP:
681 case PROPERTY_ID_BACKGROUNDCOLOR:
682 case PROPERTY_ID_ROWHEIGHT:
683 case PROPERTY_ID_CURSORCOLOR:
684 // void
685 break;
686 default:
687 if ( isFontRelatedProperty( nHandle ) )
688 aReturn = FontControlModel::getPropertyDefaultByHandle( nHandle );
689 else
690 aReturn = OControlModel::getPropertyDefaultByHandle(nHandle);
692 return aReturn;
695 OGridColumn* OGridControlModel::getColumnImplementation(const InterfaceRef& _rxIFace)
697 OGridColumn* pImplementation = NULL;
698 Reference< XUnoTunnel > xUnoTunnel( _rxIFace, UNO_QUERY );
699 if ( xUnoTunnel.is() )
700 pImplementation = reinterpret_cast<OGridColumn*>(xUnoTunnel->getSomething(OGridColumn::getUnoTunnelImplementationId()));
701 return pImplementation;
704 void OGridControlModel::gotColumn( const Reference< XInterface >& _rxColumn )
706 Reference< XSQLErrorBroadcaster > xBroadcaster( _rxColumn, UNO_QUERY );
707 if ( xBroadcaster.is() )
708 xBroadcaster->addSQLErrorListener( this );
711 void OGridControlModel::lostColumn(const Reference< XInterface >& _rxColumn)
713 if ( m_xSelection == _rxColumn )
714 { // the currently selected element was replaced
715 m_xSelection.clear();
716 EventObject aEvt( static_cast< XWeak* >( this ) );
717 m_aSelectListeners.notifyEach( &XSelectionChangeListener::selectionChanged, aEvt );
719 Reference< XSQLErrorBroadcaster > xBroadcaster( _rxColumn, UNO_QUERY );
720 if ( xBroadcaster.is() )
721 xBroadcaster->removeSQLErrorListener( this );
724 void OGridControlModel::implRemoved(const InterfaceRef& _rxObject)
726 OInterfaceContainer::implRemoved(_rxObject);
727 lostColumn(_rxObject);
730 void OGridControlModel::implInserted( const ElementDescription* _pElement )
732 OInterfaceContainer::implInserted( _pElement );
733 gotColumn( _pElement->xInterface );
736 void OGridControlModel::impl_replacedElement( const ContainerEvent& _rEvent, ::osl::ClearableMutexGuard& _rInstanceLock )
738 Reference< XInterface > xOldColumn( _rEvent.ReplacedElement, UNO_QUERY );
739 Reference< XInterface > xNewColumn( _rEvent.Element, UNO_QUERY );
740 bool bNewSelection = ( xOldColumn == m_xSelection );
741 lostColumn( xOldColumn );
742 gotColumn( xNewColumn );
743 if ( bNewSelection )
744 m_xSelection.set( xNewColumn, UNO_QUERY );
745 OInterfaceContainer::impl_replacedElement( _rEvent, _rInstanceLock );
746 // < SYNCHRONIZED
747 if ( bNewSelection )
749 m_aSelectListeners.notifyEach( &XSelectionChangeListener::selectionChanged, EventObject( *this ) );
753 ElementDescription* OGridControlModel::createElementMetaData( )
755 return new ColumnDescription;
758 void OGridControlModel::approveNewElement( const Reference< XPropertySet >& _rxObject, ElementDescription* _pElement )
760 OGridColumn* pCol = getColumnImplementation( _rxObject );
761 if ( !pCol )
762 throw IllegalArgumentException();
763 OInterfaceContainer::approveNewElement( _rxObject, _pElement );
764 // if we're here, the object passed all tests
765 if ( _pElement )
766 static_cast< ColumnDescription* >( _pElement )->pColumn = pCol;
769 // XPersistObject
770 OUString SAL_CALL OGridControlModel::getServiceName() throw ( ::com::sun::star::uno::RuntimeException, std::exception)
772 return OUString(FRM_COMPONENT_GRID); // old (non-sun) name for compatibility!
775 void OGridControlModel::write(const Reference<XObjectOutputStream>& _rxOutStream) throw ( ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException, std::exception)
777 OControlModel::write(_rxOutStream);
778 Reference<XMarkableStream> xMark(_rxOutStream, UNO_QUERY);
779 // 1. Version
780 _rxOutStream->writeShort(0x0008);
781 // 2. Columns
782 sal_Int32 nLen = getCount();
783 _rxOutStream->writeLong(nLen);
784 for (sal_Int32 i = 0; i < nLen; i++)
786 // first the service name for the unerlying model
787 OGridColumn* pCol = getColumnImplementation(m_aItems[i]);
788 DBG_ASSERT(pCol != NULL, "OGridControlModel::write : such items should never reach it into my container !");
789 _rxOutStream << pCol->getModelName();
790 // then the object itself
791 sal_Int32 nMark = xMark->createMark();
792 sal_Int32 nObjLen = 0;
793 _rxOutStream->writeLong(nObjLen);
794 // writing the column
795 pCol->write(_rxOutStream);
796 // determining the length
797 nObjLen = xMark->offsetToMark(nMark) - 4;
798 xMark->jumpToMark(nMark);
799 _rxOutStream->writeLong(nObjLen);
800 xMark->jumpToFurthest();
801 xMark->deleteMark(nMark);
803 // 3. Events
804 writeEvents(_rxOutStream);
805 // 4. Attributes
806 // Masking for all 'any' types
807 sal_uInt16 nAnyMask = 0;
808 if (m_aRowHeight.getValueType().getTypeClass() == TypeClass_LONG)
809 nAnyMask |= ROWHEIGHT;
810 if ( getFont() != getDefaultFont() )
811 nAnyMask |= FONTATTRIBS | FONTSIZE | FONTTYPE | FONTDESCRIPTOR;
812 if (m_aTabStop.getValueType().getTypeClass() == TypeClass_BOOLEAN)
813 nAnyMask |= TABSTOP;
814 if ( hasTextColor() )
815 nAnyMask |= TEXTCOLOR;
816 if (m_aBackgroundColor.getValueType().getTypeClass() == TypeClass_LONG)
817 nAnyMask |= BACKGROUNDCOLOR;
818 if (!m_bRecordMarker)
819 nAnyMask |= RECORDMARKER;
820 _rxOutStream->writeShort(nAnyMask);
821 if (nAnyMask & ROWHEIGHT)
822 _rxOutStream->writeLong(getINT32(m_aRowHeight));
823 // old structures
824 const FontDescriptor& aFont = getFont();
825 if ( nAnyMask & FONTDESCRIPTOR )
827 // Attrib
828 _rxOutStream->writeShort( sal::static_int_cast< sal_Int16 >( VCLUnoHelper::ConvertFontWeight( aFont.Weight ) ) );
829 _rxOutStream->writeShort( sal::static_int_cast< sal_Int16 >( aFont.Slant ) );
830 _rxOutStream->writeShort( aFont.Underline );
831 _rxOutStream->writeShort( aFont.Strikeout );
832 _rxOutStream->writeShort( sal_Int16(aFont.Orientation * 10) );
833 _rxOutStream->writeBoolean( aFont.Kerning );
834 _rxOutStream->writeBoolean( aFont.WordLineMode );
835 // Size
836 _rxOutStream->writeLong( aFont.Width );
837 _rxOutStream->writeLong( aFont.Height );
838 _rxOutStream->writeShort( sal::static_int_cast< sal_Int16 >( VCLUnoHelper::ConvertFontWidth( aFont.CharacterWidth ) ) );
839 // Type
840 _rxOutStream->writeUTF( aFont.Name );
841 _rxOutStream->writeUTF( aFont.StyleName );
842 _rxOutStream->writeShort( aFont.Family );
843 _rxOutStream->writeShort( aFont.CharSet );
844 _rxOutStream->writeShort( aFont.Pitch );
846 _rxOutStream << m_aDefaultControl;
847 _rxOutStream->writeShort(m_nBorder);
848 _rxOutStream->writeBoolean(m_bEnable);
849 if (nAnyMask & TABSTOP)
850 _rxOutStream->writeBoolean(getBOOL(m_aTabStop));
851 _rxOutStream->writeBoolean(m_bNavigation);
852 if (nAnyMask & TEXTCOLOR)
853 _rxOutStream->writeLong( getTextColor() );
854 // new since version 6
855 _rxOutStream << m_sHelpText;
856 if (nAnyMask & FONTDESCRIPTOR)
857 _rxOutStream << getFont();
858 if (nAnyMask & RECORDMARKER)
859 _rxOutStream->writeBoolean(m_bRecordMarker);
860 // new since version 7
861 _rxOutStream->writeBoolean(m_bPrintable);
862 // new since version 8
863 if (nAnyMask & BACKGROUNDCOLOR)
864 _rxOutStream->writeLong(getINT32(m_aBackgroundColor));
867 void OGridControlModel::read(const Reference<XObjectInputStream>& _rxInStream) throw ( ::com::sun::star::io::IOException, ::com::sun::star::uno::RuntimeException, std::exception)
869 SolarMutexGuard g;
870 OControlModel::read(_rxInStream);
871 Reference<XMarkableStream> xMark(_rxInStream, UNO_QUERY);
872 // 1. version
873 sal_Int16 nVersion = _rxInStream->readShort();
874 // 2. reading the columns
875 sal_Int32 nLen = _rxInStream->readLong();
876 if (nLen)
878 for (sal_Int32 i = 0; i < nLen; i++)
880 // reading the model names
881 OUString sModelName;
882 _rxInStream >> sModelName;
883 Reference<XPropertySet> xCol(createColumn(getColumnTypeByModelName(sModelName)));
884 DBG_ASSERT(xCol.is(), "OGridControlModel::read : unknown column type !");
885 sal_Int32 nObjLen = _rxInStream->readLong();
886 if (nObjLen)
888 sal_Int32 nMark = xMark->createMark();
889 if (xCol.is())
891 OGridColumn* pCol = getColumnImplementation(xCol);
892 pCol->read(_rxInStream);
894 xMark->jumpToMark(nMark);
895 _rxInStream->skipBytes(nObjLen);
896 xMark->deleteMark(nMark);
898 if ( xCol.is() )
899 implInsert( i, xCol, false, NULL, false );
902 // In the base implementation events are only read, elements in the container exist
903 // but since before TF_ONE for the GridControl events were always written, so they
904 // need to be read, too
905 sal_Int32 nObjLen = _rxInStream->readLong();
906 if (nObjLen)
908 sal_Int32 nMark = xMark->createMark();
909 Reference<XPersistObject> xObj(m_xEventAttacher, UNO_QUERY);
910 if (xObj.is())
911 xObj->read(_rxInStream);
912 xMark->jumpToMark(nMark);
913 _rxInStream->skipBytes(nObjLen);
914 xMark->deleteMark(nMark);
916 // reading the attachment
917 for (sal_Int32 i = 0; i < nLen; i++)
919 InterfaceRef xIfc(m_aItems[i], UNO_QUERY);
920 Reference<XPropertySet> xSet(xIfc, UNO_QUERY);
921 Any aHelper;
922 aHelper <<= xSet;
923 m_xEventAttacher->attach( i, xIfc, aHelper );
925 // 4. reading the attributes
926 if (nVersion == 1)
927 return;
928 // Masking for any
929 sal_uInt16 nAnyMask = _rxInStream->readShort();
930 if (nAnyMask & ROWHEIGHT)
932 sal_Int32 nValue = _rxInStream->readLong();
933 m_aRowHeight <<= (sal_Int32)nValue;
935 FontDescriptor aFont( getFont() );
936 if ( nAnyMask & FONTATTRIBS )
938 aFont.Weight = (float)VCLUnoHelper::ConvertFontWeight( _rxInStream->readShort() );
939 aFont.Slant = (FontSlant)_rxInStream->readShort();
940 aFont.Underline = _rxInStream->readShort();
941 aFont.Strikeout = _rxInStream->readShort();
942 aFont.Orientation = ( (float)_rxInStream->readShort() ) / 10;
943 aFont.Kerning = _rxInStream->readBoolean();
944 aFont.WordLineMode = _rxInStream->readBoolean();
946 if ( nAnyMask & FONTSIZE )
948 aFont.Width = (sal_Int16)_rxInStream->readLong();
949 aFont.Height = (sal_Int16)_rxInStream->readLong();
950 aFont.CharacterWidth = (float)VCLUnoHelper::ConvertFontWidth( _rxInStream->readShort() );
952 if ( nAnyMask & FONTTYPE )
954 aFont.Name = _rxInStream->readUTF();
955 aFont.StyleName = _rxInStream->readUTF();
956 aFont.Family = _rxInStream->readShort();
957 aFont.CharSet = _rxInStream->readShort();
958 aFont.Pitch = _rxInStream->readShort();
960 if ( nAnyMask & ( FONTATTRIBS | FONTSIZE | FONTTYPE ) )
961 setFont( aFont );
962 // Name
963 _rxInStream >> m_aDefaultControl;
964 m_nBorder = _rxInStream->readShort();
965 m_bEnable = _rxInStream->readBoolean();
966 if (nAnyMask & TABSTOP)
968 m_aTabStop = makeBoolAny(_rxInStream->readBoolean() != 0);
970 if (nVersion > 3)
971 m_bNavigation = _rxInStream->readBoolean();
972 if (nAnyMask & TEXTCOLOR)
974 sal_Int32 nValue = _rxInStream->readLong();
975 setTextColor( (sal_Int32)nValue );
977 // new since version 6
978 if (nVersion > 5)
979 _rxInStream >> m_sHelpText;
980 if (nAnyMask & FONTDESCRIPTOR)
982 FontDescriptor aUNOFont;
983 _rxInStream >> aUNOFont;
984 setFont( aFont );
986 if (nAnyMask & RECORDMARKER)
987 m_bRecordMarker = _rxInStream->readBoolean();
988 // new since version 7
989 if (nVersion > 6)
990 m_bPrintable = _rxInStream->readBoolean();
991 if (nAnyMask & BACKGROUNDCOLOR)
993 sal_Int32 nValue = _rxInStream->readLong();
994 m_aBackgroundColor <<= (sal_Int32)nValue;
1000 extern "C" SAL_DLLPUBLIC_EXPORT XInterface* SAL_CALL
1001 com_sun_star_form_OGridControlModel_get_implementation(XComponentContext* component,
1002 Sequence<Any> const &)
1004 return cppu::acquire(new frm::OGridControlModel(component));
1007 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */