File: | home/maarten/src/libreoffice/core/vcl/source/window/dialog.cxx |
Warning: | line 1512, column 23 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 <config_feature_desktop.h> | |||
21 | ||||
22 | #ifdef IOS | |||
23 | #include <premac.h> | |||
24 | #include <UIKit/UIKit.h> | |||
25 | #include <postmac.h> | |||
26 | #endif | |||
27 | ||||
28 | #include <com/sun/star/frame/theGlobalEventBroadcaster.hpp> | |||
29 | #include <comphelper/lok.hxx> | |||
30 | #include <comphelper/scopeguard.hxx> | |||
31 | #include <comphelper/processfactory.hxx> | |||
32 | #include <officecfg/Office/Common.hxx> | |||
33 | #include <osl/diagnose.h> | |||
34 | ||||
35 | #include <svdata.hxx> | |||
36 | #include <window.h> | |||
37 | #include <brdwin.hxx> | |||
38 | ||||
39 | #include <rtl/bootstrap.hxx> | |||
40 | #include <rtl/strbuf.hxx> | |||
41 | #include <sal/log.hxx> | |||
42 | ||||
43 | #include <vcl/abstdlg.hxx> | |||
44 | #include <vcl/accel.hxx> | |||
45 | #include <vcl/builder.hxx> | |||
46 | #include <vcl/layout.hxx> | |||
47 | #include <vcl/svapp.hxx> | |||
48 | #include <vcl/event.hxx> | |||
49 | #include <vcl/waitobj.hxx> | |||
50 | #include <vcl/wrkwin.hxx> | |||
51 | #include <vcl/toolkit/button.hxx> | |||
52 | #include <vcl/mnemonic.hxx> | |||
53 | #include <vcl/toolkit/dialog.hxx> | |||
54 | #include <vcl/dialoghelper.hxx> | |||
55 | #include <vcl/settings.hxx> | |||
56 | #include <vcl/virdev.hxx> | |||
57 | #include <vcl/weld.hxx> | |||
58 | #include <vcl/uitest/uiobject.hxx> | |||
59 | #include <vcl/uitest/logger.hxx> | |||
60 | #include <vcl/IDialogRenderable.hxx> | |||
61 | #include <messagedialog.hxx> | |||
62 | #include <salframe.hxx> | |||
63 | ||||
64 | #include <iostream> | |||
65 | #include <utility> | |||
66 | ||||
67 | static OString ImplGetDialogText( Dialog* pDialog ) | |||
68 | { | |||
69 | OStringBuffer aErrorStr(OUStringToOString( | |||
70 | pDialog->GetText(), RTL_TEXTENCODING_UTF8(((rtl_TextEncoding) 76)))); | |||
71 | ||||
72 | OUString sMessage; | |||
73 | if (MessageDialog* pMessDialog = dynamic_cast<MessageDialog*>(pDialog)) | |||
74 | { | |||
75 | sMessage = pMessDialog->get_primary_text(); | |||
76 | } | |||
77 | ||||
78 | if (!sMessage.isEmpty()) | |||
79 | { | |||
80 | aErrorStr.append(", "); | |||
81 | aErrorStr.append(OUStringToOString( | |||
82 | sMessage, RTL_TEXTENCODING_UTF8(((rtl_TextEncoding) 76)))); | |||
83 | } | |||
84 | return aErrorStr.makeStringAndClear(); | |||
85 | } | |||
86 | ||||
87 | static bool ImplIsMnemonicCtrl( vcl::Window* pWindow ) | |||
88 | { | |||
89 | if( ! pWindow->GetSettings().GetStyleSettings().GetAutoMnemonic() ) | |||
90 | return false; | |||
91 | ||||
92 | if ( (pWindow->GetType() == WindowType::RADIOBUTTON) || | |||
93 | (pWindow->GetType() == WindowType::CHECKBOX) || | |||
94 | (pWindow->GetType() == WindowType::TRISTATEBOX) || | |||
95 | (pWindow->GetType() == WindowType::PUSHBUTTON) ) | |||
96 | return true; | |||
97 | ||||
98 | if ( pWindow->GetType() == WindowType::FIXEDTEXT ) | |||
99 | { | |||
100 | FixedText *pText = static_cast<FixedText*>(pWindow); | |||
101 | if (pText->get_mnemonic_widget()) | |||
102 | return true; | |||
103 | //This is the legacy pre-layout logic which we retain | |||
104 | //until we can be sure we can remove it | |||
105 | if (pWindow->GetStyle() & WB_NOLABEL) | |||
106 | return false; | |||
107 | vcl::Window* pNextWindow = pWindow->GetWindow( GetWindowType::Next ); | |||
108 | if ( !pNextWindow ) | |||
109 | return false; | |||
110 | pNextWindow = pNextWindow->GetWindow( GetWindowType::Client ); | |||
111 | return !(!(pNextWindow->GetStyle() & WB_TABSTOP) || | |||
112 | (pNextWindow->GetType() == WindowType::FIXEDTEXT) || | |||
113 | (pNextWindow->GetType() == WindowType::GROUPBOX) || | |||
114 | (pNextWindow->GetType() == WindowType::RADIOBUTTON) || | |||
115 | (pNextWindow->GetType() == WindowType::CHECKBOX) || | |||
116 | (pNextWindow->GetType() == WindowType::TRISTATEBOX) || | |||
117 | (pNextWindow->GetType() == WindowType::PUSHBUTTON)); | |||
118 | } | |||
119 | ||||
120 | return false; | |||
121 | } | |||
122 | ||||
123 | // Called by native error dialog popup implementations | |||
124 | void ImplHideSplash() | |||
125 | { | |||
126 | ImplSVData* pSVData = ImplGetSVData(); | |||
127 | if( pSVData->mpIntroWindow ) | |||
128 | pSVData->mpIntroWindow->Hide(); | |||
129 | } | |||
130 | ||||
131 | vcl::Window * nextLogicalChildOfParent(const vcl::Window *pTopLevel, const vcl::Window *pChild) | |||
132 | { | |||
133 | const vcl::Window *pLastChild = pChild; | |||
134 | ||||
135 | if (pChild->GetType() == WindowType::SCROLLWINDOW) | |||
136 | pChild = static_cast<const VclScrolledWindow*>(pChild)->get_child(); | |||
137 | else if (isContainerWindow(*pChild)) | |||
138 | pChild = pChild->GetWindow(GetWindowType::FirstChild); | |||
139 | else | |||
140 | pChild = pChild->GetWindow(GetWindowType::Next); | |||
141 | ||||
142 | while (!pChild) | |||
143 | { | |||
144 | vcl::Window *pParent = pLastChild->GetParent(); | |||
145 | if (!pParent) | |||
146 | return nullptr; | |||
147 | if (pParent == pTopLevel) | |||
148 | return nullptr; | |||
149 | pLastChild = pParent; | |||
150 | pChild = pParent->GetWindow(GetWindowType::Next); | |||
151 | } | |||
152 | ||||
153 | if (isContainerWindow(*pChild)) | |||
154 | pChild = nextLogicalChildOfParent(pTopLevel, pChild); | |||
155 | ||||
156 | return const_cast<vcl::Window *>(pChild); | |||
157 | } | |||
158 | ||||
159 | vcl::Window * prevLogicalChildOfParent(const vcl::Window *pTopLevel, const vcl::Window *pChild) | |||
160 | { | |||
161 | const vcl::Window *pLastChild = pChild; | |||
162 | ||||
163 | if (pChild->GetType() == WindowType::SCROLLWINDOW) | |||
164 | pChild = static_cast<const VclScrolledWindow*>(pChild)->get_child(); | |||
165 | else if (isContainerWindow(*pChild)) | |||
166 | pChild = pChild->GetWindow(GetWindowType::LastChild); | |||
167 | else | |||
168 | pChild = pChild->GetWindow(GetWindowType::Prev); | |||
169 | ||||
170 | while (!pChild) | |||
171 | { | |||
172 | vcl::Window *pParent = pLastChild->GetParent(); | |||
173 | if (!pParent) | |||
174 | return nullptr; | |||
175 | if (pParent == pTopLevel) | |||
176 | return nullptr; | |||
177 | pLastChild = pParent; | |||
178 | pChild = pParent->GetWindow(GetWindowType::Prev); | |||
179 | } | |||
180 | ||||
181 | if (isContainerWindow(*pChild)) | |||
182 | pChild = prevLogicalChildOfParent(pTopLevel, pChild); | |||
183 | ||||
184 | return const_cast<vcl::Window *>(pChild); | |||
185 | } | |||
186 | ||||
187 | vcl::Window * firstLogicalChildOfParent(const vcl::Window *pTopLevel) | |||
188 | { | |||
189 | const vcl::Window *pChild = pTopLevel->GetWindow(GetWindowType::FirstChild); | |||
190 | if (pChild && isContainerWindow(*pChild)) | |||
191 | pChild = nextLogicalChildOfParent(pTopLevel, pChild); | |||
192 | return const_cast<vcl::Window *>(pChild); | |||
193 | } | |||
194 | ||||
195 | vcl::Window * lastLogicalChildOfParent(const vcl::Window *pTopLevel) | |||
196 | { | |||
197 | const vcl::Window *pChild = pTopLevel->GetWindow(GetWindowType::LastChild); | |||
198 | if (pChild && isContainerWindow(*pChild)) | |||
199 | pChild = prevLogicalChildOfParent(pTopLevel, pChild); | |||
200 | return const_cast<vcl::Window *>(pChild); | |||
201 | } | |||
202 | ||||
203 | void Accelerator::GenerateAutoMnemonicsOnHierarchy(const vcl::Window* pWindow) | |||
204 | { | |||
205 | MnemonicGenerator aMnemonicGenerator; | |||
206 | vcl::Window* pGetChild; | |||
207 | vcl::Window* pChild; | |||
208 | ||||
209 | // register the assigned mnemonics | |||
210 | pGetChild = pWindow->GetWindow( GetWindowType::FirstChild ); | |||
211 | while ( pGetChild ) | |||
212 | { | |||
213 | pChild = pGetChild->ImplGetWindow(); | |||
214 | aMnemonicGenerator.RegisterMnemonic( pChild->GetText() ); | |||
215 | pGetChild = nextLogicalChildOfParent(pWindow, pGetChild); | |||
216 | } | |||
217 | ||||
218 | // take the Controls of the dialog into account for TabPages | |||
219 | if ( pWindow->GetType() == WindowType::TABPAGE ) | |||
220 | { | |||
221 | vcl::Window* pParent = pWindow->GetParent(); | |||
222 | if (pParent && pParent->GetType() == WindowType::TABCONTROL ) | |||
223 | pParent = pParent->GetParent(); | |||
224 | ||||
225 | if (pParent && (pParent->GetStyle() & (WB_DIALOGCONTROL | WB_NODIALOGCONTROL)) == WB_DIALOGCONTROL ) | |||
226 | { | |||
227 | pGetChild = pParent->GetWindow( GetWindowType::FirstChild ); | |||
228 | while ( pGetChild ) | |||
229 | { | |||
230 | pChild = pGetChild->ImplGetWindow(); | |||
231 | aMnemonicGenerator.RegisterMnemonic( pChild->GetText() ); | |||
232 | pGetChild = nextLogicalChildOfParent(pWindow, pGetChild); | |||
233 | } | |||
234 | } | |||
235 | } | |||
236 | ||||
237 | // assign mnemonics to Controls which have none | |||
238 | pGetChild = pWindow->GetWindow( GetWindowType::FirstChild ); | |||
239 | while ( pGetChild ) | |||
240 | { | |||
241 | pChild = pGetChild->ImplGetWindow(); | |||
242 | if ( ImplIsMnemonicCtrl( pChild ) ) | |||
243 | { | |||
244 | OUString aText = pChild->GetText(); | |||
245 | OUString aNewText = aMnemonicGenerator.CreateMnemonic( aText ); | |||
246 | if ( aText != aNewText ) | |||
247 | pChild->SetText( aNewText ); | |||
248 | } | |||
249 | ||||
250 | pGetChild = nextLogicalChildOfParent(pWindow, pGetChild); | |||
251 | } | |||
252 | } | |||
253 | ||||
254 | static VclButtonBox* getActionArea(Dialog const *pDialog) | |||
255 | { | |||
256 | VclButtonBox *pButtonBox = nullptr; | |||
257 | if (pDialog->isLayoutEnabled()) | |||
258 | { | |||
259 | vcl::Window *pBox = pDialog->GetWindow(GetWindowType::FirstChild); | |||
260 | vcl::Window *pChild = pBox->GetWindow(GetWindowType::LastChild); | |||
261 | while (pChild) | |||
262 | { | |||
263 | pButtonBox = dynamic_cast<VclButtonBox*>(pChild); | |||
264 | if (pButtonBox) | |||
265 | break; | |||
266 | pChild = pChild->GetWindow(GetWindowType::Prev); | |||
267 | } | |||
268 | } | |||
269 | return pButtonBox; | |||
270 | } | |||
271 | ||||
272 | static vcl::Window* getActionAreaButtonList(Dialog const *pDialog) | |||
273 | { | |||
274 | VclButtonBox* pButtonBox = getActionArea(pDialog); | |||
275 | if (pButtonBox) | |||
276 | return pButtonBox->GetWindow(GetWindowType::FirstChild); | |||
277 | return pDialog->GetWindow(GetWindowType::FirstChild); | |||
278 | } | |||
279 | ||||
280 | static PushButton* ImplGetDefaultButton( Dialog const * pDialog ) | |||
281 | { | |||
282 | vcl::Window* pChild = getActionAreaButtonList(pDialog); | |||
283 | while ( pChild ) | |||
284 | { | |||
285 | if ( pChild->ImplIsPushButton() ) | |||
286 | { | |||
287 | PushButton* pPushButton = static_cast<PushButton*>(pChild); | |||
288 | if ( pPushButton->ImplIsDefButton() ) | |||
289 | return pPushButton; | |||
290 | } | |||
291 | ||||
292 | pChild = pChild->GetWindow( GetWindowType::Next ); | |||
293 | } | |||
294 | ||||
295 | return nullptr; | |||
296 | } | |||
297 | ||||
298 | static PushButton* ImplGetOKButton( Dialog const * pDialog ) | |||
299 | { | |||
300 | vcl::Window* pChild = getActionAreaButtonList(pDialog); | |||
301 | while ( pChild ) | |||
302 | { | |||
303 | if ( pChild->GetType() == WindowType::OKBUTTON ) | |||
304 | return static_cast<PushButton*>(pChild); | |||
305 | ||||
306 | pChild = pChild->GetWindow( GetWindowType::Next ); | |||
307 | } | |||
308 | ||||
309 | return nullptr; | |||
310 | } | |||
311 | ||||
312 | static PushButton* ImplGetCancelButton( Dialog const * pDialog ) | |||
313 | { | |||
314 | vcl::Window* pChild = getActionAreaButtonList(pDialog); | |||
315 | ||||
316 | while ( pChild ) | |||
317 | { | |||
318 | if ( pChild->GetType() == WindowType::CANCELBUTTON ) | |||
319 | return static_cast<PushButton*>(pChild); | |||
320 | ||||
321 | pChild = pChild->GetWindow( GetWindowType::Next ); | |||
322 | } | |||
323 | ||||
324 | return nullptr; | |||
325 | } | |||
326 | ||||
327 | static void ImplMouseAutoPos( Dialog* pDialog ) | |||
328 | { | |||
329 | MouseSettingsOptions nMouseOptions = pDialog->GetSettings().GetMouseSettings().GetOptions(); | |||
330 | if ( nMouseOptions & MouseSettingsOptions::AutoCenterPos ) | |||
331 | { | |||
332 | Size aSize = pDialog->GetOutputSizePixel(); | |||
333 | pDialog->SetPointerPosPixel( Point( aSize.Width()/2, aSize.Height()/2 ) ); | |||
334 | } | |||
335 | else if ( nMouseOptions & MouseSettingsOptions::AutoDefBtnPos ) | |||
336 | { | |||
337 | vcl::Window* pWindow = ImplGetDefaultButton( pDialog ); | |||
338 | if ( !pWindow ) | |||
339 | pWindow = ImplGetOKButton( pDialog ); | |||
340 | if ( !pWindow ) | |||
341 | pWindow = ImplGetCancelButton( pDialog ); | |||
342 | if ( !pWindow ) | |||
343 | pWindow = pDialog; | |||
344 | Size aSize = pWindow->GetOutputSizePixel(); | |||
345 | pWindow->SetPointerPosPixel( Point( aSize.Width()/2, aSize.Height()/2 ) ); | |||
346 | } | |||
347 | } | |||
348 | ||||
349 | struct DialogImpl | |||
350 | { | |||
351 | std::vector<VclPtr<PushButton>> maOwnedButtons; | |||
352 | std::map<VclPtr<vcl::Window>, short> maResponses; | |||
353 | long mnResult; | |||
354 | bool mbStartedModal; | |||
355 | VclAbstractDialog::AsyncContext maEndCtx; | |||
356 | Link<const CommandEvent&, bool> m_aPopupMenuHdl; | |||
357 | Link<void*, vcl::ILibreOfficeKitNotifier*> m_aInstallLOKNotifierHdl; | |||
358 | ||||
359 | DialogImpl() : mnResult( -1 ), mbStartedModal( false ) {} | |||
360 | ||||
361 | #ifndef NDEBUG | |||
362 | short get_response(vcl::Window *pWindow) const | |||
363 | { | |||
364 | auto aFind = maResponses.find(pWindow); | |||
365 | if (aFind != maResponses.end()) | |||
366 | return aFind->second; | |||
367 | return RET_CANCEL; | |||
368 | } | |||
369 | #endif | |||
370 | ||||
371 | ~DialogImpl() | |||
372 | { | |||
373 | for (VclPtr<PushButton> & pOwnedButton : maOwnedButtons) | |||
374 | pOwnedButton.disposeAndClear(); | |||
375 | } | |||
376 | }; | |||
377 | ||||
378 | void Dialog::disposeOwnedButtons() | |||
379 | { | |||
380 | for (VclPtr<PushButton> & pOwnedButton : mpDialogImpl->maOwnedButtons) | |||
381 | pOwnedButton.disposeAndClear(); | |||
382 | } | |||
383 | ||||
384 | void Dialog::ImplInitDialogData() | |||
385 | { | |||
386 | mpWindowImpl->mbDialog = true; | |||
387 | mbInExecute = false; | |||
388 | mbInSyncExecute = false; | |||
389 | mbInClose = false; | |||
390 | mbModalMode = false; | |||
391 | mpContentArea.clear(); | |||
392 | mpActionArea.clear(); | |||
393 | mnMousePositioned = 0; | |||
394 | mpDialogImpl.reset(new DialogImpl); | |||
395 | } | |||
396 | ||||
397 | vcl::Window* Dialog::GetDefaultParent(WinBits nStyle) | |||
398 | { | |||
399 | vcl::Window* pParent = Application::GetDefDialogParent(); | |||
400 | if (!pParent && !(nStyle & WB_SYSTEMWINDOW)) | |||
401 | pParent = ImplGetSVData()->maFrameData.mpAppWin; | |||
402 | ||||
403 | // If Parent is disabled, then we search for a modal dialog | |||
404 | // in this frame | |||
405 | if (pParent && (!pParent->IsInputEnabled() || pParent->IsInModalMode())) | |||
406 | { | |||
407 | ImplSVData* pSVData = ImplGetSVData(); | |||
408 | auto& rExecuteDialogs = pSVData->mpWinData->mpExecuteDialogs; | |||
409 | auto it = std::find_if(rExecuteDialogs.rbegin(), rExecuteDialogs.rend(), | |||
410 | [&pParent](VclPtr<Dialog>& rDialogPtr) { | |||
411 | return pParent->ImplGetFirstOverlapWindow()->IsWindowOrChild(rDialogPtr, true) && | |||
412 | rDialogPtr->IsReallyVisible() && rDialogPtr->IsEnabled() && | |||
413 | rDialogPtr->IsInputEnabled() && !rDialogPtr->IsInModalMode(); }); | |||
414 | if (it != rExecuteDialogs.rend()) | |||
415 | pParent = it->get(); | |||
416 | } | |||
417 | ||||
418 | return pParent; | |||
419 | } | |||
420 | ||||
421 | VclPtr<vcl::Window> Dialog::AddBorderWindow(vcl::Window* pParent, WinBits nStyle) | |||
422 | { | |||
423 | VclPtrInstance<ImplBorderWindow> pBorderWin( pParent, nStyle, BorderWindowStyle::Frame ); | |||
424 | ImplInit( pBorderWin, nStyle & ~WB_BORDER, nullptr ); | |||
425 | pBorderWin->mpWindowImpl->mpClientWindow = this; | |||
426 | pBorderWin->GetBorder( mpWindowImpl->mnLeftBorder, mpWindowImpl->mnTopBorder, mpWindowImpl->mnRightBorder, mpWindowImpl->mnBottomBorder ); | |||
427 | mpWindowImpl->mpBorderWindow = pBorderWin; | |||
428 | mpWindowImpl->mpRealParent = pParent; | |||
429 | ||||
430 | return pBorderWin; | |||
431 | } | |||
432 | ||||
433 | void Dialog::ImplInitDialog( vcl::Window* pParent, WinBits nStyle, InitFlag eFlag ) | |||
434 | { | |||
435 | SystemWindowFlags nSysWinMode = Application::GetSystemWindowMode(); | |||
436 | ||||
437 | if ( !(nStyle & WB_NODIALOGCONTROL) ) | |||
438 | nStyle |= WB_DIALOGCONTROL; | |||
439 | nStyle |= WB_ROLLABLE; | |||
440 | ||||
441 | // Now, all Dialogs are per default system windows !!! | |||
442 | nStyle |= WB_SYSTEMWINDOW; | |||
443 | ||||
444 | if (InitFlag::NoParent == eFlag) | |||
445 | { | |||
446 | pParent = nullptr; | |||
447 | } | |||
448 | else if (!pParent) // parent is NULL: get the default Dialog parent | |||
449 | { | |||
450 | pParent = Dialog::GetDefaultParent(nStyle); | |||
451 | } | |||
452 | ||||
453 | if ( !pParent || (nStyle & WB_SYSTEMWINDOW) || | |||
454 | (pParent->mpWindowImpl->mpFrameData->mbNeedSysWindow && !(nSysWinMode & SystemWindowFlags::NOAUTOMODE)) || | |||
455 | (nSysWinMode & SystemWindowFlags::DIALOG) ) | |||
456 | { | |||
457 | // create window with a small border ? | |||
458 | if ((nStyle & WB_ALLOWMENUBAR) || ((nStyle & (WB_BORDER | WB_NOBORDER | WB_MOVEABLE | WB_SIZEABLE | WB_CLOSEABLE)) == WB_BORDER)) | |||
459 | { | |||
460 | AddBorderWindow(pParent, nStyle); | |||
461 | } | |||
462 | else | |||
463 | { | |||
464 | mpWindowImpl->mbFrame = true; | |||
465 | mpWindowImpl->mbOverlapWin = true; | |||
466 | ImplInit( pParent, (nStyle & (WB_MOVEABLE | WB_SIZEABLE | WB_ROLLABLE | WB_STANDALONE)) | WB_CLOSEABLE, nullptr ); | |||
467 | // Now set all style bits | |||
468 | mpWindowImpl->mnStyle = nStyle; | |||
469 | } | |||
470 | } | |||
471 | else | |||
472 | { | |||
473 | VclPtrInstance<ImplBorderWindow> pBorderWin( pParent, nStyle, BorderWindowStyle::Overlap ); | |||
474 | ImplInit( pBorderWin, nStyle & ~WB_BORDER, nullptr ); | |||
475 | pBorderWin->mpWindowImpl->mpClientWindow = this; | |||
476 | pBorderWin->GetBorder( mpWindowImpl->mnLeftBorder, mpWindowImpl->mnTopBorder, mpWindowImpl->mnRightBorder, mpWindowImpl->mnBottomBorder ); | |||
477 | mpWindowImpl->mpBorderWindow = pBorderWin; | |||
478 | mpWindowImpl->mpRealParent = pParent; | |||
479 | } | |||
480 | ||||
481 | SetActivateMode( ActivateModeFlags::GrabFocus ); | |||
482 | ||||
483 | ImplInitSettings(); | |||
484 | } | |||
485 | ||||
486 | void Dialog::ApplySettings(vcl::RenderContext& rRenderContext) | |||
487 | { | |||
488 | if (IsControlBackground()) | |||
489 | { | |||
490 | // user override | |||
491 | SetBackground(GetControlBackground()); | |||
492 | } | |||
493 | else if (rRenderContext.IsNativeControlSupported(ControlType::WindowBackground, ControlPart::BackgroundDialog)) | |||
494 | { | |||
495 | // NWF background | |||
496 | mpWindowImpl->mnNativeBackground = ControlPart::BackgroundDialog; | |||
497 | EnableChildTransparentMode(); | |||
498 | } | |||
499 | else | |||
500 | { | |||
501 | // fallback to settings color | |||
502 | rRenderContext.SetBackground(GetSettings().GetStyleSettings().GetDialogColor()); | |||
503 | } | |||
504 | } | |||
505 | ||||
506 | void Dialog::ImplInitSettings() | |||
507 | { | |||
508 | // user override | |||
509 | if (IsControlBackground()) | |||
510 | SetBackground(GetControlBackground()); | |||
511 | // NWF background | |||
512 | else if( IsNativeControlSupported(ControlType::WindowBackground, ControlPart::BackgroundDialog)) | |||
513 | { | |||
514 | mpWindowImpl->mnNativeBackground = ControlPart::BackgroundDialog; | |||
515 | EnableChildTransparentMode(); | |||
516 | } | |||
517 | // fallback to settings color | |||
518 | else | |||
519 | SetBackground(GetSettings().GetStyleSettings().GetDialogColor()); | |||
520 | } | |||
521 | ||||
522 | void Dialog::ImplLOKNotifier(vcl::Window* pParent) | |||
523 | { | |||
524 | if (comphelper::LibreOfficeKit::isActive() && pParent) | |||
525 | { | |||
526 | if (VclPtr<vcl::Window> pWin = pParent->GetParentWithLOKNotifier()) | |||
527 | { | |||
528 | SetLOKNotifier(pWin->GetLOKNotifier()); | |||
529 | } | |||
530 | } | |||
531 | } | |||
532 | ||||
533 | Dialog::Dialog( WindowType nType ) | |||
534 | : SystemWindow( nType ) | |||
535 | , mnInitFlag(InitFlag::Default) | |||
536 | { | |||
537 | ImplInitDialogData(); | |||
538 | } | |||
539 | ||||
540 | void VclBuilderContainer::disposeBuilder() | |||
541 | { | |||
542 | if (m_pUIBuilder) | |||
543 | m_pUIBuilder->disposeBuilder(); | |||
544 | } | |||
545 | ||||
546 | OUString AllSettings::GetUIRootDir() | |||
547 | { | |||
548 | OUString sShareLayer("$BRAND_BASE_DIR/$BRAND_SHARE_SUBDIR/config/soffice.cfg/"); | |||
549 | rtl::Bootstrap::expandMacros(sShareLayer); | |||
550 | return sShareLayer; | |||
551 | } | |||
552 | ||||
553 | //we can't change sizeable after the fact, so need to defer until we know and then | |||
554 | //do the init. Find the real parent stashed in mpDialogParent. | |||
555 | void Dialog::doDeferredInit(WinBits nBits) | |||
556 | { | |||
557 | VclPtr<vcl::Window> pParent = mpDialogParent; | |||
558 | mpDialogParent = nullptr; | |||
559 | ImplInitDialog(pParent, nBits | WB_BORDER, mnInitFlag); | |||
560 | mbIsDeferredInit = false; | |||
561 | } | |||
562 | ||||
563 | Dialog::Dialog(vcl::Window* pParent, const OUString& rID, const OUString& rUIXMLDescription) | |||
564 | : SystemWindow(WindowType::DIALOG) | |||
565 | , mnInitFlag(InitFlag::Default) | |||
566 | { | |||
567 | ImplLOKNotifier(pParent); | |||
568 | ImplInitDialogData(); | |||
569 | loadUI(pParent, OUStringToOString(rID, RTL_TEXTENCODING_UTF8(((rtl_TextEncoding) 76))), rUIXMLDescription); | |||
570 | } | |||
571 | ||||
572 | Dialog::Dialog(vcl::Window* pParent, WinBits nStyle, InitFlag eFlag) | |||
573 | : SystemWindow(WindowType::DIALOG) | |||
574 | , mnInitFlag(eFlag) | |||
575 | { | |||
576 | ImplLOKNotifier(pParent); | |||
577 | ImplInitDialogData(); | |||
578 | ImplInitDialog( pParent, nStyle, eFlag ); | |||
579 | } | |||
580 | ||||
581 | void Dialog::set_action_area(VclButtonBox* pBox) | |||
582 | { | |||
583 | mpActionArea.set(pBox); | |||
584 | if (pBox) | |||
585 | { | |||
586 | const DialogStyle& rDialogStyle = | |||
587 | GetSettings().GetStyleSettings().GetDialogStyle(); | |||
588 | pBox->set_border_width(rDialogStyle.action_area_border); | |||
589 | } | |||
590 | } | |||
591 | ||||
592 | void Dialog::set_content_area(VclBox* pBox) | |||
593 | { | |||
594 | mpContentArea.set(pBox); | |||
595 | } | |||
596 | ||||
597 | void Dialog::settingOptimalLayoutSize(Window *pBox) | |||
598 | { | |||
599 | const DialogStyle& rDialogStyle = | |||
600 | GetSettings().GetStyleSettings().GetDialogStyle(); | |||
601 | VclBox * pBox2 = static_cast<VclBox*>(pBox); | |||
602 | pBox2->set_border_width(rDialogStyle.content_area_border); | |||
603 | } | |||
604 | ||||
605 | Dialog::~Dialog() | |||
606 | { | |||
607 | disposeOnce(); | |||
608 | } | |||
609 | ||||
610 | void Dialog::dispose() | |||
611 | { | |||
612 | mpDialogImpl.reset(); | |||
613 | RemoveFromDlgList(); | |||
614 | mpActionArea.clear(); | |||
615 | mpContentArea.clear(); | |||
616 | ||||
617 | css::uno::Reference< css::uno::XComponentContext > xContext( | |||
618 | comphelper::getProcessComponentContext() ); | |||
619 | css::uno::Reference<css::frame::XGlobalEventBroadcaster> xEventBroadcaster(css::frame::theGlobalEventBroadcaster::get(xContext), css::uno::UNO_SET_THROW); | |||
620 | css::document::DocumentEvent aObject; | |||
621 | aObject.EventName = "DialogClosed"; | |||
622 | xEventBroadcaster->documentEventOccured(aObject); | |||
623 | UITestLogger::getInstance().log("Close Dialog"); | |||
624 | ||||
625 | if (comphelper::LibreOfficeKit::isActive()) | |||
626 | { | |||
627 | if(const vcl::ILibreOfficeKitNotifier* pNotifier = GetLOKNotifier()) | |||
628 | { | |||
629 | pNotifier->notifyWindow(GetLOKWindowId(), "close"); | |||
630 | ReleaseLOKNotifier(); | |||
631 | } | |||
632 | } | |||
633 | ||||
634 | SystemWindow::dispose(); | |||
635 | } | |||
636 | ||||
637 | IMPL_LINK_NOARG(Dialog, ImplAsyncCloseHdl, void*, void)void Dialog::LinkStubImplAsyncCloseHdl(void * instance, void* data) { return static_cast<Dialog *>(instance)->ImplAsyncCloseHdl (data); } void Dialog::ImplAsyncCloseHdl(__attribute__ ((unused )) void*) | |||
638 | { | |||
639 | Close(); | |||
640 | } | |||
641 | ||||
642 | bool Dialog::EventNotify( NotifyEvent& rNEvt ) | |||
643 | { | |||
644 | // first call the base class due to Tab control | |||
645 | bool bRet = SystemWindow::EventNotify( rNEvt ); | |||
646 | if ( !bRet ) | |||
647 | { | |||
648 | if ( rNEvt.GetType() == MouseNotifyEvent::KEYINPUT ) | |||
649 | { | |||
650 | const KeyEvent* pKEvt = rNEvt.GetKeyEvent(); | |||
651 | vcl::KeyCode aKeyCode = pKEvt->GetKeyCode(); | |||
652 | sal_uInt16 nKeyCode = aKeyCode.GetCode(); | |||
653 | ||||
654 | if ( (nKeyCode == KEY_ESCAPE) && | |||
655 | ((GetStyle() & WB_CLOSEABLE) || ImplGetCancelButton( this ) || ImplGetOKButton( this )) ) | |||
656 | { | |||
657 | // #i89505# for the benefit of slightly mentally challenged implementations | |||
658 | // like e.g. SfxModelessDialog which destroy themselves inside Close() | |||
659 | // post this Close asynchronous so we can leave our key handler before | |||
660 | // we get destroyed | |||
661 | PostUserEvent( LINK( this, Dialog, ImplAsyncCloseHdl )::tools::detail::makeLink( ::tools::detail::castTo<Dialog * >(this), &Dialog::LinkStubImplAsyncCloseHdl), nullptr, true); | |||
662 | return true; | |||
663 | } | |||
664 | } | |||
665 | else if ( rNEvt.GetType() == MouseNotifyEvent::GETFOCUS ) | |||
666 | { | |||
667 | // make sure the dialog is still modal | |||
668 | // changing focus between application frames may | |||
669 | // have re-enabled input for our parent | |||
670 | if( mbInExecute && mbModalMode ) | |||
671 | { | |||
672 | ImplSetModalInputMode( false ); | |||
673 | ImplSetModalInputMode( true ); | |||
674 | ||||
675 | // #93022# def-button might have changed after show | |||
676 | if( !mnMousePositioned ) | |||
677 | { | |||
678 | mnMousePositioned = 1; | |||
679 | ImplMouseAutoPos( this ); | |||
680 | } | |||
681 | ||||
682 | } | |||
683 | } | |||
684 | } | |||
685 | ||||
686 | return bRet; | |||
687 | } | |||
688 | ||||
689 | //What we really want here is something that gives the available width and | |||
690 | //height of a users screen, taking away the space taken up the OS | |||
691 | //taskbar, menus, etc. | |||
692 | Size bestmaxFrameSizeForScreenSize(const Size &rScreenSize) | |||
693 | { | |||
694 | #ifndef IOS | |||
695 | long w = rScreenSize.Width(); | |||
696 | if (w <= 800) | |||
697 | w -= 15; | |||
698 | else if (w <= 1024) | |||
699 | w -= 65; | |||
700 | else | |||
701 | w -= 115; | |||
702 | ||||
703 | long h = rScreenSize.Height(); | |||
704 | if (h <= 768) | |||
705 | h -= 50; | |||
706 | else | |||
707 | h -= 100; | |||
708 | ||||
709 | return Size(std::max<long>(w, 640 - 15), | |||
710 | std::max<long>(h, 480 - 50)); | |||
711 | #else | |||
712 | // Don't bother with ancient magic numbers of unclear relevance on non-desktop apps anyway. It | |||
713 | // seems that at least currently in the iOS app, this function is called just once per dialog, | |||
714 | // with a rScreenSize parameter of 1x1 (!). This would lead to always returning 625x430 which is | |||
715 | // a bit random and needlessly small on an iPad at least. We want something that closely will | |||
716 | // just fit on the display in either orientation. | |||
717 | ||||
718 | // We ignore the rScreenSize as it will be the dummy 1x1 from iosinst.cxx (see "Totally wrong of course"). | |||
719 | (void) rScreenSize; | |||
720 | ||||
721 | const int n = std::min<CGFloat>([[UIScreen mainScreen] bounds].size.width, [[UIScreen mainScreen] bounds].size.height); | |||
722 | return Size(n-10, n-10); | |||
723 | #endif | |||
724 | } | |||
725 | ||||
726 | void Dialog::SetPopupMenuHdl(const Link<const CommandEvent&, bool>& rLink) | |||
727 | { | |||
728 | mpDialogImpl->m_aPopupMenuHdl = rLink; | |||
729 | } | |||
730 | ||||
731 | void Dialog::SetInstallLOKNotifierHdl(const Link<void*, vcl::ILibreOfficeKitNotifier*>& rLink) | |||
732 | { | |||
733 | mpDialogImpl->m_aInstallLOKNotifierHdl = rLink; | |||
734 | } | |||
735 | ||||
736 | void Dialog::StateChanged( StateChangedType nType ) | |||
737 | { | |||
738 | if (nType == StateChangedType::InitShow) | |||
739 | { | |||
740 | DoInitialLayout(); | |||
741 | ||||
742 | const bool bKitActive = comphelper::LibreOfficeKit::isActive(); | |||
743 | if (bKitActive) | |||
744 | { | |||
745 | std::vector<vcl::LOKPayloadItem> aItems; | |||
746 | aItems.emplace_back("type", "dialog"); | |||
747 | aItems.emplace_back("size", GetSizePixel().toString()); | |||
748 | if (!GetText().isEmpty()) | |||
749 | aItems.emplace_back("title", GetText().toUtf8()); | |||
750 | ||||
751 | if (const vcl::ILibreOfficeKitNotifier* pNotifier = GetLOKNotifier()) | |||
752 | { | |||
753 | pNotifier->notifyWindow(GetLOKWindowId(), "created", aItems); | |||
754 | pNotifier->notifyWindow(GetLOKWindowId(), "created", aItems); | |||
755 | } | |||
756 | else | |||
757 | { | |||
758 | vcl::ILibreOfficeKitNotifier* pViewShell = mpDialogImpl->m_aInstallLOKNotifierHdl.Call(nullptr); | |||
759 | if (pViewShell) | |||
760 | { | |||
761 | SetLOKNotifier(pViewShell); | |||
762 | pViewShell->notifyWindow(GetLOKWindowId(), "created", aItems); | |||
763 | } | |||
764 | } | |||
765 | } | |||
766 | ||||
767 | if ( !HasChildPathFocus() || HasFocus() ) | |||
768 | GrabFocusToFirstControl(); | |||
769 | if ( !(GetStyle() & WB_CLOSEABLE) ) | |||
770 | { | |||
771 | if ( ImplGetCancelButton( this ) || ImplGetOKButton( this ) ) | |||
772 | { | |||
773 | if ( ImplGetBorderWindow() ) | |||
774 | static_cast<ImplBorderWindow*>(ImplGetBorderWindow())->SetCloseButton(); | |||
775 | } | |||
776 | } | |||
777 | ||||
778 | ImplMouseAutoPos( this ); | |||
779 | } | |||
780 | else if (nType == StateChangedType::Text) | |||
781 | { | |||
782 | if (const vcl::ILibreOfficeKitNotifier* pNotifier = GetLOKNotifier()) | |||
783 | { | |||
784 | std::vector<vcl::LOKPayloadItem> aPayload; | |||
785 | aPayload.emplace_back("title", GetText().toUtf8()); | |||
786 | pNotifier->notifyWindow(GetLOKWindowId(), "title_changed", aPayload); | |||
787 | } | |||
788 | } | |||
789 | ||||
790 | SystemWindow::StateChanged( nType ); | |||
791 | ||||
792 | if (nType == StateChangedType::ControlBackground) | |||
793 | { | |||
794 | ImplInitSettings(); | |||
795 | Invalidate(); | |||
796 | } | |||
797 | ||||
798 | if (!mbModalMode && nType == StateChangedType::Visible) | |||
799 | { | |||
800 | if (const vcl::ILibreOfficeKitNotifier* pNotifier = GetLOKNotifier()) | |||
801 | { | |||
802 | std::vector<vcl::LOKPayloadItem> aPayload; | |||
803 | aPayload.emplace_back("title", GetText().toUtf8()); | |||
804 | pNotifier->notifyWindow(GetLOKWindowId(), IsVisible()? OUString("show"): OUString("hide"), aPayload); | |||
805 | } | |||
806 | } | |||
807 | } | |||
808 | ||||
809 | void Dialog::DataChanged( const DataChangedEvent& rDCEvt ) | |||
810 | { | |||
811 | SystemWindow::DataChanged( rDCEvt ); | |||
812 | ||||
813 | if ( (rDCEvt.GetType() == DataChangedEventType::SETTINGS) && | |||
814 | (rDCEvt.GetFlags() & AllSettingsFlags::STYLE) ) | |||
815 | { | |||
816 | ImplInitSettings(); | |||
817 | Invalidate(); | |||
818 | } | |||
819 | } | |||
820 | ||||
821 | bool Dialog::Close() | |||
822 | { | |||
823 | VclPtr<vcl::Window> xWindow = this; | |||
824 | CallEventListeners( VclEventId::WindowClose ); | |||
825 | if ( xWindow->IsDisposed() ) | |||
826 | return false; | |||
827 | ||||
828 | if ( mpWindowImpl->mxWindowPeer.is() && IsCreatedWithToolkit() && !IsInExecute() ) | |||
829 | return false; | |||
830 | ||||
831 | // If there's a cancel button with a custom handler, then always give it a chance to | |||
832 | // handle Dialog::Close | |||
833 | PushButton* pCustomCancelButton; | |||
834 | PushButton* pCancelButton = dynamic_cast<PushButton*>(get_widget_for_response(RET_CANCEL)); | |||
835 | if (!mbInClose && pCancelButton && pCancelButton->GetClickHdl().IsSet()) | |||
836 | pCustomCancelButton = pCancelButton; | |||
837 | else | |||
838 | pCustomCancelButton = nullptr; | |||
839 | ||||
840 | mbInClose = true; | |||
841 | ||||
842 | if (pCustomCancelButton) | |||
843 | { | |||
844 | pCustomCancelButton->Click(); | |||
845 | if (xWindow->IsDisposed()) | |||
846 | return true; | |||
847 | mbInClose = false; | |||
848 | return false; | |||
849 | } | |||
850 | ||||
851 | if ( !(GetStyle() & WB_CLOSEABLE) ) | |||
852 | { | |||
853 | bool bRet = true; | |||
854 | PushButton* pButton = ImplGetCancelButton( this ); | |||
855 | if ( pButton ) | |||
856 | pButton->Click(); | |||
857 | else | |||
858 | { | |||
859 | pButton = ImplGetOKButton( this ); | |||
860 | if ( pButton ) | |||
861 | pButton->Click(); | |||
862 | else | |||
863 | bRet = false; | |||
864 | } | |||
865 | if ( xWindow->IsDisposed() ) | |||
866 | return true; | |||
867 | return bRet; | |||
868 | } | |||
869 | ||||
870 | if (IsInExecute() || mpDialogImpl->maEndCtx.isSet()) | |||
871 | { | |||
872 | EndDialog(); | |||
873 | mbInClose = false; | |||
874 | return true; | |||
875 | } | |||
876 | else | |||
877 | { | |||
878 | mbInClose = false; | |||
879 | return SystemWindow::Close(); | |||
880 | } | |||
881 | } | |||
882 | ||||
883 | bool Dialog::ImplStartExecute() | |||
884 | { | |||
885 | setDeferredProperties(); | |||
886 | ||||
887 | if (IsInExecute() || mpDialogImpl->maEndCtx.isSet()) | |||
888 | { | |||
889 | #ifdef DBG_UTIL | |||
890 | SAL_WARN( "vcl", "Dialog::StartExecuteModal() is called in Dialog::StartExecuteModal(): "do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN , "vcl")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "Dialog::StartExecuteModal() is called in Dialog::StartExecuteModal(): " << ImplGetDialogText(this)) == 1) { ::sal_detail_log( ( ::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl"), ("/home/maarten/src/libreoffice/core/vcl/source/window/dialog.cxx" ":" "891" ": "), ::sal::detail::unwrapStream( ::sal::detail:: StreamStart() << "Dialog::StartExecuteModal() is called in Dialog::StartExecuteModal(): " << ImplGetDialogText(this)), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "Dialog::StartExecuteModal() is called in Dialog::StartExecuteModal(): " << ImplGetDialogText(this); ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("vcl"), ("/home/maarten/src/libreoffice/core/vcl/source/window/dialog.cxx" ":" "891" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "Dialog::StartExecuteModal() is called in Dialog::StartExecuteModal(): " << ImplGetDialogText(this)) == 1) { ::sal_detail_log( ( ::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl"), ("/home/maarten/src/libreoffice/core/vcl/source/window/dialog.cxx" ":" "891" ": "), ::sal::detail::unwrapStream( ::sal::detail:: StreamStart() << "Dialog::StartExecuteModal() is called in Dialog::StartExecuteModal(): " << ImplGetDialogText(this)), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "Dialog::StartExecuteModal() is called in Dialog::StartExecuteModal(): " << ImplGetDialogText(this); ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("vcl"), ("/home/maarten/src/libreoffice/core/vcl/source/window/dialog.cxx" ":" "891" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false) | |||
891 | << ImplGetDialogText(this) )do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN , "vcl")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "Dialog::StartExecuteModal() is called in Dialog::StartExecuteModal(): " << ImplGetDialogText(this)) == 1) { ::sal_detail_log( ( ::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl"), ("/home/maarten/src/libreoffice/core/vcl/source/window/dialog.cxx" ":" "891" ": "), ::sal::detail::unwrapStream( ::sal::detail:: StreamStart() << "Dialog::StartExecuteModal() is called in Dialog::StartExecuteModal(): " << ImplGetDialogText(this)), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "Dialog::StartExecuteModal() is called in Dialog::StartExecuteModal(): " << ImplGetDialogText(this); ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("vcl"), ("/home/maarten/src/libreoffice/core/vcl/source/window/dialog.cxx" ":" "891" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "Dialog::StartExecuteModal() is called in Dialog::StartExecuteModal(): " << ImplGetDialogText(this)) == 1) { ::sal_detail_log( ( ::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl"), ("/home/maarten/src/libreoffice/core/vcl/source/window/dialog.cxx" ":" "891" ": "), ::sal::detail::unwrapStream( ::sal::detail:: StreamStart() << "Dialog::StartExecuteModal() is called in Dialog::StartExecuteModal(): " << ImplGetDialogText(this)), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "Dialog::StartExecuteModal() is called in Dialog::StartExecuteModal(): " << ImplGetDialogText(this); ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN ), ("vcl"), ("/home/maarten/src/libreoffice/core/vcl/source/window/dialog.cxx" ":" "891" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | |||
892 | #endif | |||
893 | return false; | |||
894 | } | |||
895 | ||||
896 | ImplSVData* pSVData = ImplGetSVData(); | |||
897 | ||||
898 | const bool bKitActive = comphelper::LibreOfficeKit::isActive(); | |||
899 | ||||
900 | const bool bModal = GetType() != WindowType::MODELESSDIALOG; | |||
901 | ||||
902 | if (bModal) | |||
903 | { | |||
904 | if (bKitActive && !GetLOKNotifier()) | |||
905 | SetLOKNotifier(mpDialogImpl->m_aInstallLOKNotifierHdl.Call(nullptr)); | |||
906 | ||||
907 | switch ( Application::GetDialogCancelMode() ) | |||
908 | { | |||
909 | case DialogCancelMode::Off: | |||
910 | break; | |||
911 | case DialogCancelMode::Silent: | |||
912 | if (bModal && GetLOKNotifier()) | |||
913 | { | |||
914 | // check if there's already some dialog being ::Execute()d | |||
915 | const bool bDialogExecuting = std::any_of(pSVData->mpWinData->mpExecuteDialogs.begin(), | |||
916 | pSVData->mpWinData->mpExecuteDialogs.end(), | |||
917 | [](const Dialog* pDialog) { | |||
918 | return pDialog->IsInSyncExecute(); | |||
919 | }); | |||
920 | if (!(bDialogExecuting && IsInSyncExecute())) | |||
921 | break; | |||
922 | else | |||
923 | SAL_WARN("lok.dialog", "Dialog \"" << ImplGetDialogText(this) << "\" is being synchronously executed over an existing synchronously executing dialog.")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN , "lok.dialog")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "Dialog \"" << ImplGetDialogText (this) << "\" is being synchronously executed over an existing synchronously executing dialog." ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("lok.dialog" ), ("/home/maarten/src/libreoffice/core/vcl/source/window/dialog.cxx" ":" "923" ": "), ::sal::detail::unwrapStream( ::sal::detail:: StreamStart() << "Dialog \"" << ImplGetDialogText (this) << "\" is being synchronously executed over an existing synchronously executing dialog." ), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "Dialog \"" << ImplGetDialogText(this) << "\" is being synchronously executed over an existing synchronously executing dialog." ; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("lok.dialog" ), ("/home/maarten/src/libreoffice/core/vcl/source/window/dialog.cxx" ":" "923" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "Dialog \"" << ImplGetDialogText(this) << "\" is being synchronously executed over an existing synchronously executing dialog." ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("lok.dialog" ), ("/home/maarten/src/libreoffice/core/vcl/source/window/dialog.cxx" ":" "923" ": "), ::sal::detail::unwrapStream( ::sal::detail:: StreamStart() << "Dialog \"" << ImplGetDialogText (this) << "\" is being synchronously executed over an existing synchronously executing dialog." ), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "Dialog \"" << ImplGetDialogText(this) << "\" is being synchronously executed over an existing synchronously executing dialog." ; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("lok.dialog" ), ("/home/maarten/src/libreoffice/core/vcl/source/window/dialog.cxx" ":" "923" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | |||
924 | } | |||
925 | ||||
926 | SAL_INFO(do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO , "vcl")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "Dialog \"" << ImplGetDialogText(this) << "\"cancelled in silent mode") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO ), ("vcl"), ("/home/maarten/src/libreoffice/core/vcl/source/window/dialog.cxx" ":" "929" ": "), ::sal::detail::unwrapStream( ::sal::detail:: StreamStart() << "Dialog \"" << ImplGetDialogText (this) << "\"cancelled in silent mode"), 0); } else { :: std::ostringstream sal_detail_stream; sal_detail_stream << "Dialog \"" << ImplGetDialogText(this) << "\"cancelled in silent mode" ; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("vcl"), ("/home/maarten/src/libreoffice/core/vcl/source/window/dialog.cxx" ":" "929" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "Dialog \"" << ImplGetDialogText(this) << "\"cancelled in silent mode") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO ), ("vcl"), ("/home/maarten/src/libreoffice/core/vcl/source/window/dialog.cxx" ":" "929" ": "), ::sal::detail::unwrapStream( ::sal::detail:: StreamStart() << "Dialog \"" << ImplGetDialogText (this) << "\"cancelled in silent mode"), 0); } else { :: std::ostringstream sal_detail_stream; sal_detail_stream << "Dialog \"" << ImplGetDialogText(this) << "\"cancelled in silent mode" ; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("vcl"), ("/home/maarten/src/libreoffice/core/vcl/source/window/dialog.cxx" ":" "929" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false) | |||
927 | "vcl",do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO , "vcl")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "Dialog \"" << ImplGetDialogText(this) << "\"cancelled in silent mode") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO ), ("vcl"), ("/home/maarten/src/libreoffice/core/vcl/source/window/dialog.cxx" ":" "929" ": "), ::sal::detail::unwrapStream( ::sal::detail:: StreamStart() << "Dialog \"" << ImplGetDialogText (this) << "\"cancelled in silent mode"), 0); } else { :: std::ostringstream sal_detail_stream; sal_detail_stream << "Dialog \"" << ImplGetDialogText(this) << "\"cancelled in silent mode" ; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("vcl"), ("/home/maarten/src/libreoffice/core/vcl/source/window/dialog.cxx" ":" "929" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "Dialog \"" << ImplGetDialogText(this) << "\"cancelled in silent mode") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO ), ("vcl"), ("/home/maarten/src/libreoffice/core/vcl/source/window/dialog.cxx" ":" "929" ": "), ::sal::detail::unwrapStream( ::sal::detail:: StreamStart() << "Dialog \"" << ImplGetDialogText (this) << "\"cancelled in silent mode"), 0); } else { :: std::ostringstream sal_detail_stream; sal_detail_stream << "Dialog \"" << ImplGetDialogText(this) << "\"cancelled in silent mode" ; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("vcl"), ("/home/maarten/src/libreoffice/core/vcl/source/window/dialog.cxx" ":" "929" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false) | |||
928 | "Dialog \"" << ImplGetDialogText(this)do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO , "vcl")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "Dialog \"" << ImplGetDialogText(this) << "\"cancelled in silent mode") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO ), ("vcl"), ("/home/maarten/src/libreoffice/core/vcl/source/window/dialog.cxx" ":" "929" ": "), ::sal::detail::unwrapStream( ::sal::detail:: StreamStart() << "Dialog \"" << ImplGetDialogText (this) << "\"cancelled in silent mode"), 0); } else { :: std::ostringstream sal_detail_stream; sal_detail_stream << "Dialog \"" << ImplGetDialogText(this) << "\"cancelled in silent mode" ; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("vcl"), ("/home/maarten/src/libreoffice/core/vcl/source/window/dialog.cxx" ":" "929" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "Dialog \"" << ImplGetDialogText(this) << "\"cancelled in silent mode") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO ), ("vcl"), ("/home/maarten/src/libreoffice/core/vcl/source/window/dialog.cxx" ":" "929" ": "), ::sal::detail::unwrapStream( ::sal::detail:: StreamStart() << "Dialog \"" << ImplGetDialogText (this) << "\"cancelled in silent mode"), 0); } else { :: std::ostringstream sal_detail_stream; sal_detail_stream << "Dialog \"" << ImplGetDialogText(this) << "\"cancelled in silent mode" ; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("vcl"), ("/home/maarten/src/libreoffice/core/vcl/source/window/dialog.cxx" ":" "929" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false) | |||
929 | << "\"cancelled in silent mode")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_INFO , "vcl")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "Dialog \"" << ImplGetDialogText(this) << "\"cancelled in silent mode") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO ), ("vcl"), ("/home/maarten/src/libreoffice/core/vcl/source/window/dialog.cxx" ":" "929" ": "), ::sal::detail::unwrapStream( ::sal::detail:: StreamStart() << "Dialog \"" << ImplGetDialogText (this) << "\"cancelled in silent mode"), 0); } else { :: std::ostringstream sal_detail_stream; sal_detail_stream << "Dialog \"" << ImplGetDialogText(this) << "\"cancelled in silent mode" ; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("vcl"), ("/home/maarten/src/libreoffice/core/vcl/source/window/dialog.cxx" ":" "929" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "Dialog \"" << ImplGetDialogText(this) << "\"cancelled in silent mode") == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_INFO ), ("vcl"), ("/home/maarten/src/libreoffice/core/vcl/source/window/dialog.cxx" ":" "929" ": "), ::sal::detail::unwrapStream( ::sal::detail:: StreamStart() << "Dialog \"" << ImplGetDialogText (this) << "\"cancelled in silent mode"), 0); } else { :: std::ostringstream sal_detail_stream; sal_detail_stream << "Dialog \"" << ImplGetDialogText(this) << "\"cancelled in silent mode" ; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_INFO), ("vcl"), ("/home/maarten/src/libreoffice/core/vcl/source/window/dialog.cxx" ":" "929" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | |||
930 | return false; | |||
931 | default: // default cannot happen | |||
932 | case DialogCancelMode::Fatal: | |||
933 | std::abort(); | |||
934 | } | |||
935 | ||||
936 | #ifdef DBG_UTIL | |||
937 | vcl::Window* pParent = GetParent(); | |||
938 | if ( pParent ) | |||
939 | { | |||
940 | pParent = pParent->ImplGetFirstOverlapWindow(); | |||
941 | SAL_WARN_IF( !pParent->IsReallyVisible(), "vcl",do { if (true && (!pParent->IsReallyVisible())) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN, "vcl")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "Dialog::StartExecuteModal() - Parent not visible" ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl" ), ("/home/maarten/src/libreoffice/core/vcl/source/window/dialog.cxx" ":" "942" ": "), ::sal::detail::unwrapStream( ::sal::detail:: StreamStart() << "Dialog::StartExecuteModal() - Parent not visible" ), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "Dialog::StartExecuteModal() - Parent not visible"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl"), ( "/home/maarten/src/libreoffice/core/vcl/source/window/dialog.cxx" ":" "942" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "Dialog::StartExecuteModal() - Parent not visible" ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl" ), ("/home/maarten/src/libreoffice/core/vcl/source/window/dialog.cxx" ":" "942" ": "), ::sal::detail::unwrapStream( ::sal::detail:: StreamStart() << "Dialog::StartExecuteModal() - Parent not visible" ), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "Dialog::StartExecuteModal() - Parent not visible"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl"), ( "/home/maarten/src/libreoffice/core/vcl/source/window/dialog.cxx" ":" "942" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false) | |||
942 | "Dialog::StartExecuteModal() - Parent not visible" )do { if (true && (!pParent->IsReallyVisible())) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN, "vcl")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "Dialog::StartExecuteModal() - Parent not visible" ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl" ), ("/home/maarten/src/libreoffice/core/vcl/source/window/dialog.cxx" ":" "942" ": "), ::sal::detail::unwrapStream( ::sal::detail:: StreamStart() << "Dialog::StartExecuteModal() - Parent not visible" ), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "Dialog::StartExecuteModal() - Parent not visible"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl"), ( "/home/maarten/src/libreoffice/core/vcl/source/window/dialog.cxx" ":" "942" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "Dialog::StartExecuteModal() - Parent not visible" ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl" ), ("/home/maarten/src/libreoffice/core/vcl/source/window/dialog.cxx" ":" "942" ": "), ::sal::detail::unwrapStream( ::sal::detail:: StreamStart() << "Dialog::StartExecuteModal() - Parent not visible" ), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "Dialog::StartExecuteModal() - Parent not visible"; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl"), ( "/home/maarten/src/libreoffice/core/vcl/source/window/dialog.cxx" ":" "942" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | |||
943 | SAL_WARN_IF( !pParent->IsInputEnabled(), "vcl",do { if (true && (!pParent->IsInputEnabled())) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN, "vcl")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "Dialog::StartExecuteModal() - Parent input disabled, use another parent to ensure modality!" ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl" ), ("/home/maarten/src/libreoffice/core/vcl/source/window/dialog.cxx" ":" "944" ": "), ::sal::detail::unwrapStream( ::sal::detail:: StreamStart() << "Dialog::StartExecuteModal() - Parent input disabled, use another parent to ensure modality!" ), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "Dialog::StartExecuteModal() - Parent input disabled, use another parent to ensure modality!" ; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl"), ("/home/maarten/src/libreoffice/core/vcl/source/window/dialog.cxx" ":" "944" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "Dialog::StartExecuteModal() - Parent input disabled, use another parent to ensure modality!" ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl" ), ("/home/maarten/src/libreoffice/core/vcl/source/window/dialog.cxx" ":" "944" ": "), ::sal::detail::unwrapStream( ::sal::detail:: StreamStart() << "Dialog::StartExecuteModal() - Parent input disabled, use another parent to ensure modality!" ), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "Dialog::StartExecuteModal() - Parent input disabled, use another parent to ensure modality!" ; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl"), ("/home/maarten/src/libreoffice/core/vcl/source/window/dialog.cxx" ":" "944" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false) | |||
944 | "Dialog::StartExecuteModal() - Parent input disabled, use another parent to ensure modality!" )do { if (true && (!pParent->IsInputEnabled())) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN, "vcl")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "Dialog::StartExecuteModal() - Parent input disabled, use another parent to ensure modality!" ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl" ), ("/home/maarten/src/libreoffice/core/vcl/source/window/dialog.cxx" ":" "944" ": "), ::sal::detail::unwrapStream( ::sal::detail:: StreamStart() << "Dialog::StartExecuteModal() - Parent input disabled, use another parent to ensure modality!" ), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "Dialog::StartExecuteModal() - Parent input disabled, use another parent to ensure modality!" ; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl"), ("/home/maarten/src/libreoffice/core/vcl/source/window/dialog.cxx" ":" "944" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "Dialog::StartExecuteModal() - Parent input disabled, use another parent to ensure modality!" ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl" ), ("/home/maarten/src/libreoffice/core/vcl/source/window/dialog.cxx" ":" "944" ": "), ::sal::detail::unwrapStream( ::sal::detail:: StreamStart() << "Dialog::StartExecuteModal() - Parent input disabled, use another parent to ensure modality!" ), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "Dialog::StartExecuteModal() - Parent input disabled, use another parent to ensure modality!" ; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl"), ("/home/maarten/src/libreoffice/core/vcl/source/window/dialog.cxx" ":" "944" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | |||
945 | SAL_WARN_IF( pParent->IsInModalMode(), "vcl",do { if (true && (pParent->IsInModalMode())) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN, "vcl")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "Dialog::StartExecuteModal() - Parent already modally disabled, use another parent to ensure modality!" ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl" ), ("/home/maarten/src/libreoffice/core/vcl/source/window/dialog.cxx" ":" "946" ": "), ::sal::detail::unwrapStream( ::sal::detail:: StreamStart() << "Dialog::StartExecuteModal() - Parent already modally disabled, use another parent to ensure modality!" ), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "Dialog::StartExecuteModal() - Parent already modally disabled, use another parent to ensure modality!" ; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl"), ("/home/maarten/src/libreoffice/core/vcl/source/window/dialog.cxx" ":" "946" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "Dialog::StartExecuteModal() - Parent already modally disabled, use another parent to ensure modality!" ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl" ), ("/home/maarten/src/libreoffice/core/vcl/source/window/dialog.cxx" ":" "946" ": "), ::sal::detail::unwrapStream( ::sal::detail:: StreamStart() << "Dialog::StartExecuteModal() - Parent already modally disabled, use another parent to ensure modality!" ), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "Dialog::StartExecuteModal() - Parent already modally disabled, use another parent to ensure modality!" ; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl"), ("/home/maarten/src/libreoffice/core/vcl/source/window/dialog.cxx" ":" "946" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false) | |||
946 | "Dialog::StartExecuteModal() - Parent already modally disabled, use another parent to ensure modality!" )do { if (true && (pParent->IsInModalMode())) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN, "vcl")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "Dialog::StartExecuteModal() - Parent already modally disabled, use another parent to ensure modality!" ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl" ), ("/home/maarten/src/libreoffice/core/vcl/source/window/dialog.cxx" ":" "946" ": "), ::sal::detail::unwrapStream( ::sal::detail:: StreamStart() << "Dialog::StartExecuteModal() - Parent already modally disabled, use another parent to ensure modality!" ), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "Dialog::StartExecuteModal() - Parent already modally disabled, use another parent to ensure modality!" ; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl"), ("/home/maarten/src/libreoffice/core/vcl/source/window/dialog.cxx" ":" "946" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "Dialog::StartExecuteModal() - Parent already modally disabled, use another parent to ensure modality!" ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl" ), ("/home/maarten/src/libreoffice/core/vcl/source/window/dialog.cxx" ":" "946" ": "), ::sal::detail::unwrapStream( ::sal::detail:: StreamStart() << "Dialog::StartExecuteModal() - Parent already modally disabled, use another parent to ensure modality!" ), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "Dialog::StartExecuteModal() - Parent already modally disabled, use another parent to ensure modality!" ; ::sal::detail::log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl"), ("/home/maarten/src/libreoffice/core/vcl/source/window/dialog.cxx" ":" "946" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | |||
947 | } | |||
948 | #endif | |||
949 | ||||
950 | // link all dialogs which are being executed | |||
951 | pSVData->mpWinData->mpExecuteDialogs.push_back(this); | |||
952 | ||||
953 | // stop capturing, in order to have control over the dialog | |||
954 | if (pSVData->mpWinData->mpTrackWin) | |||
955 | pSVData->mpWinData->mpTrackWin->EndTracking(TrackingEventFlags::Cancel); | |||
956 | if (pSVData->mpWinData->mpCaptureWin) | |||
957 | pSVData->mpWinData->mpCaptureWin->ReleaseMouse(); | |||
958 | EnableInput(); | |||
959 | } | |||
960 | ||||
961 | mbInExecute = true; | |||
962 | // no real modality in LibreOfficeKit | |||
963 | if (!bKitActive && bModal) | |||
964 | SetModalInputMode(true); | |||
965 | ||||
966 | // FIXME: no layouting, workaround some clipping issues | |||
967 | ImplAdjustNWFSizes(); | |||
968 | ||||
969 | css::uno::Reference< css::uno::XComponentContext > xContext( | |||
970 | comphelper::getProcessComponentContext()); | |||
971 | bool bForceFocusAndToFront(officecfg::Office::Common::View::NewDocumentHandling::ForceFocusAndToFront::get(xContext)); | |||
972 | ShowFlags showFlags = bForceFocusAndToFront ? ShowFlags::ForegroundTask : ShowFlags::NONE; | |||
973 | Show(true, showFlags); | |||
974 | ||||
975 | if (bModal) | |||
976 | pSVData->maAppData.mnModalMode++; | |||
977 | ||||
978 | css::uno::Reference<css::frame::XGlobalEventBroadcaster> xEventBroadcaster( | |||
979 | css::frame::theGlobalEventBroadcaster::get(xContext), css::uno::UNO_SET_THROW); | |||
980 | css::document::DocumentEvent aObject; | |||
981 | aObject.EventName = "DialogExecute"; | |||
982 | xEventBroadcaster->documentEventOccured(aObject); | |||
983 | if (bModal) | |||
984 | UITestLogger::getInstance().log("Open Modal " + get_id()); | |||
985 | else | |||
986 | UITestLogger::getInstance().log("Open Modeless " + get_id()); | |||
987 | ||||
988 | if (comphelper::LibreOfficeKit::isActive()) | |||
989 | { | |||
990 | if (const vcl::ILibreOfficeKitNotifier* pNotifier = GetLOKNotifier()) | |||
991 | { | |||
992 | // Dialog boxes don't get the Resize call and they | |||
993 | // can have invalid size at 'created' message above. | |||
994 | // If there is no difference, the client should detect it and ignore us, | |||
995 | // otherwise, this should make sure that the window has the correct size. | |||
996 | std::vector<vcl::LOKPayloadItem> aItems; | |||
997 | aItems.emplace_back("size", GetSizePixel().toString()); | |||
998 | pNotifier->notifyWindow(GetLOKWindowId(), "size_changed", aItems); | |||
999 | } | |||
1000 | } | |||
1001 | ||||
1002 | return true; | |||
1003 | } | |||
1004 | ||||
1005 | void Dialog::ImplEndExecuteModal() | |||
1006 | { | |||
1007 | ImplSVData* pSVData = ImplGetSVData(); | |||
1008 | pSVData->maAppData.mnModalMode--; | |||
1009 | } | |||
1010 | ||||
1011 | short Dialog::Execute() | |||
1012 | { | |||
1013 | // Once the Android app is based on same idea as the iOS one currently | |||
1014 | // being developed, no conditional should be needed here. Until then, | |||
1015 | // play it safe. | |||
1016 | #if HAVE_FEATURE_DESKTOP1 || defined IOS | |||
1017 | VclPtr<vcl::Window> xWindow = this; | |||
1018 | ||||
1019 | mbInSyncExecute = true; | |||
1020 | comphelper::ScopeGuard aGuard([&]() { | |||
1021 | mbInSyncExecute = false; | |||
1022 | }); | |||
1023 | ||||
1024 | if ( !ImplStartExecute() ) | |||
1025 | return 0; | |||
1026 | ||||
1027 | // Yield util EndDialog is called or dialog gets destroyed | |||
1028 | // (the latter should not happen, but better safe than sorry | |||
1029 | while ( !xWindow->IsDisposed() && mbInExecute ) | |||
1030 | Application::Yield(); | |||
1031 | ||||
1032 | ImplEndExecuteModal(); | |||
1033 | #ifdef DBG_UTIL | |||
1034 | assert (!mpDialogParent || !mpDialogParent->IsDisposed())(static_cast <bool> (!mpDialogParent || !mpDialogParent ->IsDisposed()) ? void (0) : __assert_fail ("!mpDialogParent || !mpDialogParent->IsDisposed()" , "/home/maarten/src/libreoffice/core/vcl/source/window/dialog.cxx" , 1034, __extension__ __PRETTY_FUNCTION__)); | |||
1035 | #endif | |||
1036 | if ( !xWindow->IsDisposed() ) | |||
1037 | xWindow.clear(); | |||
1038 | else | |||
1039 | { | |||
1040 | OSL_FAIL( "Dialog::Execute() - Dialog destroyed in Execute()" )do { if (true && (((sal_Bool)1))) { sal_detail_logFormat ((SAL_DETAIL_LOG_LEVEL_WARN), ("legacy.osl"), ("/home/maarten/src/libreoffice/core/vcl/source/window/dialog.cxx" ":" "1040" ": "), "%s", "Dialog::Execute() - Dialog destroyed in Execute()" ); } } while (false); | |||
1041 | } | |||
1042 | ||||
1043 | long nRet = mpDialogImpl->mnResult; | |||
1044 | mpDialogImpl->mnResult = -1; | |||
1045 | ||||
1046 | return static_cast<short>(nRet); | |||
1047 | ||||
1048 | #else | |||
1049 | return RET_OK; | |||
1050 | #endif | |||
1051 | } | |||
1052 | ||||
1053 | // virtual | |||
1054 | bool Dialog::StartExecuteAsync( VclAbstractDialog::AsyncContext &rCtx ) | |||
1055 | { | |||
1056 | const bool bModal = GetType() != WindowType::MODELESSDIALOG; | |||
1057 | if (!ImplStartExecute()) | |||
1058 | { | |||
1059 | rCtx.mxOwner.disposeAndClear(); | |||
1060 | rCtx.mxOwnerDialogController.reset(); | |||
1061 | rCtx.mxOwnerSelf.reset(); | |||
1062 | return false; | |||
1063 | } | |||
1064 | ||||
1065 | mpDialogImpl->maEndCtx = rCtx; | |||
1066 | mpDialogImpl->mbStartedModal = bModal; | |||
1067 | ||||
1068 | return true; | |||
1069 | } | |||
1070 | ||||
1071 | void Dialog::RemoveFromDlgList() | |||
1072 | { | |||
1073 | ImplSVData* pSVData = ImplGetSVData(); | |||
1074 | auto& rExecuteDialogs = pSVData->mpWinData->mpExecuteDialogs; | |||
1075 | ||||
1076 | // remove dialog from the list of dialogs which are being executed | |||
1077 | rExecuteDialogs.erase(std::remove_if(rExecuteDialogs.begin(), rExecuteDialogs.end(), [this](VclPtr<Dialog>& dialog){ return dialog.get() == this; }), rExecuteDialogs.end()); | |||
1078 | } | |||
1079 | ||||
1080 | void Dialog::EndDialog( long nResult ) | |||
1081 | { | |||
1082 | if (!mbInExecute || IsDisposed()) | |||
1083 | return; | |||
1084 | ||||
1085 | const bool bModal = GetType() != WindowType::MODELESSDIALOG; | |||
1086 | ||||
1087 | Hide(); | |||
1088 | ||||
1089 | if (comphelper::LibreOfficeKit::isActive()) | |||
1090 | { | |||
1091 | if(const vcl::ILibreOfficeKitNotifier* pNotifier = GetLOKNotifier()) | |||
1092 | { | |||
1093 | pNotifier->notifyWindow(GetLOKWindowId(), "close"); | |||
1094 | ReleaseLOKNotifier(); | |||
1095 | } | |||
1096 | } | |||
1097 | ||||
1098 | if (bModal) | |||
1099 | { | |||
1100 | SetModalInputMode(false); | |||
1101 | ||||
1102 | RemoveFromDlgList(); | |||
1103 | ||||
1104 | // set focus to previous modal dialog if it is modal for | |||
1105 | // the same frame parent (or NULL) | |||
1106 | ImplSVData* pSVData = ImplGetSVData(); | |||
1107 | if (!pSVData->mpWinData->mpExecuteDialogs.empty()) | |||
1108 | { | |||
1109 | VclPtr<Dialog> pPrevious = pSVData->mpWinData->mpExecuteDialogs.back(); | |||
1110 | ||||
1111 | vcl::Window* pFrameParent = ImplGetFrameWindow()->ImplGetParent(); | |||
1112 | vcl::Window* pPrevFrameParent = pPrevious->ImplGetFrameWindow()? pPrevious->ImplGetFrameWindow()->ImplGetParent(): nullptr; | |||
1113 | if( ( !pFrameParent && !pPrevFrameParent ) || | |||
1114 | ( pFrameParent && pPrevFrameParent && pFrameParent->ImplGetFrame() == pPrevFrameParent->ImplGetFrame() ) | |||
1115 | ) | |||
1116 | { | |||
1117 | pPrevious->GrabFocus(); | |||
1118 | } | |||
1119 | } | |||
1120 | } | |||
1121 | ||||
1122 | mpDialogImpl->mnResult = nResult; | |||
1123 | ||||
1124 | if ( mpDialogImpl->mbStartedModal ) | |||
1125 | ImplEndExecuteModal(); | |||
1126 | ||||
1127 | if ( mpDialogImpl && mpDialogImpl->maEndCtx.isSet() ) | |||
1128 | { | |||
1129 | auto fn = std::move(mpDialogImpl->maEndCtx.maEndDialogFn); | |||
1130 | // std::move leaves maEndDialogFn in a valid state with unspecified | |||
1131 | // value. For the SwSyncBtnDlg case gcc and msvc left maEndDialogFn | |||
1132 | // unset, but clang left maEndDialogFn at its original value, keeping | |||
1133 | // an extra reference to the DialogController in its lambda giving | |||
1134 | // an inconsistent lifecycle for the dialog. Force it to be unset. | |||
1135 | mpDialogImpl->maEndCtx.maEndDialogFn = nullptr; | |||
1136 | fn(nResult); | |||
1137 | } | |||
1138 | ||||
1139 | if ( mpDialogImpl && mpDialogImpl->mbStartedModal ) | |||
1140 | { | |||
1141 | mpDialogImpl->mbStartedModal = false; | |||
1142 | mpDialogImpl->mnResult = -1; | |||
1143 | } | |||
1144 | mbInExecute = false; | |||
1145 | ||||
1146 | if ( mpDialogImpl ) | |||
1147 | { | |||
1148 | // Destroy ourselves (if we have a context with VclPtr owner) | |||
1149 | std::shared_ptr<weld::DialogController> xOwnerDialogController = std::move(mpDialogImpl->maEndCtx.mxOwnerDialogController); | |||
1150 | std::shared_ptr<weld::Dialog> xOwnerSelf = std::move(mpDialogImpl->maEndCtx.mxOwnerSelf); | |||
1151 | mpDialogImpl->maEndCtx.mxOwner.disposeAndClear(); | |||
1152 | xOwnerDialogController.reset(); | |||
1153 | xOwnerSelf.reset(); | |||
1154 | } | |||
1155 | } | |||
1156 | ||||
1157 | namespace vcl | |||
1158 | { | |||
1159 | void EndAllDialogs( vcl::Window const * pParent ) | |||
1160 | { | |||
1161 | ImplSVData* pSVData = ImplGetSVData(); | |||
1162 | auto& rExecuteDialogs = pSVData->mpWinData->mpExecuteDialogs; | |||
1163 | ||||
1164 | for (auto it = rExecuteDialogs.rbegin(); it != rExecuteDialogs.rend(); ++it) | |||
1165 | { | |||
1166 | if (!pParent || pParent->IsWindowOrChild(*it, true)) | |||
1167 | { | |||
1168 | (*it)->EndDialog(); | |||
1169 | (*it)->PostUserEvent(Link<void*, void>()); | |||
1170 | } | |||
1171 | } | |||
1172 | } | |||
1173 | ||||
1174 | void EnableDialogInput(vcl::Window* pWindow) | |||
1175 | { | |||
1176 | if (Dialog* pDialog = dynamic_cast<Dialog*>(pWindow)) | |||
1177 | { | |||
1178 | pDialog->EnableInput(); | |||
1179 | } | |||
1180 | } | |||
1181 | ||||
1182 | bool CloseDialog(vcl::Window* pWindow) | |||
1183 | { | |||
1184 | if (Dialog* pDialog = dynamic_cast<Dialog*>(pWindow)) | |||
1185 | { | |||
1186 | pDialog->Close(); | |||
1187 | return true; | |||
1188 | } | |||
1189 | return false; | |||
1190 | } | |||
1191 | } | |||
1192 | ||||
1193 | void Dialog::SetModalInputMode( bool bModal ) | |||
1194 | { | |||
1195 | if ( bModal == mbModalMode ) | |||
1196 | return; | |||
1197 | ||||
1198 | ImplGetFrame()->SetModal(bModal); | |||
1199 | ||||
1200 | if (GetParent()) | |||
1201 | { | |||
1202 | SalFrame* pFrame = GetParent()->ImplGetFrame(); | |||
1203 | pFrame->NotifyModalHierarchy(bModal); | |||
1204 | } | |||
1205 | ||||
1206 | ImplSetModalInputMode(bModal); | |||
1207 | } | |||
1208 | ||||
1209 | void Dialog::ImplSetModalInputMode( bool bModal ) | |||
1210 | { | |||
1211 | if ( bModal == mbModalMode ) | |||
1212 | return; | |||
1213 | ||||
1214 | // previously Execute()'d dialog - the one below the top-most one | |||
1215 | VclPtr<Dialog> pPrevious; | |||
1216 | ImplSVData* pSVData = ImplGetSVData(); | |||
1217 | auto& rExecuteDialogs = pSVData->mpWinData->mpExecuteDialogs; | |||
1218 | if (rExecuteDialogs.size() > 1) | |||
1219 | pPrevious = rExecuteDialogs[rExecuteDialogs.size() - 2]; | |||
1220 | ||||
1221 | mbModalMode = bModal; | |||
1222 | if ( bModal ) | |||
1223 | { | |||
1224 | // Disable the prev Modal Dialog, because our dialog must close at first, | |||
1225 | // before the other dialog can be closed (because the other dialog | |||
1226 | // is on stack since our dialog returns) | |||
1227 | if (pPrevious && !pPrevious->IsWindowOrChild(this, true)) | |||
1228 | pPrevious->EnableInput(false, this); | |||
1229 | ||||
1230 | // determine next overlap dialog parent | |||
1231 | vcl::Window* pParent = GetParent(); | |||
1232 | if ( pParent ) | |||
1233 | { | |||
1234 | // #103716# dialogs should always be modal to the whole frame window | |||
1235 | // #115933# disable the whole frame hierarchy, useful if our parent | |||
1236 | // is a modeless dialog | |||
1237 | mpDialogParent = pParent->mpWindowImpl->mpFrameWindow; | |||
1238 | mpDialogParent->IncModalCount(); | |||
1239 | } | |||
1240 | } | |||
1241 | else | |||
1242 | { | |||
1243 | if ( mpDialogParent ) | |||
1244 | { | |||
1245 | // #115933# re-enable the whole frame hierarchy again (see above) | |||
1246 | // note that code in getfocus assures that we do not accidentally enable | |||
1247 | // windows that were disabled before | |||
1248 | mpDialogParent->DecModalCount(); | |||
1249 | } | |||
1250 | ||||
1251 | // Enable the prev Modal Dialog | |||
1252 | if (pPrevious && !pPrevious->IsWindowOrChild(this, true)) | |||
1253 | { | |||
1254 | pPrevious->EnableInput(true, this); | |||
1255 | ||||
1256 | // ensure continued modality of prev dialog | |||
1257 | // do not change modality counter | |||
1258 | ||||
1259 | // #i119994# need find the last modal dialog before reactive it | |||
1260 | if (pPrevious->IsModalInputMode() || !pPrevious->IsWindowOrChild(this, true)) | |||
1261 | { | |||
1262 | pPrevious->ImplSetModalInputMode(false); | |||
1263 | pPrevious->ImplSetModalInputMode(true); | |||
1264 | } | |||
1265 | } | |||
1266 | } | |||
1267 | } | |||
1268 | ||||
1269 | void Dialog::GrabFocusToFirstControl() | |||
1270 | { | |||
1271 | vcl::Window* pFocusControl; | |||
1272 | ||||
1273 | // find focus control, even if the dialog has focus | |||
1274 | if ( HasFocus() ) | |||
1275 | pFocusControl = nullptr; | |||
1276 | else | |||
1277 | { | |||
1278 | // prefer a child window which had focus before | |||
1279 | pFocusControl = ImplGetFirstOverlapWindow()->mpWindowImpl->mpLastFocusWindow; | |||
1280 | // find the control out of the dialog control | |||
1281 | if ( pFocusControl ) | |||
1282 | pFocusControl = ImplFindDlgCtrlWindow( pFocusControl ); | |||
1283 | } | |||
1284 | // no control had the focus before or the control is not | |||
1285 | // part of the tab-control, now give focus to the | |||
1286 | // first control in the tab-control | |||
1287 | if ( !pFocusControl || | |||
1288 | !(pFocusControl->GetStyle() & WB_TABSTOP) || | |||
1289 | !isVisibleInLayout(pFocusControl) || | |||
1290 | !isEnabledInLayout(pFocusControl) || !pFocusControl->IsInputEnabled() ) | |||
1291 | { | |||
1292 | pFocusControl = ImplGetDlgWindow( 0, GetDlgWindowType::First ); | |||
1293 | } | |||
1294 | if ( pFocusControl ) | |||
1295 | pFocusControl->ImplControlFocus( GetFocusFlags::Init ); | |||
1296 | } | |||
1297 | ||||
1298 | void Dialog::GetDrawWindowBorder( sal_Int32& rLeftBorder, sal_Int32& rTopBorder, sal_Int32& rRightBorder, sal_Int32& rBottomBorder ) const | |||
1299 | { | |||
1300 | ScopedVclPtrInstance<ImplBorderWindow> aImplWin( static_cast<vcl::Window*>(const_cast<Dialog *>(this)), WB_BORDER|WB_STDWORK, BorderWindowStyle::Overlap ); | |||
1301 | aImplWin->GetBorder( rLeftBorder, rTopBorder, rRightBorder, rBottomBorder ); | |||
1302 | } | |||
1303 | ||||
1304 | void Dialog::Draw( OutputDevice* pDev, const Point& rPos, DrawFlags ) | |||
1305 | { | |||
1306 | Point aPos = pDev->LogicToPixel( rPos ); | |||
1307 | Size aSize = GetSizePixel(); | |||
1308 | ||||
1309 | Wallpaper aWallpaper = GetBackground(); | |||
1310 | if ( !aWallpaper.IsBitmap() ) | |||
1311 | ImplInitSettings(); | |||
1312 | ||||
1313 | pDev->Push(); | |||
1314 | pDev->SetMapMode(); | |||
1315 | pDev->SetLineColor(); | |||
1316 | ||||
1317 | if ( aWallpaper.IsBitmap() ) | |||
1318 | pDev->DrawBitmapEx( aPos, aSize, aWallpaper.GetBitmap() ); | |||
1319 | else | |||
1320 | { | |||
1321 | pDev->SetFillColor( aWallpaper.GetColor() ); | |||
1322 | pDev->DrawRect( tools::Rectangle( aPos, aSize ) ); | |||
1323 | } | |||
1324 | ||||
1325 | if (!( GetStyle() & WB_NOBORDER )) | |||
1326 | { | |||
1327 | ScopedVclPtrInstance< ImplBorderWindow > aImplWin( this, WB_BORDER|WB_STDWORK, BorderWindowStyle::Overlap ); | |||
1328 | aImplWin->SetText( GetText() ); | |||
1329 | aImplWin->setPosSizePixel( aPos.X(), aPos.Y(), aSize.Width(), aSize.Height() ); | |||
1330 | aImplWin->SetDisplayActive( true ); | |||
1331 | aImplWin->InitView(); | |||
1332 | ||||
1333 | aImplWin->Draw( pDev, aPos ); | |||
1334 | } | |||
1335 | ||||
1336 | pDev->Pop(); | |||
1337 | } | |||
1338 | ||||
1339 | void Dialog::queue_resize(StateChangedType eReason) | |||
1340 | { | |||
1341 | if (IsInClose()) | |||
1342 | return; | |||
1343 | SystemWindow::queue_resize(eReason); | |||
1344 | } | |||
1345 | ||||
1346 | void Dialog::Resize() | |||
1347 | { | |||
1348 | SystemWindow::Resize(); | |||
1349 | ||||
1350 | if (comphelper::LibreOfficeKit::isDialogPainting()) | |||
1351 | return; | |||
1352 | ||||
1353 | if (const vcl::ILibreOfficeKitNotifier* pNotifier = GetLOKNotifier()) | |||
1354 | { | |||
1355 | std::vector<vcl::LOKPayloadItem> aItems; | |||
1356 | aItems.emplace_back("size", GetSizePixel().toString()); | |||
1357 | pNotifier->notifyWindow(GetLOKWindowId(), "size_changed", aItems); | |||
1358 | } | |||
1359 | } | |||
1360 | ||||
1361 | bool Dialog::set_property(const OString &rKey, const OUString &rValue) | |||
1362 | { | |||
1363 | if (rKey == "border-width") | |||
1364 | set_border_width(rValue.toInt32()); | |||
1365 | else | |||
1366 | return SystemWindow::set_property(rKey, rValue); | |||
1367 | return true; | |||
1368 | } | |||
1369 | ||||
1370 | FactoryFunction Dialog::GetUITestFactory() const | |||
1371 | { | |||
1372 | return DialogUIObject::create; | |||
1373 | } | |||
1374 | ||||
1375 | IMPL_LINK(Dialog, ResponseHdl, Button*, pButton, void)void Dialog::LinkStubResponseHdl(void * instance, Button* data ) { return static_cast<Dialog *>(instance)->ResponseHdl (data); } void Dialog::ResponseHdl(Button* pButton) | |||
1376 | { | |||
1377 | auto aFind = mpDialogImpl->maResponses.find(pButton); | |||
1378 | if (aFind == mpDialogImpl->maResponses.end()) | |||
1379 | return; | |||
1380 | short nResponse = aFind->second; | |||
1381 | if (nResponse == RET_HELP) | |||
1382 | { | |||
1383 | vcl::Window* pFocusWin = Application::GetFocusWindow(); | |||
1384 | if (!pFocusWin) | |||
1385 | pFocusWin = pButton; | |||
1386 | HelpEvent aEvt(pFocusWin->GetPointerPosPixel(), HelpEventMode::CONTEXT); | |||
1387 | pFocusWin->RequestHelp(aEvt); | |||
1388 | return; | |||
1389 | } | |||
1390 | EndDialog(nResponse); | |||
1391 | } | |||
1392 | ||||
1393 | void Dialog::add_button(PushButton* pButton, int response, bool bTransferOwnership) | |||
1394 | { | |||
1395 | if (bTransferOwnership) | |||
1396 | mpDialogImpl->maOwnedButtons.push_back(pButton); | |||
1397 | mpDialogImpl->maResponses[pButton] = response; | |||
1398 | switch (pButton->GetType()) | |||
1399 | { | |||
1400 | case WindowType::PUSHBUTTON: | |||
1401 | { | |||
1402 | if (!pButton->GetClickHdl().IsSet()) | |||
1403 | pButton->SetClickHdl(LINK(this, Dialog, ResponseHdl)::tools::detail::makeLink( ::tools::detail::castTo<Dialog * >(this), &Dialog::LinkStubResponseHdl)); | |||
1404 | break; | |||
1405 | } | |||
1406 | //insist that the response ids match the default actions for those | |||
1407 | //widgets, and leave their default handlers in place | |||
1408 | case WindowType::OKBUTTON: | |||
1409 | assert(mpDialogImpl->get_response(pButton) == RET_OK)(static_cast <bool> (mpDialogImpl->get_response(pButton ) == RET_OK) ? void (0) : __assert_fail ("mpDialogImpl->get_response(pButton) == RET_OK" , "/home/maarten/src/libreoffice/core/vcl/source/window/dialog.cxx" , 1409, __extension__ __PRETTY_FUNCTION__)); | |||
1410 | break; | |||
1411 | case WindowType::CANCELBUTTON: | |||
1412 | assert(mpDialogImpl->get_response(pButton) == RET_CANCEL || mpDialogImpl->get_response(pButton) == RET_CLOSE)(static_cast <bool> (mpDialogImpl->get_response(pButton ) == RET_CANCEL || mpDialogImpl->get_response(pButton) == RET_CLOSE ) ? void (0) : __assert_fail ("mpDialogImpl->get_response(pButton) == RET_CANCEL || mpDialogImpl->get_response(pButton) == RET_CLOSE" , "/home/maarten/src/libreoffice/core/vcl/source/window/dialog.cxx" , 1412, __extension__ __PRETTY_FUNCTION__)); | |||
1413 | break; | |||
1414 | case WindowType::HELPBUTTON: | |||
1415 | assert(mpDialogImpl->get_response(pButton) == RET_HELP)(static_cast <bool> (mpDialogImpl->get_response(pButton ) == RET_HELP) ? void (0) : __assert_fail ("mpDialogImpl->get_response(pButton) == RET_HELP" , "/home/maarten/src/libreoffice/core/vcl/source/window/dialog.cxx" , 1415, __extension__ __PRETTY_FUNCTION__)); | |||
1416 | break; | |||
1417 | default: | |||
1418 | SAL_WARN("vcl.layout", "The type of widget " <<do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN , "vcl.layout")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "The type of widget " << pButton->GetHelpId() << " is currently not handled" ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl.layout" ), ("/home/maarten/src/libreoffice/core/vcl/source/window/dialog.cxx" ":" "1419" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "The type of widget " << pButton ->GetHelpId() << " is currently not handled"), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "The type of widget " << pButton->GetHelpId () << " is currently not handled"; ::sal::detail::log( ( ::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl.layout"), ("/home/maarten/src/libreoffice/core/vcl/source/window/dialog.cxx" ":" "1419" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "The type of widget " << pButton->GetHelpId () << " is currently not handled") == 1) { ::sal_detail_log ( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl.layout"), ("/home/maarten/src/libreoffice/core/vcl/source/window/dialog.cxx" ":" "1419" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "The type of widget " << pButton ->GetHelpId() << " is currently not handled"), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "The type of widget " << pButton->GetHelpId () << " is currently not handled"; ::sal::detail::log( ( ::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl.layout"), ("/home/maarten/src/libreoffice/core/vcl/source/window/dialog.cxx" ":" "1419" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false) | |||
1419 | pButton->GetHelpId() << " is currently not handled")do { if (true) { switch (sal_detail_log_report(::SAL_DETAIL_LOG_LEVEL_WARN , "vcl.layout")) { case SAL_DETAIL_LOG_ACTION_IGNORE: break; case SAL_DETAIL_LOG_ACTION_LOG: if (sizeof ::sal::detail::getResult ( ::sal::detail::StreamStart() << "The type of widget " << pButton->GetHelpId() << " is currently not handled" ) == 1) { ::sal_detail_log( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl.layout" ), ("/home/maarten/src/libreoffice/core/vcl/source/window/dialog.cxx" ":" "1419" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "The type of widget " << pButton ->GetHelpId() << " is currently not handled"), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "The type of widget " << pButton->GetHelpId () << " is currently not handled"; ::sal::detail::log( ( ::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl.layout"), ("/home/maarten/src/libreoffice/core/vcl/source/window/dialog.cxx" ":" "1419" ": "), sal_detail_stream, 0); }; break; case SAL_DETAIL_LOG_ACTION_FATAL : if (sizeof ::sal::detail::getResult( ::sal::detail::StreamStart () << "The type of widget " << pButton->GetHelpId () << " is currently not handled") == 1) { ::sal_detail_log ( (::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl.layout"), ("/home/maarten/src/libreoffice/core/vcl/source/window/dialog.cxx" ":" "1419" ": "), ::sal::detail::unwrapStream( ::sal::detail ::StreamStart() << "The type of widget " << pButton ->GetHelpId() << " is currently not handled"), 0); } else { ::std::ostringstream sal_detail_stream; sal_detail_stream << "The type of widget " << pButton->GetHelpId () << " is currently not handled"; ::sal::detail::log( ( ::SAL_DETAIL_LOG_LEVEL_WARN), ("vcl.layout"), ("/home/maarten/src/libreoffice/core/vcl/source/window/dialog.cxx" ":" "1419" ": "), sal_detail_stream, 0); }; std::abort(); break ; } } } while (false); | |||
1420 | break; | |||
1421 | } | |||
1422 | } | |||
1423 | ||||
1424 | vcl::Window* Dialog::get_widget_for_response(int response) | |||
1425 | { | |||
1426 | //copy explicit responses | |||
1427 | std::map<VclPtr<vcl::Window>, short> aResponses(mpDialogImpl->maResponses); | |||
1428 | ||||
1429 | if (mpActionArea) | |||
1430 | { | |||
1431 | //add implicit responses | |||
1432 | for (vcl::Window* pChild = mpActionArea->GetWindow(GetWindowType::FirstChild); pChild; | |||
1433 | pChild = pChild->GetWindow(GetWindowType::Next)) | |||
1434 | { | |||
1435 | if (aResponses.find(pChild) != aResponses.end()) | |||
1436 | continue; | |||
1437 | switch (pChild->GetType()) | |||
1438 | { | |||
1439 | case WindowType::OKBUTTON: | |||
1440 | aResponses[pChild] = RET_OK; | |||
1441 | break; | |||
1442 | case WindowType::CANCELBUTTON: | |||
1443 | aResponses[pChild] = RET_CANCEL; | |||
1444 | break; | |||
1445 | case WindowType::HELPBUTTON: | |||
1446 | aResponses[pChild] = RET_HELP; | |||
1447 | break; | |||
1448 | default: | |||
1449 | break; | |||
1450 | } | |||
1451 | } | |||
1452 | } | |||
1453 | ||||
1454 | for (const auto& a : aResponses) | |||
1455 | { | |||
1456 | if (a.second == response) | |||
1457 | return a.first; | |||
1458 | } | |||
1459 | ||||
1460 | return nullptr; | |||
1461 | } | |||
1462 | ||||
1463 | int Dialog::get_default_response() const | |||
1464 | { | |||
1465 | //copy explicit responses | |||
1466 | std::map<VclPtr<vcl::Window>, short> aResponses(mpDialogImpl->maResponses); | |||
1467 | ||||
1468 | if (mpActionArea) | |||
1469 | { | |||
1470 | //add implicit responses | |||
1471 | for (vcl::Window* pChild = mpActionArea->GetWindow(GetWindowType::FirstChild); pChild; | |||
1472 | pChild = pChild->GetWindow(GetWindowType::Next)) | |||
1473 | { | |||
1474 | if (aResponses.find(pChild) != aResponses.end()) | |||
1475 | continue; | |||
1476 | switch (pChild->GetType()) | |||
1477 | { | |||
1478 | case WindowType::OKBUTTON: | |||
1479 | aResponses[pChild] = RET_OK; | |||
1480 | break; | |||
1481 | case WindowType::CANCELBUTTON: | |||
1482 | aResponses[pChild] = RET_CANCEL; | |||
1483 | break; | |||
1484 | case WindowType::HELPBUTTON: | |||
1485 | aResponses[pChild] = RET_HELP; | |||
1486 | break; | |||
1487 | default: | |||
1488 | break; | |||
1489 | } | |||
1490 | } | |||
1491 | } | |||
1492 | ||||
1493 | for (const auto& a : aResponses) | |||
1494 | { | |||
1495 | if (a.first->GetStyle() & WB_DEFBUTTON) | |||
1496 | { | |||
1497 | return a.second; | |||
1498 | } | |||
1499 | } | |||
1500 | return RET_CANCEL; | |||
1501 | } | |||
1502 | ||||
1503 | void Dialog::set_default_response(int response) | |||
1504 | { | |||
1505 | //copy explicit responses | |||
1506 | std::map<VclPtr<vcl::Window>, short> aResponses(mpDialogImpl->maResponses); | |||
1507 | ||||
1508 | if (mpActionArea) | |||
| ||||
1509 | { | |||
1510 | //add implicit responses | |||
1511 | for (vcl::Window* pChild = mpActionArea->GetWindow(GetWindowType::FirstChild); pChild; | |||
1512 | pChild = pChild->GetWindow(GetWindowType::Next)) | |||
| ||||
1513 | { | |||
1514 | if (aResponses.find(pChild) != aResponses.end()) | |||
1515 | continue; | |||
1516 | switch (pChild->GetType()) | |||
1517 | { | |||
1518 | case WindowType::OKBUTTON: | |||
1519 | aResponses[pChild] = RET_OK; | |||
1520 | break; | |||
1521 | case WindowType::CANCELBUTTON: | |||
1522 | aResponses[pChild] = RET_CANCEL; | |||
1523 | break; | |||
1524 | case WindowType::HELPBUTTON: | |||
1525 | aResponses[pChild] = RET_HELP; | |||
1526 | break; | |||
1527 | default: | |||
1528 | break; | |||
1529 | } | |||
1530 | } | |||
1531 | } | |||
1532 | ||||
1533 | for (auto& a : aResponses) | |||
1534 | { | |||
1535 | if (a.second == response) | |||
1536 | { | |||
1537 | a.first->SetStyle(a.first->GetStyle() | WB_DEFBUTTON); | |||
1538 | a.first->GrabFocus(); | |||
1539 | } | |||
1540 | else | |||
1541 | { | |||
1542 | a.first->SetStyle(a.first->GetStyle() & ~WB_DEFBUTTON); | |||
1543 | } | |||
1544 | } | |||
1545 | } | |||
1546 | ||||
1547 | VclBuilderContainer::VclBuilderContainer() | |||
1548 | { | |||
1549 | } | |||
1550 | ||||
1551 | VclBuilderContainer::~VclBuilderContainer() | |||
1552 | { | |||
1553 | } | |||
1554 | ||||
1555 | void Dialog::Activate() | |||
1556 | { | |||
1557 | if (GetType() == WindowType::MODELESSDIALOG) | |||
1558 | { | |||
1559 | css::uno::Reference< css::uno::XComponentContext > xContext( | |||
1560 | comphelper::getProcessComponentContext() ); | |||
1561 | css::uno::Reference<css::frame::XGlobalEventBroadcaster> xEventBroadcaster(css::frame::theGlobalEventBroadcaster::get(xContext), css::uno::UNO_SET_THROW); | |||
1562 | css::document::DocumentEvent aObject; | |||
1563 | aObject.EventName = "ModelessDialogVisible"; | |||
1564 | xEventBroadcaster->documentEventOccured(aObject); | |||
1565 | } | |||
1566 | SystemWindow::Activate(); | |||
1567 | } | |||
1568 | ||||
1569 | void Dialog::Command(const CommandEvent& rCEvt) | |||
1570 | { | |||
1571 | if (mpDialogImpl && mpDialogImpl->m_aPopupMenuHdl.Call(rCEvt)) | |||
1572 | return; | |||
1573 | SystemWindow::Command(rCEvt); | |||
1574 | } | |||
1575 | ||||
1576 | void TopLevelWindowLocker::incBusy(const weld::Widget* pIgnore) | |||
1577 | { | |||
1578 | // lock any toplevel windows from being closed until busy is over | |||
1579 | std::vector<VclPtr<vcl::Window>> aTopLevels; | |||
1580 | vcl::Window *pTopWin = Application::GetFirstTopLevelWindow(); | |||
1581 | while (pTopWin) | |||
1582 | { | |||
1583 | vcl::Window* pCandidate = pTopWin; | |||
1584 | if (pCandidate->GetType() == WindowType::BORDERWINDOW) | |||
1585 | pCandidate = pCandidate->GetWindow(GetWindowType::FirstChild); | |||
1586 | // tdf#125266 ignore HelpTextWindows | |||
1587 | if (pCandidate && | |||
1588 | pCandidate->GetType() != WindowType::HELPTEXTWINDOW && | |||
1589 | pCandidate->GetType() != WindowType::FLOATINGWINDOW && | |||
1590 | pCandidate->GetFrameWeld() != pIgnore) | |||
1591 | { | |||
1592 | aTopLevels.push_back(pCandidate); | |||
1593 | } | |||
1594 | pTopWin = Application::GetNextTopLevelWindow(pTopWin); | |||
1595 | } | |||
1596 | for (auto& a : aTopLevels) | |||
1597 | { | |||
1598 | a->IncModalCount(); | |||
1599 | a->ImplGetFrame()->NotifyModalHierarchy(true); | |||
1600 | } | |||
1601 | m_aBusyStack.push(aTopLevels); | |||
1602 | } | |||
1603 | ||||
1604 | void TopLevelWindowLocker::decBusy() | |||
1605 | { | |||
1606 | // unlock locked toplevel windows from being closed now busy is over | |||
1607 | for (auto& a : m_aBusyStack.top()) | |||
1608 | { | |||
1609 | if (a->IsDisposed()) | |||
1610 | continue; | |||
1611 | a->DecModalCount(); | |||
1612 | a->ImplGetFrame()->NotifyModalHierarchy(false); | |||
1613 | } | |||
1614 | m_aBusyStack.pop(); | |||
1615 | } | |||
1616 | ||||
1617 | /* 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 |