cid#1607171 Data race condition
[LibreOffice.git] / sd / source / ui / framework / factories / ChildWindowPane.cxx
blob6e9e237c166f4553fe7f4a7a1e5213669921d27e
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <memory>
21 #include <sal/config.h>
22 #include <sal/log.hxx>
24 #include <utility>
26 #include "ChildWindowPane.hxx"
28 #include <titledockwin.hxx>
29 #include <ViewShellBase.hxx>
30 #include <ViewShellManager.hxx>
31 #include <toolkit/helper/vclunohelper.hxx>
32 #include <sfx2/viewfrm.hxx>
34 using namespace ::com::sun::star;
35 using namespace ::com::sun::star::uno;
36 using namespace ::com::sun::star::drawing::framework;
38 namespace sd::framework {
40 ChildWindowPane::ChildWindowPane (
41 const Reference<XResourceId>& rxPaneId,
42 sal_uInt16 nChildWindowId,
43 ViewShellBase& rViewShellBase,
44 ::std::unique_ptr<SfxShell> && pShell)
45 : ChildWindowPaneInterfaceBase(rxPaneId,nullptr),
46 mnChildWindowId(nChildWindowId),
47 mrViewShellBase(rViewShellBase),
48 mpShell(std::move(pShell)),
49 mbHasBeenActivated(false)
51 // ChildWindowPane shells don't implement dispatch slots, so activate them
52 // at the bottom of the shellstack.
53 mrViewShellBase.GetViewShellManager()->ActivateLowPriorityShell(mpShell.get());
55 SfxViewFrame& rViewFrame = mrViewShellBase.GetViewFrame();
57 if (mrViewShellBase.IsActive())
59 if (rViewFrame.KnowsChildWindow(mnChildWindowId))
61 if (rViewFrame.HasChildWindow(mnChildWindowId))
63 // The ViewShellBase has already been activated. Make
64 // the child window visible as soon as possible.
65 rViewFrame.SetChildWindow(mnChildWindowId, true);
67 else
69 // The window is created asynchronously. Rely on the
70 // ConfigurationUpdater to try another update, and with
71 // that another request for this window, in a short
72 // time.
75 else
77 SAL_WARN("sd", "ChildWindowPane:not known");
80 else
82 // The ViewShellBase has not yet been activated. Hide the
83 // window and wait a little before it is made visible. See
84 // comments in the GetWindow() method for an explanation.
85 rViewFrame.SetChildWindow(mnChildWindowId, false);
89 ChildWindowPane::~ChildWindowPane()
93 void ChildWindowPane::Hide()
95 SfxViewFrame& rViewFrame = mrViewShellBase.GetViewFrame();
96 if (rViewFrame.KnowsChildWindow(mnChildWindowId))
97 if (rViewFrame.HasChildWindow(mnChildWindowId))
98 rViewFrame.SetChildWindow(mnChildWindowId, false);
100 // Release the window because when the child window is shown again it
101 // may use a different window.
102 mxWindow = nullptr;
105 void SAL_CALL ChildWindowPane::disposing()
107 ::osl::MutexGuard aGuard (m_aMutex);
109 mrViewShellBase.GetViewShellManager()->DeactivateShell(mpShell.get());
110 mpShell.reset();
112 if (mxWindow.is())
114 mxWindow->removeEventListener(this);
117 Pane::disposing();
120 vcl::Window* ChildWindowPane::GetWindow()
124 if (mxWindow.is())
125 // Window already exists => nothing to do.
126 break;
128 // When the window is not yet present then obtain it only when the
129 // shell has already been activated. The activation is not
130 // necessary for the code to work properly but is used to optimize
131 // the layouting and displaying of the window. When it is made
132 // visible too early then some layouting seems to be made twice or at
133 // an inconvenient time and the overall process of initializing the
134 // Impress takes longer.
135 if (!mbHasBeenActivated && mpShell != nullptr && !mpShell->IsActive())
136 break;
138 mbHasBeenActivated = true;
139 SfxViewFrame& rViewFrame = mrViewShellBase.GetViewFrame();
140 // The view frame has to know the child window. This can be the
141 // case, when for example the document is in read-only mode: the
142 // task pane is then not available.
143 if ( ! rViewFrame.KnowsChildWindow(mnChildWindowId))
144 break;
146 rViewFrame.SetChildWindow(mnChildWindowId, true);
147 SfxChildWindow* pChildWindow = rViewFrame.GetChildWindow(mnChildWindowId);
148 if (pChildWindow == nullptr)
149 if (rViewFrame.HasChildWindow(mnChildWindowId))
151 // The child window is not yet visible. Ask the view frame
152 // to show it and try again to get access to the child
153 // window.
154 rViewFrame.ShowChildWindow(mnChildWindowId);
155 pChildWindow = rViewFrame.GetChildWindow(mnChildWindowId);
158 // When the child window is still not visible then we have to try later.
159 if (pChildWindow == nullptr)
160 break;
162 // From the child window get the docking window and from that the
163 // content window that is the container for the actual content.
164 TitledDockingWindow* pDockingWindow = dynamic_cast<TitledDockingWindow*>(
165 pChildWindow->GetWindow());
166 if (pDockingWindow == nullptr)
167 break;
169 // At last, we have access to the window and its UNO wrapper.
170 mpWindow = &pDockingWindow->GetContentWindow();
171 mxWindow = VCLUnoHelper::GetInterface(mpWindow);
173 // Register as window listener to be informed when the child window
174 // is hidden.
175 if (mxWindow.is())
176 mxWindow->addEventListener(this);
178 while (false);
180 return mpWindow;
183 Reference<awt::XWindow> SAL_CALL ChildWindowPane::getWindow()
185 if (mpWindow == nullptr || ! mxWindow.is())
186 GetWindow();
187 return Pane::getWindow();
190 IMPLEMENT_FORWARD_XINTERFACE2(
191 ChildWindowPane,
192 ChildWindowPaneInterfaceBase,
193 Pane);
194 IMPLEMENT_FORWARD_XTYPEPROVIDER2(
195 ChildWindowPane,
196 ChildWindowPaneInterfaceBase,
197 Pane);
199 //----- XEventListener --------------------------------------------------------
201 void SAL_CALL ChildWindowPane::disposing (const lang::EventObject& rEvent)
203 ThrowIfDisposed();
205 if (rEvent.Source == mxWindow)
207 // The window is gone but the pane remains alive. The next call to
208 // GetWindow() may create the window anew.
209 mxWindow = nullptr;
210 mpWindow = nullptr;
214 } // end of namespace sd::framework
216 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */