1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24 #include "precompiled_sd.hxx"
25
26 #include "ChildWindowPane.hxx"
27
28 #include "PaneDockingWindow.hxx"
29 #include "ViewShellBase.hxx"
30 #include "ViewShellManager.hxx"
31 #include "framework/FrameworkHelper.hxx"
32 #include <toolkit/helper/vclunohelper.hxx>
33 #include <vcl/svapp.hxx>
34
35 using namespace ::com::sun::star;
36 using namespace ::com::sun::star::uno;
37 using namespace ::com::sun::star::drawing::framework;
38
39 namespace sd { namespace framework {
40
41
ChildWindowPane(const Reference<XResourceId> & rxPaneId,sal_uInt16 nChildWindowId,ViewShellBase & rViewShellBase,::std::auto_ptr<SfxShell> pShell)42 ChildWindowPane::ChildWindowPane (
43 const Reference<XResourceId>& rxPaneId,
44 sal_uInt16 nChildWindowId,
45 ViewShellBase& rViewShellBase,
46 ::std::auto_ptr<SfxShell> pShell)
47 : ChildWindowPaneInterfaceBase(rxPaneId,(::Window*)NULL),
48 mnChildWindowId(nChildWindowId),
49 mrViewShellBase(rViewShellBase),
50 mpShell(pShell),
51 mbHasBeenActivated(false)
52 {
53 mrViewShellBase.GetViewShellManager()->ActivateShell(mpShell.get());
54
55 SfxViewFrame* pViewFrame = mrViewShellBase.GetViewFrame();
56 if (pViewFrame != NULL)
57 {
58 if (mrViewShellBase.IsActive())
59 {
60 if (pViewFrame->KnowsChildWindow(mnChildWindowId))
61 {
62 if (pViewFrame->HasChildWindow(mnChildWindowId))
63 {
64 // The ViewShellBase has already been activated. Make
65 // the child window visible as soon as possible.
66 pViewFrame->SetChildWindow(mnChildWindowId, sal_True);
67 OSL_TRACE("ChildWindowPane:activating now");
68 }
69 else
70 {
71 // The window is created asynchronously. Rely on the
72 // ConfigurationUpdater to try another update, and with
73 // that another request for this window, in a short
74 // time.
75 OSL_TRACE("ChildWindowPane:activated asynchronously");
76 }
77 }
78 else
79 {
80 OSL_TRACE("ChildWindowPane:not known");
81 }
82 }
83 else
84 {
85 // The ViewShellBase has not yet been activated. Hide the
86 // window and wait a little before it is made visible. See
87 // comments in the GetWindow() method for an explanation.
88 pViewFrame->SetChildWindow(mnChildWindowId, sal_False);
89 OSL_TRACE("ChildWindowPane:base not active");
90 }
91 }
92 }
93
94
95
96
~ChildWindowPane(void)97 ChildWindowPane::~ChildWindowPane (void) throw()
98 {
99 }
100
101
102
103
Hide(void)104 void ChildWindowPane::Hide (void)
105 {
106 SfxViewFrame* pViewFrame = mrViewShellBase.GetViewFrame();
107 if (pViewFrame != NULL)
108 if (pViewFrame->KnowsChildWindow(mnChildWindowId))
109 if (pViewFrame->HasChildWindow(mnChildWindowId))
110 pViewFrame->SetChildWindow(mnChildWindowId, sal_False);
111
112 // Release the window because when the child window is shown again it
113 // may use a different window.
114 mxWindow = NULL;
115 }
116
117
118
119
disposing(void)120 void SAL_CALL ChildWindowPane::disposing (void)
121 {
122 ::osl::MutexGuard aGuard (maMutex);
123
124 mrViewShellBase.GetViewShellManager()->DeactivateShell(mpShell.get());
125 mpShell.reset();
126
127 if (mxWindow.is())
128 {
129 mxWindow->removeEventListener(this);
130 }
131
132 Pane::disposing();
133 }
134
135
136
137
GetWindow(void)138 ::Window* ChildWindowPane::GetWindow (void)
139 {
140 do
141 {
142 if (mxWindow.is())
143 // Window already exists => nothing to do.
144 break;
145
146 // When the window is not yet present then obtain it only when the
147 // shell has already been activated. The activation is not
148 // necessary for the code to work properly but is used to optimize
149 // the layouting and displaying of the window. When it is made
150 // visible to early then some layouting seems to be made twice or at
151 // an inconvenient time and the overall process of initializing the
152 // Impress takes longer.
153 if ( ! mbHasBeenActivated && mpShell.get()!=NULL && ! mpShell->IsActive())
154 break;
155
156 mbHasBeenActivated = true;
157 SfxViewFrame* pViewFrame = mrViewShellBase.GetViewFrame();
158 if (pViewFrame == NULL)
159 break;
160 // The view frame has to know the child window. This can be the
161 // case, when for example the document is in read-only mode: the
162 // task pane is then not available.
163 if ( ! pViewFrame->KnowsChildWindow(mnChildWindowId))
164 break;
165
166 pViewFrame->SetChildWindow(mnChildWindowId, sal_True);
167 SfxChildWindow* pChildWindow = pViewFrame->GetChildWindow(mnChildWindowId);
168 if (pChildWindow == NULL)
169 if (pViewFrame->HasChildWindow(mnChildWindowId))
170 {
171 // The child window is not yet visible. Ask the view frame
172 // to show it and try again to get access to the child
173 // window.
174 pViewFrame->ShowChildWindow(mnChildWindowId, sal_True);
175 pChildWindow = pViewFrame->GetChildWindow(mnChildWindowId);
176 }
177
178 // When the child window is still not visible then we have to try later.
179 if (pChildWindow == NULL)
180 break;
181
182 // From the child window get the docking window and from that the
183 // content window that is the container for the actual content.
184 PaneDockingWindow* pDockingWindow = dynamic_cast<PaneDockingWindow*>(
185 pChildWindow->GetWindow());
186 if (pDockingWindow == NULL)
187 break;
188
189 // At last, we have access to the window and its UNO wrapper.
190 mpWindow = &pDockingWindow->GetContentWindow();
191 mxWindow = VCLUnoHelper::GetInterface(mpWindow);
192
193 // Register as window listener to be informed when the child window
194 // is hidden.
195 if (mxWindow.is())
196 mxWindow->addEventListener(this);
197 }
198 while (false);
199
200 return mpWindow;
201 }
202
203
204
205
getWindow(void)206 Reference<awt::XWindow> SAL_CALL ChildWindowPane::getWindow (void)
207 throw (RuntimeException)
208 {
209 if (mpWindow == NULL || ! mxWindow.is())
210 GetWindow();
211 return Pane::getWindow();
212 }
213
214
215
216 IMPLEMENT_FORWARD_XINTERFACE2(
217 ChildWindowPane,
218 ChildWindowPaneInterfaceBase,
219 Pane);
220 IMPLEMENT_FORWARD_XTYPEPROVIDER2(
221 ChildWindowPane,
222 ChildWindowPaneInterfaceBase,
223 Pane);
224
225
226
227
228 //----- XEventListener --------------------------------------------------------
229
disposing(const lang::EventObject & rEvent)230 void SAL_CALL ChildWindowPane::disposing (const lang::EventObject& rEvent)
231 throw (RuntimeException)
232 {
233 ThrowIfDisposed();
234
235 if (rEvent.Source == mxWindow)
236 {
237 // The window is gone but the pane remains alive. The next call to
238 // GetWindow() may create the window anew.
239 mxWindow = NULL;
240 mpWindow = NULL;
241 }
242 }
243
244
245
246
247 } } // end of namespace sd::framework
248