diff options
Diffstat (limited to 'forms/source/component/Grid.cxx')
-rw-r--r-- | forms/source/component/Grid.cxx | 992 |
1 files changed, 992 insertions, 0 deletions
diff --git a/forms/source/component/Grid.cxx b/forms/source/component/Grid.cxx new file mode 100644 index 000000000..308ed8228 --- /dev/null +++ b/forms/source/component/Grid.cxx @@ -0,0 +1,992 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include "Columns.hxx" +#include "findpos.hxx" +#include "Grid.hxx" +#include <property.hxx> +#include <services.hxx> +#include <com/sun/star/beans/PropertyAttribute.hpp> +#include <com/sun/star/form/FormComponentType.hpp> +#include <com/sun/star/io/XMarkableStream.hpp> +#include <com/sun/star/text/WritingMode2.hpp> +#include <comphelper/basicio.hxx> +#include <comphelper/property.hxx> +#include <comphelper/servicehelper.hxx> +#include <comphelper/types.hxx> +#include <vcl/unohelp.hxx> +#include <vcl/svapp.hxx> +#include <tools/debug.hxx> +#include <tools/diagnose_ex.h> + +using namespace ::com::sun::star::uno; + +namespace frm +{ +using namespace ::com::sun::star; +using namespace ::com::sun::star::sdb; +using namespace ::com::sun::star::sdbc; +using namespace ::com::sun::star::beans; +using namespace ::com::sun::star::container; +using namespace ::com::sun::star::form; +using namespace ::com::sun::star::awt; +using namespace ::com::sun::star::io; +using namespace ::com::sun::star::lang; +using namespace ::com::sun::star::util; +using namespace ::com::sun::star::view; +namespace WritingMode2 = ::com::sun::star::text::WritingMode2; +const sal_uInt16 ROWHEIGHT = 0x0001; +const sal_uInt16 FONTTYPE = 0x0002; +const sal_uInt16 FONTSIZE = 0x0004; +const sal_uInt16 FONTATTRIBS = 0x0008; +const sal_uInt16 TABSTOP = 0x0010; +const sal_uInt16 TEXTCOLOR = 0x0020; +const sal_uInt16 FONTDESCRIPTOR = 0x0040; +const sal_uInt16 RECORDMARKER = 0x0080; +const sal_uInt16 BACKGROUNDCOLOR = 0x0100; + +OGridControlModel::OGridControlModel(const Reference<XComponentContext>& _rxFactory) + :OControlModel(_rxFactory, OUString()) + ,OInterfaceContainer(_rxFactory, m_aMutex, cppu::UnoType<XPropertySet>::get()) + ,OErrorBroadcaster( OComponentHelper::rBHelper ) + ,FontControlModel( false ) + ,m_aSelectListeners(m_aMutex) + ,m_aResetListeners(m_aMutex) + ,m_aRowSetChangeListeners(m_aMutex) + ,m_aDefaultControl( FRM_SUN_CONTROL_GRIDCONTROL ) + ,m_nBorder(1) + ,m_nWritingMode( WritingMode2::CONTEXT ) + ,m_nContextWritingMode( WritingMode2::CONTEXT ) + ,m_bEnableVisible(true) + ,m_bEnable(true) + ,m_bNavigation(true) + ,m_bRecordMarker(true) + ,m_bPrintable(true) + ,m_bAlwaysShowCursor(false) + ,m_bDisplaySynchron(true) +{ + m_nClassId = FormComponentType::GRIDCONTROL; +} + +OGridControlModel::OGridControlModel( const OGridControlModel* _pOriginal, const Reference< XComponentContext >& _rxFactory ) + :OControlModel( _pOriginal, _rxFactory ) + ,OInterfaceContainer( _rxFactory, m_aMutex, cppu::UnoType<XPropertySet>::get() ) + ,OErrorBroadcaster( OComponentHelper::rBHelper ) + ,FontControlModel( _pOriginal ) + ,m_aSelectListeners( m_aMutex ) + ,m_aResetListeners( m_aMutex ) + ,m_aRowSetChangeListeners( m_aMutex ) +{ + m_aDefaultControl = _pOriginal->m_aDefaultControl; + m_bEnable = _pOriginal->m_bEnable; + m_bEnableVisible = _pOriginal->m_bEnableVisible; + m_bNavigation = _pOriginal->m_bNavigation; + m_nBorder = _pOriginal->m_nBorder; + m_nWritingMode = _pOriginal->m_nWritingMode; + m_nContextWritingMode = _pOriginal->m_nContextWritingMode; + m_bRecordMarker = _pOriginal->m_bRecordMarker; + m_bPrintable = _pOriginal->m_bPrintable; + m_bAlwaysShowCursor = _pOriginal->m_bAlwaysShowCursor; + m_bDisplaySynchron = _pOriginal->m_bDisplaySynchron; + // clone the columns + cloneColumns( _pOriginal ); + // TODO: clone the events? +} + +OGridControlModel::~OGridControlModel() +{ + if (!OComponentHelper::rBHelper.bDisposed) + { + acquire(); + dispose(); + } +} + +// XCloneable +Reference< XCloneable > SAL_CALL OGridControlModel::createClone( ) +{ + rtl::Reference<OGridControlModel> pClone = new OGridControlModel( this, getContext() ); + pClone->OControlModel::clonedFrom( this ); + // do not call OInterfaceContainer::clonedFrom, it would clone the elements aka columns, which is + // already done in the ctor + //pClone->OInterfaceContainer::clonedFrom( *this ); + return static_cast< XCloneable* >( static_cast< OControlModel* >( pClone.get() ) ); +} + +void OGridControlModel::cloneColumns( const OGridControlModel* _pOriginalContainer ) +{ + try + { + Reference< XCloneable > xColCloneable; + sal_Int32 nIndex = 0; + for (auto const& column : _pOriginalContainer->m_aItems) + { + // ask the col for a factory for the clone + xColCloneable.set(column, css::uno::UNO_QUERY); + DBG_ASSERT( xColCloneable.is(), "OGridControlModel::cloneColumns: column is not cloneable!" ); + if ( xColCloneable.is() ) + { + // create a clone of the column + Reference< XCloneable > xColClone( xColCloneable->createClone() ); + DBG_ASSERT( xColClone.is(), "OGridControlModel::cloneColumns: invalid column clone!" ); + if ( xColClone.is() ) + { + // insert this clone into our own container + insertByIndex( nIndex, xColClone->queryInterface( m_aElementType ) ); + } + } + ++nIndex; + } + } + catch( const Exception& ) + { + TOOLS_WARN_EXCEPTION( "forms.component", "OGridControlModel::cloneColumns: caught an exception while cloning the columns!" ); + } +} + +// XServiceInfo +css::uno::Sequence<OUString> OGridControlModel::getSupportedServiceNames() +{ + css::uno::Sequence<OUString> aSupported = OControlModel::getSupportedServiceNames(); + aSupported.realloc(aSupported.getLength() + 4); + auto pSupported = aSupported.getArray(); + pSupported[aSupported.getLength()-4] = "com.sun.star.awt.UnoControlModel"; + pSupported[aSupported.getLength()-3] = FRM_SUN_COMPONENT_GRIDCONTROL; + pSupported[aSupported.getLength()-2] = FRM_COMPONENT_GRID; + pSupported[aSupported.getLength()-1] = FRM_COMPONENT_GRIDCONTROL; + return aSupported; +} +Any SAL_CALL OGridControlModel::queryAggregation( const Type& _rType ) +{ + Any aReturn = OGridControlModel_BASE::queryInterface(_rType); + if ( !aReturn.hasValue() ) + { + aReturn = OControlModel::queryAggregation( _rType ); + if ( !aReturn.hasValue() ) + { + aReturn = OInterfaceContainer::queryInterface( _rType ); + if ( !aReturn.hasValue() ) + aReturn = OErrorBroadcaster::queryInterface( _rType ); + } + } + return aReturn; +} + +// XSQLErrorListener +void SAL_CALL OGridControlModel::errorOccured( const SQLErrorEvent& _rEvent ) +{ + // forward the errors which happened to my columns to my own listeners + onError( _rEvent ); +} + +// XRowSetSupplier +Reference< XRowSet > SAL_CALL OGridControlModel::getRowSet( ) +{ + return Reference< XRowSet >( getParent(), UNO_QUERY ); +} + +void SAL_CALL OGridControlModel::setRowSet( const Reference< XRowSet >& /*_rxDataSource*/ ) +{ + OSL_FAIL( "OGridControlModel::setRowSet: not supported!" ); +} + +void SAL_CALL OGridControlModel::addRowSetChangeListener( const Reference< XRowSetChangeListener >& i_Listener ) +{ + if ( i_Listener.is() ) + m_aRowSetChangeListeners.addInterface( i_Listener ); +} + +void SAL_CALL OGridControlModel::removeRowSetChangeListener( const Reference< XRowSetChangeListener >& i_Listener ) +{ + m_aRowSetChangeListeners.removeInterface( i_Listener ); +} + +// XChild +void SAL_CALL OGridControlModel::setParent( const css::uno::Reference<css::uno::XInterface>& i_Parent ) +{ + ::osl::ClearableMutexGuard aGuard( m_aMutex ); + if ( i_Parent == getParent() ) + return; + OControlModel::setParent( i_Parent ); + EventObject aEvent( *this ); + aGuard.clear(); + m_aRowSetChangeListeners.notifyEach( &XRowSetChangeListener::onRowSetChanged, aEvent ); +} +Sequence< Type > SAL_CALL OGridControlModel::getTypes( ) +{ + return concatSequences( + concatSequences( + OControlModel::getTypes(), + OInterfaceContainer::getTypes(), + OErrorBroadcaster::getTypes() + ), + OGridControlModel_BASE::getTypes() + ); +} + +// OComponentHelper +void OGridControlModel::disposing() +{ + OControlModel::disposing(); + OErrorBroadcaster::disposing(); + OInterfaceContainer::disposing(); + setParent(nullptr); + EventObject aEvt(static_cast<XWeak*>(this)); + m_aSelectListeners.disposeAndClear(aEvt); + m_aResetListeners.disposeAndClear(aEvt); + m_aRowSetChangeListeners.disposeAndClear(aEvt); +} + +// XEventListener +void OGridControlModel::disposing(const EventObject& _rEvent) +{ + OControlModel::disposing( _rEvent ); + OInterfaceContainer::disposing( _rEvent ); +} + +// XSelectionSupplier +sal_Bool SAL_CALL OGridControlModel::select(const Any& rElement) +{ + ::osl::ClearableMutexGuard aGuard( m_aMutex ); + Reference<XPropertySet> xSel; + if (rElement.hasValue()) + { + xSel.set(rElement, css::uno::UNO_QUERY); + if (!xSel.is()) + { + throw IllegalArgumentException(); + } + } + css::uno::Reference<css::uno::XInterface> xMe = static_cast<XWeak*>(this); + if (xSel.is()) + { + Reference<XChild> xAsChild(xSel, UNO_QUERY); + if (!xAsChild.is() || (xAsChild->getParent() != xMe)) + { + throw IllegalArgumentException(); + } + } + if ( xSel != m_xSelection ) + { + m_xSelection = xSel; + aGuard.clear(); + m_aSelectListeners.notifyEach( &XSelectionChangeListener::selectionChanged, EventObject( *this ) ); + return true; + } + return false; +} +Any SAL_CALL OGridControlModel::getSelection() +{ + return Any(m_xSelection); +} + +void OGridControlModel::addSelectionChangeListener(const Reference< XSelectionChangeListener >& _rxListener) +{ + m_aSelectListeners.addInterface(_rxListener); +} + +void OGridControlModel::removeSelectionChangeListener(const Reference< XSelectionChangeListener >& _rxListener) +{ + m_aSelectListeners.removeInterface(_rxListener); +} + +// XGridColumnFactory +Reference<XPropertySet> SAL_CALL OGridControlModel::createColumn(const OUString& ColumnType) +{ + SolarMutexGuard g; + const Sequence< OUString >& rColumnTypes = frm::getColumnTypes(); + return createColumnById( ::detail::findPos( ColumnType, rColumnTypes ) ); +} +Reference<XPropertySet> OGridControlModel::createColumnById(sal_Int32 nTypeId) const +{ + Reference<XPropertySet> xReturn; + switch (nTypeId) + { + case TYPE_CHECKBOX: xReturn = new CheckBoxColumn( getContext() ); break; + case TYPE_COMBOBOX: xReturn = new ComboBoxColumn( getContext() ); break; + case TYPE_CURRENCYFIELD: xReturn = new CurrencyFieldColumn( getContext() ); break; + case TYPE_DATEFIELD: xReturn = new DateFieldColumn( getContext() ); break; + case TYPE_LISTBOX: xReturn = new ListBoxColumn( getContext() ); break; + case TYPE_NUMERICFIELD: xReturn = new NumericFieldColumn( getContext() ); break; + case TYPE_PATTERNFIELD: xReturn = new PatternFieldColumn( getContext() ); break; + case TYPE_TEXTFIELD: xReturn = new TextFieldColumn( getContext() ); break; + case TYPE_TIMEFIELD: xReturn = new TimeFieldColumn( getContext() ); break; + case TYPE_FORMATTEDFIELD: xReturn = new FormattedFieldColumn( getContext() ); break; + default: + OSL_FAIL("OGridControlModel::createColumn: Unknown Column"); + break; + } + return xReturn; +} +css::uno::Sequence<OUString> SAL_CALL OGridControlModel::getColumnTypes() +{ + return frm::getColumnTypes(); +} + +// XReset +void SAL_CALL OGridControlModel::reset() +{ + ::comphelper::OInterfaceIteratorHelper3 aIter(m_aResetListeners); + EventObject aEvt(static_cast<XWeak*>(this)); + bool bContinue = true; + while (aIter.hasMoreElements() && bContinue) + bContinue = aIter.next()->approveReset(aEvt); + if (bContinue) + { + _reset(); + m_aResetListeners.notifyEach( &XResetListener::resetted, aEvt ); + } +} +void SAL_CALL OGridControlModel::addResetListener(const Reference<XResetListener>& _rxListener) +{ + m_aResetListeners.addInterface(_rxListener); +} +void SAL_CALL OGridControlModel::removeResetListener(const Reference<XResetListener>& _rxListener) +{ + m_aResetListeners.removeInterface(_rxListener); +} +void OGridControlModel::_reset() +{ + Reference<XReset> xReset; + sal_Int32 nCount = getCount(); + for (sal_Int32 nIndex=0; nIndex < nCount; nIndex++) + { + getByIndex( nIndex ) >>= xReset; + if (xReset.is()) + xReset->reset(); + } +} + +// XPropertySet +void OGridControlModel::describeFixedProperties( Sequence< Property >& _rProps ) const +{ + _rProps.realloc(37); + css::beans::Property* pProperties = _rProps.getArray(); + *pProperties++ = css::beans::Property(PROPERTY_NAME, PROPERTY_ID_NAME, cppu::UnoType<OUString>::get(), css::beans::PropertyAttribute::BOUND); + *pProperties++ = css::beans::Property(PROPERTY_CLASSID, PROPERTY_ID_CLASSID, cppu::UnoType<sal_Int16>::get(), css::beans::PropertyAttribute::READONLY | css::beans::PropertyAttribute::TRANSIENT); + *pProperties++ = css::beans::Property(PROPERTY_TAG, PROPERTY_ID_TAG, cppu::UnoType<OUString>::get(), css::beans::PropertyAttribute::BOUND); + *pProperties++ = css::beans::Property(PROPERTY_TABINDEX, PROPERTY_ID_TABINDEX, cppu::UnoType<sal_Int16>::get(), css::beans::PropertyAttribute::BOUND); + *pProperties++ = css::beans::Property(PROPERTY_TABSTOP, PROPERTY_ID_TABSTOP, cppu::UnoType<sal_Bool>::get(), css::beans::PropertyAttribute::BOUND | css::beans::PropertyAttribute::MAYBEDEFAULT | css::beans::PropertyAttribute::MAYBEVOID); + *pProperties++ = css::beans::Property(PROPERTY_HASNAVIGATION, PROPERTY_ID_HASNAVIGATION, cppu::UnoType<sal_Bool>::get(), css::beans::PropertyAttribute::BOUND | css::beans::PropertyAttribute::MAYBEDEFAULT); + *pProperties++ = css::beans::Property(PROPERTY_ENABLED, PROPERTY_ID_ENABLED, cppu::UnoType<sal_Bool>::get(), css::beans::PropertyAttribute::BOUND); + *pProperties++ = css::beans::Property(PROPERTY_ENABLEVISIBLE, PROPERTY_ID_ENABLEVISIBLE, cppu::UnoType<sal_Bool>::get(), css::beans::PropertyAttribute::BOUND | css::beans::PropertyAttribute::MAYBEDEFAULT); + *pProperties++ = css::beans::Property(PROPERTY_BORDER, PROPERTY_ID_BORDER, cppu::UnoType<sal_Int16>::get(), css::beans::PropertyAttribute::BOUND); + *pProperties++ = css::beans::Property(PROPERTY_BORDERCOLOR, PROPERTY_ID_BORDERCOLOR, cppu::UnoType<sal_Int16>::get(), css::beans::PropertyAttribute::BOUND | css::beans::PropertyAttribute::MAYBEVOID); + *pProperties++ = css::beans::Property(PROPERTY_DEFAULTCONTROL, PROPERTY_ID_DEFAULTCONTROL, cppu::UnoType<OUString>::get(), css::beans::PropertyAttribute::BOUND); + *pProperties++ = css::beans::Property(PROPERTY_TEXTCOLOR, PROPERTY_ID_TEXTCOLOR, cppu::UnoType<sal_Int32>::get(), css::beans::PropertyAttribute::BOUND | css::beans::PropertyAttribute::MAYBEDEFAULT | css::beans::PropertyAttribute::MAYBEVOID); + *pProperties++ = css::beans::Property(PROPERTY_BACKGROUNDCOLOR, PROPERTY_ID_BACKGROUNDCOLOR, cppu::UnoType<sal_Int32>::get(), css::beans::PropertyAttribute::BOUND | css::beans::PropertyAttribute::MAYBEDEFAULT | css::beans::PropertyAttribute::MAYBEVOID); + *pProperties++ = css::beans::Property(PROPERTY_FONT, PROPERTY_ID_FONT, cppu::UnoType<FontDescriptor>::get(), css::beans::PropertyAttribute::BOUND | css::beans::PropertyAttribute::MAYBEDEFAULT); + *pProperties++ = css::beans::Property(PROPERTY_ROWHEIGHT, PROPERTY_ID_ROWHEIGHT, cppu::UnoType<sal_Int32>::get(), css::beans::PropertyAttribute::BOUND | css::beans::PropertyAttribute::MAYBEDEFAULT | css::beans::PropertyAttribute::MAYBEVOID); + *pProperties++ = css::beans::Property(PROPERTY_HELPTEXT, PROPERTY_ID_HELPTEXT, cppu::UnoType<OUString>::get(), css::beans::PropertyAttribute::BOUND); + *pProperties++ = css::beans::Property(PROPERTY_FONT_NAME, PROPERTY_ID_FONT_NAME, cppu::UnoType<OUString>::get(), css::beans::PropertyAttribute::MAYBEDEFAULT); + *pProperties++ = css::beans::Property(PROPERTY_FONT_STYLENAME, PROPERTY_ID_FONT_STYLENAME, cppu::UnoType<OUString>::get(), css::beans::PropertyAttribute::MAYBEDEFAULT); + *pProperties++ = css::beans::Property(PROPERTY_FONT_FAMILY, PROPERTY_ID_FONT_FAMILY, cppu::UnoType<sal_Int16>::get(), css::beans::PropertyAttribute::MAYBEDEFAULT); + *pProperties++ = css::beans::Property(PROPERTY_FONT_CHARSET, PROPERTY_ID_FONT_CHARSET, cppu::UnoType<sal_Int16>::get(), css::beans::PropertyAttribute::MAYBEDEFAULT); + *pProperties++ = css::beans::Property(PROPERTY_FONT_HEIGHT, PROPERTY_ID_FONT_HEIGHT, cppu::UnoType<float>::get(), css::beans::PropertyAttribute::MAYBEDEFAULT); + *pProperties++ = css::beans::Property(PROPERTY_FONT_WEIGHT, PROPERTY_ID_FONT_WEIGHT, cppu::UnoType<float>::get(), css::beans::PropertyAttribute::MAYBEDEFAULT); + *pProperties++ = css::beans::Property(PROPERTY_FONT_SLANT, PROPERTY_ID_FONT_SLANT, cppu::UnoType<sal_Int16>::get(), css::beans::PropertyAttribute::MAYBEDEFAULT); + *pProperties++ = css::beans::Property(PROPERTY_FONT_UNDERLINE, PROPERTY_ID_FONT_UNDERLINE, cppu::UnoType<sal_Int16>::get(), css::beans::PropertyAttribute::MAYBEDEFAULT); + *pProperties++ = css::beans::Property(PROPERTY_FONT_WORDLINEMODE, PROPERTY_ID_FONT_WORDLINEMODE, cppu::UnoType<bool>::get(), + css::beans::PropertyAttribute::MAYBEDEFAULT); + *pProperties++ = css::beans::Property(PROPERTY_TEXTLINECOLOR, PROPERTY_ID_TEXTLINECOLOR, cppu::UnoType<sal_Int32>::get(), css::beans::PropertyAttribute::BOUND | css::beans::PropertyAttribute::MAYBEDEFAULT | css::beans::PropertyAttribute::MAYBEVOID); + *pProperties++ = css::beans::Property(PROPERTY_FONTEMPHASISMARK, PROPERTY_ID_FONTEMPHASISMARK, cppu::UnoType<sal_Int16>::get(), css::beans::PropertyAttribute::BOUND | css::beans::PropertyAttribute::MAYBEDEFAULT); + *pProperties++ = css::beans::Property(PROPERTY_FONTRELIEF, PROPERTY_ID_FONTRELIEF, cppu::UnoType<sal_Int16>::get(), css::beans::PropertyAttribute::BOUND | css::beans::PropertyAttribute::MAYBEDEFAULT); + *pProperties++ = css::beans::Property(PROPERTY_FONT_STRIKEOUT, PROPERTY_ID_FONT_STRIKEOUT, cppu::UnoType<sal_Int16>::get(), css::beans::PropertyAttribute::MAYBEDEFAULT); + *pProperties++ = css::beans::Property(PROPERTY_RECORDMARKER, PROPERTY_ID_RECORDMARKER, cppu::UnoType<sal_Bool>::get(), css::beans::PropertyAttribute::BOUND | css::beans::PropertyAttribute::MAYBEDEFAULT); + *pProperties++ = css::beans::Property(PROPERTY_PRINTABLE, PROPERTY_ID_PRINTABLE, cppu::UnoType<sal_Bool>::get(), css::beans::PropertyAttribute::BOUND | css::beans::PropertyAttribute::MAYBEDEFAULT); + *pProperties++ = css::beans::Property(PROPERTY_CURSORCOLOR, PROPERTY_ID_CURSORCOLOR, cppu::UnoType<sal_Int32>::get(), css::beans::PropertyAttribute::BOUND | css::beans::PropertyAttribute::MAYBEDEFAULT | + css::beans::PropertyAttribute::MAYBEVOID | css::beans::PropertyAttribute::TRANSIENT); + *pProperties++ = css::beans::Property(PROPERTY_ALWAYSSHOWCURSOR, PROPERTY_ID_ALWAYSSHOWCURSOR, cppu::UnoType<sal_Bool>::get(), css::beans::PropertyAttribute::BOUND | css::beans::PropertyAttribute::MAYBEDEFAULT | css::beans::PropertyAttribute::TRANSIENT); + *pProperties++ = css::beans::Property(PROPERTY_DISPLAYSYNCHRON, PROPERTY_ID_DISPLAYSYNCHRON, cppu::UnoType<sal_Bool>::get(), css::beans::PropertyAttribute::BOUND | css::beans::PropertyAttribute::MAYBEDEFAULT | css::beans::PropertyAttribute::TRANSIENT); + *pProperties++ = css::beans::Property(PROPERTY_HELPURL, PROPERTY_ID_HELPURL, cppu::UnoType<OUString>::get(), css::beans::PropertyAttribute::BOUND | css::beans::PropertyAttribute::MAYBEDEFAULT); + *pProperties++ = css::beans::Property(PROPERTY_WRITING_MODE, PROPERTY_ID_WRITING_MODE, cppu::UnoType<sal_Int16>::get(), css::beans::PropertyAttribute::BOUND | css::beans::PropertyAttribute::MAYBEDEFAULT); + *pProperties++ = css::beans::Property(PROPERTY_CONTEXT_WRITING_MODE, PROPERTY_ID_CONTEXT_WRITING_MODE, cppu::UnoType<sal_Int16>::get(), css::beans::PropertyAttribute::BOUND | css::beans::PropertyAttribute::MAYBEDEFAULT | css::beans::PropertyAttribute::TRANSIENT); + DBG_ASSERT( pProperties == _rProps.getArray() + _rProps.getLength(), "<...>::describeFixedProperties/getInfoHelper: forgot to adjust the count ?"); +} +void OGridControlModel::getFastPropertyValue(Any& rValue, sal_Int32 nHandle ) const +{ + switch (nHandle) + { + case PROPERTY_ID_CONTEXT_WRITING_MODE: + rValue <<= m_nContextWritingMode; + break; + case PROPERTY_ID_WRITING_MODE: + rValue <<= m_nWritingMode; + break; + case PROPERTY_ID_HELPTEXT: + rValue <<= m_sHelpText; + break; + case PROPERTY_ID_HELPURL: + rValue <<= m_sHelpURL; + break; + case PROPERTY_ID_DISPLAYSYNCHRON: + rValue <<= m_bDisplaySynchron; + break; + case PROPERTY_ID_ALWAYSSHOWCURSOR: + rValue <<= m_bAlwaysShowCursor; + break; + case PROPERTY_ID_CURSORCOLOR: + rValue = m_aCursorColor; + break; + case PROPERTY_ID_PRINTABLE: + rValue <<= m_bPrintable; + break; + case PROPERTY_ID_TABSTOP: + rValue = m_aTabStop; + break; + case PROPERTY_ID_HASNAVIGATION: + rValue <<= m_bNavigation; + break; + case PROPERTY_ID_RECORDMARKER: + rValue <<= m_bRecordMarker; + break; + case PROPERTY_ID_ENABLED: + rValue <<= m_bEnable; + break; + case PROPERTY_ID_ENABLEVISIBLE: + rValue <<= m_bEnableVisible; + break; + case PROPERTY_ID_BORDER: + rValue <<= m_nBorder; + break; + case PROPERTY_ID_BORDERCOLOR: + rValue = m_aBorderColor; + break; + case PROPERTY_ID_DEFAULTCONTROL: + rValue <<= m_aDefaultControl; + break; + case PROPERTY_ID_BACKGROUNDCOLOR: + rValue = m_aBackgroundColor; + break; + case PROPERTY_ID_ROWHEIGHT: + rValue = m_aRowHeight; + break; + default: + if ( isFontRelatedProperty( nHandle ) ) + FontControlModel::getFastPropertyValue( rValue, nHandle ); + else + OControlModel::getFastPropertyValue( rValue, nHandle ); + } +} + +sal_Bool OGridControlModel::convertFastPropertyValue( Any& rConvertedValue, Any& rOldValue, + sal_Int32 nHandle, const Any& rValue ) +{ + bool bModified(false); + switch (nHandle) + { + case PROPERTY_ID_CONTEXT_WRITING_MODE: + bModified = tryPropertyValue( rConvertedValue, rOldValue, rValue, m_nContextWritingMode ); + break; + case PROPERTY_ID_WRITING_MODE: + bModified = tryPropertyValue( rConvertedValue, rOldValue, rValue, m_nWritingMode ); + break; + case PROPERTY_ID_HELPTEXT: + bModified = tryPropertyValue(rConvertedValue, rOldValue, rValue, m_sHelpText); + break; + case PROPERTY_ID_HELPURL: + bModified = tryPropertyValue(rConvertedValue, rOldValue, rValue, m_sHelpURL); + break; + case PROPERTY_ID_DISPLAYSYNCHRON: + bModified = tryPropertyValue(rConvertedValue, rOldValue, rValue, m_bDisplaySynchron); + break; + case PROPERTY_ID_ALWAYSSHOWCURSOR: + bModified = tryPropertyValue(rConvertedValue, rOldValue, rValue, m_bAlwaysShowCursor); + break; + case PROPERTY_ID_CURSORCOLOR: + if (!rValue.hasValue() || !m_aCursorColor.hasValue()) + { + if (rValue.hasValue() && (TypeClass_LONG != rValue.getValueType().getTypeClass())) + { + throw IllegalArgumentException(); + } + rOldValue = m_aCursorColor; + rConvertedValue = rValue; + bModified = rOldValue != rConvertedValue; + } + else + bModified = tryPropertyValue(rConvertedValue, rOldValue, rValue, getINT32(m_aCursorColor)); + break; + case PROPERTY_ID_PRINTABLE: + bModified = tryPropertyValue(rConvertedValue, rOldValue, rValue, m_bPrintable); + break; + case PROPERTY_ID_TABSTOP: + bModified = tryPropertyValue(rConvertedValue, rOldValue, rValue, m_aTabStop, cppu::UnoType<bool>::get()); + break; + case PROPERTY_ID_HASNAVIGATION: + bModified = tryPropertyValue(rConvertedValue, rOldValue, rValue, m_bNavigation); + break; + case PROPERTY_ID_RECORDMARKER: + bModified = tryPropertyValue(rConvertedValue, rOldValue, rValue, m_bRecordMarker); + break; + case PROPERTY_ID_ENABLED: + bModified = tryPropertyValue(rConvertedValue, rOldValue, rValue, m_bEnable); + break; + case PROPERTY_ID_ENABLEVISIBLE: + bModified = tryPropertyValue(rConvertedValue, rOldValue, rValue, m_bEnableVisible); + break; + case PROPERTY_ID_BORDER: + bModified = tryPropertyValue(rConvertedValue, rOldValue, rValue, m_nBorder); + break; + case PROPERTY_ID_BORDERCOLOR: + bModified = tryPropertyValue(rConvertedValue, rOldValue, rValue, m_aBorderColor, cppu::UnoType<sal_Int32>::get()); + break; + case PROPERTY_ID_DEFAULTCONTROL: + bModified = tryPropertyValue(rConvertedValue, rOldValue, rValue, m_aDefaultControl); + break; + case PROPERTY_ID_BACKGROUNDCOLOR: + bModified = tryPropertyValue(rConvertedValue, rOldValue, rValue, m_aBackgroundColor, cppu::UnoType<sal_Int32>::get()); + break; + case PROPERTY_ID_ROWHEIGHT: + { + bModified = tryPropertyValue(rConvertedValue, rOldValue, rValue, m_aRowHeight, cppu::UnoType<sal_Int32>::get()); + sal_Int32 nNewVal( 0 ); + if ( ( rConvertedValue >>= nNewVal ) && ( nNewVal <= 0 ) ) + { + rConvertedValue.clear(); + bModified = m_aRowHeight.hasValue(); + } + } + break; + default: + if ( isFontRelatedProperty( nHandle ) ) + bModified = FontControlModel::convertFastPropertyValue( rConvertedValue, rOldValue, nHandle, rValue ); + else + bModified = OControlModel::convertFastPropertyValue( rConvertedValue, rOldValue, nHandle, rValue); + } + return bModified; +} +void OGridControlModel::setFastPropertyValue_NoBroadcast( sal_Int32 nHandle, const Any& rValue ) +{ + switch (nHandle) + { + case PROPERTY_ID_CONTEXT_WRITING_MODE: + rValue >>= m_nContextWritingMode; + break; + case PROPERTY_ID_WRITING_MODE: + rValue >>= m_nWritingMode; + break; + case PROPERTY_ID_HELPTEXT: + rValue >>= m_sHelpText; + break; + case PROPERTY_ID_HELPURL: + rValue >>= m_sHelpURL; + break; + case PROPERTY_ID_DISPLAYSYNCHRON: + m_bDisplaySynchron = getBOOL(rValue); + break; + case PROPERTY_ID_ALWAYSSHOWCURSOR: + m_bAlwaysShowCursor = getBOOL(rValue); + break; + case PROPERTY_ID_CURSORCOLOR: + m_aCursorColor = rValue; + break; + case PROPERTY_ID_PRINTABLE: + m_bPrintable = getBOOL(rValue); + break; + case PROPERTY_ID_TABSTOP: + m_aTabStop = rValue; + break; + case PROPERTY_ID_HASNAVIGATION: + m_bNavigation = getBOOL(rValue); + break; + case PROPERTY_ID_ENABLED: + m_bEnable = getBOOL(rValue); + break; + case PROPERTY_ID_ENABLEVISIBLE: + m_bEnableVisible = getBOOL(rValue); + break; + case PROPERTY_ID_RECORDMARKER: + m_bRecordMarker = getBOOL(rValue); + break; + case PROPERTY_ID_BORDER: + rValue >>= m_nBorder; + break; + case PROPERTY_ID_BORDERCOLOR: + m_aBorderColor = rValue; + break; + case PROPERTY_ID_DEFAULTCONTROL: + rValue >>= m_aDefaultControl; + break; + case PROPERTY_ID_BACKGROUNDCOLOR: + m_aBackgroundColor = rValue; + break; + case PROPERTY_ID_ROWHEIGHT: + m_aRowHeight = rValue; + break; + default: + if ( isFontRelatedProperty( nHandle ) ) + { + FontControlModel::setFastPropertyValue_NoBroadcast_impl( + *this, &OGridControlModel::setDependentFastPropertyValue, + nHandle, rValue); + } + else + OControlModel::setFastPropertyValue_NoBroadcast( nHandle, rValue ); + } +} + +//XPropertyState +Any OGridControlModel::getPropertyDefaultByHandle( sal_Int32 nHandle ) const +{ + Any aReturn; + switch (nHandle) + { + case PROPERTY_ID_CONTEXT_WRITING_MODE: + case PROPERTY_ID_WRITING_MODE: + aReturn <<= WritingMode2::CONTEXT; + break; + case PROPERTY_ID_DEFAULTCONTROL: + aReturn <<= OUString( STARDIV_ONE_FORM_CONTROL_GRID ); + break; + case PROPERTY_ID_PRINTABLE: + case PROPERTY_ID_HASNAVIGATION: + case PROPERTY_ID_RECORDMARKER: + case PROPERTY_ID_DISPLAYSYNCHRON: + case PROPERTY_ID_ENABLED: + case PROPERTY_ID_ENABLEVISIBLE: + aReturn <<= true; + break; + case PROPERTY_ID_ALWAYSSHOWCURSOR: + aReturn <<= false; + break; + case PROPERTY_ID_HELPURL: + case PROPERTY_ID_HELPTEXT: + aReturn <<= OUString(); + break; + case PROPERTY_ID_BORDER: + aReturn <<= sal_Int16(1); + break; + case PROPERTY_ID_BORDERCOLOR: + case PROPERTY_ID_TABSTOP: + case PROPERTY_ID_BACKGROUNDCOLOR: + case PROPERTY_ID_ROWHEIGHT: + case PROPERTY_ID_CURSORCOLOR: + // void + break; + default: + if ( isFontRelatedProperty( nHandle ) ) + aReturn = FontControlModel::getPropertyDefaultByHandle( nHandle ); + else + aReturn = OControlModel::getPropertyDefaultByHandle(nHandle); + } + return aReturn; +} + +void OGridControlModel::gotColumn( const Reference< XInterface >& _rxColumn ) +{ + Reference< XSQLErrorBroadcaster > xBroadcaster( _rxColumn, UNO_QUERY ); + if ( xBroadcaster.is() ) + xBroadcaster->addSQLErrorListener( this ); +} + +void OGridControlModel::lostColumn(const Reference< XInterface >& _rxColumn) +{ + if ( m_xSelection == _rxColumn ) + { // the currently selected element was replaced + m_xSelection.clear(); + EventObject aEvt( static_cast< XWeak* >( this ) ); + m_aSelectListeners.notifyEach( &XSelectionChangeListener::selectionChanged, aEvt ); + } + Reference< XSQLErrorBroadcaster > xBroadcaster( _rxColumn, UNO_QUERY ); + if ( xBroadcaster.is() ) + xBroadcaster->removeSQLErrorListener( this ); +} + +void OGridControlModel::implRemoved(const css::uno::Reference<css::uno::XInterface>& _rxObject) +{ + OInterfaceContainer::implRemoved(_rxObject); + lostColumn(_rxObject); +} + +void OGridControlModel::implInserted( const ElementDescription* _pElement ) +{ + OInterfaceContainer::implInserted( _pElement ); + gotColumn( _pElement->xInterface ); +} + +void OGridControlModel::impl_replacedElement( const ContainerEvent& _rEvent, ::osl::ClearableMutexGuard& _rInstanceLock ) +{ + Reference< XInterface > xOldColumn( _rEvent.ReplacedElement, UNO_QUERY ); + Reference< XInterface > xNewColumn( _rEvent.Element, UNO_QUERY ); + bool bNewSelection = ( xOldColumn == m_xSelection ); + lostColumn( xOldColumn ); + gotColumn( xNewColumn ); + if ( bNewSelection ) + m_xSelection.set( xNewColumn, UNO_QUERY ); + OInterfaceContainer::impl_replacedElement( _rEvent, _rInstanceLock ); + // < SYNCHRONIZED + if ( bNewSelection ) + { + m_aSelectListeners.notifyEach( &XSelectionChangeListener::selectionChanged, EventObject( *this ) ); + } +} + +ElementDescription* OGridControlModel::createElementMetaData( ) +{ + return new ElementDescription; +} + +void OGridControlModel::approveNewElement( const Reference< XPropertySet >& _rxObject, ElementDescription* _pElement ) +{ + OGridColumn* pCol = comphelper::getFromUnoTunnel<OGridColumn>( _rxObject ); + if ( !pCol ) + throw IllegalArgumentException(); + OInterfaceContainer::approveNewElement( _rxObject, _pElement ); +} + +// XPersistObject +OUString SAL_CALL OGridControlModel::getServiceName() +{ + return FRM_COMPONENT_GRID; // old (non-sun) name for compatibility! +} + +void OGridControlModel::write(const Reference<XObjectOutputStream>& _rxOutStream) +{ + OControlModel::write(_rxOutStream); + Reference<XMarkableStream> xMark(_rxOutStream, UNO_QUERY); + // 1. Version + _rxOutStream->writeShort(0x0008); + // 2. Columns + sal_Int32 nLen = getCount(); + _rxOutStream->writeLong(nLen); + for (sal_Int32 i = 0; i < nLen; i++) + { + // first the service name for the underlying model + OGridColumn* pCol = comphelper::getFromUnoTunnel<OGridColumn>(m_aItems[i]); + DBG_ASSERT(pCol != nullptr, "OGridControlModel::write : such items should never reach it into my container !"); + _rxOutStream << pCol->getModelName(); + // then the object itself + sal_Int32 nMark = xMark->createMark(); + sal_Int32 nObjLen = 0; + _rxOutStream->writeLong(nObjLen); + // writing the column + pCol->write(_rxOutStream); + // determining the length + nObjLen = xMark->offsetToMark(nMark) - 4; + xMark->jumpToMark(nMark); + _rxOutStream->writeLong(nObjLen); + xMark->jumpToFurthest(); + xMark->deleteMark(nMark); + } + // 3. Events + writeEvents(_rxOutStream); + // 4. Attributes + // Masking for all 'any' types + sal_uInt16 nAnyMask = 0; + if (m_aRowHeight.getValueType().getTypeClass() == TypeClass_LONG) + nAnyMask |= ROWHEIGHT; + if ( getFont() != getDefaultFont() ) + nAnyMask |= FONTATTRIBS | FONTSIZE | FONTTYPE | FONTDESCRIPTOR; + if (m_aTabStop.getValueType().getTypeClass() == TypeClass_BOOLEAN) + nAnyMask |= TABSTOP; + if ( hasTextColor() ) + nAnyMask |= TEXTCOLOR; + if (m_aBackgroundColor.getValueType().getTypeClass() == TypeClass_LONG) + nAnyMask |= BACKGROUNDCOLOR; + if (!m_bRecordMarker) + nAnyMask |= RECORDMARKER; + _rxOutStream->writeShort(nAnyMask); + if (nAnyMask & ROWHEIGHT) + _rxOutStream->writeLong(getINT32(m_aRowHeight)); + // old structures + const FontDescriptor& aFont = getFont(); + if ( nAnyMask & FONTDESCRIPTOR ) + { + // Attrib + _rxOutStream->writeShort( sal::static_int_cast< sal_Int16 >( vcl::unohelper::ConvertFontWeight( aFont.Weight ) ) ); + _rxOutStream->writeShort( sal::static_int_cast< sal_Int16 >( aFont.Slant ) ); + _rxOutStream->writeShort( aFont.Underline ); + _rxOutStream->writeShort( aFont.Strikeout ); + _rxOutStream->writeShort( sal_Int16(aFont.Orientation * 10) ); + _rxOutStream->writeBoolean( aFont.Kerning ); + _rxOutStream->writeBoolean( aFont.WordLineMode ); + // Size + _rxOutStream->writeLong( aFont.Width ); + _rxOutStream->writeLong( aFont.Height ); + _rxOutStream->writeShort( sal::static_int_cast< sal_Int16 >( vcl::unohelper::ConvertFontWidth( aFont.CharacterWidth ) ) ); + // Type + _rxOutStream->writeUTF( aFont.Name ); + _rxOutStream->writeUTF( aFont.StyleName ); + _rxOutStream->writeShort( aFont.Family ); + _rxOutStream->writeShort( aFont.CharSet ); + _rxOutStream->writeShort( aFont.Pitch ); + } + _rxOutStream << m_aDefaultControl; + _rxOutStream->writeShort(m_nBorder); + _rxOutStream->writeBoolean(m_bEnable); + if (nAnyMask & TABSTOP) + _rxOutStream->writeBoolean(getBOOL(m_aTabStop)); + _rxOutStream->writeBoolean(m_bNavigation); + if (nAnyMask & TEXTCOLOR) + _rxOutStream->writeLong( sal_Int32(getTextColor()) ); + // new since version 6 + _rxOutStream << m_sHelpText; + if (nAnyMask & FONTDESCRIPTOR) + _rxOutStream << getFont(); + if (nAnyMask & RECORDMARKER) + _rxOutStream->writeBoolean(m_bRecordMarker); + // new since version 7 + _rxOutStream->writeBoolean(m_bPrintable); + // new since version 8 + if (nAnyMask & BACKGROUNDCOLOR) + _rxOutStream->writeLong(getINT32(m_aBackgroundColor)); +} + +void OGridControlModel::read(const Reference<XObjectInputStream>& _rxInStream) +{ + SolarMutexGuard g; + OControlModel::read(_rxInStream); + Reference<XMarkableStream> xMark(_rxInStream, UNO_QUERY); + // 1. version + sal_Int16 nVersion = _rxInStream->readShort(); + // 2. reading the columns + sal_Int32 nLen = _rxInStream->readLong(); + if (nLen) + { + for (sal_Int32 i = 0; i < nLen; i++) + { + // reading the model names + OUString sModelName; + _rxInStream >> sModelName; + Reference<XPropertySet> xCol(createColumnById(getColumnTypeByModelName(sModelName))); + DBG_ASSERT(xCol.is(), "OGridControlModel::read : unknown column type !"); + sal_Int32 nObjLen = _rxInStream->readLong(); + if (nObjLen) + { + sal_Int32 nMark = xMark->createMark(); + if (xCol.is()) + { + OGridColumn* pCol = comphelper::getFromUnoTunnel<OGridColumn>(xCol); + pCol->read(_rxInStream); + } + xMark->jumpToMark(nMark); + _rxInStream->skipBytes(nObjLen); + xMark->deleteMark(nMark); + } + if ( xCol.is() ) + implInsert( i, xCol, false, nullptr, false ); + } + } + // In the base implementation events are only read, elements in the container exist + // but since before TF_ONE for the GridControl events were always written, so they + // need to be read, too + sal_Int32 nObjLen = _rxInStream->readLong(); + if (nObjLen) + { + sal_Int32 nMark = xMark->createMark(); + Reference<XPersistObject> xObj(m_xEventAttacher, UNO_QUERY); + if (xObj.is()) + xObj->read(_rxInStream); + xMark->jumpToMark(nMark); + _rxInStream->skipBytes(nObjLen); + xMark->deleteMark(nMark); + } + // reading the attachment + for (sal_Int32 i = 0; i < nLen; i++) + { + css::uno::Reference<css::uno::XInterface> xIfc(m_aItems[i], UNO_QUERY); + Reference<XPropertySet> xSet(xIfc, UNO_QUERY); + Any aHelper; + aHelper <<= xSet; + m_xEventAttacher->attach( i, xIfc, aHelper ); + } + // 4. reading the attributes + if (nVersion == 1) + return; + // Masking for any + sal_uInt16 nAnyMask = _rxInStream->readShort(); + if (nAnyMask & ROWHEIGHT) + { + sal_Int32 nValue = _rxInStream->readLong(); + m_aRowHeight <<= nValue; + } + FontDescriptor aFont( getFont() ); + if ( nAnyMask & FONTATTRIBS ) + { + aFont.Weight = static_cast<float>(vcl::unohelper::ConvertFontWeight( _rxInStream->readShort() )); + aFont.Slant = static_cast<FontSlant>(_rxInStream->readShort()); + aFont.Underline = _rxInStream->readShort(); + aFont.Strikeout = _rxInStream->readShort(); + aFont.Orientation = static_cast<float>(_rxInStream->readShort()) / 10; + aFont.Kerning = _rxInStream->readBoolean() != 0; + aFont.WordLineMode = _rxInStream->readBoolean() != 0; + } + if ( nAnyMask & FONTSIZE ) + { + aFont.Width = static_cast<sal_Int16>(_rxInStream->readLong()); + aFont.Height = static_cast<sal_Int16>(_rxInStream->readLong()); + aFont.CharacterWidth = static_cast<float>(vcl::unohelper::ConvertFontWidth( _rxInStream->readShort() )); + } + if ( nAnyMask & FONTTYPE ) + { + aFont.Name = _rxInStream->readUTF(); + aFont.StyleName = _rxInStream->readUTF(); + aFont.Family = _rxInStream->readShort(); + aFont.CharSet = _rxInStream->readShort(); + aFont.Pitch = _rxInStream->readShort(); + } + if ( nAnyMask & ( FONTATTRIBS | FONTSIZE | FONTTYPE ) ) + setFont( aFont ); + // Name + _rxInStream >> m_aDefaultControl; + m_nBorder = _rxInStream->readShort(); + m_bEnable = _rxInStream->readBoolean(); + if (nAnyMask & TABSTOP) + { + m_aTabStop <<= (_rxInStream->readBoolean() != 0); + } + if (nVersion > 3) + m_bNavigation = _rxInStream->readBoolean(); + if (nAnyMask & TEXTCOLOR) + { + sal_Int32 nValue = _rxInStream->readLong(); + setTextColor( ::Color(ColorTransparency, nValue) ); + } + // new since version 6 + if (nVersion > 5) + _rxInStream >> m_sHelpText; + if (nAnyMask & FONTDESCRIPTOR) + { + FontDescriptor aUNOFont; + _rxInStream >> aUNOFont; + setFont( aFont ); + } + if (nAnyMask & RECORDMARKER) + m_bRecordMarker = _rxInStream->readBoolean(); + // new since version 7 + if (nVersion > 6) + m_bPrintable = _rxInStream->readBoolean(); + if (nAnyMask & BACKGROUNDCOLOR) + { + sal_Int32 nValue = _rxInStream->readLong(); + m_aBackgroundColor <<= nValue; + } +} + +} + +extern "C" SAL_DLLPUBLIC_EXPORT XInterface* +com_sun_star_form_OGridControlModel_get_implementation(XComponentContext* component, + Sequence<Any> const &) +{ + return cppu::acquire(new frm::OGridControlModel(component)); +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |