File: | home/maarten/src/libreoffice/core/sfx2/source/view/lokcharthelper.cxx |
Warning: | line 102, column 47 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 -*- */ | ||||||
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 | |||||||
10 | #include <sfx2/lokcharthelper.hxx> | ||||||
11 | |||||||
12 | #include <comphelper/lok.hxx> | ||||||
13 | #include <LibreOfficeKit/LibreOfficeKitEnums.h> | ||||||
14 | #include <sfx2/ipclient.hxx> | ||||||
15 | #include <sfx2/lokhelper.hxx> | ||||||
16 | #include <toolkit/helper/vclunohelper.hxx> | ||||||
17 | #include <tools/fract.hxx> | ||||||
18 | #include <tools/mapunit.hxx> | ||||||
19 | #include <tools/UnitConversion.hxx> | ||||||
20 | #include <vcl/virdev.hxx> | ||||||
21 | |||||||
22 | #include <com/sun/star/embed/XEmbeddedObject.hpp> | ||||||
23 | #include <com/sun/star/frame/XDispatch.hpp> | ||||||
24 | #include <com/sun/star/chart2/XChartDocument.hpp> | ||||||
25 | |||||||
26 | #define TWIPS_PER_PIXEL15 15 | ||||||
27 | |||||||
28 | using namespace com::sun::star; | ||||||
29 | |||||||
30 | namespace { | ||||||
31 | |||||||
32 | Point lcl_TwipsToHMM( const Point& rPoint ) | ||||||
33 | { | ||||||
34 | return Point(convertTwipToMm100(rPoint.getX()), convertTwipToMm100(rPoint.getY())); | ||||||
35 | } | ||||||
36 | |||||||
37 | Size lcl_TwipsToHMM( const Size& rSize ) | ||||||
38 | { | ||||||
39 | return Size(convertTwipToMm100(rSize.getWidth()), convertTwipToMm100(rSize.getHeight())); | ||||||
40 | } | ||||||
41 | |||||||
42 | } // end anonymous ns | ||||||
43 | |||||||
44 | css::uno::Reference<css::frame::XController>& LokChartHelper::GetXController() | ||||||
45 | { | ||||||
46 | if(!mxController.is() && mpViewShell) | ||||||
47 | { | ||||||
48 | SfxInPlaceClient* pIPClient = mpViewShell->GetIPClient(); | ||||||
49 | if (pIPClient) | ||||||
50 | { | ||||||
51 | const css::uno::Reference< ::css::embed::XEmbeddedObject >& xEmbObj = pIPClient->GetObject(); | ||||||
52 | if( xEmbObj.is() ) | ||||||
53 | { | ||||||
54 | ::css::uno::Reference< ::css::chart2::XChartDocument > xChart( xEmbObj->getComponent(), uno::UNO_QUERY ); | ||||||
55 | if( xChart.is() ) | ||||||
56 | { | ||||||
57 | ::css::uno::Reference< ::css::frame::XController > xChartController = xChart->getCurrentController(); | ||||||
58 | if( xChartController.is() ) | ||||||
59 | { | ||||||
60 | mxController = xChartController; | ||||||
61 | } | ||||||
62 | } | ||||||
63 | } | ||||||
64 | } | ||||||
65 | } | ||||||
66 | |||||||
67 | return mxController; | ||||||
68 | } | ||||||
69 | |||||||
70 | css::uno::Reference<css::frame::XDispatch>& LokChartHelper::GetXDispatcher() | ||||||
71 | { | ||||||
72 | if( !mxDispatcher.is() ) | ||||||
73 | { | ||||||
74 | ::css::uno::Reference< ::css::frame::XController >& xChartController = GetXController(); | ||||||
75 | if( xChartController.is() ) | ||||||
76 | { | ||||||
77 | ::css::uno::Reference< ::css::frame::XDispatch > xDispatcher( xChartController, uno::UNO_QUERY ); | ||||||
78 | if( xDispatcher.is() ) | ||||||
79 | { | ||||||
80 | mxDispatcher = xDispatcher; | ||||||
81 | } | ||||||
82 | } | ||||||
83 | } | ||||||
84 | |||||||
85 | return mxDispatcher; | ||||||
86 | } | ||||||
87 | |||||||
88 | vcl::Window* LokChartHelper::GetWindow() | ||||||
89 | { | ||||||
90 | if (!mpWindow) | ||||||
91 | { | ||||||
92 | ::css::uno::Reference< ::css::frame::XController >& xChartController = GetXController(); | ||||||
93 | if( xChartController.is() ) | ||||||
94 | { | ||||||
95 | ::css::uno::Reference< ::css::frame::XFrame > xFrame = xChartController->getFrame(); | ||||||
96 | if (xFrame.is()) | ||||||
97 | { | ||||||
98 | ::css::uno::Reference< ::css::awt::XWindow > xDockerWin = xFrame->getContainerWindow(); | ||||||
99 | vcl::Window* pParent = VCLUnoHelper::GetWindow( xDockerWin ).get(); | ||||||
100 | if (pParent
| ||||||
101 | { | ||||||
102 | sal_uInt16 nTotChildren = pParent->GetChildCount(); | ||||||
| |||||||
103 | while (nTotChildren--) | ||||||
104 | { | ||||||
105 | vcl::Window* pChildWin = pParent->GetChild(nTotChildren); | ||||||
106 | if (pChildWin && pChildWin->IsChart()) | ||||||
107 | { | ||||||
108 | mpWindow = pChildWin; | ||||||
109 | break; | ||||||
110 | } | ||||||
111 | } | ||||||
112 | } | ||||||
113 | } | ||||||
114 | } | ||||||
115 | } | ||||||
116 | |||||||
117 | return mpWindow.get(); | ||||||
118 | } | ||||||
119 | |||||||
120 | tools::Rectangle LokChartHelper::GetChartBoundingBox() | ||||||
121 | { | ||||||
122 | tools::Rectangle aBBox; | ||||||
123 | if (mpViewShell) | ||||||
124 | { | ||||||
125 | SfxInPlaceClient* pIPClient = mpViewShell->GetIPClient(); | ||||||
126 | if (pIPClient) | ||||||
127 | { | ||||||
128 | vcl::Window* pRootWin = pIPClient->GetEditWin(); | ||||||
129 | if (pRootWin) | ||||||
130 | { | ||||||
131 | vcl::Window* pWindow = GetWindow(); | ||||||
132 | if (pWindow) | ||||||
133 | { | ||||||
134 | // In all cases, the following code fragment | ||||||
135 | // returns the chart bounding box in twips. | ||||||
136 | const MapMode& aCWMapMode = pWindow->GetMapMode(); | ||||||
137 | double fXScale( aCWMapMode.GetScaleX() ); | ||||||
138 | double fYScale( aCWMapMode.GetScaleY() ); | ||||||
139 | Point aOffset = pWindow->GetOffsetPixelFrom(*pRootWin); | ||||||
140 | aOffset.setX( aOffset.X() * (TWIPS_PER_PIXEL15 / fXScale) ); | ||||||
141 | aOffset.setY( aOffset.Y() * (TWIPS_PER_PIXEL15 / fYScale) ); | ||||||
142 | Size aSize = pWindow->GetSizePixel(); | ||||||
143 | aSize.setWidth( aSize.Width() * (TWIPS_PER_PIXEL15 / fXScale) ); | ||||||
144 | aSize.setHeight( aSize.Height() * (TWIPS_PER_PIXEL15 / fYScale) ); | ||||||
145 | aBBox = tools::Rectangle(aOffset, aSize); | ||||||
146 | } | ||||||
147 | } | ||||||
148 | } | ||||||
149 | } | ||||||
150 | return aBBox; | ||||||
151 | } | ||||||
152 | |||||||
153 | void LokChartHelper::Invalidate() | ||||||
154 | { | ||||||
155 | mpWindow = nullptr; | ||||||
156 | mxDispatcher.clear(); | ||||||
157 | mxController.clear(); | ||||||
158 | } | ||||||
159 | |||||||
160 | bool LokChartHelper::Hit(const Point& aPos) | ||||||
161 | { | ||||||
162 | if (mpViewShell) | ||||||
163 | { | ||||||
164 | vcl::Window* pChartWindow = GetWindow(); | ||||||
165 | if (pChartWindow) | ||||||
166 | { | ||||||
167 | tools::Rectangle rChartBBox = GetChartBoundingBox(); | ||||||
168 | return rChartBBox.IsInside(aPos); | ||||||
169 | } | ||||||
170 | } | ||||||
171 | return false; | ||||||
172 | } | ||||||
173 | |||||||
174 | bool LokChartHelper::HitAny(const Point& aPos) | ||||||
175 | { | ||||||
176 | SfxViewShell* pCurView = SfxViewShell::Current(); | ||||||
177 | int nPartForCurView = pCurView ? pCurView->getPart() : -1; | ||||||
178 | SfxViewShell* pViewShell = SfxViewShell::GetFirst(); | ||||||
179 | while (pViewShell) | ||||||
180 | { | ||||||
181 | if (pViewShell->GetDocId() == pCurView->GetDocId() && pViewShell->getPart() == nPartForCurView) | ||||||
182 | { | ||||||
183 | LokChartHelper aChartHelper(pViewShell); | ||||||
184 | if (aChartHelper.Hit(aPos)) | ||||||
185 | return true; | ||||||
186 | } | ||||||
187 | pViewShell = SfxViewShell::GetNext(*pViewShell); | ||||||
188 | } | ||||||
189 | return false; | ||||||
190 | } | ||||||
191 | |||||||
192 | void LokChartHelper::PaintTile(VirtualDevice& rRenderContext, const tools::Rectangle& rTileRect) | ||||||
193 | { | ||||||
194 | if (!mpViewShell) | ||||||
195 | return; | ||||||
196 | |||||||
197 | vcl::Window* pChartWindow = GetWindow(); | ||||||
198 | if (!pChartWindow) | ||||||
199 | return; | ||||||
200 | |||||||
201 | tools::Rectangle aChartRect = GetChartBoundingBox(); | ||||||
202 | tools::Rectangle aTestRect = rTileRect; | ||||||
203 | aTestRect.Intersection( aChartRect ); | ||||||
204 | if (aTestRect.IsEmpty()) | ||||||
205 | return; | ||||||
206 | |||||||
207 | Point aOffset( aChartRect.Left() - rTileRect.Left(), aChartRect.Top() - rTileRect.Top() ); | ||||||
208 | Point aOffsetFromTile = lcl_TwipsToHMM(aOffset); | ||||||
209 | Size aSize = lcl_TwipsToHMM(aChartRect.GetSize()); | ||||||
210 | tools::Rectangle aRectangle(Point(0,0), aSize); | ||||||
211 | |||||||
212 | bool bEnableMapMode = !pChartWindow->IsMapModeEnabled(); | ||||||
213 | pChartWindow->EnableMapMode(); | ||||||
214 | bool bRenderContextEnableMapMode = !rRenderContext.IsMapModeEnabled(); | ||||||
215 | rRenderContext.EnableMapMode(); | ||||||
216 | |||||||
217 | rRenderContext.Push(PushFlags::MAPMODE); | ||||||
218 | |||||||
219 | MapMode aCWMapMode = pChartWindow->GetMapMode(); | ||||||
220 | aCWMapMode.SetScaleX(rRenderContext.GetMapMode().GetScaleX()); | ||||||
221 | aCWMapMode.SetScaleY(rRenderContext.GetMapMode().GetScaleY()); | ||||||
222 | |||||||
223 | aCWMapMode.SetOrigin(aOffsetFromTile); | ||||||
224 | rRenderContext.SetMapMode(aCWMapMode); | ||||||
225 | |||||||
226 | pChartWindow->Paint(rRenderContext, aRectangle); | ||||||
227 | |||||||
228 | rRenderContext.Pop(); | ||||||
229 | |||||||
230 | if (bRenderContextEnableMapMode) | ||||||
231 | rRenderContext.EnableMapMode(false); | ||||||
232 | if (bEnableMapMode) | ||||||
233 | pChartWindow->EnableMapMode(false); | ||||||
234 | } | ||||||
235 | |||||||
236 | void LokChartHelper::PaintAllChartsOnTile(VirtualDevice& rDevice, | ||||||
237 | int nOutputWidth, int nOutputHeight, | ||||||
238 | int nTilePosX, int nTilePosY, | ||||||
239 | long nTileWidth, long nTileHeight) | ||||||
240 | { | ||||||
241 | if (comphelper::LibreOfficeKit::isTiledAnnotations()) | ||||||
242 | return; | ||||||
243 | |||||||
244 | // Resizes the virtual device so to contain the entries context | ||||||
245 | rDevice.SetOutputSizePixel(Size(nOutputWidth, nOutputHeight)); | ||||||
246 | |||||||
247 | rDevice.Push(PushFlags::MAPMODE); | ||||||
248 | MapMode aMapMode(rDevice.GetMapMode()); | ||||||
249 | |||||||
250 | // Scaling. Must convert from pixels to twips. We know | ||||||
251 | // that VirtualDevices use a DPI of 96. | ||||||
252 | Fraction scaleX = Fraction(nOutputWidth, 96) * Fraction(1440) / Fraction(nTileWidth); | ||||||
253 | Fraction scaleY = Fraction(nOutputHeight, 96) * Fraction(1440) / Fraction(nTileHeight); | ||||||
254 | aMapMode.SetScaleX(scaleX); | ||||||
255 | aMapMode.SetScaleY(scaleY); | ||||||
256 | rDevice.SetMapMode(aMapMode); | ||||||
257 | |||||||
258 | SfxViewShell* pCurView = SfxViewShell::Current(); | ||||||
259 | int nPartForCurView = pCurView ? pCurView->getPart() : -1; | ||||||
260 | tools::Rectangle aTileRect(Point(nTilePosX, nTilePosY), Size(nTileWidth, nTileHeight)); | ||||||
261 | SfxViewShell* pViewShell = SfxViewShell::GetFirst(); | ||||||
262 | while (pViewShell) | ||||||
263 | { | ||||||
264 | if (pCurView && pViewShell->GetDocId() == pCurView->GetDocId() && pViewShell->getPart() == nPartForCurView) | ||||||
265 | { | ||||||
266 | LokChartHelper aChartHelper(pViewShell); | ||||||
267 | aChartHelper.PaintTile(rDevice, aTileRect); | ||||||
268 | } | ||||||
269 | pViewShell = SfxViewShell::GetNext(*pViewShell); | ||||||
270 | } | ||||||
271 | rDevice.Pop(); | ||||||
272 | } | ||||||
273 | |||||||
274 | bool LokChartHelper::postMouseEvent(int nType, int nX, int nY, | ||||||
275 | int nCount, int nButtons, int nModifier, | ||||||
276 | double fScaleX, double fScaleY) | ||||||
277 | { | ||||||
278 | Point aMousePos(nX, nY); | ||||||
279 | vcl::Window* pChartWindow = GetWindow(); | ||||||
280 | if (pChartWindow) | ||||||
281 | { | ||||||
282 | tools::Rectangle rChartBBox = GetChartBoundingBox(); | ||||||
283 | if (rChartBBox.IsInside(aMousePos)) | ||||||
284 | { | ||||||
285 | int nChartWinX = nX - rChartBBox.Left(); | ||||||
286 | int nChartWinY = nY - rChartBBox.Top(); | ||||||
287 | |||||||
288 | // chart window expects pixels, but the conversion factor | ||||||
289 | // can depend on the client zoom | ||||||
290 | Point aPos(nChartWinX * fScaleX, nChartWinY * fScaleY); | ||||||
291 | |||||||
292 | LokMouseEventData aMouseEventData(nType, aPos, nCount, MouseEventModifiers::SIMPLECLICK, | ||||||
293 | nButtons, nModifier); | ||||||
294 | SfxLokHelper::postMouseEventAsync(pChartWindow, aMouseEventData); | ||||||
295 | |||||||
296 | return true; | ||||||
297 | } | ||||||
298 | } | ||||||
299 | return false; | ||||||
300 | } | ||||||
301 | |||||||
302 | bool LokChartHelper::setTextSelection(int nType, int nX, int nY) | ||||||
303 | { | ||||||
304 | tools::Rectangle rChartBBox = GetChartBoundingBox(); | ||||||
305 | if (rChartBBox.IsInside(Point(nX, nY))) | ||||||
306 | { | ||||||
307 | css::uno::Reference<css::frame::XDispatch> xDispatcher = GetXDispatcher(); | ||||||
308 | if (xDispatcher.is()) | ||||||
309 | { | ||||||
310 | int nChartWinX = nX - rChartBBox.Left(); | ||||||
311 | int nChartWinY = nY - rChartBBox.Top(); | ||||||
312 | |||||||
313 | // no scale here the chart controller expects twips | ||||||
314 | // that are converted to hmm | ||||||
315 | util::URL aURL; | ||||||
316 | aURL.Path = "LOKSetTextSelection"; | ||||||
317 | uno::Sequence< beans::PropertyValue > aArgs(3); | ||||||
318 | aArgs[0].Value <<= static_cast<sal_Int32>(nType); | ||||||
319 | aArgs[1].Value <<= static_cast<sal_Int32>(nChartWinX); | ||||||
320 | aArgs[2].Value <<= static_cast<sal_Int32>(nChartWinY); | ||||||
321 | xDispatcher->dispatch(aURL, aArgs); | ||||||
322 | } | ||||||
323 | return true; | ||||||
324 | } | ||||||
325 | return false; | ||||||
326 | } | ||||||
327 | |||||||
328 | bool LokChartHelper::setGraphicSelection(int nType, int nX, int nY, | ||||||
329 | double fScaleX, double fScaleY) | ||||||
330 | { | ||||||
331 | tools::Rectangle rChartBBox = GetChartBoundingBox(); | ||||||
| |||||||
332 | if (rChartBBox.IsInside(Point(nX, nY))) | ||||||
333 | { | ||||||
334 | int nChartWinX = nX - rChartBBox.Left(); | ||||||
335 | int nChartWinY = nY - rChartBBox.Top(); | ||||||
336 | |||||||
337 | vcl::Window* pChartWindow = GetWindow(); | ||||||
338 | |||||||
339 | Point aPos(nChartWinX * fScaleX, nChartWinY * fScaleY); | ||||||
340 | switch (nType) | ||||||
341 | { | ||||||
342 | case LOK_SETGRAPHICSELECTION_START: | ||||||
343 | { | ||||||
344 | MouseEvent aClickEvent(aPos, 1, MouseEventModifiers::SIMPLECLICK, MOUSE_LEFT(sal_uInt16(0x0001))); | ||||||
345 | pChartWindow->MouseButtonDown(aClickEvent); | ||||||
346 | MouseEvent aMoveEvent(aPos, 0, MouseEventModifiers::SIMPLEMOVE, MOUSE_LEFT(sal_uInt16(0x0001))); | ||||||
347 | pChartWindow->MouseMove(aMoveEvent); | ||||||
348 | } | ||||||
349 | break; | ||||||
350 | case LOK_SETGRAPHICSELECTION_END: | ||||||
351 | { | ||||||
352 | MouseEvent aMoveEvent(aPos, 0, MouseEventModifiers::SIMPLEMOVE, MOUSE_LEFT(sal_uInt16(0x0001))); | ||||||
353 | pChartWindow->MouseMove(aMoveEvent); | ||||||
354 | MouseEvent aClickEvent(aPos, 1, MouseEventModifiers::SIMPLECLICK, MOUSE_LEFT(sal_uInt16(0x0001))); | ||||||
355 | pChartWindow->MouseButtonUp(aClickEvent); | ||||||
356 | } | ||||||
357 | break; | ||||||
358 | default: | ||||||
359 | assert(false)(static_cast <bool> (false) ? void (0) : __assert_fail ( "false", "/home/maarten/src/libreoffice/core/sfx2/source/view/lokcharthelper.cxx" , 359, __extension__ __PRETTY_FUNCTION__)); | ||||||
360 | break; | ||||||
361 | } | ||||||
362 | return true; | ||||||
363 | } | ||||||
364 | return false; | ||||||
365 | } | ||||||
366 | |||||||
367 | |||||||
368 | /* 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 |