File: | home/maarten/src/libreoffice/core/vbahelper/source/vbahelper/vbahelper.cxx |
Warning: | line 666, column 29 Use of memory after it is freed |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
1 | /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column:100 -*- */ | ||||||
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 <com/sun/star/util/URLTransformer.hpp> | ||||||
21 | #include <com/sun/star/util/XURLTransformer.hpp> | ||||||
22 | #include <com/sun/star/frame/XDispatchProvider.hpp> | ||||||
23 | #include <com/sun/star/frame/XModel.hpp> | ||||||
24 | #include <com/sun/star/frame/XFrame.hpp> | ||||||
25 | #include <com/sun/star/frame/XController.hpp> | ||||||
26 | #include <com/sun/star/frame/XModel2.hpp> | ||||||
27 | #include <com/sun/star/script/BasicErrorException.hpp> | ||||||
28 | #include <com/sun/star/script/XDefaultProperty.hpp> | ||||||
29 | #include <com/sun/star/script/XInvocation.hpp> | ||||||
30 | #include <com/sun/star/script/Converter.hpp> | ||||||
31 | #include <com/sun/star/uno/XComponentContext.hpp> | ||||||
32 | #include <com/sun/star/lang/XUnoTunnel.hpp> | ||||||
33 | #include <com/sun/star/beans/XPropertySet.hpp> | ||||||
34 | #include <com/sun/star/beans/theIntrospection.hpp> | ||||||
35 | #include <com/sun/star/util/MeasureUnit.hpp> | ||||||
36 | #include <com/sun/star/awt/XControl.hpp> | ||||||
37 | #include <com/sun/star/awt/XWindow.hpp> | ||||||
38 | #include <com/sun/star/awt/XDialog.hpp> | ||||||
39 | #include <com/sun/star/awt/XUnitConversion.hpp> | ||||||
40 | #include <com/sun/star/drawing/XShape.hpp> | ||||||
41 | #include <ooo/vba/XHelperInterface.hpp> | ||||||
42 | |||||||
43 | #include <comphelper/automationinvokedzone.hxx> | ||||||
44 | #include <comphelper/processfactory.hxx> | ||||||
45 | #include <comphelper/sequence.hxx> | ||||||
46 | |||||||
47 | #include <sfx2/objsh.hxx> | ||||||
48 | #include <sfx2/viewfrm.hxx> | ||||||
49 | #include <sfx2/dispatch.hxx> | ||||||
50 | #include <sfx2/app.hxx> | ||||||
51 | #include <sfx2/sfxsids.hrc> | ||||||
52 | #include <svl/stritem.hxx> | ||||||
53 | #include <svl/eitem.hxx> | ||||||
54 | #include <svl/intitem.hxx> | ||||||
55 | #include <svl/itemset.hxx> | ||||||
56 | #include <sfx2/docfac.hxx> | ||||||
57 | #include <sfx2/viewfac.hxx> | ||||||
58 | |||||||
59 | #include <basic/sbstar.hxx> | ||||||
60 | #include <basic/basmgr.hxx> | ||||||
61 | #include <basic/sbmod.hxx> | ||||||
62 | #include <basic/sbuno.hxx> | ||||||
63 | #include <basic/sberrors.hxx> | ||||||
64 | #include <rtl/ustrbuf.hxx> | ||||||
65 | #include <sfx2/viewsh.hxx> | ||||||
66 | #include <sal/log.hxx> | ||||||
67 | #include <toolkit/helper/vclunohelper.hxx> | ||||||
68 | #include <vcl/svapp.hxx> | ||||||
69 | #include <vcl/window.hxx> | ||||||
70 | #include <vcl/syswin.hxx> | ||||||
71 | #include <tools/diagnose_ex.h> | ||||||
72 | #include <vbahelper/vbahelper.hxx> | ||||||
73 | |||||||
74 | using namespace ::com::sun::star; | ||||||
75 | using namespace ::ooo::vba; | ||||||
76 | |||||||
77 | |||||||
78 | namespace ooo::vba | ||||||
79 | { | ||||||
80 | |||||||
81 | namespace { const double factor = 2540.0 / 72.0; } | ||||||
82 | |||||||
83 | // helper method to determine if the view ( calc ) is in print-preview mode | ||||||
84 | static bool isInPrintPreview( SfxViewFrame* pView ) | ||||||
85 | { | ||||||
86 | sal_uInt16 nViewNo = SID_VIEWSHELL1(5000 + 631) - SID_VIEWSHELL0(5000 + 630); | ||||||
87 | if ( pView->GetObjectShell()->GetFactory().GetViewFactoryCount() > | ||||||
88 | nViewNo && !pView->GetObjectShell()->IsInPlaceActive() ) | ||||||
89 | { | ||||||
90 | SfxViewFactory &rViewFactory = | ||||||
91 | pView->GetObjectShell()->GetFactory().GetViewFactory(nViewNo); | ||||||
92 | if ( pView->GetCurViewId() == rViewFactory.GetOrdinal() ) | ||||||
93 | return true; | ||||||
94 | } | ||||||
95 | return false; | ||||||
96 | } | ||||||
97 | |||||||
98 | uno::Reference< beans::XIntrospectionAccess > | ||||||
99 | getIntrospectionAccess( const uno::Any& aObject ) | ||||||
100 | { | ||||||
101 | static uno::Reference< beans::XIntrospection > xIntrospection( beans::theIntrospection::get( comphelper::getProcessComponentContext() ) ); | ||||||
102 | return xIntrospection->inspect( aObject ); | ||||||
103 | } | ||||||
104 | |||||||
105 | uno::Reference< script::XTypeConverter > const & | ||||||
106 | getTypeConverter( const uno::Reference< uno::XComponentContext >& xContext ) | ||||||
107 | { | ||||||
108 | static uno::Reference< script::XTypeConverter > xTypeConv( script::Converter::create(xContext) ); | ||||||
109 | return xTypeConv; | ||||||
110 | } | ||||||
111 | const uno::Any& | ||||||
112 | aNULL() | ||||||
113 | { | ||||||
114 | static uno::Any aNULLL = uno::makeAny( uno::Reference< uno::XInterface >() ); | ||||||
115 | return aNULLL; | ||||||
116 | } | ||||||
117 | |||||||
118 | void dispatchExecute(SfxViewShell const * pViewShell, sal_uInt16 nSlot) | ||||||
119 | { | ||||||
120 | SfxViewFrame* pViewFrame = nullptr; | ||||||
121 | if ( pViewShell ) | ||||||
122 | pViewFrame = pViewShell->GetViewFrame(); | ||||||
123 | if ( pViewFrame ) | ||||||
124 | { | ||||||
125 | SfxDispatcher* pDispatcher = pViewFrame->GetDispatcher(); | ||||||
126 | if( pDispatcher ) | ||||||
127 | { | ||||||
128 | pDispatcher->Execute( nSlot , SfxCallMode::SYNCHRON ); | ||||||
129 | } | ||||||
130 | } | ||||||
131 | } | ||||||
132 | |||||||
133 | void | ||||||
134 | dispatchRequests (const uno::Reference< frame::XModel>& xModel, const OUString & aUrl, const uno::Sequence< beans::PropertyValue >& sProps ) | ||||||
135 | { | ||||||
136 | util::URL url; | ||||||
137 | url.Complete = aUrl; | ||||||
138 | uno::Reference<frame::XController> xController = xModel->getCurrentController(); | ||||||
139 | uno::Reference<frame::XFrame> xFrame = xController->getFrame(); | ||||||
140 | uno::Reference<frame::XDispatchProvider> xDispatchProvider (xFrame,uno::UNO_QUERY_THROW); | ||||||
141 | try | ||||||
142 | { | ||||||
143 | uno::Reference<uno::XComponentContext > xContext( | ||||||
144 | comphelper::getProcessComponentContext() ); | ||||||
145 | uno::Reference<util::XURLTransformer> xParser( util::URLTransformer::create(xContext) ); | ||||||
146 | xParser->parseStrict (url); | ||||||
147 | } | ||||||
148 | catch (const uno::Exception&) | ||||||
149 | { | ||||||
150 | return; | ||||||
151 | } | ||||||
152 | |||||||
153 | uno::Reference<frame::XDispatch> xDispatcher = xDispatchProvider->queryDispatch(url,"",0); | ||||||
154 | |||||||
155 | uno::Sequence<beans::PropertyValue> dispatchProps(1); | ||||||
156 | |||||||
157 | sal_Int32 nProps = sProps.getLength(); | ||||||
158 | if ( nProps ) | ||||||
159 | { | ||||||
160 | dispatchProps.realloc( nProps + 1 ); | ||||||
161 | std::copy(sProps.begin(), sProps.end(), dispatchProps.begin()); | ||||||
162 | } | ||||||
163 | |||||||
164 | if ( xDispatcher.is() ) | ||||||
165 | { | ||||||
166 | xDispatcher->dispatch( url, dispatchProps ); | ||||||
167 | } | ||||||
168 | } | ||||||
169 | |||||||
170 | void | ||||||
171 | dispatchRequests( const uno::Reference< frame::XModel>& xModel, const OUString& aUrl ) | ||||||
172 | { | ||||||
173 | uno::Sequence<beans::PropertyValue> dispatchProps; | ||||||
174 | dispatchRequests( xModel, aUrl, dispatchProps ); | ||||||
175 | } | ||||||
176 | |||||||
177 | uno::Reference< frame::XModel > | ||||||
178 | getCurrentDoc( const OUString& sKey ) | ||||||
179 | { | ||||||
180 | uno::Reference< frame::XModel > xModel; | ||||||
181 | SbxObject* pBasic = dynamic_cast< SbxObject* > ( SfxApplication::GetBasic() ); | ||||||
182 | SbxObject* basicChosen = pBasic ; | ||||||
183 | if ( basicChosen == nullptr) | ||||||
184 | { | ||||||
185 | SAL_INFO("vbahelper", "getModelFromBasic() StarBASIC* is NULL" )do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO , "vbahelper")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "getModelFromBasic() StarBASIC* is NULL" ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("vbahelper" ), ("/home/maarten/src/libreoffice/core/vbahelper/source/vbahelper/vbahelper.cxx" ":" "185" ": "), ::sal::detail::unwrapStream( ::sal::detail:: StreamStart() << "getModelFromBasic() StarBASIC* is NULL" ), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "getModelFromBasic() StarBASIC* is NULL"; ::sal::detail ::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("vbahelper"), ("/home/maarten/src/libreoffice/core/vbahelper/source/vbahelper/vbahelper.cxx" ":" "185" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "getModelFromBasic() StarBASIC* is NULL") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("vbahelper" ), ("/home/maarten/src/libreoffice/core/vbahelper/source/vbahelper/vbahelper.cxx" ":" "185" ": "), ::sal::detail::unwrapStream( ::sal::detail:: StreamStart() << "getModelFromBasic() StarBASIC* is NULL" ), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "getModelFromBasic() StarBASIC* is NULL"; ::sal::detail ::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("vbahelper"), ("/home/maarten/src/libreoffice/core/vbahelper/source/vbahelper/vbahelper.cxx" ":" "185" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | ||||||
186 | return xModel; | ||||||
187 | } | ||||||
188 | SbxObject* p = pBasic; | ||||||
189 | SbxObject* pParent = p->GetParent(); | ||||||
190 | SbxObject* pParentParent = pParent ? pParent->GetParent() : nullptr; | ||||||
191 | |||||||
192 | if( pParentParent ) | ||||||
193 | { | ||||||
194 | basicChosen = pParentParent; | ||||||
195 | } | ||||||
196 | else if( pParent ) | ||||||
197 | { | ||||||
198 | basicChosen = pParent; | ||||||
199 | } | ||||||
200 | |||||||
201 | |||||||
202 | uno::Any aModel; | ||||||
203 | SbxVariable *pCompVar = basicChosen->Find( sKey, SbxClassType::Object ); | ||||||
204 | |||||||
205 | if ( pCompVar ) | ||||||
206 | { | ||||||
207 | aModel = sbxToUnoValue( pCompVar ); | ||||||
208 | if ( !( aModel >>= xModel ) || !xModel.is() ) | ||||||
209 | { | ||||||
210 | throw uno::RuntimeException( | ||||||
211 | "Can't extract model from basic ( it's obviously not set yet therefore don't know the current document context)" ); | ||||||
212 | } | ||||||
213 | SAL_INFO("vbahelper", "Have model points to url " << xModel->getURL())do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO , "vbahelper")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "Have model points to url " << xModel->getURL()) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO ), ("vbahelper"), ("/home/maarten/src/libreoffice/core/vbahelper/source/vbahelper/vbahelper.cxx" ":" "213" ": "), ::sal::detail::unwrapStream( ::sal::detail:: StreamStart() << "Have model points to url " << xModel ->getURL()), 0); } else { ::std::ostringstream sal_detail_stream ; sal_detail_stream << "Have model points to url " << xModel->getURL(); ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO ), ("vbahelper"), ("/home/maarten/src/libreoffice/core/vbahelper/source/vbahelper/vbahelper.cxx" ":" "213" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "Have model points to url " << xModel->getURL ()) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO), ( "vbahelper"), ("/home/maarten/src/libreoffice/core/vbahelper/source/vbahelper/vbahelper.cxx" ":" "213" ": "), ::sal::detail::unwrapStream( ::sal::detail:: StreamStart() << "Have model points to url " << xModel ->getURL()), 0); } else { ::std::ostringstream sal_detail_stream ; sal_detail_stream << "Have model points to url " << xModel->getURL(); ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO ), ("vbahelper"), ("/home/maarten/src/libreoffice/core/vbahelper/source/vbahelper/vbahelper.cxx" ":" "213" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | ||||||
214 | } | ||||||
215 | else | ||||||
216 | { | ||||||
217 | SAL_INFO("vbahelper", "Failed to get " << sKey)do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO , "vbahelper")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "Failed to get " << sKey) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO ), ("vbahelper"), ("/home/maarten/src/libreoffice/core/vbahelper/source/vbahelper/vbahelper.cxx" ":" "217" ": "), ::sal::detail::unwrapStream( ::sal::detail:: StreamStart() << "Failed to get " << sKey), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "Failed to get " << sKey; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("vbahelper"), ("/home/maarten/src/libreoffice/core/vbahelper/source/vbahelper/vbahelper.cxx" ":" "217" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "Failed to get " << sKey) == 1) { ::sal_detail_log ( (::SAL_DETAIL_LOG_LEVEL_INFO), ("vbahelper"), ("/home/maarten/src/libreoffice/core/vbahelper/source/vbahelper/vbahelper.cxx" ":" "217" ": "), ::sal::detail::unwrapStream( ::sal::detail:: StreamStart() << "Failed to get " << sKey), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "Failed to get " << sKey; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("vbahelper"), ("/home/maarten/src/libreoffice/core/vbahelper/source/vbahelper/vbahelper.cxx" ":" "217" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | ||||||
218 | throw uno::RuntimeException( "Can't determine the currently selected document" ); | ||||||
219 | } | ||||||
220 | return xModel; | ||||||
221 | } | ||||||
222 | |||||||
223 | /// @throws uno::RuntimeException | ||||||
224 | static uno::Reference< frame::XModel > | ||||||
225 | getCurrentDocCtx( const OUString& ctxName, const uno::Reference< uno::XComponentContext >& xContext ) | ||||||
226 | { | ||||||
227 | uno::Reference< frame::XModel > xModel; | ||||||
228 | // try fallback to calling doc | ||||||
229 | css::uno::Reference< css::container::XNameAccess > xNameAccess( xContext, css::uno::UNO_QUERY_THROW ); | ||||||
230 | xModel.set( xNameAccess->getByName( ctxName ), uno::UNO_QUERY_THROW ); | ||||||
231 | return xModel; | ||||||
232 | } | ||||||
233 | |||||||
234 | uno::Reference< frame::XModel > | ||||||
235 | getThisExcelDoc( const uno::Reference< uno::XComponentContext >& xContext ) | ||||||
236 | { | ||||||
237 | return getCurrentDocCtx( "ExcelDocumentContext" , xContext ); | ||||||
238 | } | ||||||
239 | |||||||
240 | uno::Reference< frame::XModel > | ||||||
241 | getThisWordDoc( const uno::Reference< uno::XComponentContext >& xContext ) | ||||||
242 | { | ||||||
243 | return getCurrentDocCtx( "WordDocumentContext" , xContext ); | ||||||
244 | } | ||||||
245 | |||||||
246 | uno::Reference< frame::XModel > | ||||||
247 | getCurrentExcelDoc( const uno::Reference< uno::XComponentContext >& xContext ) | ||||||
248 | { | ||||||
249 | uno::Reference< frame::XModel > xModel; | ||||||
250 | try | ||||||
251 | { | ||||||
252 | xModel = getCurrentDoc( "ThisExcelDoc" ); | ||||||
253 | } | ||||||
254 | catch (const uno::Exception&) | ||||||
255 | { | ||||||
256 | try | ||||||
257 | { | ||||||
258 | xModel = getThisExcelDoc( xContext ); | ||||||
259 | } | ||||||
260 | catch (const uno::Exception&) | ||||||
261 | { | ||||||
262 | } | ||||||
263 | } | ||||||
264 | return xModel; | ||||||
265 | } | ||||||
266 | |||||||
267 | uno::Reference< frame::XModel > | ||||||
268 | getCurrentWordDoc( const uno::Reference< uno::XComponentContext >& xContext ) | ||||||
269 | { | ||||||
270 | uno::Reference< frame::XModel > xModel; | ||||||
271 | try | ||||||
272 | { | ||||||
273 | xModel = getCurrentDoc( "ThisWordDoc" ); | ||||||
274 | } | ||||||
275 | catch (const uno::Exception&) | ||||||
276 | { | ||||||
277 | try | ||||||
278 | { | ||||||
279 | xModel = getThisWordDoc( xContext ); | ||||||
280 | } | ||||||
281 | catch (const uno::Exception&) | ||||||
282 | { | ||||||
283 | } | ||||||
284 | } | ||||||
285 | return xModel; | ||||||
286 | } | ||||||
287 | |||||||
288 | sal_Int32 | ||||||
289 | OORGBToXLRGB( sal_Int32 nCol ) | ||||||
290 | { | ||||||
291 | sal_Int32 nAutoBits = nCol; | ||||||
292 | nAutoBits &= 0xFF000000; | ||||||
293 | sal_Int32 nRed = nCol; | ||||||
294 | nRed &= 0x00FF0000; | ||||||
295 | nRed >>= 16; | ||||||
296 | sal_Int32 nGreen = nCol; | ||||||
297 | nGreen &= 0x0000FF00; | ||||||
298 | nGreen >>= 8; | ||||||
299 | sal_Int32 nBlue = nCol; | ||||||
300 | nBlue &= 0x000000FF; | ||||||
301 | sal_Int32 nRGB = ( nAutoBits | (nBlue << 16) | (nGreen << 8) | nRed ); | ||||||
302 | return nRGB; | ||||||
303 | } | ||||||
304 | |||||||
305 | sal_Int32 | ||||||
306 | XLRGBToOORGB( sal_Int32 nCol ) | ||||||
307 | { | ||||||
308 | sal_Int32 nAutoBits = nCol; | ||||||
309 | nAutoBits &= 0xFF000000; | ||||||
310 | |||||||
311 | sal_Int32 nBlue = nCol; | ||||||
312 | nBlue &= 0x00FF0000; | ||||||
313 | nBlue >>= 16; | ||||||
314 | sal_Int32 nGreen = nCol; | ||||||
315 | nGreen &= 0x0000FF00; | ||||||
316 | nGreen >>= 8; | ||||||
317 | sal_Int32 nRed = nCol; | ||||||
318 | nRed &= 0x000000FF; | ||||||
319 | sal_Int32 nRGB = ( nAutoBits | (nRed << 16) | (nGreen << 8) | nBlue ); | ||||||
320 | return nRGB; | ||||||
321 | } | ||||||
322 | uno::Any | ||||||
323 | OORGBToXLRGB( const uno::Any& aCol ) | ||||||
324 | { | ||||||
325 | sal_Int32 nCol(0); | ||||||
326 | aCol >>= nCol; | ||||||
327 | nCol = OORGBToXLRGB( nCol ); | ||||||
328 | return uno::makeAny( nCol ); | ||||||
329 | } | ||||||
330 | uno::Any | ||||||
331 | XLRGBToOORGB( const uno::Any& aCol ) | ||||||
332 | { | ||||||
333 | sal_Int32 nCol(0); | ||||||
334 | aCol >>= nCol; | ||||||
335 | nCol = XLRGBToOORGB( nCol ); | ||||||
336 | return uno::makeAny( nCol ); | ||||||
337 | } | ||||||
338 | |||||||
339 | void PrintOutHelper( SfxViewShell const * pViewShell, const uno::Any& From, const uno::Any& To, const uno::Any& Copies, const uno::Any& Preview, const uno::Any& /*ActivePrinter*/, const uno::Any& /*PrintToFile*/, const uno::Any& Collate, const uno::Any& PrToFileName, bool bUseSelection ) | ||||||
340 | { | ||||||
341 | sal_Int32 nTo = 0; | ||||||
342 | sal_Int32 nFrom = 0; | ||||||
343 | sal_Int16 nCopies = 1; | ||||||
344 | bool bPreview = false; | ||||||
345 | bool bCollate = false; | ||||||
346 | bool bSelection = bUseSelection; | ||||||
347 | From >>= nFrom; | ||||||
348 | To >>= nTo; | ||||||
349 | Copies >>= nCopies; | ||||||
350 | Preview >>= bPreview; | ||||||
351 | if ( nCopies > 1 ) // Collate only useful when more that 1 copy | ||||||
352 | Collate >>= bCollate; | ||||||
353 | |||||||
354 | OUString sRange( "-" ); | ||||||
355 | OUString sFileName; | ||||||
356 | |||||||
357 | if ( nFrom || nTo ) | ||||||
358 | { | ||||||
359 | if ( nFrom ) | ||||||
360 | sRange = OUString::number( nFrom ) + sRange; | ||||||
361 | if ( nTo ) | ||||||
362 | sRange += OUString::number( nTo ); | ||||||
363 | } | ||||||
364 | |||||||
365 | PrToFileName >>= sFileName; | ||||||
366 | SfxViewFrame* pViewFrame = nullptr; | ||||||
367 | if ( pViewShell ) | ||||||
368 | pViewFrame = pViewShell->GetViewFrame(); | ||||||
369 | if ( !pViewFrame ) | ||||||
370 | return; | ||||||
371 | |||||||
372 | SfxAllItemSet aArgs( SfxGetpApp()->GetPool() ); | ||||||
373 | |||||||
374 | SfxBoolItem sfxCollate( SID_PRINT_COLLATE(5000 +1590), bCollate ); | ||||||
375 | aArgs.Put( sfxCollate, sfxCollate.Which() ); | ||||||
376 | SfxInt16Item sfxCopies( SID_PRINT_COPIES(5000 + 3), nCopies ); | ||||||
377 | aArgs.Put( sfxCopies, sfxCopies.Which() ); | ||||||
378 | if ( !sFileName.isEmpty() ) | ||||||
379 | { | ||||||
380 | SfxStringItem sfxFileName( SID_FILE_NAME(5000 + 507), sFileName); | ||||||
381 | aArgs.Put( sfxFileName, sfxFileName.Which() ); | ||||||
382 | |||||||
383 | } | ||||||
384 | if ( !sRange.isEmpty() ) | ||||||
385 | { | ||||||
386 | SfxStringItem sfxRange( SID_PRINT_PAGES(5000 +1589), sRange ); | ||||||
387 | aArgs.Put( sfxRange, sfxRange.Which() ); | ||||||
388 | } | ||||||
389 | SfxBoolItem sfxSelection( SID_SELECTIONTypedWhichId<SfxBoolItem>(5000 + 346), bSelection ); | ||||||
390 | aArgs.Put( sfxSelection, sfxSelection.Which() ); | ||||||
391 | SfxBoolItem sfxAsync( SID_ASYNCHRON(5000 + 811), false ); | ||||||
392 | aArgs.Put( sfxAsync, sfxAsync.Which() ); | ||||||
393 | SfxDispatcher* pDispatcher = pViewFrame->GetDispatcher(); | ||||||
394 | |||||||
395 | if ( !pDispatcher ) | ||||||
396 | return; | ||||||
397 | |||||||
398 | if ( bPreview ) | ||||||
399 | { | ||||||
400 | if ( !pViewFrame->GetFrame().IsInPlace() ) | ||||||
401 | { | ||||||
402 | // #TODO is this necessary ( calc specific ) | ||||||
403 | // SC_MOD()->InputEnterHandler(); | ||||||
404 | pViewFrame->GetDispatcher()->Execute( SID_VIEWSHELL1(5000 + 631), SfxCallMode::SYNCHRON ); | ||||||
405 | WaitUntilPreviewIsClosed( pViewFrame ); | ||||||
406 | } | ||||||
407 | } | ||||||
408 | else | ||||||
409 | pDispatcher->Execute( sal_uInt16(SID_PRINTDOC(5000 + 504)), SfxCallMode::SYNCHRON, aArgs ); | ||||||
410 | |||||||
411 | |||||||
412 | // #FIXME #TODO | ||||||
413 | // 1 ActivePrinter ( how/can we switch a printer via API? ) | ||||||
414 | // 2 PrintToFile ( ms behaviour if this option is specified but no | ||||||
415 | // filename supplied 'PrToFileName' then the user will be prompted ) | ||||||
416 | // 3 Need to check behaviour of Selected sheets with range ( e.g. From & To | ||||||
417 | // values ) in oOO these options are mutually exclusive | ||||||
418 | // 4 There is a pop up to do with transparent objects in the print source | ||||||
419 | // should be able to disable that via configuration for the duration | ||||||
420 | // of this method | ||||||
421 | } | ||||||
422 | |||||||
423 | void PrintPreviewHelper( const css::uno::Any& /*EnableChanges*/, SfxViewShell const * pViewShell ) | ||||||
424 | { | ||||||
425 | SfxViewFrame* pViewFrame = nullptr; | ||||||
426 | if ( pViewShell ) | ||||||
427 | pViewFrame = pViewShell->GetViewFrame(); | ||||||
428 | if ( pViewFrame ) | ||||||
429 | { | ||||||
430 | if ( !pViewFrame->GetFrame().IsInPlace() ) | ||||||
431 | { | ||||||
432 | dispatchExecute( pViewShell, SID_VIEWSHELL1(5000 + 631) ); | ||||||
433 | WaitUntilPreviewIsClosed( pViewFrame ); | ||||||
434 | } | ||||||
435 | } | ||||||
436 | } | ||||||
437 | |||||||
438 | void WaitUntilPreviewIsClosed( SfxViewFrame* pViewFrame ) | ||||||
439 | { | ||||||
440 | while ( pViewFrame && isInPrintPreview( pViewFrame ) ) | ||||||
441 | Application::Yield(); | ||||||
442 | } | ||||||
443 | |||||||
444 | bool extractBoolFromAny( const uno::Any& rAny ) | ||||||
445 | { | ||||||
446 | switch( rAny.getValueType().getTypeClass() ) | ||||||
447 | { | ||||||
448 | case uno::TypeClass_BOOLEAN: | ||||||
449 | return rAny.get< bool >(); | ||||||
450 | case uno::TypeClass_FLOAT: | ||||||
451 | return rAny.get< float >() != 0.0; | ||||||
452 | case uno::TypeClass_DOUBLE: | ||||||
453 | return rAny.get< double >() != 0.0; | ||||||
454 | case uno::TypeClass_BYTE: | ||||||
455 | case uno::TypeClass_SHORT: | ||||||
456 | case uno::TypeClass_LONG: | ||||||
457 | return rAny.get< sal_Int32 >() != 0; | ||||||
458 | case uno::TypeClass_HYPER: | ||||||
459 | return rAny.get< sal_Int64 >() != 0; | ||||||
460 | default:; | ||||||
461 | } | ||||||
462 | throw uno::RuntimeException( "Invalid type, cannot convert to boolean." , nullptr ); | ||||||
463 | } | ||||||
464 | |||||||
465 | OUString extractStringFromAny( const uno::Any& rAny, bool bUppercaseBool ) | ||||||
466 | { | ||||||
467 | switch( rAny.getValueType().getTypeClass() ) | ||||||
468 | { | ||||||
469 | case uno::TypeClass_STRING: | ||||||
470 | return rAny.get< OUString >(); | ||||||
471 | case uno::TypeClass_BOOLEAN: | ||||||
472 | return bUppercaseBool ? | ||||||
473 | (rAny.get< bool >() ? OUString( "TRUE" ) : OUString( "FALSE" )) : | ||||||
474 | OUString::boolean( rAny.get< bool >() ); | ||||||
475 | case uno::TypeClass_FLOAT: | ||||||
476 | return OUString::number( rAny.get< float >() ); | ||||||
477 | case uno::TypeClass_DOUBLE: | ||||||
478 | return OUString::number( rAny.get< double >() ); | ||||||
479 | case uno::TypeClass_BYTE: | ||||||
480 | case uno::TypeClass_SHORT: | ||||||
481 | case uno::TypeClass_LONG: | ||||||
482 | return OUString::number( rAny.get< sal_Int32 >() ); | ||||||
483 | case uno::TypeClass_HYPER: | ||||||
484 | return OUString::number( rAny.get< sal_Int64 >() ); | ||||||
485 | default:; | ||||||
486 | } | ||||||
487 | throw uno::RuntimeException( "Invalid type, cannot convert to string." , nullptr ); | ||||||
488 | } | ||||||
489 | |||||||
490 | OUString extractStringFromAny( const uno::Any& rAny, const OUString& rDefault, bool bUppercaseBool ) | ||||||
491 | { | ||||||
492 | return rAny.hasValue() ? extractStringFromAny( rAny, bUppercaseBool ) : rDefault; | ||||||
493 | } | ||||||
494 | |||||||
495 | OUString getAnyAsString( const uno::Any& pvargItem ) | ||||||
496 | { | ||||||
497 | return extractStringFromAny( pvargItem ); | ||||||
498 | } | ||||||
499 | |||||||
500 | |||||||
501 | OUString | ||||||
502 | ContainerUtilities::getUniqueName( const uno::Sequence< OUString >& _slist, const OUString& _sElementName, const OUString& _sSuffixSeparator) | ||||||
503 | { | ||||||
504 | return getUniqueName(_slist, _sElementName, _sSuffixSeparator, sal_Int32(2)); | ||||||
505 | } | ||||||
506 | |||||||
507 | OUString | ||||||
508 | ContainerUtilities::getUniqueName( const uno::Sequence< OUString >& _slist, const OUString& _sElementName, const OUString& _sSuffixSeparator, sal_Int32 _nStartSuffix) | ||||||
509 | { | ||||||
510 | if ( !_slist.hasElements() ) | ||||||
511 | return _sElementName; | ||||||
512 | |||||||
513 | OUString scompname = _sElementName; | ||||||
514 | sal_Int32 a = _nStartSuffix; | ||||||
515 | |||||||
516 | for (;;) | ||||||
517 | { | ||||||
518 | if (FieldInList(_slist, scompname) == -1) | ||||||
519 | return scompname; | ||||||
520 | |||||||
521 | scompname = _sElementName + _sSuffixSeparator + OUString::number( a++ ); | ||||||
522 | } | ||||||
523 | } | ||||||
524 | |||||||
525 | sal_Int32 | ||||||
526 | ContainerUtilities::FieldInList( const uno::Sequence< OUString >& SearchList, const OUString& SearchString ) | ||||||
527 | { | ||||||
528 | // I wonder why comparing lexicographically is done | ||||||
529 | // when it's a match, is it interesting? | ||||||
530 | return comphelper::findValue(SearchList, SearchString); | ||||||
531 | } | ||||||
532 | |||||||
533 | static bool NeedEsc(sal_Unicode cCode) | ||||||
534 | { | ||||||
535 | return OUString(".^$+\\|{}()").indexOf(cCode) != -1; | ||||||
536 | } | ||||||
537 | |||||||
538 | OUString VBAToRegexp(const OUString &rIn) | ||||||
539 | { | ||||||
540 | OUStringBuffer sResult; | ||||||
541 | const sal_Unicode *start = rIn.getStr(); | ||||||
542 | const sal_Unicode *end = start + rIn.getLength(); | ||||||
543 | |||||||
544 | int seenright = 0; | ||||||
545 | |||||||
546 | while (start < end) | ||||||
547 | { | ||||||
548 | switch (*start) | ||||||
549 | { | ||||||
550 | case '?': | ||||||
551 | sResult.append('.'); | ||||||
552 | start++; | ||||||
553 | break; | ||||||
554 | case '*': | ||||||
555 | sResult.append(".*"); | ||||||
556 | start++; | ||||||
557 | break; | ||||||
558 | case '#': | ||||||
559 | sResult.append("[0-9]"); | ||||||
560 | start++; | ||||||
561 | break; | ||||||
562 | case '~': | ||||||
563 | sResult.append('\\'); | ||||||
564 | sResult.append(*(++start)); | ||||||
565 | start++; | ||||||
566 | break; | ||||||
567 | // dump the ~ and escape the next character | ||||||
568 | case ']': | ||||||
569 | sResult.append('\\'); | ||||||
570 | sResult.append(*start++); | ||||||
571 | break; | ||||||
572 | case '[': | ||||||
573 | sResult.append(*start++); | ||||||
574 | seenright = 0; | ||||||
575 | while (start < end && !seenright) | ||||||
576 | { | ||||||
577 | switch (*start) | ||||||
578 | { | ||||||
579 | case '[': | ||||||
580 | case '?': | ||||||
581 | case '*': | ||||||
582 | sResult.append('\\'); | ||||||
583 | sResult.append(*start); | ||||||
584 | break; | ||||||
585 | case ']': | ||||||
586 | sResult.append(*start); | ||||||
587 | seenright = 1; | ||||||
588 | break; | ||||||
589 | case '!': | ||||||
590 | sResult.append('^'); | ||||||
591 | break; | ||||||
592 | default: | ||||||
593 | if (NeedEsc(*start)) | ||||||
594 | sResult.append('\\'); | ||||||
595 | sResult.append(*start); | ||||||
596 | break; | ||||||
597 | } | ||||||
598 | start++; | ||||||
599 | } | ||||||
600 | break; | ||||||
601 | default: | ||||||
602 | if (NeedEsc(*start)) | ||||||
603 | sResult.append('\\'); | ||||||
604 | sResult.append(*start++); | ||||||
605 | } | ||||||
606 | } | ||||||
607 | |||||||
608 | return sResult.makeStringAndClear( ); | ||||||
609 | } | ||||||
610 | |||||||
611 | double getPixelTo100thMillimeterConversionFactor( const css::uno::Reference< css::awt::XDevice >& xDevice, bool bVertical) | ||||||
612 | { | ||||||
613 | double fConvertFactor = 1.0; | ||||||
614 | if( bVertical ) | ||||||
615 | { | ||||||
616 | fConvertFactor = xDevice->getInfo().PixelPerMeterY/100000; | ||||||
617 | } | ||||||
618 | else | ||||||
619 | { | ||||||
620 | fConvertFactor = xDevice->getInfo().PixelPerMeterX/100000; | ||||||
621 | } | ||||||
622 | return fConvertFactor; | ||||||
623 | } | ||||||
624 | |||||||
625 | double PointsToPixels( const css::uno::Reference< css::awt::XDevice >& xDevice, double fPoints, bool bVertical) | ||||||
626 | { | ||||||
627 | double fConvertFactor = getPixelTo100thMillimeterConversionFactor( xDevice, bVertical ); | ||||||
628 | return PointsToHmm( fPoints ) * fConvertFactor; | ||||||
629 | } | ||||||
630 | double PixelsToPoints( const css::uno::Reference< css::awt::XDevice >& xDevice, double fPixels, bool bVertical) | ||||||
631 | { | ||||||
632 | double fConvertFactor = getPixelTo100thMillimeterConversionFactor( xDevice, bVertical ); | ||||||
633 | return HmmToPoints(static_cast<sal_Int32>(fPixels/fConvertFactor)); | ||||||
634 | } | ||||||
635 | |||||||
636 | sal_Int32 PointsToHmm( double fPoints ) | ||||||
637 | { | ||||||
638 | return static_cast<sal_Int32>( fPoints * factor + 0.5 ); | ||||||
639 | } | ||||||
640 | |||||||
641 | double HmmToPoints( sal_Int32 nHmm ) | ||||||
642 | { | ||||||
643 | return nHmm / factor; | ||||||
644 | } | ||||||
645 | |||||||
646 | ConcreteXShapeGeometryAttributes::ConcreteXShapeGeometryAttributes( const css::uno::Reference< css::drawing::XShape >& xShape ) | ||||||
647 | { | ||||||
648 | m_pShapeHelper.reset( new ShapeHelper( xShape ) ); | ||||||
649 | } | ||||||
650 | ConcreteXShapeGeometryAttributes::~ConcreteXShapeGeometryAttributes() | ||||||
651 | { | ||||||
652 | } | ||||||
653 | |||||||
654 | PointerStyle getPointerStyle( const uno::Reference< frame::XModel >& xModel ) | ||||||
655 | { | ||||||
656 | |||||||
657 | PointerStyle nPointerStyle( PointerStyle::Arrow ); | ||||||
658 | try | ||||||
659 | { | ||||||
660 | const uno::Reference< frame::XController > xController( xModel->getCurrentController(), uno::UNO_SET_THROW ); | ||||||
661 | const uno::Reference< frame::XFrame > xFrame ( xController->getFrame(), uno::UNO_SET_THROW ); | ||||||
662 | const uno::Reference< awt::XWindow > xWindow ( xFrame->getContainerWindow(), uno::UNO_SET_THROW ); | ||||||
663 | // why the heck isn't there an XWindowPeer::getPointer, but a setPointer only? | ||||||
664 | const vcl::Window* pWindow = VCLUnoHelper::GetWindow( xWindow ); | ||||||
| |||||||
665 | if ( pWindow
| ||||||
666 | nPointerStyle = pWindow->GetSystemWindow()->GetPointer(); | ||||||
| |||||||
667 | } | ||||||
668 | catch (const uno::Exception&) | ||||||
669 | { | ||||||
670 | DBG_UNHANDLED_EXCEPTION("vbahelper")DbgUnhandledException( DbgGetCaughtException(), __func__, "/home/maarten/src/libreoffice/core/vbahelper/source/vbahelper/vbahelper.cxx" ":" "670" ": ", "vbahelper" );; | ||||||
671 | } | ||||||
672 | return nPointerStyle; | ||||||
673 | } | ||||||
674 | |||||||
675 | // #FIXME this method looks wrong, shouldn't it just affect calc *or* writer | ||||||
676 | // document/frame/window(s) but not both ( and depending on what api called | ||||||
677 | // this ) | ||||||
678 | void setCursorHelper( const uno::Reference< frame::XModel >& xModel, PointerStyle nPointer, bool bOverWrite ) | ||||||
679 | { | ||||||
680 | ::std::vector< uno::Reference< frame::XController > > aControllers; | ||||||
681 | |||||||
682 | uno::Reference< frame::XModel2 > xModel2( xModel, uno::UNO_QUERY ); | ||||||
683 | if ( xModel2.is() ) | ||||||
684 | { | ||||||
685 | const uno::Reference< container::XEnumeration > xEnumControllers( xModel2->getControllers(), uno::UNO_SET_THROW ); | ||||||
686 | while ( xEnumControllers->hasMoreElements() ) | ||||||
687 | { | ||||||
688 | const uno::Reference< frame::XController > xController( xEnumControllers->nextElement(), uno::UNO_QUERY_THROW ); | ||||||
689 | aControllers.push_back( xController ); | ||||||
690 | } | ||||||
691 | } | ||||||
692 | else | ||||||
693 | { | ||||||
694 | if ( xModel.is() ) | ||||||
695 | { | ||||||
696 | const uno::Reference< frame::XController > xController( xModel->getCurrentController(), uno::UNO_SET_THROW ); | ||||||
697 | aControllers.push_back( xController ); | ||||||
698 | } | ||||||
699 | } | ||||||
700 | |||||||
701 | for ( const auto& rController : aControllers ) | ||||||
702 | { | ||||||
703 | const uno::Reference< frame::XFrame > xFrame ( rController->getFrame(), uno::UNO_SET_THROW ); | ||||||
704 | const uno::Reference< awt::XWindow > xWindow ( xFrame->getContainerWindow(), uno::UNO_SET_THROW ); | ||||||
705 | |||||||
706 | VclPtr<vcl::Window> pWindow = VCLUnoHelper::GetWindow( xWindow ); | ||||||
707 | SAL_WARN_IF( !pWindow, "vbahelper", "ScVbaApplication::setCursor: no window!" )do { if (true && (!pWindow)) { switch (sal_detail_log_report (::SAL_DETAIL_LOG_LEVEL_WARN, "vbahelper")) { case SAL_DETAIL_LOG_ACTION_IGNORE : break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail ::getResult( ::sal::detail::StreamStart() << "ScVbaApplication::setCursor: no window!" ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vbahelper" ), ("/home/maarten/src/libreoffice/core/vbahelper/source/vbahelper/vbahelper.cxx" ":" "707" ": "), ::sal::detail::unwrapStream( ::sal::detail:: StreamStart() << "ScVbaApplication::setCursor: no window!" ), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "ScVbaApplication::setCursor: no window!"; ::sal::detail ::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vbahelper"), ("/home/maarten/src/libreoffice/core/vbahelper/source/vbahelper/vbahelper.cxx" ":" "707" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "ScVbaApplication::setCursor: no window!") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vbahelper" ), ("/home/maarten/src/libreoffice/core/vbahelper/source/vbahelper/vbahelper.cxx" ":" "707" ": "), ::sal::detail::unwrapStream( ::sal::detail:: StreamStart() << "ScVbaApplication::setCursor: no window!" ), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "ScVbaApplication::setCursor: no window!"; ::sal::detail ::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vbahelper"), ("/home/maarten/src/libreoffice/core/vbahelper/source/vbahelper/vbahelper.cxx" ":" "707" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | ||||||
708 | if ( !pWindow ) | ||||||
709 | continue; | ||||||
710 | |||||||
711 | pWindow->GetSystemWindow()->SetPointer( nPointer ); | ||||||
712 | pWindow->GetSystemWindow()->EnableChildPointerOverwrite( bOverWrite ); | ||||||
713 | } | ||||||
714 | } | ||||||
715 | |||||||
716 | void setDefaultPropByIntrospection( const uno::Any& aObj, const uno::Any& aValue ) | ||||||
717 | { | ||||||
718 | uno::Reference< beans::XIntrospectionAccess > xUnoAccess( getIntrospectionAccess( aObj ) ); | ||||||
719 | |||||||
720 | // #MAYBE #FIXME sort of a bit of a hack, | ||||||
721 | uno::Reference< script::XDefaultProperty > xDflt( aObj, uno::UNO_QUERY_THROW ); | ||||||
722 | uno::Reference< beans::XPropertySet > xPropSet; | ||||||
723 | |||||||
724 | if ( xUnoAccess.is() ) | ||||||
725 | xPropSet.set( xUnoAccess->queryAdapter( cppu::UnoType<beans::XPropertySet>::get()), uno::UNO_QUERY); | ||||||
726 | |||||||
727 | if ( !xPropSet.is() ) | ||||||
728 | throw uno::RuntimeException(); | ||||||
729 | |||||||
730 | xPropSet->setPropertyValue( xDflt->getDefaultPropertyName(), aValue ); | ||||||
731 | } | ||||||
732 | |||||||
733 | uno::Any getPropertyValue( const uno::Sequence< beans::PropertyValue >& aProp, const OUString& aName ) | ||||||
734 | { | ||||||
735 | auto pProp = std::find_if(aProp.begin(), aProp.end(), | ||||||
736 | [&aName](const beans::PropertyValue& rProp) { return rProp.Name == aName; }); | ||||||
737 | if (pProp != aProp.end()) | ||||||
738 | return pProp->Value; | ||||||
739 | return uno::Any(); | ||||||
740 | } | ||||||
741 | |||||||
742 | bool setPropertyValue( uno::Sequence< beans::PropertyValue >& aProp, const OUString& aName, const uno::Any& aValue ) | ||||||
743 | { | ||||||
744 | auto pProp = std::find_if(aProp.begin(), aProp.end(), | ||||||
745 | [&aName](const beans::PropertyValue& rProp) { return rProp.Name == aName; }); | ||||||
746 | if (pProp != aProp.end()) | ||||||
747 | { | ||||||
748 | pProp->Value = aValue; | ||||||
749 | return true; | ||||||
750 | } | ||||||
751 | return false; | ||||||
752 | } | ||||||
753 | |||||||
754 | void setOrAppendPropertyValue( uno::Sequence< beans::PropertyValue >& aProp, const OUString& aName, const uno::Any& aValue ) | ||||||
755 | { | ||||||
756 | if( setPropertyValue( aProp, aName, aValue ) ) | ||||||
757 | return; | ||||||
758 | |||||||
759 | // append the property | ||||||
760 | sal_Int32 nLength = aProp.getLength(); | ||||||
761 | aProp.realloc( nLength + 1 ); | ||||||
762 | aProp[ nLength ].Name = aName; | ||||||
763 | aProp[ nLength ].Value = aValue; | ||||||
764 | } | ||||||
765 | |||||||
766 | // ====UserFormGeomentryHelper==== | ||||||
767 | |||||||
768 | UserFormGeometryHelper::UserFormGeometryHelper( | ||||||
769 | const uno::Reference< awt::XControl >& xControl, | ||||||
770 | double fOffsetX, double fOffsetY ) : | ||||||
771 | mfOffsetX( fOffsetX ), | ||||||
772 | mfOffsetY( fOffsetY ), | ||||||
773 | mbDialog( uno::Reference< awt::XDialog >( xControl, uno::UNO_QUERY ).is() ) | ||||||
774 | { | ||||||
775 | if ( !xControl.is() ) | ||||||
776 | throw uno::RuntimeException( "No control is provided!" ); | ||||||
777 | |||||||
778 | mxWindow.set( xControl->getPeer(), uno::UNO_QUERY_THROW ); | ||||||
779 | mxModelProps.set( xControl->getModel(), uno::UNO_QUERY_THROW ); | ||||||
780 | mxUnitConv.set( mxWindow, uno::UNO_QUERY_THROW ); | ||||||
781 | } | ||||||
782 | |||||||
783 | double UserFormGeometryHelper::getLeft() const | ||||||
784 | { | ||||||
785 | return implGetPos( false ); | ||||||
786 | } | ||||||
787 | |||||||
788 | void UserFormGeometryHelper::setLeft( double fLeft ) | ||||||
789 | { | ||||||
790 | implSetPos( fLeft, false ); | ||||||
791 | } | ||||||
792 | |||||||
793 | double UserFormGeometryHelper::getTop() const | ||||||
794 | { | ||||||
795 | return implGetPos( true ); | ||||||
796 | } | ||||||
797 | |||||||
798 | void UserFormGeometryHelper::setTop( double fTop ) | ||||||
799 | { | ||||||
800 | implSetPos( fTop, true ); | ||||||
801 | } | ||||||
802 | |||||||
803 | double UserFormGeometryHelper::getWidth() const | ||||||
804 | { | ||||||
805 | return implGetSize( false, true ); | ||||||
806 | } | ||||||
807 | |||||||
808 | void UserFormGeometryHelper::setWidth( double fWidth ) | ||||||
809 | { | ||||||
810 | implSetSize( fWidth, false, true ); | ||||||
811 | } | ||||||
812 | |||||||
813 | double UserFormGeometryHelper::getHeight() const | ||||||
814 | { | ||||||
815 | return implGetSize( true, true ); | ||||||
816 | } | ||||||
817 | |||||||
818 | void UserFormGeometryHelper::setHeight( double fHeight ) | ||||||
819 | { | ||||||
820 | implSetSize( fHeight, true, true ); | ||||||
821 | } | ||||||
822 | |||||||
823 | double UserFormGeometryHelper::getInnerWidth() const | ||||||
824 | { | ||||||
825 | return implGetSize( false, false ); | ||||||
826 | } | ||||||
827 | |||||||
828 | void UserFormGeometryHelper::setInnerWidth( double fWidth ) | ||||||
829 | { | ||||||
830 | implSetSize( fWidth, false, false ); | ||||||
831 | } | ||||||
832 | |||||||
833 | double UserFormGeometryHelper::getInnerHeight() const | ||||||
834 | { | ||||||
835 | return implGetSize( true, false ); | ||||||
836 | } | ||||||
837 | |||||||
838 | void UserFormGeometryHelper::setInnerHeight( double fHeight ) | ||||||
839 | { | ||||||
840 | implSetSize( fHeight, true, false ); | ||||||
841 | } | ||||||
842 | |||||||
843 | double UserFormGeometryHelper::getOffsetX() const | ||||||
844 | { | ||||||
845 | return mfOffsetX; | ||||||
846 | } | ||||||
847 | |||||||
848 | double UserFormGeometryHelper::getOffsetY() const | ||||||
849 | { | ||||||
850 | return mfOffsetY; | ||||||
851 | } | ||||||
852 | |||||||
853 | |||||||
854 | const char saPosXName[] = "PositionX"; | ||||||
855 | const char saPosYName[] = "PositionY"; | ||||||
856 | const char saWidthName[] = "Width"; | ||||||
857 | const char saHeightName[] = "Height"; | ||||||
858 | |||||||
859 | double UserFormGeometryHelper::implGetPos( bool bPosY ) const | ||||||
860 | { | ||||||
861 | sal_Int32 nPosAppFont = mxModelProps->getPropertyValue( bPosY ? OUString(saPosYName) : OUString(saPosXName) ).get< sal_Int32 >(); | ||||||
862 | // appfont to pixel | ||||||
863 | awt::Point aPosPixel = mxUnitConv->convertPointToPixel( awt::Point( nPosAppFont, nPosAppFont ), util::MeasureUnit::APPFONT ); | ||||||
864 | // pixel to VBA points | ||||||
865 | awt::Point aPosPoint = mxUnitConv->convertPointToLogic( aPosPixel, util::MeasureUnit::POINT ); | ||||||
866 | return bPosY ? (aPosPoint.Y - mfOffsetY) : (aPosPoint.X - mfOffsetX); | ||||||
867 | } | ||||||
868 | |||||||
869 | void UserFormGeometryHelper::implSetPos( double fPos, bool bPosY ) | ||||||
870 | { | ||||||
871 | // convert passed VBA points to pixels | ||||||
872 | sal_Int32 nPosPixel = static_cast< sal_Int32 >( fPos + (bPosY ? mfOffsetY : mfOffsetX) ); | ||||||
873 | awt::Point aPosPixel = mxUnitConv->convertPointToPixel( awt::Point( nPosPixel, nPosPixel ), util::MeasureUnit::POINT ); | ||||||
874 | // pixel to appfont | ||||||
875 | awt::Point aPosAppFont = mxUnitConv->convertPointToLogic( aPosPixel, util::MeasureUnit::APPFONT ); | ||||||
876 | mxModelProps->setPropertyValue( bPosY ? OUString(saPosYName) : OUString(saPosXName), uno::Any( bPosY ? aPosAppFont.Y : aPosAppFont.X ) ); | ||||||
877 | } | ||||||
878 | |||||||
879 | double UserFormGeometryHelper::implGetSize( bool bHeight, bool bOuter ) const | ||||||
880 | { | ||||||
881 | sal_Int32 nSizeAppFont = mxModelProps->getPropertyValue( bHeight ? OUString(saHeightName) : OUString(saWidthName) ).get< sal_Int32 >(); | ||||||
882 | // appfont to pixel | ||||||
883 | awt::Size aSizePixel = mxUnitConv->convertSizeToPixel( awt::Size( nSizeAppFont, nSizeAppFont ), util::MeasureUnit::APPFONT ); | ||||||
884 | |||||||
885 | /* The VBA symbols 'Width' and 'Height' return the outer size including | ||||||
886 | window decoration (in difference to the symbols 'InnerWidth' and | ||||||
887 | 'InnerHeight'), but the window API returns the inner size. */ | ||||||
888 | if( mbDialog && bOuter ) | ||||||
889 | { | ||||||
890 | if( const vcl::Window* pWindow = VCLUnoHelper::GetWindow( mxWindow ) ) | ||||||
891 | { | ||||||
892 | tools::Rectangle aOuterRect = pWindow->GetWindowExtentsRelative( nullptr ); | ||||||
893 | aSizePixel = awt::Size( aOuterRect.getWidth(), aOuterRect.getHeight() ); | ||||||
894 | } | ||||||
895 | } | ||||||
896 | |||||||
897 | // pixel to VBA points | ||||||
898 | awt::Size aSizePoint = mxUnitConv->convertSizeToLogic( aSizePixel, util::MeasureUnit::POINT ); | ||||||
899 | return bHeight ? aSizePoint.Height : aSizePoint.Width; | ||||||
900 | } | ||||||
901 | |||||||
902 | void UserFormGeometryHelper::implSetSize( double fSize, bool bHeight, bool bOuter ) | ||||||
903 | { | ||||||
904 | // convert passed VBA points to pixels | ||||||
905 | sal_Int32 nSize = static_cast< sal_Int32 >( fSize ); | ||||||
906 | awt::Size aSizePixel = mxUnitConv->convertSizeToPixel( awt::Size( nSize, nSize ), util::MeasureUnit::POINT ); | ||||||
907 | |||||||
908 | /* The VBA symbols 'Width' and 'Height' set the outer size (in difference | ||||||
909 | to the symbols 'InnerWidth' and 'InnerHeight'), but the dialog model | ||||||
910 | expects the inner size. We have to remove the window extents from the | ||||||
911 | pixel height to get the same result. */ | ||||||
912 | if ( mbDialog && bOuter ) | ||||||
913 | { | ||||||
914 | if( const vcl::Window* pWindow = VCLUnoHelper::GetWindow( mxWindow ) ) | ||||||
915 | { | ||||||
916 | tools::Rectangle aOuterRect = pWindow->GetWindowExtentsRelative( nullptr ); | ||||||
917 | if( !aOuterRect.IsEmpty() ) | ||||||
918 | { | ||||||
919 | awt::Rectangle aInnerRect = mxWindow->getPosSize(); | ||||||
920 | sal_Int32 nDecorWidth = aOuterRect.getWidth() - aInnerRect.Width; | ||||||
921 | sal_Int32 nDecorHeight = aOuterRect.getHeight() - aInnerRect.Height; | ||||||
922 | aSizePixel.Width = ::std::max< sal_Int32 >( aSizePixel.Width - nDecorWidth, 1 ); | ||||||
923 | aSizePixel.Height = ::std::max< sal_Int32 >( aSizePixel.Height - nDecorHeight, 1 ); | ||||||
924 | } | ||||||
925 | } | ||||||
926 | } | ||||||
927 | |||||||
928 | awt::Size aSizeAppFont = mxUnitConv->convertSizeToLogic( aSizePixel, util::MeasureUnit::APPFONT ); | ||||||
929 | mxModelProps->setPropertyValue( bHeight ? OUString(saHeightName) : OUString(saWidthName), uno::Any( bHeight ? aSizeAppFont.Height : aSizeAppFont.Width ) ); | ||||||
930 | } | ||||||
931 | |||||||
932 | |||||||
933 | double ConcreteXShapeGeometryAttributes::getLeft() const | ||||||
934 | { | ||||||
935 | return m_pShapeHelper->getLeft(); | ||||||
936 | } | ||||||
937 | void ConcreteXShapeGeometryAttributes::setLeft( double nLeft ) | ||||||
938 | { | ||||||
939 | m_pShapeHelper->setLeft( nLeft ); | ||||||
940 | } | ||||||
941 | double ConcreteXShapeGeometryAttributes::getTop() const | ||||||
942 | { | ||||||
943 | return m_pShapeHelper->getTop(); | ||||||
944 | } | ||||||
945 | void ConcreteXShapeGeometryAttributes::setTop( double nTop ) | ||||||
946 | { | ||||||
947 | m_pShapeHelper->setTop( nTop ); | ||||||
948 | } | ||||||
949 | |||||||
950 | double ConcreteXShapeGeometryAttributes::getHeight() const | ||||||
951 | { | ||||||
952 | return m_pShapeHelper->getHeight(); | ||||||
953 | } | ||||||
954 | void ConcreteXShapeGeometryAttributes::setHeight( double nHeight ) | ||||||
955 | { | ||||||
956 | m_pShapeHelper->setHeight( nHeight ); | ||||||
957 | } | ||||||
958 | double ConcreteXShapeGeometryAttributes::getWidth() const | ||||||
959 | { | ||||||
960 | return m_pShapeHelper->getWidth(); | ||||||
961 | } | ||||||
962 | void ConcreteXShapeGeometryAttributes::setWidth( double nWidth) | ||||||
963 | { | ||||||
964 | m_pShapeHelper->setWidth( nWidth ); | ||||||
965 | } | ||||||
966 | |||||||
967 | |||||||
968 | ShapeHelper::ShapeHelper( const css::uno::Reference< css::drawing::XShape >& _xShape) | ||||||
969 | : xShape( _xShape ) | ||||||
970 | { | ||||||
971 | if( !xShape.is() ) | ||||||
972 | throw css::uno::RuntimeException( "No valid shape for helper" ); | ||||||
973 | } | ||||||
974 | |||||||
975 | double ShapeHelper::getHeight() const | ||||||
976 | { | ||||||
977 | return Millimeter::getInPoints(xShape->getSize().Height); | ||||||
978 | } | ||||||
979 | |||||||
980 | void ShapeHelper::setHeight(double _fheight) | ||||||
981 | { | ||||||
982 | css::awt::Size aSize = xShape->getSize(); | ||||||
983 | aSize.Height = Millimeter::getInHundredthsOfOneMillimeter(_fheight); | ||||||
984 | xShape->setSize(aSize); | ||||||
985 | } | ||||||
986 | |||||||
987 | double ShapeHelper::getWidth() const | ||||||
988 | { | ||||||
989 | return Millimeter::getInPoints(xShape->getSize().Width); | ||||||
990 | } | ||||||
991 | |||||||
992 | void ShapeHelper::setWidth(double _fWidth) | ||||||
993 | { | ||||||
994 | css::awt::Size aSize = xShape->getSize(); | ||||||
995 | aSize.Width = Millimeter::getInHundredthsOfOneMillimeter(_fWidth); | ||||||
996 | xShape->setSize(aSize); | ||||||
997 | } | ||||||
998 | |||||||
999 | double ShapeHelper::getLeft() const | ||||||
1000 | { | ||||||
1001 | return Millimeter::getInPoints(xShape->getPosition().X); | ||||||
1002 | } | ||||||
1003 | |||||||
1004 | void ShapeHelper::setLeft(double _fLeft) | ||||||
1005 | { | ||||||
1006 | css::awt::Point aPoint = xShape->getPosition(); | ||||||
1007 | aPoint.X = Millimeter::getInHundredthsOfOneMillimeter(_fLeft); | ||||||
1008 | xShape->setPosition(aPoint); | ||||||
1009 | } | ||||||
1010 | |||||||
1011 | double ShapeHelper::getTop() const | ||||||
1012 | { | ||||||
1013 | return Millimeter::getInPoints(xShape->getPosition().Y); | ||||||
1014 | } | ||||||
1015 | |||||||
1016 | void ShapeHelper::setTop(double _fTop) | ||||||
1017 | { | ||||||
1018 | css::awt::Point aPoint = xShape->getPosition(); | ||||||
1019 | aPoint.Y = Millimeter::getInHundredthsOfOneMillimeter(_fTop); | ||||||
1020 | xShape->setPosition(aPoint); | ||||||
1021 | } | ||||||
1022 | |||||||
1023 | void DebugHelper::basicexception( const css::uno::Exception& ex, ErrCode err, const OUString& /*additionalArgument*/ ) | ||||||
1024 | { | ||||||
1025 | // #TODO #FIXME ( do we want to support additionalArg here ) | ||||||
1026 | throw css::script::BasicErrorException( ex.Message, css::uno::Reference< css::uno::XInterface >(), sal_uInt32(err), OUString() ); | ||||||
1027 | } | ||||||
1028 | |||||||
1029 | void DebugHelper::basicexception( ErrCode err, const OUString& additionalArgument ) | ||||||
1030 | { | ||||||
1031 | basicexception( css::uno::Exception(), err, additionalArgument ); | ||||||
1032 | } | ||||||
1033 | |||||||
1034 | void DebugHelper::basicexception( const css::uno::Exception& ex ) | ||||||
1035 | { | ||||||
1036 | basicexception( ex, ERRCODE_BASIC_INTERNAL_ERRORErrCode( ErrCodeArea::Sbx, ErrCodeClass::Unknown, 9), OUString() ); | ||||||
1037 | } | ||||||
1038 | |||||||
1039 | void DebugHelper::runtimeexception( ErrCode err ) | ||||||
1040 | { | ||||||
1041 | // #TODO #FIXME ( do we want to support additionalArg here ) | ||||||
1042 | throw css::uno::RuntimeException( css::uno::Exception().Message + " " + OUString::number(sal_uInt32(err)), | ||||||
1043 | css::uno::Reference< css::uno::XInterface >() ); | ||||||
1044 | } | ||||||
1045 | |||||||
1046 | Millimeter::Millimeter():m_nMillimeter(0) {} | ||||||
1047 | |||||||
1048 | Millimeter::Millimeter(double mm):m_nMillimeter(mm) {} | ||||||
1049 | |||||||
1050 | void Millimeter::setInPoints(double points) | ||||||
1051 | { | ||||||
1052 | m_nMillimeter = points * factor / 100.0; | ||||||
1053 | } | ||||||
1054 | |||||||
1055 | double Millimeter::getInHundredthsOfOneMillimeter() const | ||||||
1056 | { | ||||||
1057 | return m_nMillimeter * 100; | ||||||
1058 | } | ||||||
1059 | |||||||
1060 | sal_Int32 Millimeter::getInHundredthsOfOneMillimeter(double points) | ||||||
1061 | { | ||||||
1062 | sal_Int32 mm = static_cast<sal_Int32>(points * factor); | ||||||
1063 | return mm; | ||||||
1064 | } | ||||||
1065 | |||||||
1066 | double Millimeter::getInPoints(int _hmm) | ||||||
1067 | { | ||||||
1068 | double points = double( static_cast<double>(_hmm) / factor); | ||||||
1069 | return points; | ||||||
1070 | } | ||||||
1071 | |||||||
1072 | uno::Reference< XHelperInterface > getVBADocument( const uno::Reference< frame::XModel >& xModel ) | ||||||
1073 | { | ||||||
1074 | uno::Reference< XHelperInterface > xIf; | ||||||
1075 | try | ||||||
1076 | { | ||||||
1077 | uno::Reference< beans::XPropertySet > xDocProps( xModel, uno::UNO_QUERY_THROW ); | ||||||
1078 | OUString aCodeName; | ||||||
1079 | xDocProps->getPropertyValue( "CodeName" ) >>= aCodeName; | ||||||
1080 | xIf = getUnoDocModule( aCodeName, getSfxObjShell( xModel ) ); | ||||||
1081 | } | ||||||
1082 | catch (const uno::Exception&) | ||||||
1083 | { | ||||||
1084 | } | ||||||
1085 | return xIf; | ||||||
1086 | } | ||||||
1087 | |||||||
1088 | uno::Reference< XHelperInterface > getUnoDocModule( const OUString& aModName, SfxObjectShell const * pShell ) | ||||||
1089 | { | ||||||
1090 | uno::Reference< XHelperInterface > xIf; | ||||||
1091 | if ( pShell ) | ||||||
1092 | { | ||||||
1093 | OUString sProj( "Standard" ); | ||||||
1094 | // GetBasicManager() causes a SolarMutex assertion failure in some use cases from | ||||||
1095 | // Automation, at least when opening a Calc Document through ooo::vba::excel:: | ||||||
1096 | // XWorkbooks::Open(). Let's see if this check is a good way around that. It does seem that | ||||||
1097 | // callers are prepared for this to return null? | ||||||
1098 | if (comphelper::Automation::AutomationInvokedZone::isActive()) | ||||||
1099 | return xIf; | ||||||
1100 | BasicManager* pBasMgr = pShell->GetBasicManager(); | ||||||
1101 | if ( pBasMgr && !pBasMgr->GetName().isEmpty() ) | ||||||
1102 | sProj = pBasMgr->GetName(); | ||||||
1103 | if( StarBASIC* pBasic = pShell->GetBasicManager()->GetLib( sProj ) ) | ||||||
1104 | if( SbModule* pMod = pBasic->FindModule( aModName ) ) | ||||||
1105 | xIf.set( pMod->GetUnoModule(), uno::UNO_QUERY ); | ||||||
1106 | } | ||||||
1107 | return xIf; | ||||||
1108 | } | ||||||
1109 | |||||||
1110 | SfxObjectShell* getSfxObjShell( const uno::Reference< frame::XModel >& xModel ) | ||||||
1111 | { | ||||||
1112 | SfxObjectShell* pFoundShell = nullptr; | ||||||
1113 | if ( xModel.is() ) | ||||||
1114 | { | ||||||
1115 | uno::Reference< lang::XUnoTunnel > xObjShellTunnel( xModel, uno::UNO_QUERY_THROW ); | ||||||
1116 | pFoundShell = reinterpret_cast<SfxObjectShell*>( xObjShellTunnel->getSomething(SfxObjectShell::getUnoTunnelId())); | ||||||
1117 | } | ||||||
1118 | if ( !pFoundShell ) | ||||||
1119 | throw uno::RuntimeException(); | ||||||
1120 | return pFoundShell; | ||||||
1121 | } | ||||||
1122 | |||||||
1123 | } //org | ||||||
1124 | |||||||
1125 | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |
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 | #ifndef INCLUDED_RTL_REF_HXX |
21 | #define INCLUDED_RTL_REF_HXX |
22 | |
23 | #include "sal/config.h" |
24 | |
25 | #include <cassert> |
26 | #include <cstddef> |
27 | #include <functional> |
28 | #ifdef LIBO_INTERNAL_ONLY1 |
29 | #include <type_traits> |
30 | #endif |
31 | |
32 | #include "sal/types.h" |
33 | |
34 | namespace rtl |
35 | { |
36 | |
37 | /** Template reference class for reference type. |
38 | */ |
39 | template <class reference_type> |
40 | class Reference |
41 | { |
42 | /** The <b>reference_type</b> body pointer. |
43 | */ |
44 | reference_type * m_pBody; |
45 | |
46 | |
47 | public: |
48 | /** Constructor... |
49 | */ |
50 | Reference() |
51 | : m_pBody (NULL__null) |
52 | {} |
53 | |
54 | |
55 | /** Constructor... |
56 | */ |
57 | Reference (reference_type * pBody, __sal_NoAcquire) |
58 | : m_pBody (pBody) |
59 | { |
60 | } |
61 | |
62 | /** Constructor... |
63 | */ |
64 | Reference (reference_type * pBody) |
65 | : m_pBody (pBody) |
66 | { |
67 | if (m_pBody) |
68 | m_pBody->acquire(); |
69 | } |
70 | |
71 | /** Copy constructor... |
72 | */ |
73 | Reference (const Reference<reference_type> & handle) |
74 | : m_pBody (handle.m_pBody) |
75 | { |
76 | if (m_pBody) |
77 | m_pBody->acquire(); |
78 | } |
79 | |
80 | #ifdef LIBO_INTERNAL_ONLY1 |
81 | /** Move constructor... |
82 | */ |
83 | Reference (Reference<reference_type> && handle) noexcept |
84 | : m_pBody (handle.m_pBody) |
85 | { |
86 | handle.m_pBody = nullptr; |
87 | } |
88 | #endif |
89 | |
90 | #if defined LIBO_INTERNAL_ONLY1 |
91 | /** Up-casting conversion constructor: Copies interface reference. |
92 | |
93 | Does not work for up-casts to ambiguous bases. |
94 | |
95 | @param rRef another reference |
96 | */ |
97 | template< class derived_type > |
98 | inline Reference( |
99 | const Reference< derived_type > & rRef, |
100 | std::enable_if_t<std::is_base_of_v<reference_type, derived_type>, int> = 0 ) |
101 | : m_pBody (rRef.get()) |
102 | { |
103 | if (m_pBody) |
104 | m_pBody->acquire(); |
105 | } |
106 | #endif |
107 | |
108 | /** Destructor... |
109 | */ |
110 | ~Reference() COVERITY_NOEXCEPT_FALSE |
111 | { |
112 | if (m_pBody) |
113 | m_pBody->release(); |
114 | } |
115 | |
116 | /** Set... |
117 | Similar to assignment. |
118 | */ |
119 | Reference<reference_type> & |
120 | SAL_CALL set (reference_type * pBody) |
121 | { |
122 | if (pBody) |
123 | pBody->acquire(); |
124 | reference_type * const pOld = m_pBody; |
125 | m_pBody = pBody; |
126 | if (pOld) |
127 | pOld->release(); |
128 | return *this; |
129 | } |
130 | |
131 | /** Assignment. |
132 | Unbinds this instance from its body (if bound) and |
133 | bind it to the body represented by the handle. |
134 | */ |
135 | Reference<reference_type> & |
136 | SAL_CALL operator= (const Reference<reference_type> & handle) |
137 | { |
138 | return set( handle.m_pBody ); |
139 | } |
140 | |
141 | #ifdef LIBO_INTERNAL_ONLY1 |
142 | /** Assignment. |
143 | * Unbinds this instance from its body (if bound), |
144 | * bind it to the body represented by the handle, and |
145 | * set the body represented by the handle to nullptr. |
146 | */ |
147 | Reference<reference_type> & |
148 | operator= (Reference<reference_type> && handle) |
149 | { |
150 | // self-movement guts ourself |
151 | if (m_pBody) |
152 | m_pBody->release(); |
153 | m_pBody = handle.m_pBody; |
154 | handle.m_pBody = nullptr; |
155 | return *this; |
156 | } |
157 | #endif |
158 | |
159 | /** Assignment... |
160 | */ |
161 | Reference<reference_type> & |
162 | SAL_CALL operator= (reference_type * pBody) |
163 | { |
164 | return set( pBody ); |
165 | } |
166 | |
167 | /** Unbind the body from this handle. |
168 | Note that for a handle representing a large body, |
169 | "handle.clear().set(new body());" _might_ |
170 | perform a little bit better than "handle.set(new body());", |
171 | since in the second case two large objects exist in memory |
172 | (the old body and the new body). |
173 | */ |
174 | Reference<reference_type> & SAL_CALL clear() |
175 | { |
176 | if (m_pBody) |
177 | { |
178 | reference_type * const pOld = m_pBody; |
179 | m_pBody = NULL__null; |
180 | pOld->release(); |
181 | } |
182 | return *this; |
183 | } |
184 | |
185 | |
186 | /** Get the body. Can be used instead of operator->(). |
187 | I.e. handle->someBodyOp() and handle.get()->someBodyOp() |
188 | are the same. |
189 | */ |
190 | reference_type * SAL_CALL get() const |
191 | { |
192 | return m_pBody; |
193 | } |
194 | |
195 | |
196 | /** Probably most common used: handle->someBodyOp(). |
197 | */ |
198 | reference_type * SAL_CALL operator->() const |
199 | { |
200 | assert(m_pBody != NULL)(static_cast <bool> (m_pBody != __null) ? void (0) : __assert_fail ("m_pBody != NULL", "/home/maarten/src/libreoffice/core/include/rtl/ref.hxx" , 200, __extension__ __PRETTY_FUNCTION__)); |
201 | return m_pBody; |
202 | } |
203 | |
204 | |
205 | /** Allows (*handle).someBodyOp(). |
206 | */ |
207 | reference_type & SAL_CALL operator*() const |
208 | { |
209 | assert(m_pBody != NULL)(static_cast <bool> (m_pBody != __null) ? void (0) : __assert_fail ("m_pBody != NULL", "/home/maarten/src/libreoffice/core/include/rtl/ref.hxx" , 209, __extension__ __PRETTY_FUNCTION__)); |
210 | return *m_pBody; |
211 | } |
212 | |
213 | |
214 | /** Returns True if the handle does point to a valid body. |
215 | */ |
216 | bool SAL_CALL is() const |
217 | { |
218 | return (m_pBody != NULL__null); |
219 | } |
220 | |
221 | #if defined LIBO_INTERNAL_ONLY1 |
222 | /** Returns True if the handle does point to a valid body. |
223 | */ |
224 | explicit operator bool() const |
225 | { |
226 | return is(); |
227 | } |
228 | #endif |
229 | |
230 | /** Returns True if this points to pBody. |
231 | */ |
232 | bool SAL_CALL operator== (const reference_type * pBody) const |
233 | { |
234 | return (m_pBody == pBody); |
235 | } |
236 | |
237 | |
238 | /** Returns True if handle points to the same body. |
239 | */ |
240 | bool |
241 | SAL_CALL operator== (const Reference<reference_type> & handle) const |
242 | { |
243 | return (m_pBody == handle.m_pBody); |
244 | } |
245 | |
246 | |
247 | /** Needed to place References into STL collection. |
248 | */ |
249 | bool |
250 | SAL_CALL operator!= (const Reference<reference_type> & handle) const |
251 | { |
252 | return (m_pBody != handle.m_pBody); |
253 | } |
254 | |
255 | |
256 | /** Needed to place References into STL collection. |
257 | */ |
258 | bool |
259 | SAL_CALL operator< (const Reference<reference_type> & handle) const |
260 | { |
261 | return (m_pBody < handle.m_pBody); |
262 | } |
263 | |
264 | |
265 | /** Needed to place References into STL collection. |
266 | */ |
267 | bool |
268 | SAL_CALL operator> (const Reference<reference_type> & handle) const |
269 | { |
270 | return (m_pBody > handle.m_pBody); |
271 | } |
272 | }; |
273 | |
274 | } // namespace rtl |
275 | |
276 | #if defined LIBO_INTERNAL_ONLY1 |
277 | namespace std |
278 | { |
279 | |
280 | /// @cond INTERNAL |
281 | /** |
282 | Make rtl::Reference hashable by default for use in STL containers. |
283 | |
284 | @since LibreOffice 6.3 |
285 | */ |
286 | template<typename T> |
287 | struct hash<::rtl::Reference<T>> |
288 | { |
289 | std::size_t operator()(::rtl::Reference<T> const & s) const |
290 | { return std::size_t(s.get()); } |
291 | }; |
292 | /// @endcond |
293 | |
294 | } |
295 | |
296 | #endif |
297 | |
298 | #endif /* ! INCLUDED_RTL_REF_HXX */ |
299 | |
300 | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |
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 | #ifndef INCLUDED_VCL_Reference_HXX |
20 | #define INCLUDED_VCL_Reference_HXX |
21 | |
22 | #include <vcl/dllapi.h> |
23 | #include <osl/interlck.h> |
24 | |
25 | class VCL_DLLPUBLIC__attribute__ ((visibility("default"))) VclReferenceBase |
26 | { |
27 | mutable oslInterlockedCount mnRefCnt; |
28 | |
29 | template<typename T> friend class VclPtr; |
30 | |
31 | public: |
32 | void acquire() const |
33 | { |
34 | osl_atomic_increment(&mnRefCnt)__sync_add_and_fetch((&mnRefCnt), 1); |
35 | } |
36 | |
37 | void release() const |
38 | { |
39 | if (osl_atomic_decrement(&mnRefCnt)__sync_sub_and_fetch((&mnRefCnt), 1) == 0) |
40 | delete this; |
41 | } |
42 | #ifdef DBG_UTIL |
43 | #ifndef _WIN32 |
44 | sal_Int32 getRefCount() const { return mnRefCnt; } |
45 | #endif |
46 | #endif |
47 | |
48 | |
49 | private: |
50 | VclReferenceBase(const VclReferenceBase&) = delete; |
51 | VclReferenceBase& operator=(const VclReferenceBase&) = delete; |
52 | |
53 | bool mbDisposed : 1; |
54 | |
55 | protected: |
56 | VclReferenceBase(); |
57 | protected: |
58 | virtual ~VclReferenceBase(); |
59 | |
60 | protected: |
61 | virtual void dispose(); |
62 | |
63 | public: |
64 | void disposeOnce(); |
65 | bool isDisposed() const { return mbDisposed; } |
66 | |
67 | }; |
68 | #endif |