LibreOffice Module sd (master) 1
ChildWindowPane.cxx
Go to the documentation of this file.
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 <memory>
21#include <sal/config.h>
22#include <sal/log.hxx>
23
24#include <utility>
25
26#include "ChildWindowPane.hxx"
27
28#include <titledockwin.hxx>
29#include <ViewShellBase.hxx>
30#include <ViewShellManager.hxx>
32#include <sfx2/viewfrm.hxx>
33
34using namespace ::com::sun::star;
35using namespace ::com::sun::star::uno;
37
38namespace sd::framework {
39
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)
50{
51 mrViewShellBase.GetViewShellManager()->ActivateShell(mpShell.get());
52
54
56 {
57 if (rViewFrame.KnowsChildWindow(mnChildWindowId))
58 {
59 if (rViewFrame.HasChildWindow(mnChildWindowId))
60 {
61 // The ViewShellBase has already been activated. Make
62 // the child window visible as soon as possible.
63 rViewFrame.SetChildWindow(mnChildWindowId, true);
64 }
65 else
66 {
67 // The window is created asynchronously. Rely on the
68 // ConfigurationUpdater to try another update, and with
69 // that another request for this window, in a short
70 // time.
71 }
72 }
73 else
74 {
75 SAL_WARN("sd", "ChildWindowPane:not known");
76 }
77 }
78 else
79 {
80 // The ViewShellBase has not yet been activated. Hide the
81 // window and wait a little before it is made visible. See
82 // comments in the GetWindow() method for an explanation.
83 rViewFrame.SetChildWindow(mnChildWindowId, false);
84 }
85}
86
88{
89}
90
92{
94 if (rViewFrame.KnowsChildWindow(mnChildWindowId))
95 if (rViewFrame.HasChildWindow(mnChildWindowId))
96 rViewFrame.SetChildWindow(mnChildWindowId, false);
97
98 // Release the window because when the child window is shown again it
99 // may use a different window.
100 mxWindow = nullptr;
101}
102
104{
105 ::osl::MutexGuard aGuard (m_aMutex);
106
107 mrViewShellBase.GetViewShellManager()->DeactivateShell(mpShell.get());
108 mpShell.reset();
109
110 if (mxWindow.is())
111 {
112 mxWindow->removeEventListener(this);
113 }
114
116}
117
119{
120 do
121 {
122 if (mxWindow.is())
123 // Window already exists => nothing to do.
124 break;
125
126 // When the window is not yet present then obtain it only when the
127 // shell has already been activated. The activation is not
128 // necessary for the code to work properly but is used to optimize
129 // the layouting and displaying of the window. When it is made
130 // visible too early then some layouting seems to be made twice or at
131 // an inconvenient time and the overall process of initializing the
132 // Impress takes longer.
133 if (!mbHasBeenActivated && mpShell != nullptr && !mpShell->IsActive())
134 break;
135
136 mbHasBeenActivated = true;
138 // The view frame has to know the child window. This can be the
139 // case, when for example the document is in read-only mode: the
140 // task pane is then not available.
141 if ( ! rViewFrame.KnowsChildWindow(mnChildWindowId))
142 break;
143
144 rViewFrame.SetChildWindow(mnChildWindowId, true);
145 SfxChildWindow* pChildWindow = rViewFrame.GetChildWindow(mnChildWindowId);
146 if (pChildWindow == nullptr)
147 if (rViewFrame.HasChildWindow(mnChildWindowId))
148 {
149 // The child window is not yet visible. Ask the view frame
150 // to show it and try again to get access to the child
151 // window.
153 pChildWindow = rViewFrame.GetChildWindow(mnChildWindowId);
154 }
155
156 // When the child window is still not visible then we have to try later.
157 if (pChildWindow == nullptr)
158 break;
159
160 // From the child window get the docking window and from that the
161 // content window that is the container for the actual content.
162 TitledDockingWindow* pDockingWindow = dynamic_cast<TitledDockingWindow*>(
163 pChildWindow->GetWindow());
164 if (pDockingWindow == nullptr)
165 break;
166
167 // At last, we have access to the window and its UNO wrapper.
168 mpWindow = &pDockingWindow->GetContentWindow();
170
171 // Register as window listener to be informed when the child window
172 // is hidden.
173 if (mxWindow.is())
174 mxWindow->addEventListener(this);
175 }
176 while (false);
177
178 return mpWindow;
179}
180
181Reference<awt::XWindow> SAL_CALL ChildWindowPane::getWindow()
182{
183 if (mpWindow == nullptr || ! mxWindow.is())
184 GetWindow();
185 return Pane::getWindow();
186}
187
191 Pane);
195 Pane);
196
197//----- XEventListener --------------------------------------------------------
198
199void SAL_CALL ChildWindowPane::disposing (const lang::EventObject& rEvent)
200{
201 ThrowIfDisposed();
202
203 if (rEvent.Source == mxWindow)
204 {
205 // The window is gone but the pane remains alive. The next call to
206 // GetWindow() may create the window anew.
207 mxWindow = nullptr;
208 mpWindow = nullptr;
209 }
210}
211
212} // end of namespace sd::framework
213
214/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
vcl::Window * GetWindow() const
bool IsActive() const
bool HasChildWindow(sal_uInt16)
void SetChildWindow(sal_uInt16 nId, bool bVisible, bool bSetFocus=true)
SfxChildWindow * GetChildWindow(sal_uInt16)
bool KnowsChildWindow(sal_uInt16)
void ShowChildWindow(sal_uInt16, bool bVisible=true)
SfxViewFrame & GetViewFrame() const
static css::uno::Reference< css::awt::XWindow > GetInterface(vcl::Window *pWindow)
vcl::Window & GetContentWindow()
returns the content window, which is to be used as parent window for any content to be displayed in t...
SfxViewShell descendant that the stacked Draw/Impress shells are based on.
std::shared_ptr< ViewShellManager > const & GetViewShellManager() const
The ChildWindowPane listens to the child window and disposes itself when the child window becomes ina...
bool mbHasBeenActivated
This flag is set when the pane shell has been activated at least once.
virtual vcl::Window * GetWindow() override
This returns the content window when the child window is already visible.
ChildWindowPane(const css::uno::Reference< css::drawing::framework::XResourceId > &rxPaneId, sal_uInt16 nChildWindowId, ViewShellBase &rViewShellBase, ::std::unique_ptr< SfxShell > &&pShell)
virtual css::uno::Reference< css::awt::XWindow > SAL_CALL getWindow() override
The local getWindow() first calls GetWindow() to provide a valid window pointer before forwarding the...
virtual ~ChildWindowPane() override
::std::unique_ptr< SfxShell > mpShell
virtual void SAL_CALL disposing() override
A pane is a wrapper for a window and possibly for a tab bar (for view switching).
Definition: Pane.hxx:51
virtual void SAL_CALL disposing() override
Definition: Pane.cxx:50
virtual css::uno::Reference< css::awt::XWindow > SAL_CALL getWindow() override
For a UNO API based implementation of a view this may the most important method of this class because...
Definition: Pane.cxx:66
std::mutex m_aMutex
#define SAL_WARN(area, stream)
::cppu::ImplInheritanceHelper< ::sd::framework::Pane, css::lang::XEventListener > ChildWindowPaneInterfaceBase
IMPLEMENT_FORWARD_XTYPEPROVIDER2(ChildWindowPane, ChildWindowPaneInterfaceBase, Pane)
IMPLEMENT_FORWARD_XINTERFACE2(ChildWindowPane, ChildWindowPaneInterfaceBase, Pane)
VclPtr< vcl::Window > mpWindow