Line data Source code
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 <sal/config.h>
21 :
22 : #include <utility>
23 :
24 : #include "ChildWindowPane.hxx"
25 :
26 : #include "PaneDockingWindow.hxx"
27 : #include "ViewShellBase.hxx"
28 : #include "ViewShellManager.hxx"
29 : #include "framework/FrameworkHelper.hxx"
30 : #include <toolkit/helper/vclunohelper.hxx>
31 : #include <vcl/svapp.hxx>
32 :
33 : using namespace ::com::sun::star;
34 : using namespace ::com::sun::star::uno;
35 : using namespace ::com::sun::star::drawing::framework;
36 :
37 : namespace sd { namespace framework {
38 :
39 126 : ChildWindowPane::ChildWindowPane (
40 : const Reference<XResourceId>& rxPaneId,
41 : sal_uInt16 nChildWindowId,
42 : ViewShellBase& rViewShellBase,
43 : ::std::unique_ptr<SfxShell> && pShell)
44 : : ChildWindowPaneInterfaceBase(rxPaneId,nullptr),
45 : mnChildWindowId(nChildWindowId),
46 : mrViewShellBase(rViewShellBase),
47 126 : mpShell(std::move(pShell)),
48 252 : mbHasBeenActivated(false)
49 : {
50 126 : mrViewShellBase.GetViewShellManager()->ActivateShell(mpShell.get());
51 :
52 126 : SfxViewFrame* pViewFrame = mrViewShellBase.GetViewFrame();
53 126 : if (pViewFrame != NULL)
54 : {
55 126 : if (mrViewShellBase.IsActive())
56 : {
57 0 : if (pViewFrame->KnowsChildWindow(mnChildWindowId))
58 : {
59 0 : if (pViewFrame->HasChildWindow(mnChildWindowId))
60 : {
61 : // The ViewShellBase has already been activated. Make
62 : // the child window visible as soon as possible.
63 0 : pViewFrame->SetChildWindow(mnChildWindowId, true);
64 : OSL_TRACE("ChildWindowPane:activating now");
65 : }
66 : else
67 : {
68 : // The window is created asynchronously. Rely on the
69 : // ConfigurationUpdater to try another update, and with
70 : // that another request for this window, in a short
71 : // time.
72 : OSL_TRACE("ChildWindowPane:activated asynchronously");
73 : }
74 : }
75 : else
76 : {
77 : OSL_TRACE("ChildWindowPane:not known");
78 : }
79 : }
80 : else
81 : {
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 126 : pViewFrame->SetChildWindow(mnChildWindowId, false);
86 : OSL_TRACE("ChildWindowPane:base not active");
87 : }
88 : }
89 126 : }
90 :
91 0 : ChildWindowPane::~ChildWindowPane()
92 : {
93 0 : }
94 :
95 192 : void ChildWindowPane::Hide()
96 : {
97 192 : SfxViewFrame* pViewFrame = mrViewShellBase.GetViewFrame();
98 192 : if (pViewFrame != NULL)
99 192 : if (pViewFrame->KnowsChildWindow(mnChildWindowId))
100 192 : if (pViewFrame->HasChildWindow(mnChildWindowId))
101 66 : pViewFrame->SetChildWindow(mnChildWindowId, false);
102 :
103 : // Release the window because when the child window is shown again it
104 : // may use a different window.
105 192 : mxWindow = NULL;
106 192 : }
107 :
108 0 : void SAL_CALL ChildWindowPane::disposing()
109 : {
110 0 : ::osl::MutexGuard aGuard (maMutex);
111 :
112 0 : mrViewShellBase.GetViewShellManager()->DeactivateShell(mpShell.get());
113 0 : mpShell.reset();
114 :
115 0 : if (mxWindow.is())
116 : {
117 0 : mxWindow->removeEventListener(this);
118 : }
119 :
120 0 : Pane::disposing();
121 0 : }
122 :
123 192 : vcl::Window* ChildWindowPane::GetWindow()
124 : {
125 : do
126 : {
127 192 : if (mxWindow.is())
128 : // Window already exists => nothing to do.
129 0 : break;
130 :
131 : // When the window is not yet present then obtain it only when the
132 : // shell has already been activated. The activation is not
133 : // necessary for the code to work properly but is used to optimize
134 : // the layouting and displaying of the window. When it is made
135 : // visible to early then some layouting seems to be made twice or at
136 : // an inconvenient time and the overall process of initializing the
137 : // Impress takes longer.
138 192 : if ( ! mbHasBeenActivated && mpShell.get()!=NULL && ! mpShell->IsActive())
139 126 : break;
140 :
141 66 : mbHasBeenActivated = true;
142 66 : SfxViewFrame* pViewFrame = mrViewShellBase.GetViewFrame();
143 66 : if (pViewFrame == NULL)
144 0 : break;
145 : // The view frame has to know the child window. This can be the
146 : // case, when for example the document is in read-only mode: the
147 : // task pane is then not available.
148 66 : if ( ! pViewFrame->KnowsChildWindow(mnChildWindowId))
149 0 : break;
150 :
151 66 : pViewFrame->SetChildWindow(mnChildWindowId, true);
152 66 : SfxChildWindow* pChildWindow = pViewFrame->GetChildWindow(mnChildWindowId);
153 66 : if (pChildWindow == NULL)
154 0 : if (pViewFrame->HasChildWindow(mnChildWindowId))
155 : {
156 : // The child window is not yet visible. Ask the view frame
157 : // to show it and try again to get access to the child
158 : // window.
159 0 : pViewFrame->ShowChildWindow(mnChildWindowId, true);
160 0 : pChildWindow = pViewFrame->GetChildWindow(mnChildWindowId);
161 : }
162 :
163 : // When the child window is still not visible then we have to try later.
164 66 : if (pChildWindow == NULL)
165 0 : break;
166 :
167 : // From the child window get the docking window and from that the
168 : // content window that is the container for the actual content.
169 : PaneDockingWindow* pDockingWindow = dynamic_cast<PaneDockingWindow*>(
170 66 : pChildWindow->GetWindow());
171 66 : if (pDockingWindow == NULL)
172 0 : break;
173 :
174 : // At last, we have access to the window and its UNO wrapper.
175 66 : mpWindow = &pDockingWindow->GetContentWindow();
176 66 : mxWindow = VCLUnoHelper::GetInterface(mpWindow);
177 :
178 : // Register as window listener to be informed when the child window
179 : // is hidden.
180 66 : if (mxWindow.is())
181 66 : mxWindow->addEventListener(this);
182 : }
183 : while (false);
184 :
185 192 : return mpWindow;
186 : }
187 :
188 260 : Reference<awt::XWindow> SAL_CALL ChildWindowPane::getWindow()
189 : throw (RuntimeException, std::exception)
190 : {
191 260 : if (mpWindow == nullptr || ! mxWindow.is())
192 192 : GetWindow();
193 260 : return Pane::getWindow();
194 : }
195 :
196 11859 : IMPLEMENT_FORWARD_XINTERFACE2(
197 : ChildWindowPane,
198 : ChildWindowPaneInterfaceBase,
199 : Pane);
200 0 : IMPLEMENT_FORWARD_XTYPEPROVIDER2(
201 : ChildWindowPane,
202 : ChildWindowPaneInterfaceBase,
203 : Pane);
204 :
205 : //----- XEventListener --------------------------------------------------------
206 :
207 66 : void SAL_CALL ChildWindowPane::disposing (const lang::EventObject& rEvent)
208 : throw (RuntimeException, std::exception)
209 : {
210 66 : ThrowIfDisposed();
211 :
212 66 : if (rEvent.Source == mxWindow)
213 : {
214 : // The window is gone but the pane remains alive. The next call to
215 : // GetWindow() may create the window anew.
216 66 : mxWindow = NULL;
217 66 : mpWindow = NULL;
218 : }
219 66 : }
220 :
221 66 : } } // end of namespace sd::framework
222 :
223 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|