bc91cc4750
Change-Id: Ia765a03e033acb82e367873380d289587ea87d6c Reviewed-on: https://gerrit.libreoffice.org/c/core/+/167449 Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk> Tested-by: Jenkins
687 lines
29 KiB
C++
687 lines
29 KiB
C++
/* -*- 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 <formcontrolfactory.hxx>
|
|
#include <fmcontrollayout.hxx>
|
|
#include <fmprop.hxx>
|
|
#include <svx/strings.hrc>
|
|
#include <fmservs.hxx>
|
|
#include <svx/dialmgr.hxx>
|
|
#include <svx/svdouno.hxx>
|
|
|
|
#include <com/sun/star/form/XFormComponent.hpp>
|
|
#include <com/sun/star/form/FormComponentType.hpp>
|
|
#include <com/sun/star/awt/ScrollBarOrientation.hpp>
|
|
#include <com/sun/star/awt/MouseWheelBehavior.hpp>
|
|
#include <com/sun/star/form/XGridColumnFactory.hpp>
|
|
#include <com/sun/star/style/VerticalAlignment.hpp>
|
|
#include <com/sun/star/awt/LineEndFormat.hpp>
|
|
#include <com/sun/star/awt/ImageScaleMode.hpp>
|
|
#include <com/sun/star/sdbc/DataType.hpp>
|
|
#include <com/sun/star/sdbc/XDataSource.hpp>
|
|
#include <com/sun/star/util/XNumberFormatTypes.hpp>
|
|
#include <com/sun/star/sdbc/ColumnValue.hpp>
|
|
#include <com/sun/star/text/WritingMode2.hpp>
|
|
|
|
#include <comphelper/numbers.hxx>
|
|
#include <comphelper/processfactory.hxx>
|
|
#include <unotools/syslocale.hxx>
|
|
#include <tools/gen.hxx>
|
|
#include <comphelper/diagnose_ex.hxx>
|
|
#include <connectivity/dbtools.hxx>
|
|
#include <i18nlangtag/languagetag.hxx>
|
|
|
|
#include <set>
|
|
|
|
using namespace ::dbtools;
|
|
|
|
namespace svxform
|
|
{
|
|
|
|
|
|
using ::com::sun::star::uno::Reference;
|
|
using ::com::sun::star::uno::UNO_QUERY;
|
|
using ::com::sun::star::uno::UNO_QUERY_THROW;
|
|
using ::com::sun::star::uno::UNO_SET_THROW;
|
|
using ::com::sun::star::uno::Exception;
|
|
using ::com::sun::star::uno::Any;
|
|
using ::com::sun::star::uno::Sequence;
|
|
using ::com::sun::star::uno::XComponentContext;
|
|
using ::com::sun::star::beans::XPropertySet;
|
|
using ::com::sun::star::form::XFormComponent;
|
|
using ::com::sun::star::container::XIndexAccess;
|
|
using ::com::sun::star::beans::XPropertySetInfo;
|
|
using ::com::sun::star::beans::PropertyValue;
|
|
using ::com::sun::star::container::XChild;
|
|
using ::com::sun::star::form::XGridColumnFactory;
|
|
using ::com::sun::star::style::VerticalAlignment_MIDDLE;
|
|
using ::com::sun::star::beans::Property;
|
|
using ::com::sun::star::uno::TypeClass_DOUBLE;
|
|
using ::com::sun::star::uno::TypeClass_LONG;
|
|
using ::com::sun::star::util::XNumberFormats;
|
|
using ::com::sun::star::util::XNumberFormatTypes;
|
|
using ::com::sun::star::lang::XServiceInfo;
|
|
using ::com::sun::star::container::XNameAccess;
|
|
|
|
namespace FormComponentType = ::com::sun::star::form::FormComponentType;
|
|
namespace ScrollBarOrientation = ::com::sun::star::awt::ScrollBarOrientation;
|
|
namespace MouseWheelBehavior = ::com::sun::star::awt::MouseWheelBehavior;
|
|
namespace LineEndFormat = ::com::sun::star::awt::LineEndFormat;
|
|
namespace ImageScaleMode = ::com::sun::star::awt::ImageScaleMode;
|
|
namespace DataType = ::com::sun::star::sdbc::DataType;
|
|
namespace ColumnValue = ::com::sun::star::sdbc::ColumnValue;
|
|
namespace WritingMode2 = ::com::sun::star::text::WritingMode2;
|
|
|
|
FormControlFactory::FormControlFactory( const Reference<XComponentContext>& _rContext )
|
|
:m_xContext( _rContext )
|
|
{
|
|
}
|
|
|
|
FormControlFactory::FormControlFactory( )
|
|
:m_xContext( comphelper::getProcessComponentContext() )
|
|
{
|
|
}
|
|
|
|
|
|
FormControlFactory::~FormControlFactory()
|
|
{
|
|
}
|
|
|
|
|
|
sal_Int16 FormControlFactory::initializeControlModel( const DocumentType _eDocType, const SdrUnoObj& _rObject )
|
|
{
|
|
return initializeControlModel(
|
|
_eDocType,
|
|
Reference< XPropertySet >( _rObject.GetUnoControlModel(), UNO_QUERY ),
|
|
_rObject.GetCurrentBoundRect()
|
|
);
|
|
}
|
|
|
|
|
|
void FormControlFactory::initializeControlModel( const DocumentType _eDocType, const Reference< XPropertySet >& _rxControlModel )
|
|
{
|
|
initializeControlModel(
|
|
_eDocType, _rxControlModel, tools::Rectangle()
|
|
);
|
|
}
|
|
|
|
|
|
namespace
|
|
{
|
|
|
|
OUString lcl_getUniqueLabel_nothrow( const Reference< XPropertySet >& _rxControlModel, const OUString& _rBaseLabel )
|
|
{
|
|
OUString sLabel( _rBaseLabel );
|
|
try
|
|
{
|
|
typedef ::std::set< OUString > StringBag;
|
|
StringBag aUsedLabels;
|
|
|
|
Reference< XFormComponent > xFormComponent( _rxControlModel, UNO_QUERY_THROW );
|
|
Reference< XIndexAccess > xContainer( xFormComponent->getParent(), UNO_QUERY_THROW );
|
|
// loop through all siblings of the control model, and collect their labels
|
|
for ( sal_Int32 index=xContainer->getCount(); index>0; )
|
|
{
|
|
Reference< XPropertySet > xElement( xContainer->getByIndex( --index ), UNO_QUERY_THROW );
|
|
if ( xElement == _rxControlModel )
|
|
continue;
|
|
|
|
Reference< XPropertySetInfo > xPSI( xElement->getPropertySetInfo(), UNO_SET_THROW );
|
|
if ( !xPSI->hasPropertyByName( FM_PROP_LABEL ) )
|
|
continue;
|
|
|
|
OUString sElementLabel;
|
|
OSL_VERIFY( xElement->getPropertyValue( FM_PROP_LABEL ) >>= sElementLabel );
|
|
aUsedLabels.insert( sElementLabel );
|
|
}
|
|
|
|
// now find a free label
|
|
sal_Int32 i=2;
|
|
while ( aUsedLabels.find( sLabel ) != aUsedLabels.end() )
|
|
sLabel = _rBaseLabel + " " + OUString::number( i++ );
|
|
}
|
|
catch( const Exception& )
|
|
{
|
|
DBG_UNHANDLED_EXCEPTION("svx");
|
|
}
|
|
return sLabel;
|
|
}
|
|
|
|
|
|
Sequence< PropertyValue > lcl_getDataSourceIndirectProperties( const Reference< XPropertySet >& _rxControlModel,
|
|
const Reference<XComponentContext>& _rContext )
|
|
{
|
|
OSL_PRECOND( _rxControlModel.is(), "lcl_getDataSourceIndirectProperties: invalid model!" );
|
|
|
|
Sequence< PropertyValue > aInfo;
|
|
try
|
|
{
|
|
Reference< XChild > xChild( _rxControlModel, UNO_QUERY );
|
|
Reference< XPropertySet > xForm;
|
|
if ( xChild.is() )
|
|
xForm.set(xChild->getParent(), css::uno::UNO_QUERY);
|
|
|
|
if ( Reference< XGridColumnFactory >( xForm, UNO_QUERY ).is() )
|
|
{ // hmm. the model is a grid column, in real
|
|
xChild.set(xForm, css::uno::UNO_QUERY);
|
|
xForm.set(xChild->getParent(), css::uno::UNO_QUERY);
|
|
}
|
|
|
|
OSL_ENSURE( xForm.is(), "lcl_getDataSourceIndirectProperties: could not determine the form!" );
|
|
if ( !xForm.is() )
|
|
return aInfo;
|
|
OUString sDataSourceName;
|
|
xForm->getPropertyValue( FM_PROP_DATASOURCE ) >>= sDataSourceName;
|
|
|
|
Reference< XPropertySet > xDsProperties;
|
|
if ( !sDataSourceName.isEmpty() )
|
|
xDsProperties.set(getDataSource( sDataSourceName, _rContext ), css::uno::UNO_QUERY);
|
|
if ( xDsProperties.is() )
|
|
xDsProperties->getPropertyValue(u"Info"_ustr) >>= aInfo;
|
|
}
|
|
catch( const Exception& )
|
|
{
|
|
TOOLS_WARN_EXCEPTION( "svx", "lcl_getDataSourceIndirectProperties" );
|
|
}
|
|
return aInfo;
|
|
}
|
|
|
|
|
|
constexpr OUString aCharacterAndParagraphProperties[]
|
|
{
|
|
u"CharFontName"_ustr,
|
|
u"CharFontStyleName"_ustr,
|
|
u"CharFontFamily"_ustr,
|
|
u"CharFontCharSet"_ustr,
|
|
u"CharFontPitch"_ustr,
|
|
u"CharColor"_ustr,
|
|
u"CharEscapement"_ustr,
|
|
u"CharHeight"_ustr,
|
|
u"CharUnderline"_ustr,
|
|
u"CharWeight"_ustr,
|
|
u"CharPosture"_ustr,
|
|
u"CharAutoKerning"_ustr,
|
|
u"CharBackColor"_ustr,
|
|
u"CharBackTransparent"_ustr,
|
|
u"CharCaseMap"_ustr,
|
|
u"CharCrossedOut"_ustr,
|
|
u"CharFlash"_ustr,
|
|
u"CharStrikeout"_ustr,
|
|
u"CharWordMode"_ustr,
|
|
u"CharKerning"_ustr,
|
|
u"CharLocale"_ustr,
|
|
u"CharKeepTogether"_ustr,
|
|
u"CharNoLineBreak"_ustr,
|
|
u"CharShadowed"_ustr,
|
|
u"CharFontType"_ustr,
|
|
u"CharStyleName"_ustr,
|
|
u"CharContoured"_ustr,
|
|
u"CharCombineIsOn"_ustr,
|
|
u"CharCombinePrefix"_ustr,
|
|
u"CharCombineSuffix"_ustr,
|
|
u"CharEmphasize"_ustr,
|
|
u"CharRelief"_ustr,
|
|
u"RubyText"_ustr,
|
|
u"RubyAdjust"_ustr,
|
|
u"RubyCharStyleName"_ustr,
|
|
u"RubyIsAbove"_ustr,
|
|
u"CharRotation"_ustr,
|
|
u"CharRotationIsFitToLine"_ustr,
|
|
u"CharScaleWidth"_ustr,
|
|
u"HyperLinkURL"_ustr,
|
|
u"HyperLinkTarget"_ustr,
|
|
u"HyperLinkName"_ustr,
|
|
u"VisitedCharStyleName"_ustr,
|
|
u"UnvisitedCharStyleName"_ustr,
|
|
u"CharEscapementHeight"_ustr,
|
|
u"CharNoHyphenation"_ustr,
|
|
u"CharUnderlineColor"_ustr,
|
|
u"CharUnderlineHasColor"_ustr,
|
|
u"CharStyleNames"_ustr,
|
|
u"CharHeightAsian"_ustr,
|
|
u"CharWeightAsian"_ustr,
|
|
u"CharFontNameAsian"_ustr,
|
|
u"CharFontStyleNameAsian"_ustr,
|
|
u"CharFontFamilyAsian"_ustr,
|
|
u"CharFontCharSetAsian"_ustr,
|
|
u"CharFontPitchAsian"_ustr,
|
|
u"CharPostureAsian"_ustr,
|
|
u"CharLocaleAsian"_ustr,
|
|
u"ParaIsCharacterDistance"_ustr,
|
|
u"ParaIsForbiddenRules"_ustr,
|
|
u"ParaIsHangingPunctuation"_ustr,
|
|
u"CharHeightComplex"_ustr,
|
|
u"CharWeightComplex"_ustr,
|
|
u"CharFontNameComplex"_ustr,
|
|
u"CharFontStyleNameComplex"_ustr,
|
|
u"CharFontFamilyComplex"_ustr,
|
|
u"CharFontCharSetComplex"_ustr,
|
|
u"CharFontPitchComplex"_ustr,
|
|
u"CharPostureComplex"_ustr,
|
|
u"CharLocaleComplex"_ustr,
|
|
u"ParaAdjust"_ustr,
|
|
u"ParaLineSpacing"_ustr,
|
|
u"ParaBackColor"_ustr,
|
|
u"ParaBackTransparent"_ustr,
|
|
u"ParaBackGraphic"_ustr,
|
|
u"ParaBackGraphicURL"_ustr,
|
|
u"ParaBackGraphicFilter"_ustr,
|
|
u"ParaBackGraphicLocation"_ustr,
|
|
u"ParaLastLineAdjust"_ustr,
|
|
u"ParaExpandSingleWord"_ustr,
|
|
u"ParaLeftMargin"_ustr,
|
|
u"ParaRightMargin"_ustr,
|
|
u"ParaTopMargin"_ustr,
|
|
u"ParaBottomMargin"_ustr,
|
|
u"ParaLineNumberCount"_ustr,
|
|
u"ParaLineNumberStartValue"_ustr,
|
|
u"PageDescName"_ustr,
|
|
u"PageNumberOffset"_ustr,
|
|
u"ParaRegisterModeActive"_ustr,
|
|
u"ParaTabStops"_ustr,
|
|
u"ParaStyleName"_ustr,
|
|
u"DropCapFormat"_ustr,
|
|
u"DropCapWholeWord"_ustr,
|
|
u"ParaKeepTogether"_ustr,
|
|
u"Setting"_ustr,
|
|
u"ParaSplit"_ustr,
|
|
u"Setting"_ustr,
|
|
u"NumberingLevel"_ustr,
|
|
u"NumberingRules"_ustr,
|
|
u"NumberingStartValue"_ustr,
|
|
u"ParaIsNumberingRestart"_ustr,
|
|
u"NumberingStyleName"_ustr,
|
|
u"ParaOrphans"_ustr,
|
|
u"ParaWidows"_ustr,
|
|
u"ParaShadowFormat"_ustr,
|
|
u"LeftBorder"_ustr,
|
|
u"RightBorder"_ustr,
|
|
u"TopBorder"_ustr,
|
|
u"BottomBorder"_ustr,
|
|
u"BorderDistance"_ustr,
|
|
u"LeftBorderDistance"_ustr,
|
|
u"RightBorderDistance"_ustr,
|
|
u"TopBorderDistance"_ustr,
|
|
u"BottomBorderDistance"_ustr,
|
|
u"BreakType"_ustr,
|
|
u"DropCapCharStyleName"_ustr,
|
|
u"ParaFirstLineIndent"_ustr,
|
|
u"ParaIsAutoFirstLineIndent"_ustr,
|
|
u"ParaIsHyphenation"_ustr,
|
|
u"ParaHyphenationMaxHyphens"_ustr,
|
|
u"ParaHyphenationMaxLeadingChars"_ustr,
|
|
u"ParaHyphenationMaxTrailingChars"_ustr,
|
|
u"ParaVertAlignment"_ustr,
|
|
u"ParaUserDefinedAttributes"_ustr,
|
|
u"NumberingIsNumber"_ustr,
|
|
u"ParaIsConnectBorder"_ustr
|
|
};
|
|
|
|
|
|
void lcl_initializeCharacterAttributes( const Reference< XPropertySet >& _rxModel )
|
|
{
|
|
try
|
|
{
|
|
Reference< XPropertySet > xStyle( ControlLayouter::getDefaultDocumentTextStyle( _rxModel ), UNO_SET_THROW );
|
|
|
|
// transfer all properties which are described by the style
|
|
Reference< XPropertySetInfo > xSourcePropInfo( xStyle->getPropertySetInfo(), UNO_SET_THROW );
|
|
Reference< XPropertySetInfo > xDestPropInfo( _rxModel->getPropertySetInfo(), UNO_SET_THROW );
|
|
|
|
for (const OUString & sPropertyName : aCharacterAndParagraphProperties)
|
|
{
|
|
if ( xSourcePropInfo->hasPropertyByName( sPropertyName ) && xDestPropInfo->hasPropertyByName( sPropertyName ) )
|
|
_rxModel->setPropertyValue( sPropertyName, xStyle->getPropertyValue( sPropertyName ) );
|
|
}
|
|
}
|
|
catch( const Exception& )
|
|
{
|
|
DBG_UNHANDLED_EXCEPTION("svx");
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
sal_Int16 FormControlFactory::initializeControlModel( const DocumentType _eDocType, const Reference< XPropertySet >& _rxControlModel,
|
|
const tools::Rectangle& _rControlBoundRect )
|
|
{
|
|
sal_Int16 nClassId = FormComponentType::CONTROL;
|
|
|
|
OSL_ENSURE( _rxControlModel.is(), "FormControlFactory::initializeControlModel: invalid model!" );
|
|
if ( !_rxControlModel.is() )
|
|
return nClassId;
|
|
|
|
try
|
|
{
|
|
ControlLayouter::initializeControlLayout( _rxControlModel, _eDocType );
|
|
|
|
_rxControlModel->getPropertyValue( FM_PROP_CLASSID ) >>= nClassId;
|
|
Reference< XPropertySetInfo > xPSI( _rxControlModel->getPropertySetInfo(), UNO_SET_THROW );
|
|
switch ( nClassId )
|
|
{
|
|
case FormComponentType::SCROLLBAR:
|
|
_rxControlModel->setPropertyValue(u"LiveScroll"_ustr, Any( true ) );
|
|
[[fallthrough]];
|
|
case FormComponentType::SPINBUTTON:
|
|
{
|
|
sal_Int32 eOrientation = ScrollBarOrientation::HORIZONTAL;
|
|
if ( !_rControlBoundRect.IsEmpty() && ( _rControlBoundRect.GetWidth() < _rControlBoundRect.GetHeight() ) )
|
|
eOrientation = ScrollBarOrientation::VERTICAL;
|
|
_rxControlModel->setPropertyValue( FM_PROP_ORIENTATION, Any( eOrientation ) );
|
|
}
|
|
break;
|
|
|
|
case FormComponentType::LISTBOX:
|
|
case FormComponentType::COMBOBOX:
|
|
{
|
|
bool bDropDown = !_rControlBoundRect.IsEmpty() && ( _rControlBoundRect.GetWidth() >= 3 * _rControlBoundRect.GetHeight() );
|
|
if ( xPSI->hasPropertyByName( FM_PROP_DROPDOWN ) )
|
|
_rxControlModel->setPropertyValue( FM_PROP_DROPDOWN, Any( bDropDown ) );
|
|
_rxControlModel->setPropertyValue( FM_PROP_LINECOUNT, Any( sal_Int16( 20 ) ) );
|
|
}
|
|
break;
|
|
|
|
case FormComponentType::TEXTFIELD:
|
|
{
|
|
initializeTextFieldLineEnds( _rxControlModel );
|
|
lcl_initializeCharacterAttributes( _rxControlModel );
|
|
|
|
if ( !_rControlBoundRect.IsEmpty()
|
|
&& ( _rControlBoundRect.GetWidth() <= 4 * _rControlBoundRect.GetHeight() )
|
|
)
|
|
{
|
|
if ( xPSI->hasPropertyByName( FM_PROP_MULTILINE ) )
|
|
_rxControlModel->setPropertyValue( FM_PROP_MULTILINE, Any( true ) );
|
|
}
|
|
}
|
|
break;
|
|
|
|
case FormComponentType::RADIOBUTTON:
|
|
case FormComponentType::CHECKBOX:
|
|
case FormComponentType::FIXEDTEXT:
|
|
{
|
|
OUString sVertAlignPropertyName( u"VerticalAlign"_ustr );
|
|
if ( xPSI->hasPropertyByName( sVertAlignPropertyName ) )
|
|
_rxControlModel->setPropertyValue( sVertAlignPropertyName, Any( VerticalAlignment_MIDDLE ) );
|
|
}
|
|
break;
|
|
|
|
case FormComponentType::IMAGEBUTTON:
|
|
case FormComponentType::IMAGECONTROL:
|
|
{
|
|
static constexpr OUString sScaleModeProperty( u"ScaleMode"_ustr );
|
|
if ( xPSI->hasPropertyByName( sScaleModeProperty ) )
|
|
_rxControlModel->setPropertyValue( sScaleModeProperty, Any( ImageScaleMode::ISOTROPIC ) );
|
|
}
|
|
break;
|
|
}
|
|
|
|
// initial default label for the control
|
|
if ( xPSI->hasPropertyByName( FM_PROP_LABEL ) )
|
|
{
|
|
OUString sExistingLabel;
|
|
OSL_VERIFY( _rxControlModel->getPropertyValue( FM_PROP_LABEL ) >>= sExistingLabel );
|
|
if ( sExistingLabel.isEmpty() )
|
|
{
|
|
OUString sInitialLabel;
|
|
OSL_VERIFY( _rxControlModel->getPropertyValue( FM_PROP_NAME ) >>= sInitialLabel );
|
|
|
|
TranslateId pTitleResId;
|
|
switch ( nClassId )
|
|
{
|
|
case FormComponentType::COMMANDBUTTON: pTitleResId = RID_STR_PROPTITLE_PUSHBUTTON; break;
|
|
case FormComponentType::RADIOBUTTON: pTitleResId = RID_STR_PROPTITLE_RADIOBUTTON; break;
|
|
case FormComponentType::CHECKBOX: pTitleResId = RID_STR_PROPTITLE_CHECKBOX; break;
|
|
case FormComponentType::GROUPBOX: pTitleResId = RID_STR_PROPTITLE_GROUPBOX; break;
|
|
case FormComponentType::FIXEDTEXT: pTitleResId = RID_STR_PROPTITLE_FIXEDTEXT; break;
|
|
}
|
|
|
|
if (pTitleResId)
|
|
sInitialLabel = SvxResId(pTitleResId);
|
|
|
|
_rxControlModel->setPropertyValue(
|
|
FM_PROP_LABEL,
|
|
Any( lcl_getUniqueLabel_nothrow( _rxControlModel, sInitialLabel ) )
|
|
);
|
|
}
|
|
}
|
|
|
|
// strict format = yes is the default (i93467)
|
|
if ( xPSI->hasPropertyByName( FM_PROP_STRICTFORMAT ) )
|
|
{
|
|
_rxControlModel->setPropertyValue( FM_PROP_STRICTFORMAT, Any( true ) );
|
|
}
|
|
|
|
// mouse wheel: don't use it for scrolling by default (i110036)
|
|
if ( xPSI->hasPropertyByName( FM_PROP_MOUSE_WHEEL_BEHAVIOR ) )
|
|
{
|
|
_rxControlModel->setPropertyValue( FM_PROP_MOUSE_WHEEL_BEHAVIOR, Any( MouseWheelBehavior::SCROLL_DISABLED ) );
|
|
}
|
|
|
|
if ( xPSI->hasPropertyByName( FM_PROP_WRITING_MODE ) )
|
|
_rxControlModel->setPropertyValue( FM_PROP_WRITING_MODE, Any( WritingMode2::CONTEXT ) );
|
|
}
|
|
catch( const Exception& )
|
|
{
|
|
DBG_UNHANDLED_EXCEPTION("svx");
|
|
}
|
|
return nClassId;
|
|
}
|
|
|
|
|
|
void FormControlFactory::initializeTextFieldLineEnds( const Reference< XPropertySet >& _rxModel )
|
|
{
|
|
OSL_PRECOND( _rxModel.is(), "initializeTextFieldLineEnds: invalid model!" );
|
|
if ( !_rxModel.is() )
|
|
return;
|
|
|
|
try
|
|
{
|
|
Reference< XPropertySetInfo > xInfo = _rxModel->getPropertySetInfo();
|
|
if ( !xInfo.is() || !xInfo->hasPropertyByName( FM_PROP_LINEENDFORMAT ) )
|
|
return;
|
|
|
|
// let's see if the data source which the form belongs to (if any)
|
|
// has a setting for the preferred line end format
|
|
bool bDosLineEnds = false;
|
|
const Sequence< PropertyValue > aInfo = lcl_getDataSourceIndirectProperties( _rxModel, m_xContext );
|
|
const PropertyValue* pInfo = std::find_if(aInfo.begin(), aInfo.end(),
|
|
[](const PropertyValue& rInfo) { return rInfo.Name == "PreferDosLikeLineEnds"; });
|
|
if (pInfo != aInfo.end())
|
|
pInfo->Value >>= bDosLineEnds;
|
|
|
|
sal_Int16 nLineEndFormat = bDosLineEnds ? LineEndFormat::CARRIAGE_RETURN_LINE_FEED : LineEndFormat::LINE_FEED;
|
|
_rxModel->setPropertyValue( FM_PROP_LINEENDFORMAT, Any( nLineEndFormat ) );
|
|
}
|
|
catch( const Exception& )
|
|
{
|
|
DBG_UNHANDLED_EXCEPTION("svx");
|
|
}
|
|
}
|
|
|
|
|
|
void FormControlFactory::initializeFieldDependentProperties( const Reference< XPropertySet >& _rxDatabaseField,
|
|
const Reference< XPropertySet >& _rxControlModel, const Reference< XNumberFormats >& _rxNumberFormats )
|
|
{
|
|
OSL_PRECOND( _rxDatabaseField.is() && _rxControlModel.is(),
|
|
"FormControlFactory::initializeFieldDependentProperties: illegal params!" );
|
|
if ( !_rxDatabaseField.is() || !_rxControlModel.is() )
|
|
return;
|
|
|
|
try
|
|
{
|
|
|
|
// if the field has a numeric format, and the model has a "Scale" property, sync it
|
|
Reference< XPropertySetInfo > xFieldPSI( _rxDatabaseField->getPropertySetInfo(), UNO_SET_THROW );
|
|
Reference< XPropertySetInfo > xModelPSI( _rxControlModel->getPropertySetInfo(), UNO_SET_THROW );
|
|
|
|
if ( xModelPSI->hasPropertyByName( FM_PROP_DECIMAL_ACCURACY ) )
|
|
{
|
|
sal_Int32 nFormatKey = 0;
|
|
if ( xFieldPSI->hasPropertyByName( FM_PROP_FORMATKEY ) )
|
|
{
|
|
_rxDatabaseField->getPropertyValue( FM_PROP_FORMATKEY ) >>= nFormatKey;
|
|
}
|
|
else
|
|
{
|
|
nFormatKey = getDefaultNumberFormat(
|
|
_rxDatabaseField,
|
|
Reference< XNumberFormatTypes >( _rxNumberFormats, UNO_QUERY ),
|
|
SvtSysLocale().GetLanguageTag().getLocale()
|
|
);
|
|
}
|
|
|
|
Any aScaleVal( ::comphelper::getNumberFormatDecimals( _rxNumberFormats, nFormatKey ) );
|
|
_rxControlModel->setPropertyValue( FM_PROP_DECIMAL_ACCURACY, aScaleVal );
|
|
}
|
|
|
|
|
|
// minimum and maximum of the control according to the type of the database field
|
|
sal_Int32 nDataType = DataType::OTHER;
|
|
OSL_VERIFY( _rxDatabaseField->getPropertyValue( FM_PROP_FIELDTYPE ) >>= nDataType );
|
|
|
|
if ( xModelPSI->hasPropertyByName( FM_PROP_VALUEMIN )
|
|
&& xModelPSI->hasPropertyByName( FM_PROP_VALUEMAX )
|
|
)
|
|
{
|
|
sal_Int32 nMinValue = -1000000000, nMaxValue = 1000000000;
|
|
switch ( nDataType )
|
|
{
|
|
case DataType::TINYINT : nMinValue = 0; nMaxValue = 255; break;
|
|
case DataType::SMALLINT : nMinValue = -32768; nMaxValue = 32767; break;
|
|
case DataType::INTEGER : nMinValue = 0x80000000; nMaxValue = 0x7FFFFFFF; break;
|
|
// double and singles are ignored
|
|
}
|
|
|
|
Any aValue;
|
|
|
|
// both the minimum and the maximum value properties can be either Long or Double
|
|
Property aProperty = xModelPSI->getPropertyByName( FM_PROP_VALUEMIN );
|
|
if ( aProperty.Type.getTypeClass() == TypeClass_DOUBLE )
|
|
aValue <<= static_cast<double>(nMinValue);
|
|
else if ( aProperty.Type.getTypeClass() == TypeClass_LONG )
|
|
aValue <<= nMinValue;
|
|
else
|
|
{
|
|
OSL_FAIL( "FormControlFactory::initializeFieldDependentProperties: unexpected property type (MinValue)!" );
|
|
}
|
|
_rxControlModel->setPropertyValue( FM_PROP_VALUEMIN, aValue );
|
|
|
|
// both the minimum and the maximum value properties can be either Long or Double
|
|
aProperty = xModelPSI->getPropertyByName( FM_PROP_VALUEMAX );
|
|
if ( aProperty.Type.getTypeClass() == TypeClass_DOUBLE )
|
|
aValue <<= static_cast<double>(nMaxValue);
|
|
else if ( aProperty.Type.getTypeClass() == TypeClass_LONG )
|
|
aValue <<= nMaxValue;
|
|
else
|
|
{
|
|
OSL_FAIL( "FormControlFactory::initializeFieldDependentProperties: unexpected property type (MaxValue)!" );
|
|
}
|
|
_rxControlModel->setPropertyValue( FM_PROP_VALUEMAX, aValue );
|
|
}
|
|
|
|
|
|
// a check box can be tristate if and only if the column it is bound to is nullable
|
|
sal_Int16 nClassId = FormComponentType::CONTROL;
|
|
OSL_VERIFY( _rxControlModel->getPropertyValue( FM_PROP_CLASSID ) >>= nClassId );
|
|
if ( nClassId == FormComponentType::CHECKBOX )
|
|
{
|
|
sal_Int32 nNullable = ColumnValue::NULLABLE_UNKNOWN;
|
|
OSL_VERIFY( _rxDatabaseField->getPropertyValue( FM_PROP_ISNULLABLE ) >>= nNullable );
|
|
_rxControlModel->setPropertyValue( FM_PROP_TRISTATE, Any( ColumnValue::NO_NULLS != nNullable ) );
|
|
}
|
|
}
|
|
catch( const Exception& )
|
|
{
|
|
DBG_UNHANDLED_EXCEPTION("svx");
|
|
}
|
|
}
|
|
|
|
|
|
OUString FormControlFactory::getDefaultName( sal_Int16 _nClassId, const Reference< XServiceInfo >& _rxObject )
|
|
{
|
|
TranslateId pResId;
|
|
|
|
switch ( _nClassId )
|
|
{
|
|
case FormComponentType::COMMANDBUTTON: pResId = RID_STR_PROPTITLE_PUSHBUTTON; break;
|
|
case FormComponentType::RADIOBUTTON: pResId = RID_STR_PROPTITLE_RADIOBUTTON; break;
|
|
case FormComponentType::CHECKBOX: pResId = RID_STR_PROPTITLE_CHECKBOX; break;
|
|
case FormComponentType::LISTBOX: pResId = RID_STR_PROPTITLE_LISTBOX; break;
|
|
case FormComponentType::COMBOBOX: pResId = RID_STR_PROPTITLE_COMBOBOX; break;
|
|
case FormComponentType::GROUPBOX: pResId = RID_STR_PROPTITLE_GROUPBOX; break;
|
|
case FormComponentType::IMAGEBUTTON: pResId = RID_STR_PROPTITLE_IMAGEBUTTON; break;
|
|
case FormComponentType::FIXEDTEXT: pResId = RID_STR_PROPTITLE_FIXEDTEXT; break;
|
|
case FormComponentType::GRIDCONTROL: pResId = RID_STR_PROPTITLE_DBGRID; break;
|
|
case FormComponentType::FILECONTROL: pResId = RID_STR_PROPTITLE_FILECONTROL; break;
|
|
case FormComponentType::DATEFIELD: pResId = RID_STR_PROPTITLE_DATEFIELD; break;
|
|
case FormComponentType::TIMEFIELD: pResId = RID_STR_PROPTITLE_TIMEFIELD; break;
|
|
case FormComponentType::NUMERICFIELD: pResId = RID_STR_PROPTITLE_NUMERICFIELD; break;
|
|
case FormComponentType::CURRENCYFIELD: pResId = RID_STR_PROPTITLE_CURRENCYFIELD; break;
|
|
case FormComponentType::PATTERNFIELD: pResId = RID_STR_PROPTITLE_PATTERNFIELD; break;
|
|
case FormComponentType::IMAGECONTROL: pResId = RID_STR_PROPTITLE_IMAGECONTROL; break;
|
|
case FormComponentType::HIDDENCONTROL: pResId = RID_STR_PROPTITLE_HIDDEN; break;
|
|
case FormComponentType::SCROLLBAR: pResId = RID_STR_PROPTITLE_SCROLLBAR; break;
|
|
case FormComponentType::SPINBUTTON: pResId = RID_STR_PROPTITLE_SPINBUTTON; break;
|
|
case FormComponentType::NAVIGATIONBAR: pResId = RID_STR_PROPTITLE_NAVBAR; break;
|
|
|
|
case FormComponentType::TEXTFIELD:
|
|
pResId = RID_STR_PROPTITLE_EDIT;
|
|
if ( _rxObject.is() && _rxObject->supportsService( FM_SUN_COMPONENT_FORMATTEDFIELD ) )
|
|
pResId = RID_STR_PROPTITLE_FORMATTED;
|
|
break;
|
|
|
|
default:
|
|
pResId = RID_STR_CONTROL; break;
|
|
}
|
|
|
|
return SvxResId(pResId);
|
|
}
|
|
|
|
|
|
OUString FormControlFactory::getDefaultUniqueName_ByComponentType( const Reference< XNameAccess >& _rxContainer,
|
|
const Reference< XPropertySet >& _rxObject )
|
|
{
|
|
sal_Int16 nClassId = FormComponentType::CONTROL;
|
|
OSL_VERIFY( _rxObject->getPropertyValue( FM_PROP_CLASSID ) >>= nClassId );
|
|
OUString sBaseName = getDefaultName( nClassId, Reference< XServiceInfo >( _rxObject, UNO_QUERY ) );
|
|
|
|
return getUniqueName( _rxContainer, sBaseName );
|
|
}
|
|
|
|
|
|
OUString FormControlFactory::getUniqueName( const Reference< XNameAccess >& _rxContainer, std::u16string_view _rBaseName )
|
|
{
|
|
sal_Int32 n = 0;
|
|
OUString sName;
|
|
do
|
|
{
|
|
sName = OUString::Concat(_rBaseName) + " " + OUString::number( ++n );
|
|
}
|
|
while ( _rxContainer->hasByName( sName ) );
|
|
|
|
return sName;
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|