File: | home/maarten/src/libreoffice/core/include/rtl/ref.hxx |
Warning: | line 192, column 9 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 | * 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 <DrawViewShell.hxx> | |||
21 | #include <ViewShellImplementation.hxx> | |||
22 | ||||
23 | #include <DrawController.hxx> | |||
24 | #include <com/sun/star/embed/XEmbeddedObject.hpp> | |||
25 | ||||
26 | #include <comphelper/scopeguard.hxx> | |||
27 | #include <rtl/ref.hxx> | |||
28 | ||||
29 | #include <svx/svxids.hrc> | |||
30 | #include <svx/svdpagv.hxx> | |||
31 | #include <sfx2/viewfrm.hxx> | |||
32 | #include <sfx2/bindings.hxx> | |||
33 | #include <sfx2/lokhelper.hxx> | |||
34 | #include <svx/svdoole2.hxx> | |||
35 | #include <sfx2/dispatch.hxx> | |||
36 | #include <sfx2/module.hxx> | |||
37 | #include <vcl/scrbar.hxx> | |||
38 | #include <svx/svdopage.hxx> | |||
39 | #include <svx/fmshell.hxx> | |||
40 | #include <tools/debug.hxx> | |||
41 | #include <tools/diagnose_ex.h> | |||
42 | ||||
43 | #include <view/viewoverlaymanager.hxx> | |||
44 | ||||
45 | #include <app.hrc> | |||
46 | ||||
47 | #include <fupoor.hxx> | |||
48 | #include <unokywds.hxx> | |||
49 | #include <sdpage.hxx> | |||
50 | #include <FrameView.hxx> | |||
51 | #include <Window.hxx> | |||
52 | #include <drawview.hxx> | |||
53 | #include <drawdoc.hxx> | |||
54 | #include <DrawDocShell.hxx> | |||
55 | #include <Ruler.hxx> | |||
56 | #include <Client.hxx> | |||
57 | #include <slideshow.hxx> | |||
58 | #include <AnimationChildWindow.hxx> | |||
59 | #include <ToolBarManager.hxx> | |||
60 | #include <FormShellManager.hxx> | |||
61 | #include <ViewShellBase.hxx> | |||
62 | #include <LayerTabBar.hxx> | |||
63 | #include <ViewShellManager.hxx> | |||
64 | #include <ViewShellHint.hxx> | |||
65 | #include <SlideSorter.hxx> | |||
66 | #include <SlideSorterViewShell.hxx> | |||
67 | #include <controller/SlideSorterController.hxx> | |||
68 | #include <controller/SlsPageSelector.hxx> | |||
69 | ||||
70 | #include <comphelper/lok.hxx> | |||
71 | #include <LibreOfficeKit/LibreOfficeKitEnums.h> | |||
72 | #include <vcl/uitest/logger.hxx> | |||
73 | #include <vcl/uitest/eventdescription.hxx> | |||
74 | ||||
75 | using namespace com::sun::star; | |||
76 | ||||
77 | namespace sd { | |||
78 | ||||
79 | void DrawViewShell::Activate(bool bIsMDIActivate) | |||
80 | { | |||
81 | ViewShell::Activate(bIsMDIActivate); | |||
82 | ||||
83 | // When the mode is switched to normal the main view shell grabs focus. | |||
84 | // This is done for getting cut/copy/paste commands on slides in the left | |||
85 | // pane (slide sorter view shell) to work properly. | |||
86 | SfxShell* pTopViewShell = this->GetViewShellBase().GetViewShellManager()->GetTopViewShell(); | |||
87 | if (pTopViewShell && pTopViewShell == this) | |||
88 | { | |||
89 | this->GetActiveWindow()->GrabFocus(); | |||
90 | } | |||
91 | } | |||
92 | ||||
93 | void DrawViewShell::UIActivating( SfxInPlaceClient* pCli ) | |||
94 | { | |||
95 | ViewShell::UIActivating(pCli); | |||
96 | ||||
97 | // Disable own controls | |||
98 | maTabControl->Disable(); | |||
99 | if (GetLayerTabControl() != nullptr) | |||
100 | GetLayerTabControl()->Disable(); | |||
101 | } | |||
102 | ||||
103 | void DrawViewShell::UIDeactivated( SfxInPlaceClient* pCli ) | |||
104 | { | |||
105 | // Enable own controls | |||
106 | maTabControl->Enable(); | |||
107 | if (GetLayerTabControl() != nullptr) | |||
108 | GetLayerTabControl()->Enable(); | |||
109 | ||||
110 | ViewShell::UIDeactivated(pCli); | |||
111 | } | |||
112 | ||||
113 | void DrawViewShell::Deactivate(bool bIsMDIActivate) | |||
114 | { | |||
115 | // Temporarily disable context broadcasting while the Deactivate() | |||
116 | // call is forwarded to our base class. | |||
117 | const bool bIsContextBroadcasterEnabled (SfxShell::SetContextBroadcasterEnabled(false)); | |||
118 | ||||
119 | ViewShell::Deactivate(bIsMDIActivate); | |||
120 | ||||
121 | SfxShell::SetContextBroadcasterEnabled(bIsContextBroadcasterEnabled); | |||
122 | } | |||
123 | ||||
124 | namespace | |||
125 | { | |||
126 | class LockUI | |||
127 | { | |||
128 | private: | |||
129 | void Lock(bool bLock); | |||
130 | SfxViewFrame *mpFrame; | |||
131 | public: | |||
132 | explicit LockUI(SfxViewFrame *pFrame) : mpFrame(pFrame) { Lock(true); } | |||
133 | ~LockUI() { Lock(false); } | |||
134 | ||||
135 | }; | |||
136 | ||||
137 | void LockUI::Lock(bool bLock) | |||
138 | { | |||
139 | if (!mpFrame) | |||
140 | return; | |||
141 | mpFrame->Enable( !bLock ); | |||
142 | } | |||
143 | } | |||
144 | ||||
145 | /** | |||
146 | * Called, if state of selection of view is changed | |||
147 | */ | |||
148 | ||||
149 | void DrawViewShell::SelectionHasChanged() | |||
150 | { | |||
151 | Invalidate(); | |||
152 | ||||
153 | //Update3DWindow(); // 3D-Controller | |||
154 | SfxBoolItem aItem( SID_3D_STATE( 10000 + 645 ), true ); | |||
155 | GetViewFrame()->GetDispatcher()->ExecuteList( | |||
156 | SID_3D_STATE( 10000 + 645 ), SfxCallMode::ASYNCHRON | SfxCallMode::RECORD, { &aItem }); | |||
157 | ||||
158 | SdrOle2Obj* pOleObj = nullptr; | |||
159 | ||||
160 | if ( mpDrawView->AreObjectsMarked() ) | |||
161 | { | |||
162 | const SdrMarkList& rMarkList = mpDrawView->GetMarkedObjectList(); | |||
163 | ||||
164 | if (rMarkList.GetMarkCount() == 1) | |||
165 | { | |||
166 | SdrMark* pMark = rMarkList.GetMark(0); | |||
167 | SdrObject* pObj = pMark->GetMarkedSdrObj(); | |||
168 | ||||
169 | SdrInventor nInv = pObj->GetObjInventor(); | |||
170 | sal_uInt16 nSdrObjKind = pObj->GetObjIdentifier(); | |||
171 | ||||
172 | if (nInv == SdrInventor::Default && nSdrObjKind == OBJ_OLE2) | |||
173 | { | |||
174 | pOleObj = static_cast<SdrOle2Obj*>(pObj); | |||
175 | UpdateIMapDlg( pObj ); | |||
176 | } | |||
177 | else if (nSdrObjKind == OBJ_GRAF) | |||
178 | UpdateIMapDlg( pObj ); | |||
179 | } | |||
180 | } | |||
181 | ||||
182 | ViewShellBase& rBase = GetViewShellBase(); | |||
183 | rBase.SetVerbs( uno::Sequence< embed::VerbDescriptor >() ); | |||
184 | ||||
185 | try | |||
186 | { | |||
187 | Client* pIPClient = static_cast<Client*>(rBase.GetIPClient()); | |||
188 | if ( pIPClient && pIPClient->IsObjectInPlaceActive() ) | |||
189 | { | |||
190 | // as appropriate take ole-objects into account and deactivate | |||
191 | ||||
192 | // this means we recently deselected an inplace active ole object so | |||
193 | // we need to deselect it now | |||
194 | if (!pOleObj) | |||
195 | { | |||
196 | //#i47279# disable frame until after object has completed unload | |||
197 | LockUI aUILock(GetViewFrame()); | |||
198 | pIPClient->DeactivateObject(); | |||
199 | //HMHmpDrView->ShowMarkHdl(); | |||
200 | } | |||
201 | else | |||
202 | { | |||
203 | const uno::Reference < embed::XEmbeddedObject >& xObj = pOleObj->GetObjRef(); | |||
204 | if ( xObj.is() ) | |||
205 | { | |||
206 | rBase.SetVerbs( xObj->getSupportedVerbs() ); | |||
207 | } | |||
208 | else | |||
209 | { | |||
210 | rBase.SetVerbs( uno::Sequence < embed::VerbDescriptor >() ); | |||
211 | } | |||
212 | } | |||
213 | } | |||
214 | else | |||
215 | { | |||
216 | if ( pOleObj ) | |||
217 | { | |||
218 | const uno::Reference < embed::XEmbeddedObject >& xObj = pOleObj->GetObjRef(); | |||
219 | if ( xObj.is() ) | |||
220 | { | |||
221 | rBase.SetVerbs( xObj->getSupportedVerbs() ); | |||
222 | } | |||
223 | else | |||
224 | { | |||
225 | rBase.SetVerbs( uno::Sequence < embed::VerbDescriptor >() ); | |||
226 | } | |||
227 | } | |||
228 | else | |||
229 | { | |||
230 | rBase.SetVerbs( uno::Sequence < embed::VerbDescriptor >() ); | |||
231 | } | |||
232 | } | |||
233 | } | |||
234 | catch( css::uno::Exception& ) | |||
235 | { | |||
236 | TOOLS_WARN_EXCEPTION( "sd", "sd::DrawViewShell::SelectionHasChanged()" )do { css::uno::Any tools_warn_exception( DbgGetCaughtException () ); do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN , "sd")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "sd::DrawViewShell::SelectionHasChanged()" << " " << exceptionToString(tools_warn_exception)) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sd"), ("/home/maarten/src/libreoffice/core/sd/source/ui/view/drviews1.cxx" ":" "236" ": "), ::sal::detail::unwrapStream( ::sal::detail:: StreamStart() << "sd::DrawViewShell::SelectionHasChanged()" << " " << exceptionToString(tools_warn_exception )), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "sd::DrawViewShell::SelectionHasChanged()" << " " << exceptionToString(tools_warn_exception); ::sal:: detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sd"), ("/home/maarten/src/libreoffice/core/sd/source/ui/view/drviews1.cxx" ":" "236" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "sd::DrawViewShell::SelectionHasChanged()" << " " << exceptionToString(tools_warn_exception)) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sd"), ("/home/maarten/src/libreoffice/core/sd/source/ui/view/drviews1.cxx" ":" "236" ": "), ::sal::detail::unwrapStream( ::sal::detail:: StreamStart() << "sd::DrawViewShell::SelectionHasChanged()" << " " << exceptionToString(tools_warn_exception )), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "sd::DrawViewShell::SelectionHasChanged()" << " " << exceptionToString(tools_warn_exception); ::sal:: detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("sd"), ("/home/maarten/src/libreoffice/core/sd/source/ui/view/drviews1.cxx" ":" "236" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); } while (false); | |||
237 | } | |||
238 | ||||
239 | if( HasCurrentFunction() ) | |||
240 | { | |||
241 | GetCurrentFunction()->SelectionHasChanged(); | |||
242 | } | |||
243 | else | |||
244 | { | |||
245 | GetViewShellBase().GetToolBarManager()->SelectionHasChanged(*this,*mpDrawView); | |||
246 | } | |||
247 | ||||
248 | // Invalidate for every subshell | |||
249 | GetViewShellBase().GetViewShellManager()->InvalidateAllSubShells(this); | |||
250 | ||||
251 | mpDrawView->UpdateSelectionClipboard( false ); | |||
252 | ||||
253 | GetViewShellBase().GetDrawController().FireSelectionChangeListener(); | |||
254 | } | |||
255 | ||||
256 | namespace { | |||
257 | ||||
258 | void collectUIInformation(const OUString& aZoom) | |||
259 | { | |||
260 | EventDescription aDescription; | |||
261 | aDescription.aID = "impress_win"; | |||
262 | aDescription.aParameters = {{"ZOOM", aZoom}}; | |||
263 | aDescription.aAction = "SET"; | |||
264 | aDescription.aKeyWord = "ImpressWindowUIObject"; | |||
265 | aDescription.aParent = "MainWindow"; | |||
266 | ||||
267 | UITestLogger::getInstance().logEvent(aDescription); | |||
268 | } | |||
269 | ||||
270 | } | |||
271 | ||||
272 | /** | |||
273 | * set zoom factor | |||
274 | */ | |||
275 | void DrawViewShell::SetZoom( long nZoom ) | |||
276 | { | |||
277 | // Make sure that the zoom factor will not be recalculated on | |||
278 | // following window resizings. | |||
279 | mbZoomOnPage = false; | |||
280 | ViewShell::SetZoom( nZoom ); | |||
281 | GetViewFrame()->GetBindings().Invalidate( SID_ATTR_ZOOMTypedWhichId<SvxZoomItem>(10000 + 0) ); | |||
282 | GetViewFrame()->GetBindings().Invalidate( SID_ATTR_ZOOMSLIDER( 10000 + 1065 ) ); | |||
283 | mpViewOverlayManager->onZoomChanged(); | |||
284 | collectUIInformation(OUString::number(nZoom)); | |||
285 | } | |||
286 | ||||
287 | /** | |||
288 | * Set zoom rectangle for active window | |||
289 | */ | |||
290 | ||||
291 | void DrawViewShell::SetZoomRect( const ::tools::Rectangle& rZoomRect ) | |||
292 | { | |||
293 | ViewShell::SetZoomRect( rZoomRect ); | |||
294 | GetViewFrame()->GetBindings().Invalidate( SID_ATTR_ZOOMTypedWhichId<SvxZoomItem>(10000 + 0) ); | |||
295 | GetViewFrame()->GetBindings().Invalidate( SID_ATTR_ZOOMSLIDER( 10000 + 1065 ) ); | |||
296 | mpViewOverlayManager->onZoomChanged(); | |||
297 | } | |||
298 | ||||
299 | /** | |||
300 | * PrepareClose, as appropriate end text input, so other viewshells | |||
301 | * discover a refreshed text object. | |||
302 | */ | |||
303 | ||||
304 | bool DrawViewShell::PrepareClose( bool bUI ) | |||
305 | { | |||
306 | if ( !ViewShell::PrepareClose(bUI) ) | |||
307 | return false; | |||
308 | ||||
309 | if( HasCurrentFunction() ) | |||
310 | { | |||
311 | sal_uInt16 nID = GetCurrentFunction()->GetSlotID(); | |||
312 | if (nID == SID_TEXTEDIT(27000 +76) || nID == SID_ATTR_CHAR( 10000 + 6 )) | |||
313 | { | |||
314 | mpDrawView->SdrEndTextEdit(); | |||
315 | } | |||
316 | } | |||
317 | ||||
318 | return true; | |||
319 | } | |||
320 | ||||
321 | ||||
322 | /** | |||
323 | * Set status (enabled/disabled) of menu SfxSlots | |||
324 | */ | |||
325 | ||||
326 | void DrawViewShell::ChangeEditMode(EditMode eEMode, bool bIsLayerModeActive) | |||
327 | { | |||
328 | if (meEditMode == eEMode && mbIsLayerModeActive == bIsLayerModeActive) | |||
329 | return; | |||
330 | ||||
331 | ViewShellManager::UpdateLock aLock (GetViewShellBase().GetViewShellManager()); | |||
332 | ||||
333 | sal_uInt16 nActualPageId = maTabControl->GetPageId(0); | |||
334 | ||||
335 | if (mePageKind == PageKind::Handout) | |||
336 | { | |||
337 | // at handouts only allow MasterPage | |||
338 | eEMode = EditMode::MasterPage; | |||
339 | } | |||
340 | ||||
341 | GetViewShellBase().GetDrawController().FireChangeEditMode (eEMode == EditMode::MasterPage); | |||
342 | GetViewShellBase().GetDrawController().FireChangeLayerMode (bIsLayerModeActive); | |||
343 | ||||
344 | if ( mpDrawView->IsTextEdit() ) | |||
345 | { | |||
346 | mpDrawView->SdrEndTextEdit(); | |||
347 | } | |||
348 | ||||
349 | LayerTabBar* pLayerBar = GetLayerTabControl(); | |||
350 | if (pLayerBar != nullptr) | |||
351 | pLayerBar->EndEditMode(); | |||
352 | maTabControl->EndEditMode(); | |||
353 | ||||
354 | GetViewShellBase().GetDrawController().BroadcastContextChange(); | |||
355 | ||||
356 | meEditMode = eEMode; | |||
357 | ||||
358 | if(pLayerBar) | |||
359 | { | |||
360 | // #i87182# only switch activation mode of LayerTabBar when there is one, | |||
361 | // else it will not get initialized with the current set of Layers as needed | |||
362 | mbIsLayerModeActive = bIsLayerModeActive; | |||
363 | } | |||
364 | ||||
365 | // Determine whether to show the master view toolbar. The master | |||
366 | // page mode has to be active and the shell must not be a handout | |||
367 | // view. | |||
368 | bool bShowMasterViewToolbar (meEditMode == EditMode::MasterPage | |||
369 | && GetShellType() != ViewShell::ST_HANDOUT); | |||
370 | bool bShowPresentationToolbar (meEditMode != EditMode::MasterPage | |||
371 | && GetShellType() != ViewShell::ST_HANDOUT | |||
372 | && GetShellType() != ViewShell::ST_DRAW); | |||
373 | ||||
374 | // If the master view toolbar is not shown we hide it before | |||
375 | // switching the edit mode. | |||
376 | if (::sd::ViewShell::mpImpl->mbIsInitialized | |||
377 | && IsMainViewShell()) | |||
378 | { | |||
379 | if ( !bShowMasterViewToolbar ) | |||
380 | GetViewShellBase().GetToolBarManager()->ResetToolBars(ToolBarManager::ToolBarGroup::MasterMode); | |||
381 | if ( !bShowPresentationToolbar ) | |||
382 | GetViewShellBase().GetToolBarManager()->ResetToolBars(ToolBarManager::ToolBarGroup::CommonTask); | |||
383 | } | |||
384 | ||||
385 | ConfigureAppBackgroundColor(); | |||
386 | ||||
387 | if (meEditMode == EditMode::Page) | |||
388 | { | |||
389 | /****************************************************************** | |||
390 | * PAGEMODE | |||
391 | ******************************************************************/ | |||
392 | ||||
393 | maTabControl->Clear(); | |||
394 | ||||
395 | SdPage* pPage; | |||
396 | sal_uInt16 nPageCnt = GetDoc()->GetSdPageCount(mePageKind); | |||
397 | ||||
398 | for (sal_uInt16 i = 0; i < nPageCnt; i++) | |||
399 | { | |||
400 | pPage = GetDoc()->GetSdPage(i, mePageKind); | |||
401 | OUString aPageName = pPage->GetName(); | |||
402 | maTabControl->InsertPage(pPage->getPageId(), aPageName); | |||
403 | ||||
404 | if ( pPage->IsSelected() ) | |||
405 | { | |||
406 | nActualPageId = pPage->getPageId(); | |||
407 | } | |||
408 | } | |||
409 | ||||
410 | maTabControl->SetCurPageId(nActualPageId); | |||
411 | ||||
412 | SwitchPage(maTabControl->GetPagePos(nActualPageId)); | |||
413 | ||||
414 | //tdf#102343 re-enable common undo on switch back from master mode | |||
415 | mpDrawView->GetModel()->SetDisableTextEditUsesCommonUndoManager(false); | |||
416 | } | |||
417 | else | |||
418 | { | |||
419 | /****************************************************************** | |||
420 | * MASTERPAGE | |||
421 | ******************************************************************/ | |||
422 | GetViewFrame()->SetChildWindow( | |||
423 | AnimationChildWindow::GetChildWindowId(), false ); | |||
424 | ||||
425 | if (comphelper::LibreOfficeKit::isActive()) | |||
426 | GetViewShell()->libreOfficeKitViewCallback(LOK_CALLBACK_STATE_CHANGED, | |||
427 | ".uno:SlideMasterPage=true"); | |||
428 | if (!mpActualPage) | |||
429 | { | |||
430 | // as long as there is no mpActualPage, take first | |||
431 | mpActualPage = GetDoc()->GetSdPage(0, mePageKind); | |||
432 | } | |||
433 | ||||
434 | maTabControl->Clear(); | |||
435 | sal_uInt16 nActualMasterPageId = maTabControl->GetPageId(0); | |||
436 | sal_uInt16 nMasterPageCnt = GetDoc()->GetMasterSdPageCount(mePageKind); | |||
437 | ||||
438 | for (sal_uInt16 i = 0; i < nMasterPageCnt; i++) | |||
439 | { | |||
440 | SdPage* pMaster = GetDoc()->GetMasterSdPage(i, mePageKind); | |||
441 | OUString aLayoutName = pMaster->GetLayoutName(); | |||
442 | sal_Int32 nPos = aLayoutName.indexOf(SD_LT_SEPARATOR"~LT~"); | |||
443 | if (nPos != -1) | |||
444 | aLayoutName = aLayoutName.copy(0, nPos); | |||
445 | ||||
446 | maTabControl->InsertPage(pMaster->getPageId(), aLayoutName); | |||
447 | ||||
448 | if (&(mpActualPage->TRG_GetMasterPage()) == pMaster) | |||
449 | { | |||
450 | nActualMasterPageId = pMaster->getPageId(); | |||
451 | } | |||
452 | } | |||
453 | ||||
454 | maTabControl->SetCurPageId(nActualMasterPageId); | |||
455 | SwitchPage(maTabControl->GetPagePos(nActualMasterPageId)); | |||
456 | ||||
457 | //tdf#102343 changing attributes of textboxes in master typically | |||
458 | //changes the stylesheet they are linked to, so if the common | |||
459 | //undo manager is in use, those stylesheet changes are thrown | |||
460 | //away at present | |||
461 | mpDrawView->GetModel()->SetDisableTextEditUsesCommonUndoManager(true); | |||
462 | } | |||
463 | ||||
464 | // If the master view toolbar is to be shown we turn it on after the | |||
465 | // edit mode has been changed. | |||
466 | if (::sd::ViewShell::mpImpl->mbIsInitialized | |||
467 | && IsMainViewShell()) | |||
468 | { | |||
469 | if (bShowMasterViewToolbar) | |||
470 | GetViewShellBase().GetToolBarManager()->SetToolBar( | |||
471 | ToolBarManager::ToolBarGroup::MasterMode, | |||
472 | ToolBarManager::msMasterViewToolBar); | |||
473 | if (bShowPresentationToolbar) | |||
474 | GetViewShellBase().GetToolBarManager()->SetToolBar( | |||
475 | ToolBarManager::ToolBarGroup::CommonTask, | |||
476 | ToolBarManager::msCommonTaskToolBar); | |||
477 | } | |||
478 | ||||
479 | if ( ! mbIsLayerModeActive) | |||
480 | { | |||
481 | maTabControl->Show(); | |||
482 | // Set the tab control only for draw pages. For master page | |||
483 | // this has been done already above. | |||
484 | if (meEditMode == EditMode::Page) | |||
485 | maTabControl->SetCurPageId (nActualPageId); | |||
486 | } | |||
487 | ||||
488 | ResetActualLayer(); | |||
489 | ||||
490 | Invalidate( SID_PAGEMODE(27000 +46) ); | |||
491 | Invalidate( SID_LAYERMODE(27000 +47) ); | |||
492 | Invalidate( SID_MASTERPAGE(27000 +50) ); | |||
493 | Invalidate( SID_DELETE_MASTER_PAGE(27000 +432) ); | |||
494 | Invalidate( SID_DELETE_PAGE(27000 +80) ); | |||
495 | Invalidate( SID_SLIDE_MASTER_MODE(27000 +348) ); | |||
496 | Invalidate( SID_NOTES_MASTER_MODE(27000 +350) ); | |||
497 | Invalidate( SID_HANDOUT_MASTER_MODE(27000 +70) ); | |||
498 | InvalidateWindows(); | |||
499 | ||||
500 | SetContextName(GetSidebarContextName()); | |||
501 | ||||
502 | } | |||
503 | ||||
504 | /** | |||
505 | * Generate horizontal ruler | |||
506 | */ | |||
507 | ||||
508 | VclPtr<SvxRuler> DrawViewShell::CreateHRuler (::sd::Window* pWin) | |||
509 | { | |||
510 | VclPtr<Ruler> pRuler; | |||
511 | WinBits aWBits; | |||
512 | SvxRulerSupportFlags nFlags = SvxRulerSupportFlags::OBJECT; | |||
513 | ||||
514 | aWBits = WB_HSCROLL | WB_3DLOOK | WB_BORDER | WB_EXTRAFIELD; | |||
515 | nFlags |= SvxRulerSupportFlags::SET_NULLOFFSET | | |||
516 | SvxRulerSupportFlags::TABS | | |||
517 | SvxRulerSupportFlags::PARAGRAPH_MARGINS; // new | |||
518 | ||||
519 | pRuler = VclPtr<Ruler>::Create(*this, GetParentWindow(), pWin, nFlags, | |||
520 | GetViewFrame()->GetBindings(), aWBits); | |||
521 | ||||
522 | // Metric ... | |||
523 | sal_uInt16 nMetric = static_cast<sal_uInt16>(GetDoc()->GetUIUnit()); | |||
524 | ||||
525 | if( nMetric == 0xffff ) | |||
526 | nMetric = static_cast<sal_uInt16>(GetViewShellBase().GetViewFrame()->GetDispatcher()->GetModule()->GetFieldUnit()); | |||
527 | ||||
528 | pRuler->SetUnit( FieldUnit( nMetric ) ); | |||
529 | ||||
530 | // ... and also set DefTab at the ruler | |||
531 | pRuler->SetDefTabDist( GetDoc()->GetDefaultTabulator() ); // new | |||
532 | ||||
533 | Fraction aUIScale(pWin->GetMapMode().GetScaleX()); | |||
534 | aUIScale *= GetDoc()->GetUIScale(); | |||
535 | pRuler->SetZoom(aUIScale); | |||
536 | ||||
537 | return pRuler; | |||
538 | } | |||
539 | ||||
540 | /** | |||
541 | * Generate vertical ruler | |||
542 | */ | |||
543 | ||||
544 | VclPtr<SvxRuler> DrawViewShell::CreateVRuler(::sd::Window* pWin) | |||
545 | { | |||
546 | VclPtr<SvxRuler> pRuler; | |||
547 | WinBits aWBits = WB_VSCROLL | WB_3DLOOK | WB_BORDER; | |||
548 | SvxRulerSupportFlags nFlags = SvxRulerSupportFlags::OBJECT; | |||
549 | ||||
550 | pRuler = VclPtr<Ruler>::Create(*this, GetParentWindow(), pWin, nFlags, | |||
| ||||
551 | GetViewFrame()->GetBindings(), aWBits); | |||
552 | ||||
553 | // Metric same as HRuler, use document setting | |||
554 | sal_uInt16 nMetric = static_cast<sal_uInt16>(GetDoc()->GetUIUnit()); | |||
555 | ||||
556 | if( nMetric == 0xffff ) | |||
557 | nMetric = static_cast<sal_uInt16>(GetViewShellBase().GetViewFrame()->GetDispatcher()->GetModule()->GetFieldUnit()); | |||
558 | ||||
559 | pRuler->SetUnit( FieldUnit( nMetric ) ); | |||
560 | ||||
561 | Fraction aUIScale(pWin->GetMapMode().GetScaleY()); | |||
562 | aUIScale *= GetDoc()->GetUIScale(); | |||
563 | pRuler->SetZoom(aUIScale); | |||
564 | ||||
565 | return pRuler; | |||
566 | } | |||
567 | ||||
568 | /** | |||
569 | * Refresh horizontal ruler | |||
570 | */ | |||
571 | ||||
572 | void DrawViewShell::UpdateHRuler() | |||
573 | { | |||
574 | Invalidate( SID_ATTR_LONG_LRSPACE( 10000 + 285 ) ); | |||
575 | Invalidate( SID_RULER_PAGE_POSTypedWhichId<SvxRulerItem>( 10000 + 82 ) ); | |||
576 | Invalidate( SID_RULER_OBJECTTypedWhichId<SvxRulerItem>( 10000 + 81 ) ); | |||
577 | Invalidate( SID_RULER_TEXT_RIGHT_TO_LEFT( 10000 + 952 ) ); | |||
578 | ||||
579 | if (mpHorizontalRuler) | |||
580 | mpHorizontalRuler->ForceUpdate(); | |||
581 | } | |||
582 | ||||
583 | /** | |||
584 | * Refresh vertical ruler | |||
585 | */ | |||
586 | ||||
587 | void DrawViewShell::UpdateVRuler() | |||
588 | { | |||
589 | Invalidate( SID_ATTR_LONG_LRSPACE( 10000 + 285 ) ); | |||
590 | Invalidate( SID_RULER_PAGE_POSTypedWhichId<SvxRulerItem>( 10000 + 82 ) ); | |||
591 | Invalidate( SID_RULER_OBJECTTypedWhichId<SvxRulerItem>( 10000 + 81 ) ); | |||
592 | ||||
593 | if (mpVerticalRuler) | |||
594 | mpVerticalRuler->ForceUpdate(); | |||
595 | } | |||
596 | ||||
597 | /** | |||
598 | * Refresh TabControl on splitter change | |||
599 | */ | |||
600 | ||||
601 | IMPL_LINK( DrawViewShell, TabSplitHdl, TabBar *, pTab, void )void DrawViewShell::LinkStubTabSplitHdl(void * instance, TabBar * data) { return static_cast<DrawViewShell *>(instance )->TabSplitHdl(data); } void DrawViewShell::TabSplitHdl(TabBar * pTab) | |||
602 | { | |||
603 | const long int nMax = maViewSize.Width() - maScrBarWH.Width() | |||
604 | - maTabControl->GetPosPixel().X() ; | |||
605 | ||||
606 | Size aTabSize = maTabControl->GetSizePixel(); | |||
607 | aTabSize.setWidth( std::min(pTab->GetSplitSize(), static_cast<long>(nMax-1)) ); | |||
608 | ||||
609 | maTabControl->SetSizePixel(aTabSize); | |||
610 | ||||
611 | if(GetLayerTabControl()) // #i87182# | |||
612 | { | |||
613 | GetLayerTabControl()->SetSizePixel(aTabSize); | |||
614 | } | |||
615 | ||||
616 | Point aPos = maTabControl->GetPosPixel(); | |||
617 | aPos.AdjustX(aTabSize.Width() ); | |||
618 | ||||
619 | Size aScrSize(nMax - aTabSize.Width(), maScrBarWH.Height()); | |||
620 | mpHorizontalScrollBar->SetPosSizePixel(aPos, aScrSize); | |||
621 | } | |||
622 | ||||
623 | /// inherited from sd::ViewShell | |||
624 | SdPage* DrawViewShell::getCurrentPage() const | |||
625 | { | |||
626 | const sal_uInt16 nPageCount = (meEditMode == EditMode::Page)? | |||
627 | GetDoc()->GetSdPageCount(mePageKind): | |||
628 | GetDoc()->GetMasterSdPageCount(mePageKind); | |||
629 | ||||
630 | sal_uInt16 nCurrentPage = maTabControl->GetCurPagePos(); | |||
631 | DBG_ASSERT((nCurrentPage<nPageCount), "sd::DrawViewShell::getCurrentPage(), illegal page index!")do { if (true && (!((nCurrentPage<nPageCount)))) { sal_detail_logFormat((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.tools" ), ("/home/maarten/src/libreoffice/core/sd/source/ui/view/drviews1.cxx" ":" "631" ": "), "%s", "sd::DrawViewShell::getCurrentPage(), illegal page index!" ); } } while (false); | |||
632 | if (nCurrentPage >= nPageCount) | |||
633 | nCurrentPage = 0; // play safe here | |||
634 | ||||
635 | if (meEditMode == EditMode::Page) | |||
636 | { | |||
637 | return GetDoc()->GetSdPage(nCurrentPage, mePageKind); | |||
638 | } | |||
639 | else // EditMode::MasterPage | |||
640 | { | |||
641 | return GetDoc()->GetMasterSdPage(nCurrentPage, mePageKind); | |||
642 | } | |||
643 | } | |||
644 | ||||
645 | /** | |||
646 | * Select new refreshed page, in case of a page order change (eg. by undo) | |||
647 | */ | |||
648 | ||||
649 | void DrawViewShell::ResetActualPage() | |||
650 | { | |||
651 | if (!GetDoc()) | |||
652 | return; | |||
653 | ||||
654 | sal_uInt16 nCurrentPageId = maTabControl->GetCurPageId(); | |||
655 | sal_uInt16 nCurrentPageNum = maTabControl->GetPagePos(nCurrentPageId); | |||
656 | sal_uInt16 nPageCount = (meEditMode == EditMode::Page)?GetDoc()->GetSdPageCount(mePageKind):GetDoc()->GetMasterSdPageCount(mePageKind); | |||
657 | ||||
658 | if (meEditMode == EditMode::Page) | |||
659 | { | |||
660 | ||||
661 | // Update for TabControl | |||
662 | maTabControl->Clear(); | |||
663 | ||||
664 | SdPage* pPage = nullptr; | |||
665 | ||||
666 | for (sal_uInt16 i = 0; i < nPageCount; i++) | |||
667 | { | |||
668 | pPage = GetDoc()->GetSdPage(i, mePageKind); | |||
669 | OUString aPageName = pPage->GetName(); | |||
670 | maTabControl->InsertPage(pPage->getPageId(), aPageName); | |||
671 | ||||
672 | if (nCurrentPageId == pPage->getPageId()) | |||
673 | { | |||
674 | nCurrentPageNum = i; | |||
675 | GetDoc()->SetSelected(pPage, true); | |||
676 | } | |||
677 | else | |||
678 | GetDoc()->SetSelected(pPage, false); | |||
679 | } | |||
680 | ||||
681 | maTabControl->SetCurPageId(maTabControl->GetPageId(nCurrentPageNum)); | |||
682 | } | |||
683 | else // EditMode::MasterPage | |||
684 | { | |||
685 | maTabControl->Clear(); | |||
686 | ||||
687 | sal_uInt16 nMasterPageCnt = GetDoc()->GetMasterSdPageCount(mePageKind); | |||
688 | for (sal_uInt16 i = 0; i < nMasterPageCnt; i++) | |||
689 | { | |||
690 | SdPage* pMaster = GetDoc()->GetMasterSdPage(i, mePageKind); | |||
691 | OUString aLayoutName = pMaster->GetLayoutName(); | |||
692 | sal_Int32 nPos = aLayoutName.indexOf(SD_LT_SEPARATOR"~LT~"); | |||
693 | if (nPos != -1) | |||
694 | aLayoutName = aLayoutName.copy(0, nPos); | |||
695 | maTabControl->InsertPage(pMaster->getPageId(), aLayoutName); | |||
696 | ||||
697 | if (pMaster->getPageId() == nCurrentPageId) | |||
698 | nCurrentPageNum = i; | |||
699 | } | |||
700 | ||||
701 | maTabControl->SetCurPageId(maTabControl->GetPageId(nCurrentPageNum)); | |||
702 | SwitchPage(nCurrentPageNum); | |||
703 | } | |||
704 | ||||
705 | GetViewFrame()->GetDispatcher()->Execute(SID_SWITCHPAGE(27000 +42), | |||
706 | SfxCallMode::ASYNCHRON | SfxCallMode::RECORD); | |||
707 | } | |||
708 | ||||
709 | /** | |||
710 | * Apply "Verb" on OLE-object. | |||
711 | */ | |||
712 | ||||
713 | ErrCode DrawViewShell::DoVerb(long nVerb) | |||
714 | { | |||
715 | if ( mpDrawView->AreObjectsMarked() ) | |||
716 | { | |||
717 | const SdrMarkList& rMarkList = mpDrawView->GetMarkedObjectList(); | |||
718 | ||||
719 | if (rMarkList.GetMarkCount() == 1) | |||
720 | { | |||
721 | SdrMark* pMark = rMarkList.GetMark(0); | |||
722 | SdrObject* pObj = pMark->GetMarkedSdrObj(); | |||
723 | ||||
724 | SdrInventor nInv = pObj->GetObjInventor(); | |||
725 | sal_uInt16 nSdrObjKind = pObj->GetObjIdentifier(); | |||
726 | ||||
727 | if (nInv == SdrInventor::Default && nSdrObjKind == OBJ_OLE2) | |||
728 | { | |||
729 | ActivateObject( static_cast<SdrOle2Obj*>(pObj), nVerb); | |||
730 | } | |||
731 | } | |||
732 | } | |||
733 | ||||
734 | return ERRCODE_NONEErrCode(0); | |||
735 | } | |||
736 | ||||
737 | /** | |||
738 | * Activate OLE-object | |||
739 | */ | |||
740 | ||||
741 | bool DrawViewShell::ActivateObject(SdrOle2Obj* pObj, long nVerb) | |||
742 | { | |||
743 | bool bActivated = false; | |||
744 | ||||
745 | if ( !GetDocSh()->IsUIActive() ) | |||
746 | { | |||
747 | ToolBarManager::UpdateLock aLock (GetViewShellBase().GetToolBarManager()); | |||
748 | ||||
749 | bActivated = ViewShell::ActivateObject(pObj, nVerb); | |||
750 | } | |||
751 | ||||
752 | return bActivated; | |||
753 | } | |||
754 | ||||
755 | /** | |||
756 | * Mark the desired page as selected (1), deselected (0), toggle (2). | |||
757 | * nPage refers to the page in question. | |||
758 | */ | |||
759 | bool DrawViewShell::SelectPage(sal_uInt16 nPage, sal_uInt16 nSelect) | |||
760 | { | |||
761 | SdPage* pPage = GetDoc()->GetSdPage(nPage, PageKind::Standard); | |||
762 | ||||
763 | //page selector marks pages to selected in view | |||
764 | auto &pageSelector = sd::slidesorter::SlideSorterViewShell::GetSlideSorter(GetViewShellBase())->GetSlideSorter().GetController().GetPageSelector(); | |||
765 | ||||
766 | if (pPage) | |||
767 | { | |||
768 | if (nSelect == 0) | |||
769 | { | |||
770 | GetDoc()->SetSelected(pPage, false); // Deselect. | |||
771 | pageSelector.DeselectPage(nPage); | |||
772 | } | |||
773 | else if (nSelect == 1) | |||
774 | { | |||
775 | GetDoc()->SetSelected(pPage, true); // Select. | |||
776 | pageSelector.SelectPage(nPage); | |||
777 | } | |||
778 | else | |||
779 | { | |||
780 | // Toggle. | |||
781 | if (pPage->IsSelected()) | |||
782 | { | |||
783 | GetDoc()->SetSelected(pPage, false); | |||
784 | pageSelector.DeselectPage(nPage); | |||
785 | } | |||
786 | else | |||
787 | { | |||
788 | GetDoc()->SetSelected(pPage, true); | |||
789 | pageSelector.SelectPage(nPage); | |||
790 | } | |||
791 | } | |||
792 | return true; | |||
793 | } | |||
794 | ||||
795 | return false; | |||
796 | } | |||
797 | ||||
798 | bool DrawViewShell::IsSelected(sal_uInt16 nPage) | |||
799 | { | |||
800 | slidesorter::SlideSorterViewShell* pVShell | |||
801 | = slidesorter::SlideSorterViewShell::GetSlideSorter(GetViewShellBase()); | |||
802 | if (pVShell != nullptr) | |||
803 | return pVShell->GetSlideSorter().GetController().GetPageSelector().IsPageSelected(nPage); | |||
804 | ||||
805 | return false; | |||
806 | } | |||
807 | ||||
808 | bool DrawViewShell::IsVisible(sal_uInt16 nPage) | |||
809 | { | |||
810 | slidesorter::SlideSorterViewShell* pVShell | |||
811 | = slidesorter::SlideSorterViewShell::GetSlideSorter(GetViewShellBase()); | |||
812 | if (pVShell != nullptr) | |||
813 | return pVShell->GetSlideSorter().GetController().GetPageSelector().IsPageVisible(nPage); | |||
814 | ||||
815 | return false; | |||
816 | } | |||
817 | ||||
818 | /** | |||
819 | * Switch to desired page. | |||
820 | * nSelectPage refers to the current EditMode | |||
821 | */ | |||
822 | bool DrawViewShell::SwitchPage(sal_uInt16 nSelectedPage) | |||
823 | { | |||
824 | /** Under some circumstances there are nested calls to SwitchPage() and | |||
825 | may crash the application (activation of form controls when the | |||
826 | shell of the edit view is not on top of the shell stack, see issue | |||
827 | 83888 for details.) Therefore the nested calls are ignored (they | |||
828 | would jump to the wrong page anyway.) | |||
829 | */ | |||
830 | ||||
831 | if (mbIsInSwitchPage) | |||
832 | return false; | |||
833 | mbIsInSwitchPage = true; | |||
834 | comphelper::ScopeGuard aGuard( | |||
835 | [this] () { this->mbIsInSwitchPage = false; } ); | |||
836 | ||||
837 | if (GetActiveWindow()->IsInPaint()) | |||
838 | { | |||
839 | // Switching the current page while a Paint is being executed is | |||
840 | // dangerous. So, post it for later execution and return. | |||
841 | maAsynchronousSwitchPageCall.Post( | |||
842 | [this, nSelectedPage] () { this->SwitchPage(nSelectedPage); } ); | |||
843 | return false; | |||
844 | } | |||
845 | ||||
846 | bool bOK = false; | |||
847 | ||||
848 | // With the current implementation of FuSlideShow there is a problem | |||
849 | // when it displays the show in a window: when the show is stopped it | |||
850 | // returns at one point in time SDRPAGE_NOTFOUND as current page index. | |||
851 | // Because FuSlideShow is currently being rewritten this bug is fixed | |||
852 | // here. | |||
853 | // This is not as bad a hack as it may look because making SwitchPage() | |||
854 | // more robust with respect to invalid page numbers is a good thing | |||
855 | // anyway. | |||
856 | if (nSelectedPage == SDRPAGE_NOTFOUND0xFFFF) | |||
857 | { | |||
858 | nSelectedPage = 0; | |||
859 | } | |||
860 | else | |||
861 | { | |||
862 | // Make sure that the given page index points to an existing page. Move | |||
863 | // the index into the valid range if necessary. | |||
864 | sal_uInt16 nPageCount = (meEditMode == EditMode::Page) | |||
865 | ? GetDoc()->GetSdPageCount(mePageKind) | |||
866 | : GetDoc()->GetMasterSdPageCount(mePageKind); | |||
867 | if (nSelectedPage >= nPageCount) | |||
868 | nSelectedPage = nPageCount-1; | |||
869 | } | |||
870 | ||||
871 | if (IsSwitchPageAllowed()) | |||
872 | { | |||
873 | ModifyGuard aGuard2( GetDoc() ); | |||
874 | ||||
875 | bOK = true; | |||
876 | ||||
877 | if (mpActualPage) | |||
878 | { | |||
879 | SdPage* pNewPage = nullptr; | |||
880 | ||||
881 | if (meEditMode == EditMode::MasterPage) | |||
882 | { | |||
883 | if( GetDoc()->GetMasterSdPageCount(mePageKind) > nSelectedPage ) | |||
884 | pNewPage = GetDoc()->GetMasterSdPage(nSelectedPage, mePageKind); | |||
885 | ||||
886 | if( pNewPage ) | |||
887 | { | |||
888 | SdrPageView* pPV = mpDrawView->GetSdrPageView(); | |||
889 | OUString sPageText(pNewPage->GetLayoutName()); | |||
890 | sal_Int32 nPos = sPageText.indexOf(SD_LT_SEPARATOR"~LT~"); | |||
891 | if (nPos != -1) | |||
892 | sPageText = sPageText.copy(0, nPos); | |||
893 | if (pPV | |||
894 | && pNewPage == dynamic_cast< SdPage* >( pPV->GetPage() ) | |||
895 | && sPageText == maTabControl->GetPageText(maTabControl->GetPageId(nSelectedPage))) | |||
896 | { | |||
897 | // this slide is already visible | |||
898 | return true; | |||
899 | } | |||
900 | } | |||
901 | } | |||
902 | else | |||
903 | { | |||
904 | OSL_ASSERT(mpFrameView!=nullptr)do { if (true && (!(mpFrameView!=nullptr))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sd/source/ui/view/drviews1.cxx" ":" "904" ": "), "OSL_ASSERT: %s", "mpFrameView!=nullptr"); } } while (false); | |||
905 | mpFrameView->SetSelectedPage(nSelectedPage); | |||
906 | ||||
907 | if (GetDoc()->GetSdPageCount(mePageKind) > nSelectedPage) | |||
908 | pNewPage = GetDoc()->GetSdPage(nSelectedPage, mePageKind); | |||
909 | ||||
910 | if (mpActualPage == pNewPage) | |||
911 | { | |||
912 | SdrPageView* pPV = mpDrawView->GetSdrPageView(); | |||
913 | ||||
914 | SdPage* pCurrentPage = pPV ? dynamic_cast<SdPage*>(pPV->GetPage()) : nullptr; | |||
915 | if (pCurrentPage | |||
916 | && pNewPage == pCurrentPage | |||
917 | && maTabControl->GetPageText(maTabControl->GetPageId(nSelectedPage)) == pNewPage->GetName() | |||
918 | && SfxLokHelper::getDeviceFormFactor() != LOKDeviceFormFactor::MOBILE) | |||
919 | { | |||
920 | // this slide is already visible | |||
921 | return true; | |||
922 | } | |||
923 | } | |||
924 | } | |||
925 | } | |||
926 | ||||
927 | mpDrawView->SdrEndTextEdit(); | |||
928 | ||||
929 | mpActualPage = nullptr; | |||
930 | ||||
931 | if (meEditMode == EditMode::Page) | |||
932 | { | |||
933 | mpActualPage = GetDoc()->GetSdPage(nSelectedPage, mePageKind); | |||
934 | } | |||
935 | else | |||
936 | { | |||
937 | SdPage* pMaster = GetDoc()->GetMasterSdPage(nSelectedPage, mePageKind); | |||
938 | ||||
939 | // does the selected page fit to the masterpage? | |||
940 | sal_uInt16 nPageCount = GetDoc()->GetSdPageCount(mePageKind); | |||
941 | for (sal_uInt16 i = 0; i < nPageCount; i++) | |||
942 | { | |||
943 | SdPage* pPage = GetDoc()->GetSdPage(i, mePageKind); | |||
944 | if(pPage && pPage->IsSelected() && pMaster == &(pPage->TRG_GetMasterPage())) | |||
945 | { | |||
946 | mpActualPage = pPage; | |||
947 | break; | |||
948 | } | |||
949 | } | |||
950 | ||||
951 | if (!mpActualPage) | |||
952 | { | |||
953 | // take the first page, that fits to the masterpage | |||
954 | for (sal_uInt16 i = 0; i < nPageCount; i++) | |||
955 | { | |||
956 | SdPage* pPage = GetDoc()->GetSdPage(i, mePageKind); | |||
957 | if(pPage && pMaster == &(pPage->TRG_GetMasterPage())) | |||
958 | { | |||
959 | mpActualPage = pPage; | |||
960 | break; | |||
961 | } | |||
962 | } | |||
963 | } | |||
964 | } | |||
965 | ||||
966 | for (sal_uInt16 i = 0; i < GetDoc()->GetSdPageCount(mePageKind); i++) | |||
967 | { | |||
968 | // deselect all pages | |||
969 | GetDoc()->SetSelected( GetDoc()->GetSdPage(i, mePageKind), false); | |||
970 | } | |||
971 | ||||
972 | if (!mpActualPage) | |||
973 | { | |||
974 | // as far as there is no mpActualPage, take the first | |||
975 | mpActualPage = GetDoc()->GetSdPage(0, mePageKind); | |||
976 | } | |||
977 | ||||
978 | // also select this page (mpActualPage always points at a drawing page, | |||
979 | // never at a masterpage) | |||
980 | GetDoc()->SetSelected(mpActualPage, true); | |||
981 | ||||
982 | if (comphelper::LibreOfficeKit::isActive()) | |||
983 | { | |||
984 | // notify LibreOfficeKit about changed page | |||
985 | OString aPayload = OString::number(nSelectedPage); | |||
986 | if (SfxViewShell* pViewShell = GetViewShell()) | |||
987 | pViewShell->libreOfficeKitViewCallback(LOK_CALLBACK_SET_PART, aPayload.getStr()); | |||
988 | } | |||
989 | ||||
990 | rtl::Reference< sd::SlideShow > xSlideshow( SlideShow::GetSlideShow( GetDoc() ) ); | |||
991 | if( !xSlideshow.is() || !xSlideshow->isRunning() || ( xSlideshow->getAnimationMode() != ANIMATIONMODE_SHOW ) ) | |||
992 | { | |||
993 | // tighten VisArea, to possibly deactivate objects | |||
994 | // !!! only if we are not in presentation mode (#96279) !!! | |||
995 | OSL_ASSERT (GetViewShell()!=nullptr)do { if (true && (!(GetViewShell()!=nullptr))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/sd/source/ui/view/drviews1.cxx" ":" "995" ": "), "OSL_ASSERT: %s", "GetViewShell()!=nullptr" ); } } while (false); | |||
996 | GetViewShell()->DisconnectAllClients(); | |||
997 | VisAreaChanged(::tools::Rectangle(Point(), Size(1, 1))); | |||
998 | } | |||
999 | ||||
1000 | if (meEditMode == EditMode::Page) | |||
1001 | { | |||
1002 | /********************************************************************** | |||
1003 | * PAGEMODE | |||
1004 | **********************************************************************/ | |||
1005 | GetDoc()->SetSelected(mpActualPage, true); | |||
1006 | ||||
1007 | SdrPageView* pPageView = mpDrawView->GetSdrPageView(); | |||
1008 | ||||
1009 | if (pPageView) | |||
1010 | { | |||
1011 | mpFrameView->SetVisibleLayers( pPageView->GetVisibleLayers() ); | |||
1012 | mpFrameView->SetPrintableLayers( pPageView->GetPrintableLayers() ); | |||
1013 | mpFrameView->SetLockedLayers( pPageView->GetLockedLayers() ); | |||
1014 | ||||
1015 | if (mePageKind == PageKind::Notes) | |||
1016 | { | |||
1017 | mpFrameView->SetNotesHelpLines( pPageView->GetHelpLines() ); | |||
1018 | } | |||
1019 | else if (mePageKind == PageKind::Handout) | |||
1020 | { | |||
1021 | mpFrameView->SetHandoutHelpLines( pPageView->GetHelpLines() ); | |||
1022 | } | |||
1023 | else | |||
1024 | { | |||
1025 | mpFrameView->SetStandardHelpLines( pPageView->GetHelpLines() ); | |||
1026 | } | |||
1027 | } | |||
1028 | ||||
1029 | mpDrawView->HideSdrPage(); | |||
1030 | maTabControl->SetCurPageId(maTabControl->GetPageId(nSelectedPage)); | |||
1031 | mpDrawView->ShowSdrPage(mpActualPage); | |||
1032 | GetViewShellBase().GetDrawController().FireSwitchCurrentPage(mpActualPage); | |||
1033 | ||||
1034 | SdrPageView* pNewPageView = mpDrawView->GetSdrPageView(); | |||
1035 | ||||
1036 | if (pNewPageView) | |||
1037 | { | |||
1038 | pNewPageView->SetVisibleLayers( mpFrameView->GetVisibleLayers() ); | |||
1039 | pNewPageView->SetPrintableLayers( mpFrameView->GetPrintableLayers() ); | |||
1040 | pNewPageView->SetLockedLayers( mpFrameView->GetLockedLayers() ); | |||
1041 | ||||
1042 | if (mePageKind == PageKind::Notes) | |||
1043 | { | |||
1044 | pNewPageView->SetHelpLines( mpFrameView->GetNotesHelpLines() ); | |||
1045 | } | |||
1046 | else if (mePageKind == PageKind::Handout) | |||
1047 | { | |||
1048 | pNewPageView->SetHelpLines( mpFrameView->GetHandoutHelpLines() ); | |||
1049 | } | |||
1050 | else | |||
1051 | { | |||
1052 | pNewPageView->SetHelpLines( mpFrameView->GetStandardHelpLines() ); | |||
1053 | } | |||
1054 | } | |||
1055 | ||||
1056 | OUString aPageName = mpActualPage->GetName(); | |||
1057 | ||||
1058 | if (maTabControl->GetPageText(maTabControl->GetPageId(nSelectedPage)) != aPageName) | |||
1059 | { | |||
1060 | maTabControl->SetPageText(maTabControl->GetPageId(nSelectedPage), aPageName); | |||
1061 | } | |||
1062 | } | |||
1063 | else | |||
1064 | { | |||
1065 | /********************************************************************** | |||
1066 | * MASTERPAGE | |||
1067 | **********************************************************************/ | |||
1068 | SdrPageView* pPageView = mpDrawView->GetSdrPageView(); | |||
1069 | ||||
1070 | if (pPageView) | |||
1071 | { | |||
1072 | mpFrameView->SetVisibleLayers( pPageView->GetVisibleLayers() ); | |||
1073 | mpFrameView->SetPrintableLayers( pPageView->GetPrintableLayers() ); | |||
1074 | mpFrameView->SetLockedLayers( pPageView->GetLockedLayers() ); | |||
1075 | ||||
1076 | if (mePageKind == PageKind::Notes) | |||
1077 | { | |||
1078 | mpFrameView->SetNotesHelpLines( pPageView->GetHelpLines() ); | |||
1079 | } | |||
1080 | else if (mePageKind == PageKind::Handout) | |||
1081 | { | |||
1082 | mpFrameView->SetHandoutHelpLines( pPageView->GetHelpLines() ); | |||
1083 | } | |||
1084 | else | |||
1085 | { | |||
1086 | mpFrameView->SetStandardHelpLines( pPageView->GetHelpLines() ); | |||
1087 | } | |||
1088 | } | |||
1089 | ||||
1090 | mpDrawView->HideSdrPage(); | |||
1091 | maTabControl->SetCurPageId(maTabControl->GetPageId(nSelectedPage)); | |||
1092 | ||||
1093 | SdPage* pMaster = GetDoc()->GetMasterSdPage(nSelectedPage, mePageKind); | |||
1094 | ||||
1095 | if( !pMaster ) // if this page should not exist | |||
1096 | pMaster = GetDoc()->GetMasterSdPage(0, mePageKind); | |||
1097 | ||||
1098 | sal_uInt16 nNum = pMaster->GetPageNum(); | |||
1099 | mpDrawView->ShowSdrPage(mpDrawView->GetModel()->GetMasterPage(nNum)); | |||
1100 | ||||
1101 | GetViewShellBase().GetDrawController().FireSwitchCurrentPage(pMaster); | |||
1102 | ||||
1103 | SdrPageView* pNewPageView = mpDrawView->GetSdrPageView(); | |||
1104 | ||||
1105 | if (pNewPageView) | |||
1106 | { | |||
1107 | pNewPageView->SetVisibleLayers( mpFrameView->GetVisibleLayers() ); | |||
1108 | pNewPageView->SetPrintableLayers( mpFrameView->GetPrintableLayers() ); | |||
1109 | pNewPageView->SetLockedLayers( mpFrameView->GetLockedLayers() ); | |||
1110 | ||||
1111 | if (mePageKind == PageKind::Notes) | |||
1112 | { | |||
1113 | pNewPageView->SetHelpLines( mpFrameView->GetNotesHelpLines() ); | |||
1114 | } | |||
1115 | else if (mePageKind == PageKind::Handout) | |||
1116 | { | |||
1117 | pNewPageView->SetHelpLines( mpFrameView->GetHandoutHelpLines() ); | |||
1118 | } | |||
1119 | else | |||
1120 | { | |||
1121 | pNewPageView->SetHelpLines( mpFrameView->GetStandardHelpLines() ); | |||
1122 | } | |||
1123 | } | |||
1124 | ||||
1125 | OUString aLayoutName(pMaster->GetLayoutName()); | |||
1126 | sal_Int32 nPos = aLayoutName.indexOf(SD_LT_SEPARATOR"~LT~"); | |||
1127 | if (nPos != -1) | |||
1128 | aLayoutName = aLayoutName.copy(0, nPos); | |||
1129 | ||||
1130 | if (maTabControl->GetPageText(maTabControl->GetPageId(nSelectedPage)) != aLayoutName) | |||
1131 | { | |||
1132 | maTabControl->SetPageText(maTabControl->GetPageId(nSelectedPage), aLayoutName); | |||
1133 | } | |||
1134 | ||||
1135 | if( mePageKind == PageKind::Handout ) | |||
1136 | { | |||
1137 | // set pages for all available handout presentation objects | |||
1138 | sd::ShapeList& rShapeList = pMaster->GetPresentationShapeList(); | |||
1139 | SdrObject* pObj = nullptr; | |||
1140 | rShapeList.seekShape(0); | |||
1141 | ||||
1142 | while( (pObj = rShapeList.getNextShape()) ) | |||
1143 | { | |||
1144 | if( pMaster->GetPresObjKind(pObj) == PresObjKind::Handout ) | |||
1145 | { | |||
1146 | // #i105146# We want no content to be displayed for PageKind::Handout, | |||
1147 | // so just never set a page as content | |||
1148 | static_cast<SdrPageObj*>(pObj)->SetReferencedPage(nullptr); | |||
1149 | } | |||
1150 | } | |||
1151 | } | |||
1152 | } | |||
1153 | ||||
1154 | Size aVisSizePixel = GetActiveWindow()->GetOutputSizePixel(); | |||
1155 | ::tools::Rectangle aVisAreaWin = GetActiveWindow()->PixelToLogic( ::tools::Rectangle( Point(0,0), aVisSizePixel) ); | |||
1156 | VisAreaChanged(aVisAreaWin); | |||
1157 | mpDrawView->VisAreaChanged(GetActiveWindow()); | |||
1158 | ||||
1159 | // so navigator (and effect window) notice that | |||
1160 | SfxBindings& rBindings = GetViewFrame()->GetBindings(); | |||
1161 | rBindings.Invalidate(SID_NAVIGATOR_STATE(27000 +288), true); | |||
1162 | rBindings.Invalidate(SID_NAVIGATOR_PAGENAME(27000 +287), true); | |||
1163 | rBindings.Invalidate(SID_STATUS_PAGE(27000 +86), true); | |||
1164 | rBindings.Invalidate(SID_DELETE_MASTER_PAGE(27000 +432), true); | |||
1165 | rBindings.Invalidate(SID_DELETE_PAGE(27000 +80), true); | |||
1166 | rBindings.Invalidate(SID_ASSIGN_LAYOUT(27000 +435), true); | |||
1167 | rBindings.Invalidate(SID_INSERTPAGE(27000 +14), true); | |||
1168 | UpdatePreview( mpActualPage ); | |||
1169 | ||||
1170 | mpDrawView->AdjustMarkHdl(); | |||
1171 | } | |||
1172 | ||||
1173 | return bOK; | |||
1174 | } | |||
1175 | ||||
1176 | /** | |||
1177 | * Check if page change is allowed | |||
1178 | */ | |||
1179 | ||||
1180 | bool DrawViewShell::IsSwitchPageAllowed() const | |||
1181 | { | |||
1182 | bool bOK = true; | |||
1183 | ||||
1184 | FmFormShell* pFormShell = GetViewShellBase().GetFormShellManager()->GetFormShell(); | |||
1185 | if (pFormShell != nullptr && !pFormShell->PrepareClose(false)) | |||
1186 | bOK = false; | |||
1187 | ||||
1188 | return bOK; | |||
1189 | } | |||
1190 | ||||
1191 | /** | |||
1192 | * Select new refreshed page, in case of a page order change (eg. by undo) | |||
1193 | */ | |||
1194 | ||||
1195 | void DrawViewShell::ResetActualLayer() | |||
1196 | { | |||
1197 | LayerTabBar* pLayerBar = GetLayerTabControl(); | |||
1198 | if (pLayerBar == nullptr) | |||
1199 | return; | |||
1200 | ||||
1201 | // remember old tab count and current tab id | |||
1202 | // this is needed when one layer is renamed to | |||
1203 | // restore current tab | |||
1204 | sal_uInt16 nOldLayerCnt = pLayerBar->GetPageCount(); // actually it is tab count | |||
1205 | sal_uInt16 nOldLayerPos = pLayerBar->GetCurPageId(); // actually it is a tab nId | |||
1206 | ||||
1207 | /** | |||
1208 | * Update for LayerTab | |||
1209 | */ | |||
1210 | pLayerBar->Clear(); | |||
1211 | ||||
1212 | OUString aName; // a real layer name | |||
1213 | OUString aActiveLayer = mpDrawView->GetActiveLayer(); | |||
1214 | sal_uInt16 nActiveLayerPos = SDRLAYERPOS_NOTFOUND0xffff; | |||
1215 | SdrLayerAdmin& rLayerAdmin = GetDoc()->GetLayerAdmin(); | |||
1216 | sal_uInt16 nLayerCnt = rLayerAdmin.GetLayerCount(); | |||
1217 | ||||
1218 | for ( sal_uInt16 nLayerPos = 0; nLayerPos < nLayerCnt; nLayerPos++ ) | |||
1219 | { | |||
1220 | aName = rLayerAdmin.GetLayer(nLayerPos)->GetName(); | |||
1221 | ||||
1222 | if ( aName == aActiveLayer ) | |||
1223 | { | |||
1224 | nActiveLayerPos = nLayerPos; | |||
1225 | } | |||
1226 | ||||
1227 | if ( aName != sUNO_LayerName_background ) // layer "background" has never a tab | |||
1228 | { | |||
1229 | if (meEditMode == EditMode::MasterPage) | |||
1230 | { | |||
1231 | // don't show page layer onto the masterpage | |||
1232 | if (aName != sUNO_LayerName_layout && | |||
1233 | aName != sUNO_LayerName_controls && | |||
1234 | aName != sUNO_LayerName_measurelines) | |||
1235 | { | |||
1236 | TabBarPageBits nBits = TabBarPageBits::NONE; | |||
1237 | SdrPageView* pPV = mpDrawView->GetSdrPageView(); | |||
1238 | if (pPV) | |||
1239 | { | |||
1240 | if (!pPV->IsLayerVisible(aName)) | |||
1241 | { | |||
1242 | nBits |= TabBarPageBits::Blue; | |||
1243 | } | |||
1244 | if (pPV->IsLayerLocked(aName)) | |||
1245 | { | |||
1246 | nBits |= TabBarPageBits::Italic; | |||
1247 | } | |||
1248 | if (!pPV->IsLayerPrintable(aName)) | |||
1249 | { | |||
1250 | nBits |= TabBarPageBits::Underline; | |||
1251 | } | |||
1252 | } | |||
1253 | ||||
1254 | pLayerBar->InsertPage(nLayerPos+1, aName, nBits); // why +1? It is a nId, not a position. Position is APPEND. | |||
1255 | } | |||
1256 | } | |||
1257 | else | |||
1258 | { | |||
1259 | // don't show masterpage layer onto the page | |||
1260 | if (aName != sUNO_LayerName_background_objects) | |||
1261 | { | |||
1262 | TabBarPageBits nBits = TabBarPageBits::NONE; | |||
1263 | if (!mpDrawView->GetSdrPageView()->IsLayerVisible(aName)) | |||
1264 | { | |||
1265 | nBits = TabBarPageBits::Blue; | |||
1266 | } | |||
1267 | if (mpDrawView->GetSdrPageView()->IsLayerLocked(aName)) | |||
1268 | { | |||
1269 | nBits |= TabBarPageBits::Italic; | |||
1270 | } | |||
1271 | if (!mpDrawView->GetSdrPageView()->IsLayerPrintable(aName)) | |||
1272 | { | |||
1273 | nBits |= TabBarPageBits::Underline; | |||
1274 | } | |||
1275 | ||||
1276 | pLayerBar->InsertPage(nLayerPos+1, aName, nBits);// why +1? | |||
1277 | } | |||
1278 | } | |||
1279 | } | |||
1280 | } | |||
1281 | ||||
1282 | if ( nActiveLayerPos == SDRLAYERPOS_NOTFOUND0xffff ) | |||
1283 | { | |||
1284 | if( nOldLayerCnt == pLayerBar->GetPageCount() ) | |||
1285 | { | |||
1286 | nActiveLayerPos = nOldLayerPos - 1; | |||
1287 | } | |||
1288 | else | |||
1289 | { | |||
1290 | nActiveLayerPos = ( meEditMode == EditMode::MasterPage ) ? 2 : 0; | |||
1291 | } | |||
1292 | ||||
1293 | mpDrawView->SetActiveLayer( pLayerBar->GetLayerName(nActiveLayerPos + 1) );// why +1? | |||
1294 | } | |||
1295 | ||||
1296 | pLayerBar->SetCurPageId(nActiveLayerPos + 1); | |||
1297 | GetViewFrame()->GetBindings().Invalidate( SID_MODIFYLAYER(27000 +45) ); | |||
1298 | GetViewFrame()->GetBindings().Invalidate( SID_DELETE_LAYER(27000 +81) ); | |||
1299 | } | |||
1300 | ||||
1301 | /** | |||
1302 | * AcceptDrop | |||
1303 | */ | |||
1304 | ||||
1305 | sal_Int8 DrawViewShell::AcceptDrop ( | |||
1306 | const AcceptDropEvent& rEvt, | |||
1307 | DropTargetHelper& rTargetHelper, | |||
1308 | ::sd::Window* /*pTargetWindow*/, | |||
1309 | sal_uInt16 /*nPage*/, | |||
1310 | SdrLayerID nLayer ) | |||
1311 | { | |||
1312 | if( SlideShow::IsRunning( GetViewShellBase() ) ) | |||
1313 | return DND_ACTION_NONEcss::datatransfer::dnd::DNDConstants::ACTION_NONE; | |||
1314 | ||||
1315 | return mpDrawView->AcceptDrop( rEvt, rTargetHelper, nLayer ); | |||
1316 | } | |||
1317 | ||||
1318 | /** | |||
1319 | * ExecuteDrop | |||
1320 | */ | |||
1321 | ||||
1322 | sal_Int8 DrawViewShell::ExecuteDrop ( | |||
1323 | const ExecuteDropEvent& rEvt, | |||
1324 | DropTargetHelper& /*rTargetHelper*/, | |||
1325 | ::sd::Window* pTargetWindow, | |||
1326 | sal_uInt16 nPage, | |||
1327 | SdrLayerID nLayer) | |||
1328 | { | |||
1329 | if( nPage != SDRPAGE_NOTFOUND0xFFFF ) | |||
1330 | nPage = GetDoc()->GetSdPage( nPage, mePageKind )->GetPageNum(); | |||
1331 | ||||
1332 | if( SlideShow::IsRunning( GetViewShellBase() ) ) | |||
1333 | return DND_ACTION_NONEcss::datatransfer::dnd::DNDConstants::ACTION_NONE; | |||
1334 | ||||
1335 | Broadcast(ViewShellHint(ViewShellHint::HINT_COMPLEX_MODEL_CHANGE_START)); | |||
1336 | sal_Int8 nResult (mpDrawView->ExecuteDrop( rEvt, pTargetWindow, nPage, nLayer )); | |||
1337 | Broadcast(ViewShellHint(ViewShellHint::HINT_COMPLEX_MODEL_CHANGE_END)); | |||
1338 | ||||
1339 | return nResult; | |||
1340 | } | |||
1341 | ||||
1342 | } // end of namespace sd | |||
1343 | ||||
1344 | /* 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_VCL_PTR_HXX |
21 | #define INCLUDED_VCL_PTR_HXX |
22 | |
23 | #include <sal/config.h> |
24 | |
25 | #include <rtl/ref.hxx> |
26 | |
27 | #include <utility> |
28 | #include <type_traits> |
29 | |
30 | #ifdef DBG_UTIL |
31 | #ifndef _WIN32 |
32 | #include <vcl/vclmain.hxx> |
33 | #endif |
34 | #endif |
35 | |
36 | class VclReferenceBase; |
37 | |
38 | namespace vcl::detail { |
39 | |
40 | template<typename> |
41 | constexpr bool isIncompleteOrDerivedFromVclReferenceBase(...) { return true; } |
42 | |
43 | template<typename T> constexpr bool isIncompleteOrDerivedFromVclReferenceBase( |
44 | int (*)[sizeof(T)]) |
45 | { return std::is_base_of<VclReferenceBase, T>::value; } |
46 | |
47 | } // namespace vcl::detail |
48 | |
49 | /** |
50 | * A thin wrapper around rtl::Reference to implement the acquire and dispose semantics we want for references to vcl::Window subclasses. |
51 | * |
52 | * For more details on the design please see vcl/README.lifecycle |
53 | * |
54 | * @param reference_type must be a subclass of vcl::Window |
55 | */ |
56 | template <class reference_type> |
57 | class VclPtr |
58 | { |
59 | static_assert( |
60 | vcl::detail::isIncompleteOrDerivedFromVclReferenceBase<reference_type>( |
61 | nullptr), |
62 | "template argument type must be derived from VclReferenceBase"); |
63 | |
64 | ::rtl::Reference<reference_type> m_rInnerRef; |
65 | |
66 | public: |
67 | /** Constructor... |
68 | */ |
69 | VclPtr() |
70 | : m_rInnerRef() |
71 | {} |
72 | |
73 | /** Constructor... |
74 | */ |
75 | VclPtr (reference_type * pBody) |
76 | : m_rInnerRef(pBody) |
77 | {} |
78 | |
79 | /** Constructor... that doesn't take a ref. |
80 | */ |
81 | VclPtr (reference_type * pBody, __sal_NoAcquire) |
82 | : m_rInnerRef(pBody, SAL_NO_ACQUIRE) |
83 | {} |
84 | |
85 | /** Up-casting conversion constructor: Copies interface reference. |
86 | |
87 | Does not work for up-casts to ambiguous bases. For the special case of |
88 | up-casting to Reference< XInterface >, see the corresponding conversion |
89 | operator. |
90 | |
91 | @param rRef another reference |
92 | */ |
93 | template< class derived_type > |
94 | VclPtr( |
95 | const VclPtr< derived_type > & rRef, |
96 | typename std::enable_if< |
97 | std::is_base_of<reference_type, derived_type>::value, int>::type |
98 | = 0 ) |
99 | : m_rInnerRef( static_cast<reference_type*>(rRef) ) |
100 | { |
101 | } |
102 | |
103 | #if defined(DBG_UTIL) && !defined(_WIN32) |
104 | virtual ~VclPtr() |
105 | { |
106 | assert(m_rInnerRef.get() == nullptr || vclmain::isAlive())(static_cast <bool> (m_rInnerRef.get() == nullptr || vclmain ::isAlive()) ? void (0) : __assert_fail ("m_rInnerRef.get() == nullptr || vclmain::isAlive()" , "/home/maarten/src/libreoffice/core/include/vcl/vclptr.hxx" , 106, __extension__ __PRETTY_FUNCTION__)); |
107 | // We can be one of the intermediate counts, but if we are the last |
108 | // VclPtr keeping this object alive, then something forgot to call dispose(). |
109 | assert((!m_rInnerRef.get() || m_rInnerRef->isDisposed() || m_rInnerRef->getRefCount() > 1)(static_cast <bool> ((!m_rInnerRef.get() || m_rInnerRef ->isDisposed() || m_rInnerRef->getRefCount() > 1) && "someone forgot to call dispose()") ? void (0) : __assert_fail ("(!m_rInnerRef.get() || m_rInnerRef->isDisposed() || m_rInnerRef->getRefCount() > 1) && \"someone forgot to call dispose()\"" , "/home/maarten/src/libreoffice/core/include/vcl/vclptr.hxx" , 110, __extension__ __PRETTY_FUNCTION__)) |
110 | && "someone forgot to call dispose()")(static_cast <bool> ((!m_rInnerRef.get() || m_rInnerRef ->isDisposed() || m_rInnerRef->getRefCount() > 1) && "someone forgot to call dispose()") ? void (0) : __assert_fail ("(!m_rInnerRef.get() || m_rInnerRef->isDisposed() || m_rInnerRef->getRefCount() > 1) && \"someone forgot to call dispose()\"" , "/home/maarten/src/libreoffice/core/include/vcl/vclptr.hxx" , 110, __extension__ __PRETTY_FUNCTION__)); |
111 | } |
112 | VclPtr(VclPtr const &) = default; |
113 | VclPtr(VclPtr &&) = default; |
114 | VclPtr & operator =(VclPtr const &) = default; |
115 | VclPtr & operator =(VclPtr &&) = default; |
116 | #endif |
117 | |
118 | /** |
119 | * A construction helper for VclPtr. Since VclPtr types are created |
120 | * with a reference-count of one - to help fit into the existing |
121 | * code-flow; this helps us to construct them easily. |
122 | * |
123 | * For more details on the design please see vcl/README.lifecycle |
124 | * |
125 | * @tparam reference_type must be a subclass of vcl::Window |
126 | */ |
127 | template<typename... Arg> [[nodiscard]] static VclPtr< reference_type > Create(Arg &&... arg) |
128 | { |
129 | return VclPtr< reference_type >( new reference_type(std::forward<Arg>(arg)...), SAL_NO_ACQUIRE ); |
130 | } |
131 | |
132 | /** Probably most common used: handle->someBodyOp(). |
133 | */ |
134 | reference_type * operator->() const |
135 | { |
136 | return m_rInnerRef.get(); |
137 | } |
138 | |
139 | /** Get the body. Can be used instead of operator->(). |
140 | I.e. handle->someBodyOp() and handle.get()->someBodyOp() |
141 | are the same. |
142 | */ |
143 | reference_type * get() const |
144 | { |
145 | return m_rInnerRef.get(); |
146 | } |
147 | |
148 | void set(reference_type *pBody) |
149 | { |
150 | m_rInnerRef.set(pBody); |
151 | } |
152 | |
153 | void reset(reference_type *pBody) |
154 | { |
155 | m_rInnerRef.set(pBody); |
156 | } |
157 | |
158 | /** Up-casting copy assignment operator. |
159 | |
160 | Does not work for up-casts to ambiguous bases. |
161 | |
162 | @param rRef another reference |
163 | */ |
164 | template<typename derived_type> |
165 | typename std::enable_if< |
166 | std::is_base_of<reference_type, derived_type>::value, |
167 | VclPtr &>::type |
168 | operator =(VclPtr<derived_type> const & rRef) |
169 | { |
170 | m_rInnerRef.set(rRef.get()); |
171 | return *this; |
172 | } |
173 | |
174 | VclPtr & operator =(reference_type * pBody) |
175 | { |
176 | m_rInnerRef.set(pBody); |
177 | return *this; |
178 | } |
179 | |
180 | operator reference_type * () const |
181 | { |
182 | return m_rInnerRef.get(); |
183 | } |
184 | |
185 | explicit operator bool () const |
186 | { |
187 | return m_rInnerRef.get() != nullptr; |
188 | } |
189 | |
190 | void clear() |
191 | { |
192 | m_rInnerRef.clear(); |
193 | } |
194 | |
195 | void reset() |
196 | { |
197 | m_rInnerRef.clear(); |
198 | } |
199 | |
200 | void disposeAndClear() |
201 | { |
202 | // hold it alive for the lifetime of this method |
203 | ::rtl::Reference<reference_type> aTmp(m_rInnerRef); |
204 | m_rInnerRef.clear(); // we should use some 'swap' method ideally ;-) |
205 | if (aTmp.get()) { |
206 | aTmp->disposeOnce(); |
207 | } |
208 | } |
209 | |
210 | /** Needed to place VclPtr's into STL collection. |
211 | */ |
212 | bool operator< (const VclPtr<reference_type> & handle) const |
213 | { |
214 | return (m_rInnerRef < handle.m_rInnerRef); |
215 | } |
216 | }; // class VclPtr |
217 | |
218 | template<typename T1, typename T2> |
219 | inline bool operator ==(VclPtr<T1> const & p1, VclPtr<T2> const & p2) { |
220 | return p1.get() == p2.get(); |
221 | } |
222 | |
223 | template<typename T> inline bool operator ==(VclPtr<T> const & p1, T const * p2) |
224 | { |
225 | return p1.get() == p2; |
226 | } |
227 | |
228 | template<typename T> inline bool operator ==(VclPtr<T> const & p1, T * p2) { |
229 | return p1.get() == p2; |
230 | } |
231 | |
232 | template<typename T> inline bool operator ==(T const * p1, VclPtr<T> const & p2) |
233 | { |
234 | return p1 == p2.get(); |
235 | } |
236 | |
237 | template<typename T> inline bool operator ==(T * p1, VclPtr<T> const & p2) { |
238 | return p1 == p2.get(); |
239 | } |
240 | |
241 | template<typename T1, typename T2> |
242 | inline bool operator !=(VclPtr<T1> const & p1, VclPtr<T2> const & p2) { |
243 | return !(p1 == p2); |
244 | } |
245 | |
246 | template<typename T> inline bool operator !=(VclPtr<T> const & p1, T const * p2) |
247 | { |
248 | return !(p1 == p2); |
249 | } |
250 | |
251 | template<typename T> inline bool operator !=(VclPtr<T> const & p1, T * p2) { |
252 | return !(p1 == p2); |
253 | } |
254 | |
255 | template<typename T> inline bool operator !=(T const * p1, VclPtr<T> const & p2) |
256 | { |
257 | return !(p1 == p2); |
258 | } |
259 | |
260 | template<typename T> inline bool operator !=(T * p1, VclPtr<T> const & p2) { |
261 | return !(p1 == p2); |
262 | } |
263 | |
264 | /** |
265 | * A construction helper for a temporary VclPtr. Since VclPtr types |
266 | * are created with a reference-count of one - to help fit into |
267 | * the existing code-flow; this helps us to construct them easily. |
268 | * see also VclPtr::Create and ScopedVclPtr |
269 | * |
270 | * For more details on the design please see vcl/README.lifecycle |
271 | * |
272 | * @param reference_type must be a subclass of vcl::Window |
273 | */ |
274 | template <class reference_type> |
275 | class SAL_WARN_UNUSED__attribute__((warn_unused)) VclPtrInstance final : public VclPtr<reference_type> |
276 | { |
277 | public: |
278 | template<typename... Arg> VclPtrInstance(Arg &&... arg) |
279 | : VclPtr<reference_type>( new reference_type(std::forward<Arg>(arg)...), SAL_NO_ACQUIRE ) |
280 | { |
281 | } |
282 | |
283 | /** |
284 | * Override and disallow this, to prevent people accidentally calling it and actually |
285 | * getting VclPtr::Create and getting a naked VclPtr<> instance |
286 | */ |
287 | template<typename... Arg> static VclPtrInstance< reference_type > Create(Arg &&... ) = delete; |
288 | }; |
289 | |
290 | template <class reference_type> |
291 | class ScopedVclPtr : public VclPtr<reference_type> |
292 | { |
293 | public: |
294 | /** Constructor... |
295 | */ |
296 | ScopedVclPtr() |
297 | : VclPtr<reference_type>() |
298 | {} |
299 | |
300 | /** Constructor |
301 | */ |
302 | ScopedVclPtr (reference_type * pBody) |
303 | : VclPtr<reference_type>(pBody) |
304 | {} |
305 | |
306 | /** Copy constructor... |
307 | */ |
308 | ScopedVclPtr (const VclPtr<reference_type> & handle) |
309 | : VclPtr<reference_type>(handle) |
310 | {} |
311 | |
312 | /** |
313 | Assignment that releases the last reference. |
314 | */ |
315 | void disposeAndReset(reference_type *pBody) |
316 | { |
317 | if (pBody != this->get()) { |
318 | VclPtr<reference_type>::disposeAndClear(); |
319 | VclPtr<reference_type>::set(pBody); |
320 | } |
321 | } |
322 | |
323 | /** |
324 | Assignment that releases the last reference. |
325 | */ |
326 | ScopedVclPtr<reference_type>& operator = (reference_type * pBody) |
327 | { |
328 | disposeAndReset(pBody); |
329 | return *this; |
330 | } |
331 | |
332 | /** Up-casting conversion constructor: Copies interface reference. |
333 | |
334 | Does not work for up-casts to ambiguous bases. For the special case of |
335 | up-casting to Reference< XInterface >, see the corresponding conversion |
336 | operator. |
337 | |
338 | @param rRef another reference |
339 | */ |
340 | template< class derived_type > |
341 | ScopedVclPtr( |
342 | const VclPtr< derived_type > & rRef, |
343 | typename std::enable_if< |
344 | std::is_base_of<reference_type, derived_type>::value, int>::type |
345 | = 0 ) |
346 | : VclPtr<reference_type>( rRef ) |
347 | { |
348 | } |
349 | |
350 | /** Up-casting assignment operator. |
351 | |
352 | Does not work for up-casts to ambiguous bases. |
353 | |
354 | @param rRef another VclPtr |
355 | */ |
356 | template<typename derived_type> |
357 | typename std::enable_if< |
358 | std::is_base_of<reference_type, derived_type>::value, |
359 | ScopedVclPtr &>::type |
360 | operator =(VclPtr<derived_type> const & rRef) |
361 | { |
362 | disposeAndReset(rRef.get()); |
363 | return *this; |
364 | } |
365 | |
366 | /** |
367 | * Override and disallow this, to prevent people accidentally calling it and actually |
368 | * getting VclPtr::Create and getting a naked VclPtr<> instance |
369 | */ |
370 | template<typename... Arg> static ScopedVclPtr< reference_type > Create(Arg &&... ) = delete; |
371 | |
372 | ~ScopedVclPtr() |
373 | { |
374 | VclPtr<reference_type>::disposeAndClear(); |
375 | assert(VclPtr<reference_type>::get() == nullptr)(static_cast <bool> (VclPtr<reference_type>::get( ) == nullptr) ? void (0) : __assert_fail ("VclPtr<reference_type>::get() == nullptr" , "/home/maarten/src/libreoffice/core/include/vcl/vclptr.hxx" , 375, __extension__ __PRETTY_FUNCTION__)); // make sure there are no lingering references |
376 | } |
377 | |
378 | private: |
379 | // Most likely we don't want this default copy-constructor. |
380 | ScopedVclPtr (const ScopedVclPtr<reference_type> &) = delete; |
381 | // And certainly we don't want a default assignment operator. |
382 | ScopedVclPtr<reference_type>& operator = (const ScopedVclPtr<reference_type> &) = delete; |
383 | // And disallow reset as that doesn't call disposeAndClear on the original reference |
384 | void reset() = delete; |
385 | void reset(reference_type *pBody) = delete; |
386 | |
387 | protected: |
388 | ScopedVclPtr (reference_type * pBody, __sal_NoAcquire) |
389 | : VclPtr<reference_type>(pBody, SAL_NO_ACQUIRE) |
390 | {} |
391 | }; |
392 | |
393 | /** |
394 | * A construction helper for ScopedVclPtr. Since VclPtr types are created |
395 | * with a reference-count of one - to help fit into the existing |
396 | * code-flow; this helps us to construct them easily. |
397 | * |
398 | * For more details on the design please see vcl/README.lifecycle |
399 | * |
400 | * @param reference_type must be a subclass of vcl::Window |
401 | */ |
402 | #if defined _MSC_VER |
403 | #pragma warning(push) |
404 | #pragma warning(disable: 4521) // " multiple copy constructors specified" |
405 | #endif |
406 | template <class reference_type> |
407 | class SAL_WARN_UNUSED__attribute__((warn_unused)) ScopedVclPtrInstance final : public ScopedVclPtr<reference_type> |
408 | { |
409 | public: |
410 | template<typename... Arg> ScopedVclPtrInstance(Arg &&... arg) |
411 | : ScopedVclPtr<reference_type>( new reference_type(std::forward<Arg>(arg)...), SAL_NO_ACQUIRE ) |
412 | { |
413 | } |
414 | |
415 | /** |
416 | * Override and disallow this, to prevent people accidentally calling it and actually |
417 | * getting VclPtr::Create and getting a naked VclPtr<> instance |
418 | */ |
419 | template<typename... Arg> static ScopedVclPtrInstance< reference_type > Create(Arg &&...) = delete; |
420 | |
421 | private: |
422 | // Prevent the above perfect forwarding ctor from hijacking (accidental) |
423 | // attempts at ScopedVclPtrInstance copy construction (where the hijacking |
424 | // would typically lead to somewhat obscure error messages); both non-const |
425 | // and const variants are needed here, as the ScopedVclPtr base class has a |
426 | // const--variant copy ctor, so the implicitly declared copy ctor for |
427 | // ScopedVclPtrInstance would also be the const variant, so non-const copy |
428 | // construction attempts would be hijacked by the perfect forwarding ctor; |
429 | // but if we only declared a non-const variant here, the const variant would |
430 | // no longer be implicitly declared (as there would already be an explicitly |
431 | // declared copy ctor), so const copy construction attempts would then be |
432 | // hijacked by the perfect forwarding ctor: |
433 | ScopedVclPtrInstance(ScopedVclPtrInstance &) = delete; |
434 | ScopedVclPtrInstance(ScopedVclPtrInstance const &) = delete; |
435 | }; |
436 | #if defined _MSC_VER |
437 | #pragma warning(pop) |
438 | #endif |
439 | |
440 | #endif // INCLUDED_VCL_PTR_HXX |
441 | |
442 | /* 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 |