1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: FormShellManager.cxx,v $
10 * $Revision: 1.12.34.1 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sd.hxx"
34 #include "FormShellManager.hxx"
36 #include "EventMultiplexer.hxx"
37 #include "ViewShell.hxx"
38 #include "ViewShellBase.hxx"
39 #include "ViewShellManager.hxx"
41 #include <svx/fmshell.hxx>
47 /** This factory is responsible for creating and deleting the FmFormShell.
49 class FormShellManagerFactory
50 : public ::sd::ShellFactory
<SfxShell
>
53 FormShellManagerFactory (ViewShell
& rViewShell
, FormShellManager
& rManager
);
54 virtual FmFormShell
* CreateShell (ShellId nId
, ::Window
* pParentWindow
, FrameView
* pFrameView
);
55 virtual void ReleaseShell (SfxShell
* pShell
);
58 ::sd::ViewShell
& mrViewShell
;
59 FormShellManager
& mrFormShellManager
;
62 } // end of anonymous namespace
65 FormShellManager::FormShellManager (ViewShellBase
& rBase
)
68 mbFormShellAboveViewShell(false),
70 mbIsMainViewChangePending(false),
71 mpMainViewShellWindow(NULL
)
73 // Register at the EventMultiplexer to be informed about changes in the
75 Link
aLink (LINK(this, FormShellManager
, ConfigurationUpdateHandler
));
76 mrBase
.GetEventMultiplexer()->AddEventListener(
78 sd::tools::EventMultiplexerEvent::EID_MAIN_VIEW_REMOVED
79 | sd::tools::EventMultiplexerEvent::EID_MAIN_VIEW_ADDED
80 | sd::tools::EventMultiplexerEvent::EID_CONFIGURATION_UPDATED
);
82 RegisterAtCenterPane();
88 FormShellManager::~FormShellManager (void)
91 UnregisterAtCenterPane();
93 // Unregister from the EventMultiplexer.
94 Link
aLink (LINK(this, FormShellManager
, ConfigurationUpdateHandler
));
95 mrBase
.GetEventMultiplexer()->RemoveEventListener(aLink
);
97 if (mpSubShellFactory
.get() != NULL
)
99 ViewShell
* pShell
= mrBase
.GetMainViewShell().get();
101 mrBase
.GetViewShellManager()->RemoveSubShellFactory(pShell
,mpSubShellFactory
);
108 void FormShellManager::SetFormShell (FmFormShell
* pFormShell
)
110 if (mpFormShell
!= pFormShell
)
112 // Disconnect from the old form shell.
113 if (mpFormShell
!= NULL
)
115 mpFormShell
->SetControlActivationHandler(Link());
116 EndListening(*mpFormShell
);
117 mpFormShell
->SetView(NULL
);
120 mpFormShell
= pFormShell
;
122 // Connect to the new form shell.
123 if (mpFormShell
!= NULL
)
125 mpFormShell
->SetControlActivationHandler(
129 FormControlActivated
));
130 StartListening(*mpFormShell
);
132 ViewShell
* pMainViewShell
= mrBase
.GetMainViewShell().get();
133 if (pMainViewShell
!= NULL
)
135 // Prevent setting the view twice at the FmFormShell.
136 FmFormView
* pFormView
= static_cast<FmFormView
*>(pMainViewShell
->GetView());
137 if (mpFormShell
->GetFormView() != pFormView
)
138 mpFormShell
->SetView(pFormView
);
142 // Tell the ViewShellManager where on the stack to place the form shell.
143 mrBase
.GetViewShellManager()->SetFormShell(
144 mrBase
.GetMainViewShell().get(),
146 mbFormShellAboveViewShell
);
153 FmFormShell
* FormShellManager::GetFormShell (void)
161 void FormShellManager::RegisterAtCenterPane (void)
165 ViewShell
* pShell
= mrBase
.GetMainViewShell().get();
169 // No form shell for the slide sorter. Besides that it is not
170 // necessary, using both together results in crashes.
171 if (pShell
->GetShellType() == ViewShell::ST_SLIDE_SORTER
)
174 mpMainViewShellWindow
= pShell
->GetActiveWindow();
175 if (mpMainViewShellWindow
== NULL
)
178 // Register at the window to get informed when to move the form
179 // shell to the bottom of the shell stack.
180 mpMainViewShellWindow
->AddEventListener(
184 WindowEventHandler
));
186 // Create a shell factory and with it activate the form shell.
187 OSL_ASSERT(mpSubShellFactory
.get()==NULL
);
188 mpSubShellFactory
.reset(new FormShellManagerFactory(*pShell
, *this));
189 mrBase
.GetViewShellManager()->AddSubShellFactory(pShell
,mpSubShellFactory
);
190 mrBase
.GetViewShellManager()->ActivateSubShell(*pShell
, RID_FORMLAYER_TOOLBOX
);
198 void FormShellManager::UnregisterAtCenterPane (void)
202 if (mpMainViewShellWindow
!= NULL
)
204 // Unregister from the window.
205 mpMainViewShellWindow
->RemoveEventListener(
209 WindowEventHandler
));
210 mpMainViewShellWindow
= NULL
;
213 // Unregister form at the form shell.
216 // Deactivate the form shell and destroy the shell factory.
217 ViewShell
* pShell
= mrBase
.GetMainViewShell().get();
220 mrBase
.GetViewShellManager()->DeactivateSubShell(*pShell
, RID_FORMLAYER_TOOLBOX
);
221 mrBase
.GetViewShellManager()->RemoveSubShellFactory(pShell
, mpSubShellFactory
);
224 mpSubShellFactory
.reset();
232 IMPL_LINK(FormShellManager
, FormControlActivated
, FmFormShell
*, EMPTYARG
)
234 // The form shell has been actived. To give it priority in reacting to
235 // slot calls the form shell is moved to the top of the object bar shell
237 ViewShell
* pShell
= mrBase
.GetMainViewShell().get();
238 if (pShell
!=NULL
&& !mbFormShellAboveViewShell
)
240 mbFormShellAboveViewShell
= true;
242 ViewShellManager::UpdateLock
aLock (mrBase
.GetViewShellManager());
243 mrBase
.GetViewShellManager()->SetFormShell(pShell
,mpFormShell
,mbFormShellAboveViewShell
);
252 IMPL_LINK(FormShellManager
, ConfigurationUpdateHandler
, sd::tools::EventMultiplexerEvent
*, pEvent
)
254 switch (pEvent
->meEventId
)
256 case sd::tools::EventMultiplexerEvent::EID_MAIN_VIEW_REMOVED
:
257 UnregisterAtCenterPane();
260 case sd::tools::EventMultiplexerEvent::EID_MAIN_VIEW_ADDED
:
261 mbIsMainViewChangePending
= true;
264 case sd::tools::EventMultiplexerEvent::EID_CONFIGURATION_UPDATED
:
265 if (mbIsMainViewChangePending
)
267 mbIsMainViewChangePending
= false;
268 RegisterAtCenterPane();
282 IMPL_LINK(FormShellManager
, WindowEventHandler
, VclWindowEvent
*, pEvent
)
286 switch (pEvent
->GetId())
288 case VCLEVENT_WINDOW_GETFOCUS
:
290 // The window of the center pane got the focus. Therefore
291 // the form shell is moved to the bottom of the object bar
293 ViewShell
* pShell
= mrBase
.GetMainViewShell().get();
294 if (pShell
!=NULL
&& mbFormShellAboveViewShell
)
296 mbFormShellAboveViewShell
= false;
297 ViewShellManager::UpdateLock
aLock (mrBase
.GetViewShellManager());
298 mrBase
.GetViewShellManager()->SetFormShell(
301 mbFormShellAboveViewShell
);
306 case VCLEVENT_WINDOW_LOSEFOCUS
:
307 // We follow the sloppy focus policy. Losing the focus is
308 // ignored. We wait for the focus to be placed either in
309 // the window or the form shell. The later, however, is
310 // notified over the FormControlActivated handler, not this
314 case VCLEVENT_OBJECT_DYING
:
315 mpMainViewShellWindow
= NULL
;
326 void FormShellManager::Notify(SfxBroadcaster
&, const SfxHint
& rHint
)
328 const SfxSimpleHint
* pSimpleHint
= dynamic_cast<const SfxSimpleHint
*>(&rHint
);
329 if (pSimpleHint
!=NULL
&& pSimpleHint
->GetId()==SFX_HINT_DYING
)
331 // If all goes well this listener is called after the
332 // FormShellManager was notified about the dying form shell by the
333 // FormShellManagerFactory.
334 OSL_ASSERT(mpFormShell
==NULL
);
335 if (mpFormShell
!= NULL
)
338 mrBase
.GetViewShellManager()->SetFormShell(
339 mrBase
.GetMainViewShell().get(),
350 //===== FormShellManagerFactory ===============================================
354 FormShellManagerFactory::FormShellManagerFactory (
355 ::sd::ViewShell
& rViewShell
,
356 FormShellManager
& rManager
)
357 : mrViewShell(rViewShell
),
358 mrFormShellManager(rManager
)
365 FmFormShell
* FormShellManagerFactory::CreateShell (
370 FmFormShell
* pShell
= NULL
;
372 ::sd::View
* pView
= mrViewShell
.GetView();
373 if (nId
== RID_FORMLAYER_TOOLBOX
)
375 pShell
= new FmFormShell(&mrViewShell
.GetViewShellBase(), pView
);
376 mrFormShellManager
.SetFormShell(pShell
);
385 void FormShellManagerFactory::ReleaseShell (SfxShell
* pShell
)
389 mrFormShellManager
.SetFormShell(NULL
);
394 } // end of anonymous namespace
396 } // end of namespace sd