LibreOffice Module extensions (master) 1
handlerhelper.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 */
19
20#include "handlerhelper.hxx"
21#include <yesno.hrc>
22#include "modulepcr.hxx"
23
24#include <com/sun/star/container/XNameContainer.hpp>
25#include <com/sun/star/inspection/StringRepresentation.hpp>
26#include <com/sun/star/util/XModifiable.hpp>
27#include <com/sun/star/awt/XWindow.hpp>
28#include <com/sun/star/inspection/LineDescriptor.hpp>
29#include <com/sun/star/inspection/PropertyControlType.hpp>
30#include <com/sun/star/inspection/XStringListControl.hpp>
31#include <com/sun/star/inspection/XNumericControl.hpp>
33#include <vcl/svapp.hxx>
34#include <vcl/weld.hxx>
35#include <vcl/weldutils.hxx>
36
37#include <algorithm>
38
39
40namespace pcr
41{
42
43
44 using namespace ::com::sun::star::uno;
45 using namespace ::com::sun::star::lang;
46 using namespace ::com::sun::star::awt;
47 using namespace ::com::sun::star::util;
48 using namespace ::com::sun::star::beans;
49 using namespace ::com::sun::star::script;
50 using namespace ::com::sun::star::inspection;
51
52
53 //= PropertyHandlerHelper
54
55
56 void PropertyHandlerHelper::describePropertyLine( const Property& _rProperty,
57 LineDescriptor& /* [out] */ _out_rDescriptor, const Reference< XPropertyControlFactory >& _rxControlFactory )
58 {
59 // display the pure property name - no L10N
60 _out_rDescriptor.DisplayName = _rProperty.Name;
61
62 OSL_PRECOND( _rxControlFactory.is(), "PropertyHandlerHelper::describePropertyLine: no factory -> no control!" );
63 if ( !_rxControlFactory.is() )
64 return;
65
66 bool bReadOnlyControl = requiresReadOnlyControl( _rProperty.Attributes );
67
68 // special handling for booleans (this will become a list)
69 if ( _rProperty.Type.getTypeClass() == TypeClass_BOOLEAN )
70 {
71 _out_rDescriptor.Control = createListBoxControl(_rxControlFactory, RID_RSC_ENUM_YESNO, SAL_N_ELEMENTS(RID_RSC_ENUM_YESNO), bReadOnlyControl);
72 return;
73 }
74
75 sal_Int16 nControlType = PropertyControlType::TextField;
76 switch ( _rProperty.Type.getTypeClass() )
77 {
78 case TypeClass_BYTE:
79 case TypeClass_SHORT:
80 case TypeClass_UNSIGNED_SHORT:
81 case TypeClass_LONG:
82 case TypeClass_UNSIGNED_LONG:
83 case TypeClass_HYPER:
84 case TypeClass_UNSIGNED_HYPER:
85 case TypeClass_FLOAT:
86 case TypeClass_DOUBLE:
87 nControlType = PropertyControlType::NumericField;
88 break;
89
90 case TypeClass_SEQUENCE:
91 nControlType = PropertyControlType::StringListField;
92 break;
93
94 default:
95 OSL_FAIL( "PropertyHandlerHelper::describePropertyLine: don't know how to represent this at the UI!" );
96 [[fallthrough]];
97
98 case TypeClass_STRING:
99 nControlType = PropertyControlType::TextField;
100 break;
101 }
102
103 // create a control
104 _out_rDescriptor.Control = _rxControlFactory->createPropertyControl( nControlType, bReadOnlyControl );
105 }
106
107
108 namespace
109 {
110 Reference< XPropertyControl > lcl_implCreateListLikeControl(
111 const Reference< XPropertyControlFactory >& _rxControlFactory,
112 std::vector< OUString >&& _rInitialListEntries,
113 bool _bReadOnlyControl,
114 bool _bSorted,
115 bool _bTrueIfListBoxFalseIfComboBox
116 )
117 {
118 Reference< XStringListControl > xListControl(
119 _rxControlFactory->createPropertyControl(
120 _bTrueIfListBoxFalseIfComboBox ? PropertyControlType::ListBox : PropertyControlType::ComboBox, _bReadOnlyControl
121 ),
122 UNO_QUERY_THROW
123 );
124
125 if ( _bSorted )
126 std::sort( _rInitialListEntries.begin(), _rInitialListEntries.end() );
127
128 for (auto const& initialEntry : _rInitialListEntries)
129 xListControl->appendListEntry(initialEntry);
130 return xListControl;
131 }
132 }
133
134 Reference< XPropertyControl > PropertyHandlerHelper::createListBoxControl( const Reference< XPropertyControlFactory >& _rxControlFactory,
135 std::vector< OUString >&& _rInitialListEntries, bool _bReadOnlyControl, bool _bSorted )
136 {
137 return lcl_implCreateListLikeControl(_rxControlFactory, std::move(_rInitialListEntries), _bReadOnlyControl, _bSorted, true);
138 }
139
140 Reference< XPropertyControl > PropertyHandlerHelper::createListBoxControl( const Reference< XPropertyControlFactory >& _rxControlFactory,
141 const TranslateId* pTransIds, size_t nElements, bool _bReadOnlyControl )
142 {
143 std::vector<OUString> aInitialListEntries;
144 for (size_t i = 0; i < nElements; ++i)
145 aInitialListEntries.push_back(PcrRes(pTransIds[i]));
146 return lcl_implCreateListLikeControl(_rxControlFactory, std::move(aInitialListEntries), _bReadOnlyControl, /*_bSorted*/false, true);
147 }
148
149 Reference< XPropertyControl > PropertyHandlerHelper::createComboBoxControl( const Reference< XPropertyControlFactory >& _rxControlFactory,
150 std::vector< OUString >&& _rInitialListEntries, bool _bSorted )
151 {
152 return lcl_implCreateListLikeControl( _rxControlFactory, std::move(_rInitialListEntries), /*_bReadOnlyControl*/false, _bSorted, false );
153 }
154
155
156 Reference< XPropertyControl > PropertyHandlerHelper::createNumericControl( const Reference< XPropertyControlFactory >& _rxControlFactory,
157 sal_Int16 _nDigits, const Optional< double >& _rMinValue, const Optional< double >& _rMaxValue )
158 {
159 Reference< XNumericControl > xNumericControl(
160 _rxControlFactory->createPropertyControl( PropertyControlType::NumericField, /*_bReadOnlyControl*/false ),
161 UNO_QUERY_THROW
162 );
163
164 xNumericControl->setDecimalDigits( _nDigits );
165 xNumericControl->setMinValue( _rMinValue );
166 xNumericControl->setMaxValue( _rMaxValue );
167
168 return xNumericControl;
169 }
170
171
172 Any PropertyHandlerHelper::convertToPropertyValue( const Reference< XComponentContext >& _rxContext,const Reference< XTypeConverter >& _rxTypeConverter,
173 const Property& _rProperty, const Any& _rControlValue )
174 {
175 Any aPropertyValue( _rControlValue );
176 if ( !aPropertyValue.hasValue() )
177 // NULL is converted to NULL
178 return aPropertyValue;
179
180 if ( aPropertyValue.getValueType().equals( _rProperty.Type ) )
181 // nothing to do, type is already as desired
182 return aPropertyValue;
183
184 if ( _rControlValue.getValueType().getTypeClass() == TypeClass_STRING )
185 {
186 OUString sControlValue;
187 _rControlValue >>= sControlValue;
188
189 Reference< XStringRepresentation > xConversionHelper = StringRepresentation::create( _rxContext,_rxTypeConverter );
190 aPropertyValue = xConversionHelper->convertToPropertyValue( sControlValue, _rProperty.Type );
191 }
192 else
193 {
194 try
195 {
196 if ( _rxTypeConverter.is() )
197 aPropertyValue = _rxTypeConverter->convertTo( _rControlValue, _rProperty.Type );
198 }
199 catch( const Exception& )
200 {
201 TOOLS_WARN_EXCEPTION("extensions.propctrlr",
202 "caught an exception while converting via TypeConverter!");
203 }
204 }
205
206 return aPropertyValue;
207 }
208
209
210 Any PropertyHandlerHelper::convertToControlValue( const Reference< XComponentContext >& _rxContext,const Reference< XTypeConverter >& _rxTypeConverter,
211 const Any& _rPropertyValue, const Type& _rControlValueType )
212 {
213 Any aControlValue( _rPropertyValue );
214 if ( !aControlValue.hasValue() )
215 // NULL is converted to NULL
216 return aControlValue;
217
218 if ( _rControlValueType.getTypeClass() == TypeClass_STRING )
219 {
220 Reference< XStringRepresentation > xConversionHelper = StringRepresentation::create( _rxContext,_rxTypeConverter );
221 aControlValue <<= xConversionHelper->convertToControlValue( _rPropertyValue );
222 }
223 else
224 {
225 try
226 {
227 if ( _rxTypeConverter.is() )
228 aControlValue = _rxTypeConverter->convertTo( _rPropertyValue, _rControlValueType );
229 }
230 catch( const Exception& )
231 {
232 TOOLS_WARN_EXCEPTION("extensions.propctrlr",
233 "caught an exception while converting via TypeConverter!");
234 }
235 }
236
237 return aControlValue;
238 }
239
240
241 void PropertyHandlerHelper::setContextDocumentModified( const Reference<XComponentContext> & rContext )
242 {
243 try
244 {
245 Reference< XModifiable > xDocumentModifiable( getContextDocument_throw(rContext), UNO_QUERY_THROW );
246 xDocumentModifiable->setModified( true );
247 }
248 catch( const Exception& )
249 {
250 DBG_UNHANDLED_EXCEPTION("extensions.propctrlr");
251 }
252 }
253
254 Reference< XInterface > PropertyHandlerHelper::getContextDocument( const Reference<XComponentContext> & rContext )
255 {
257 try
258 {
259 xI = getContextDocument_throw( rContext );
260 }
261 catch( const Exception& )
262 {
263 TOOLS_WARN_EXCEPTION( "extensions.propctrlr", "PropertyHandler::getContextValueByName" );
264 }
265 return xI;
266 }
267
268 Reference< XInterface > PropertyHandlerHelper::getContextDocument_throw( const Reference<XComponentContext> & rContext )
269 {
271 Any aReturn = rContext->getValueByName( "ContextDocument" );
272 aReturn >>= xI;
273 return xI;
274 }
275
276 weld::Window* PropertyHandlerHelper::getDialogParentFrame(const Reference<XComponentContext>& rContext)
277 {
278 weld::Window* pInspectorWindow = nullptr;
279 try
280 {
281 Reference< XWindow > xInspectorWindow(rContext->getValueByName( "DialogParentWindow" ), UNO_QUERY_THROW);
282 pInspectorWindow = Application::GetFrameWeld(xInspectorWindow);
283 }
284 catch( const Exception& )
285 {
286 DBG_UNHANDLED_EXCEPTION("extensions.propctrlr");
287 }
288 return pInspectorWindow;
289 }
290
291 std::unique_ptr<weld::Builder> PropertyHandlerHelper::makeBuilder(const OUString& rUIFile, const Reference<XComponentContext>& rContext)
292 {
293 Reference<XWindow> xWindow(rContext->getValueByName("BuilderParent"), UNO_QUERY_THROW);
294 weld::TransportAsXWindow& rTunnel = dynamic_cast<weld::TransportAsXWindow&>(*xWindow);
295 return Application::CreateBuilder(rTunnel.getWidget(), rUIFile);
296 }
297
298 void PropertyHandlerHelper::setBuilderParent(const css::uno::Reference<css::uno::XComponentContext>& rContext, weld::Widget* pParent)
299 {
300 Reference<css::container::XNameContainer> xName(rContext, UNO_QUERY_THROW);
301 Reference<XWindow> xWindow(new weld::TransportAsXWindow(pParent));
302 xName->insertByName("BuilderParent", Any(xWindow));
303 }
304
305 void PropertyHandlerHelper::clearBuilderParent(const css::uno::Reference<css::uno::XComponentContext>& rContext)
306 {
307 Reference<css::container::XNameContainer> xName(rContext, UNO_QUERY_THROW);
308 xName->removeByName("BuilderParent");
309 }
310
311} // namespace pcr
312
313
314/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
static weld::Window * GetFrameWeld(const css::uno::Reference< css::awt::XWindow > &rWindow)
static std::unique_ptr< weld::Builder > CreateBuilder(weld::Widget *pParent, const OUString &rUIFile, bool bMobile=false, sal_uInt64 nLOKWindowId=0)
static css::uno::Reference< css::uno::XInterface > getContextDocument(const css::uno::Reference< css::uno::XComponentContext > &_rContext)
static css::uno::Reference< css::inspection::XPropertyControl > createComboBoxControl(const css::uno::Reference< css::inspection::XPropertyControlFactory > &_rxControlFactory, std::vector< OUString > &&_rInitialListEntries, bool _bSorted)
creates an <member scope="css::inspection">PropertyControlType::ComboBox</member>-type control and fi...
static css::uno::Reference< css::uno::XInterface > getContextDocument_throw(const css::uno::Reference< css::uno::XComponentContext > &_rContext)
static css::uno::Reference< css::inspection::XPropertyControl > createListBoxControl(const css::uno::Reference< css::inspection::XPropertyControlFactory > &_rxControlFactory, std::vector< OUString > &&_rInitialListEntries, bool _bReadOnlyControl, bool _bSorted)
creates an <member scope="css::inspection">PropertyControlType::ListBox</member>-type control and fil...
static css::uno::Any convertToPropertyValue(const css::uno::Reference< css::uno::XComponentContext > &_rxContext, const css::uno::Reference< css::script::XTypeConverter > &_rxTypeConverter, const css::beans::Property &_rProperty, const css::uno::Any &_rControlValue)
helper for implementing XPropertyHandler::convertToPropertyValue
static void setBuilderParent(const css::uno::Reference< css::uno::XComponentContext > &rContext, weld::Widget *pParent)
static weld::Window * getDialogParentFrame(const css::uno::Reference< css::uno::XComponentContext > &_rContext)
gets the window of the ObjectInspector in which a property handler lives
static void clearBuilderParent(const css::uno::Reference< css::uno::XComponentContext > &rContext)
static bool requiresReadOnlyControl(sal_Int16 _nPropertyAttributes)
determines whether given PropertyAttributes require a to-be-created <type scope="css::inspection">XPr...
static std::unique_ptr< weld::Builder > makeBuilder(const OUString &rUIFile, const css::uno::Reference< css::uno::XComponentContext > &rContext)
static void setContextDocumentModified(const css::uno::Reference< css::uno::XComponentContext > &_rContext)
marks the document passed in our UNO context as modified
static css::uno::Any convertToControlValue(const css::uno::Reference< css::uno::XComponentContext > &_rxContext, const css::uno::Reference< css::script::XTypeConverter > &_rxTypeConverter, const css::uno::Any &_rPropertyValue, const css::uno::Type &_rControlValueType)
helper for implementing XPropertyHandler::convertToControlValue
static void describePropertyLine(const css::beans::Property &_rProperty, css::inspection::LineDescriptor &_out_rDescriptor, const css::uno::Reference< css::inspection::XPropertyControlFactory > &_rxControlFactory)
helper for implementing XPropertyHandler::describePropertyLine in a generic way
static css::uno::Reference< css::inspection::XPropertyControl > createNumericControl(const css::uno::Reference< css::inspection::XPropertyControlFactory > &_rxControlFactory, sal_Int16 _nDigits, const css::beans::Optional< double > &_rMinValue, const css::beans::Optional< double > &_rMaxValue)
creates an <member scope="css::inspection">PropertyControlType::NumericField</member>-type control an...
weld::Widget * getWidget() const
sal_Int32 nElements
#define TOOLS_WARN_EXCEPTION(area, stream)
#define DBG_UNHANDLED_EXCEPTION(...)
#define SAL_N_ELEMENTS(arr)
@ Exception
Type
int i
a property handler for any virtual string properties
Definition: browserline.cxx:39
OUString PcrRes(TranslateId aId)
Definition: modulepcr.cxx:26