Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : :
30 : : #include "FormShellManager.hxx"
31 : :
32 : : #include "EventMultiplexer.hxx"
33 : : #include "ViewShell.hxx"
34 : : #include "ViewShellBase.hxx"
35 : : #include "ViewShellManager.hxx"
36 : : #include "Window.hxx"
37 : : #include <svx/fmshell.hxx>
38 : :
39 : : namespace sd {
40 : :
41 : : namespace {
42 : :
43 : : /** This factory is responsible for creating and deleting the FmFormShell.
44 : : */
45 [ - + ]: 260 : class FormShellManagerFactory
46 : : : public ::sd::ShellFactory<SfxShell>
47 : : {
48 : : public:
49 : : FormShellManagerFactory (ViewShell& rViewShell, FormShellManager& rManager);
50 : : virtual FmFormShell* CreateShell (ShellId nId, ::Window* pParentWindow, FrameView* pFrameView);
51 : : virtual void ReleaseShell (SfxShell* pShell);
52 : :
53 : : private:
54 : : ::sd::ViewShell& mrViewShell;
55 : : FormShellManager& mrFormShellManager;
56 : : };
57 : :
58 : : } // end of anonymous namespace
59 : :
60 : :
61 : 130 : FormShellManager::FormShellManager (ViewShellBase& rBase)
62 : : : mrBase(rBase),
63 : : mpFormShell(NULL),
64 : : mbFormShellAboveViewShell(false),
65 : : mpSubShellFactory(),
66 : : mbIsMainViewChangePending(false),
67 [ + - ]: 130 : mpMainViewShellWindow(NULL)
68 : : {
69 : : // Register at the EventMultiplexer to be informed about changes in the
70 : : // center pane.
71 [ + - ]: 130 : Link aLink (LINK(this, FormShellManager, ConfigurationUpdateHandler));
72 : : mrBase.GetEventMultiplexer()->AddEventListener(
73 : : aLink,
74 : : sd::tools::EventMultiplexerEvent::EID_MAIN_VIEW_REMOVED
75 : : | sd::tools::EventMultiplexerEvent::EID_MAIN_VIEW_ADDED
76 [ + - ][ + - ]: 130 : | sd::tools::EventMultiplexerEvent::EID_CONFIGURATION_UPDATED);
[ + - ]
77 : :
78 [ + - ]: 130 : RegisterAtCenterPane();
79 : 130 : }
80 : :
81 : :
82 : :
83 : :
84 [ + - ]: 130 : FormShellManager::~FormShellManager (void)
85 : : {
86 [ + - ]: 130 : SetFormShell(NULL);
87 [ + - ]: 130 : UnregisterAtCenterPane();
88 : :
89 : : // Unregister from the EventMultiplexer.
90 [ + - ]: 130 : Link aLink (LINK(this, FormShellManager, ConfigurationUpdateHandler));
91 [ + - ][ + - ]: 130 : mrBase.GetEventMultiplexer()->RemoveEventListener(aLink);
[ + - ]
92 : :
93 [ - + ]: 130 : if (mpSubShellFactory.get() != NULL)
94 : : {
95 [ # # ][ # # ]: 0 : ViewShell* pShell = mrBase.GetMainViewShell().get();
96 [ # # ]: 0 : if (pShell != NULL)
97 [ # # ][ # # ]: 0 : mrBase.GetViewShellManager()->RemoveSubShellFactory(pShell,mpSubShellFactory);
[ # # ]
98 : : }
99 [ - + ]: 260 : }
100 : :
101 : :
102 : :
103 : :
104 : 650 : void FormShellManager::SetFormShell (FmFormShell* pFormShell)
105 : : {
106 [ + + ]: 650 : if (mpFormShell != pFormShell)
107 : : {
108 : : // Disconnect from the old form shell.
109 [ + + ]: 260 : if (mpFormShell != NULL)
110 : : {
111 [ + - ]: 130 : mpFormShell->SetControlActivationHandler(Link());
112 : 130 : EndListening(*mpFormShell);
113 : 130 : mpFormShell->SetView(NULL);
114 : : }
115 : :
116 : 260 : mpFormShell = pFormShell;
117 : :
118 : : // Connect to the new form shell.
119 [ + + ]: 260 : if (mpFormShell != NULL)
120 : : {
121 : : mpFormShell->SetControlActivationHandler(
122 : : LINK(
123 : : this,
124 : : FormShellManager,
125 [ + - ]: 130 : FormControlActivated));
126 : 130 : StartListening(*mpFormShell);
127 : :
128 : 130 : ViewShell* pMainViewShell = mrBase.GetMainViewShell().get();
129 [ + - ]: 130 : if (pMainViewShell != NULL)
130 : : {
131 : : // Prevent setting the view twice at the FmFormShell.
132 : 130 : FmFormView* pFormView = static_cast<FmFormView*>(pMainViewShell->GetView());
133 [ - + ]: 130 : if (mpFormShell->GetFormView() != pFormView)
134 : 0 : mpFormShell->SetView(pFormView);
135 : : }
136 : : }
137 : :
138 : : // Tell the ViewShellManager where on the stack to place the form shell.
139 : : mrBase.GetViewShellManager()->SetFormShell(
140 : 520 : mrBase.GetMainViewShell().get(),
141 : : mpFormShell,
142 [ + - ][ + - ]: 260 : mbFormShellAboveViewShell);
[ + - ]
143 : : }
144 : 650 : }
145 : :
146 : :
147 : :
148 : :
149 : 1376 : FmFormShell* FormShellManager::GetFormShell (void)
150 : : {
151 : 1376 : return mpFormShell;
152 : : }
153 : :
154 : :
155 : :
156 : :
157 : 260 : void FormShellManager::RegisterAtCenterPane (void)
158 : : {
159 : 260 : ViewShell* pShell = mrBase.GetMainViewShell().get();
160 [ + + ]: 260 : if (pShell == NULL)
161 : 130 : return;
162 : :
163 : : // No form shell for the slide sorter. Besides that it is not
164 : : // necessary, using both together results in crashes.
165 [ - + ]: 130 : if (pShell->GetShellType() == ViewShell::ST_SLIDE_SORTER)
166 : 0 : return;
167 : :
168 : 130 : mpMainViewShellWindow = pShell->GetActiveWindow();
169 [ - + ]: 130 : if (mpMainViewShellWindow == NULL)
170 : 0 : return;
171 : :
172 : : // Register at the window to get informed when to move the form
173 : : // shell to the bottom of the shell stack.
174 : : mpMainViewShellWindow->AddEventListener(
175 : : LINK(
176 : : this,
177 : : FormShellManager,
178 [ + - ]: 130 : WindowEventHandler));
179 : :
180 : : // Create a shell factory and with it activate the form shell.
181 : : OSL_ASSERT(mpSubShellFactory.get()==NULL);
182 [ + - ]: 130 : mpSubShellFactory.reset(new FormShellManagerFactory(*pShell, *this));
183 [ + - ]: 130 : mrBase.GetViewShellManager()->AddSubShellFactory(pShell,mpSubShellFactory);
184 [ + - ]: 260 : mrBase.GetViewShellManager()->ActivateSubShell(*pShell, RID_FORMLAYER_TOOLBOX);
185 : : }
186 : :
187 : :
188 : :
189 : :
190 : 260 : void FormShellManager::UnregisterAtCenterPane (void)
191 : : {
192 [ + + ]: 260 : if (mpMainViewShellWindow != NULL)
193 : : {
194 : : // Unregister from the window.
195 : : mpMainViewShellWindow->RemoveEventListener(
196 : : LINK(
197 : : this,
198 : : FormShellManager,
199 [ + - ]: 130 : WindowEventHandler));
200 : 130 : mpMainViewShellWindow = NULL;
201 : : }
202 : :
203 : : // Unregister form at the form shell.
204 : 260 : SetFormShell(NULL);
205 : :
206 : : // Deactivate the form shell and destroy the shell factory.
207 : 260 : ViewShell* pShell = mrBase.GetMainViewShell().get();
208 [ - + ]: 260 : if (pShell != NULL)
209 : : {
210 [ # # ]: 0 : mrBase.GetViewShellManager()->DeactivateSubShell(*pShell, RID_FORMLAYER_TOOLBOX);
211 [ # # ]: 0 : mrBase.GetViewShellManager()->RemoveSubShellFactory(pShell, mpSubShellFactory);
212 : : }
213 : :
214 : 260 : mpSubShellFactory.reset();
215 : 260 : }
216 : :
217 : :
218 : :
219 : :
220 : 0 : IMPL_LINK_NOARG(FormShellManager, FormControlActivated)
221 : : {
222 : : // The form shell has been actived. To give it priority in reacting to
223 : : // slot calls the form shell is moved to the top of the object bar shell
224 : : // stack.
225 : 0 : ViewShell* pShell = mrBase.GetMainViewShell().get();
226 [ # # ][ # # ]: 0 : if (pShell!=NULL && !mbFormShellAboveViewShell)
227 : : {
228 : 0 : mbFormShellAboveViewShell = true;
229 : :
230 [ # # ][ # # ]: 0 : ViewShellManager::UpdateLock aLock (mrBase.GetViewShellManager());
[ # # ]
231 [ # # ][ # # ]: 0 : mrBase.GetViewShellManager()->SetFormShell(pShell,mpFormShell,mbFormShellAboveViewShell);
[ # # ][ # # ]
232 : : }
233 : :
234 : 0 : return 0;
235 : : }
236 : :
237 : :
238 : :
239 : :
240 : 6905 : IMPL_LINK(FormShellManager, ConfigurationUpdateHandler, sd::tools::EventMultiplexerEvent*, pEvent)
241 : : {
242 [ + + + + ]: 6905 : switch (pEvent->meEventId)
243 : : {
244 : : case sd::tools::EventMultiplexerEvent::EID_MAIN_VIEW_REMOVED:
245 : 130 : UnregisterAtCenterPane();
246 : 130 : break;
247 : :
248 : : case sd::tools::EventMultiplexerEvent::EID_MAIN_VIEW_ADDED:
249 : 130 : mbIsMainViewChangePending = true;
250 : 130 : break;
251 : :
252 : : case sd::tools::EventMultiplexerEvent::EID_CONFIGURATION_UPDATED:
253 [ + + ]: 412 : if (mbIsMainViewChangePending)
254 : : {
255 : 130 : mbIsMainViewChangePending = false;
256 : 130 : RegisterAtCenterPane();
257 : : }
258 : 412 : break;
259 : :
260 : : default:
261 : 6233 : break;
262 : : }
263 : :
264 : 6905 : return 0;
265 : : }
266 : :
267 : :
268 : :
269 : :
270 : 760 : IMPL_LINK(FormShellManager, WindowEventHandler, VclWindowEvent*, pEvent)
271 : : {
272 [ + - ]: 760 : if (pEvent != NULL)
273 : : {
274 [ - - - + ]: 760 : switch (pEvent->GetId())
275 : : {
276 : : case VCLEVENT_WINDOW_GETFOCUS:
277 : : {
278 : : // The window of the center pane got the focus. Therefore
279 : : // the form shell is moved to the bottom of the object bar
280 : : // stack.
281 : 0 : ViewShell* pShell = mrBase.GetMainViewShell().get();
282 [ # # ][ # # ]: 0 : if (pShell!=NULL && mbFormShellAboveViewShell)
283 : : {
284 : 0 : mbFormShellAboveViewShell = false;
285 [ # # ][ # # ]: 0 : ViewShellManager::UpdateLock aLock (mrBase.GetViewShellManager());
[ # # ]
286 : : mrBase.GetViewShellManager()->SetFormShell(
287 : : pShell,
288 : : mpFormShell,
289 [ # # ][ # # ]: 0 : mbFormShellAboveViewShell);
[ # # ][ # # ]
290 : : }
291 : : }
292 : 0 : break;
293 : :
294 : : case VCLEVENT_WINDOW_LOSEFOCUS:
295 : : // We follow the sloppy focus policy. Losing the focus is
296 : : // ignored. We wait for the focus to be placed either in
297 : : // the window or the form shell. The later, however, is
298 : : // notified over the FormControlActivated handler, not this
299 : : // one.
300 : 0 : break;
301 : :
302 : : case VCLEVENT_OBJECT_DYING:
303 : 0 : mpMainViewShellWindow = NULL;
304 : 760 : break;
305 : : }
306 : : }
307 : :
308 : 760 : return 0;
309 : : }
310 : :
311 : :
312 : :
313 : :
314 : 15 : void FormShellManager::Notify(SfxBroadcaster&, const SfxHint& rHint)
315 : : {
316 [ - + ]: 15 : const SfxSimpleHint* pSimpleHint = dynamic_cast<const SfxSimpleHint*>(&rHint);
317 [ - + ][ # # ]: 15 : if (pSimpleHint!=NULL && pSimpleHint->GetId()==SFX_HINT_DYING)
[ - + ]
318 : : {
319 : : // If all goes well this listener is called after the
320 : : // FormShellManager was notified about the dying form shell by the
321 : : // FormShellManagerFactory.
322 : : OSL_ASSERT(mpFormShell==NULL);
323 [ # # ]: 0 : if (mpFormShell != NULL)
324 : : {
325 : 0 : mpFormShell = NULL;
326 : : mrBase.GetViewShellManager()->SetFormShell(
327 : 0 : mrBase.GetMainViewShell().get(),
328 : : NULL,
329 [ # # ][ # # ]: 0 : false);
[ # # ]
330 : : }
331 : : }
332 : 15 : }
333 : :
334 : :
335 : :
336 : :
337 : :
338 : : //===== FormShellManagerFactory ===============================================
339 : :
340 : : namespace {
341 : :
342 : 130 : FormShellManagerFactory::FormShellManagerFactory (
343 : : ::sd::ViewShell& rViewShell,
344 : : FormShellManager& rManager)
345 : : : mrViewShell(rViewShell),
346 : 130 : mrFormShellManager(rManager)
347 : : {
348 : 130 : }
349 : :
350 : :
351 : :
352 : :
353 : 130 : FmFormShell* FormShellManagerFactory::CreateShell (
354 : : ::sd::ShellId nId,
355 : : ::Window*,
356 : : ::sd::FrameView*)
357 : : {
358 : 130 : FmFormShell* pShell = NULL;
359 : :
360 : 130 : ::sd::View* pView = mrViewShell.GetView();
361 [ + - ]: 130 : if (nId == RID_FORMLAYER_TOOLBOX)
362 : : {
363 [ + - ]: 130 : pShell = new FmFormShell(&mrViewShell.GetViewShellBase(), pView);
364 : 130 : mrFormShellManager.SetFormShell(pShell);
365 : : }
366 : :
367 : 130 : return pShell;
368 : : }
369 : :
370 : :
371 : :
372 : :
373 : 130 : void FormShellManagerFactory::ReleaseShell (SfxShell* pShell)
374 : : {
375 [ + - ]: 130 : if (pShell != NULL)
376 : : {
377 : 130 : mrFormShellManager.SetFormShell(NULL);
378 [ + - ]: 130 : delete pShell;
379 : : }
380 : 130 : }
381 : :
382 : : } // end of anonymous namespace
383 : :
384 : : } // end of namespace sd
385 : :
386 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|