fdo#74697 Add Bluez 5 support for impress remote.
[LibreOffice.git] / sd / source / ui / view / FormShellManager.cxx
blob91627e039a1e3dced0faee8fc9a8dcf229a96d87
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
21 #include "FormShellManager.hxx"
23 #include "EventMultiplexer.hxx"
24 #include "ViewShell.hxx"
25 #include "ViewShellBase.hxx"
26 #include "ViewShellManager.hxx"
27 #include "Window.hxx"
28 #include <svx/fmshell.hxx>
30 namespace sd {
32 namespace {
34 /** This factory is responsible for creating and deleting the FmFormShell.
36 class FormShellManagerFactory
37 : public ::sd::ShellFactory<SfxShell>
39 public:
40 FormShellManagerFactory (ViewShell& rViewShell, FormShellManager& rManager);
41 virtual FmFormShell* CreateShell (ShellId nId, ::Window* pParentWindow, FrameView* pFrameView);
42 virtual void ReleaseShell (SfxShell* pShell);
44 private:
45 ::sd::ViewShell& mrViewShell;
46 FormShellManager& mrFormShellManager;
49 } // end of anonymous namespace
52 FormShellManager::FormShellManager (ViewShellBase& rBase)
53 : mrBase(rBase),
54 mpFormShell(NULL),
55 mbFormShellAboveViewShell(false),
56 mpSubShellFactory(),
57 mbIsMainViewChangePending(false),
58 mpMainViewShellWindow(NULL)
60 // Register at the EventMultiplexer to be informed about changes in the
61 // center pane.
62 Link aLink (LINK(this, FormShellManager, ConfigurationUpdateHandler));
63 mrBase.GetEventMultiplexer()->AddEventListener(
64 aLink,
65 sd::tools::EventMultiplexerEvent::EID_MAIN_VIEW_REMOVED
66 | sd::tools::EventMultiplexerEvent::EID_MAIN_VIEW_ADDED
67 | sd::tools::EventMultiplexerEvent::EID_CONFIGURATION_UPDATED);
69 RegisterAtCenterPane();
75 FormShellManager::~FormShellManager (void)
77 SetFormShell(NULL);
78 UnregisterAtCenterPane();
80 // Unregister from the EventMultiplexer.
81 Link aLink (LINK(this, FormShellManager, ConfigurationUpdateHandler));
82 mrBase.GetEventMultiplexer()->RemoveEventListener(aLink);
84 if (mpSubShellFactory.get() != NULL)
86 ViewShell* pShell = mrBase.GetMainViewShell().get();
87 if (pShell != NULL)
88 mrBase.GetViewShellManager()->RemoveSubShellFactory(pShell,mpSubShellFactory);
95 void FormShellManager::SetFormShell (FmFormShell* pFormShell)
97 if (mpFormShell != pFormShell)
99 // Disconnect from the old form shell.
100 if (mpFormShell != NULL)
102 mpFormShell->SetControlActivationHandler(Link());
103 EndListening(*mpFormShell);
104 mpFormShell->SetView(NULL);
107 mpFormShell = pFormShell;
109 // Connect to the new form shell.
110 if (mpFormShell != NULL)
112 mpFormShell->SetControlActivationHandler(
113 LINK(
114 this,
115 FormShellManager,
116 FormControlActivated));
117 StartListening(*mpFormShell);
119 ViewShell* pMainViewShell = mrBase.GetMainViewShell().get();
120 if (pMainViewShell != NULL)
122 // Prevent setting the view twice at the FmFormShell.
123 FmFormView* pFormView = static_cast<FmFormView*>(pMainViewShell->GetView());
124 if (mpFormShell->GetFormView() != pFormView)
125 mpFormShell->SetView(pFormView);
129 // Tell the ViewShellManager where on the stack to place the form shell.
130 mrBase.GetViewShellManager()->SetFormShell(
131 mrBase.GetMainViewShell().get(),
132 mpFormShell,
133 mbFormShellAboveViewShell);
140 FmFormShell* FormShellManager::GetFormShell (void)
142 return mpFormShell;
148 void FormShellManager::RegisterAtCenterPane (void)
150 ViewShell* pShell = mrBase.GetMainViewShell().get();
151 if (pShell == NULL)
152 return;
154 // No form shell for the slide sorter. Besides that it is not
155 // necessary, using both together results in crashes.
156 if (pShell->GetShellType() == ViewShell::ST_SLIDE_SORTER)
157 return;
159 mpMainViewShellWindow = pShell->GetActiveWindow();
160 if (mpMainViewShellWindow == NULL)
161 return;
163 // Register at the window to get informed when to move the form
164 // shell to the bottom of the shell stack.
165 mpMainViewShellWindow->AddEventListener(
166 LINK(
167 this,
168 FormShellManager,
169 WindowEventHandler));
171 // Create a shell factory and with it activate the form shell.
172 OSL_ASSERT(mpSubShellFactory.get()==NULL);
173 mpSubShellFactory.reset(new FormShellManagerFactory(*pShell, *this));
174 mrBase.GetViewShellManager()->AddSubShellFactory(pShell,mpSubShellFactory);
175 mrBase.GetViewShellManager()->ActivateSubShell(*pShell, RID_FORMLAYER_TOOLBOX);
181 void FormShellManager::UnregisterAtCenterPane (void)
183 if (mpMainViewShellWindow != NULL)
185 // Unregister from the window.
186 mpMainViewShellWindow->RemoveEventListener(
187 LINK(
188 this,
189 FormShellManager,
190 WindowEventHandler));
191 mpMainViewShellWindow = NULL;
194 // Unregister form at the form shell.
195 SetFormShell(NULL);
197 // Deactivate the form shell and destroy the shell factory.
198 ViewShell* pShell = mrBase.GetMainViewShell().get();
199 if (pShell != NULL)
201 mrBase.GetViewShellManager()->DeactivateSubShell(*pShell, RID_FORMLAYER_TOOLBOX);
202 mrBase.GetViewShellManager()->RemoveSubShellFactory(pShell, mpSubShellFactory);
205 mpSubShellFactory.reset();
211 IMPL_LINK_NOARG(FormShellManager, FormControlActivated)
213 // The form shell has been actived. To give it priority in reacting to
214 // slot calls the form shell is moved to the top of the object bar shell
215 // stack.
216 ViewShell* pShell = mrBase.GetMainViewShell().get();
217 if (pShell!=NULL && !mbFormShellAboveViewShell)
219 mbFormShellAboveViewShell = true;
221 ViewShellManager::UpdateLock aLock (mrBase.GetViewShellManager());
222 mrBase.GetViewShellManager()->SetFormShell(pShell,mpFormShell,mbFormShellAboveViewShell);
225 return 0;
231 IMPL_LINK(FormShellManager, ConfigurationUpdateHandler, sd::tools::EventMultiplexerEvent*, pEvent)
233 switch (pEvent->meEventId)
235 case sd::tools::EventMultiplexerEvent::EID_MAIN_VIEW_REMOVED:
236 UnregisterAtCenterPane();
237 break;
239 case sd::tools::EventMultiplexerEvent::EID_MAIN_VIEW_ADDED:
240 mbIsMainViewChangePending = true;
241 break;
243 case sd::tools::EventMultiplexerEvent::EID_CONFIGURATION_UPDATED:
244 if (mbIsMainViewChangePending)
246 mbIsMainViewChangePending = false;
247 RegisterAtCenterPane();
249 break;
251 default:
252 break;
255 return 0;
261 IMPL_LINK(FormShellManager, WindowEventHandler, VclWindowEvent*, pEvent)
263 if (pEvent != NULL)
265 switch (pEvent->GetId())
267 case VCLEVENT_WINDOW_GETFOCUS:
269 // The window of the center pane got the focus. Therefore
270 // the form shell is moved to the bottom of the object bar
271 // stack.
272 ViewShell* pShell = mrBase.GetMainViewShell().get();
273 if (pShell!=NULL && mbFormShellAboveViewShell)
275 mbFormShellAboveViewShell = false;
276 ViewShellManager::UpdateLock aLock (mrBase.GetViewShellManager());
277 mrBase.GetViewShellManager()->SetFormShell(
278 pShell,
279 mpFormShell,
280 mbFormShellAboveViewShell);
283 break;
285 case VCLEVENT_WINDOW_LOSEFOCUS:
286 // We follow the sloppy focus policy. Losing the focus is
287 // ignored. We wait for the focus to be placed either in
288 // the window or the form shell. The later, however, is
289 // notified over the FormControlActivated handler, not this
290 // one.
291 break;
293 case VCLEVENT_OBJECT_DYING:
294 mpMainViewShellWindow = NULL;
295 break;
299 return 0;
305 void FormShellManager::Notify(SfxBroadcaster&, const SfxHint& rHint)
307 const SfxSimpleHint* pSimpleHint = dynamic_cast<const SfxSimpleHint*>(&rHint);
308 if (pSimpleHint!=NULL && pSimpleHint->GetId()==SFX_HINT_DYING)
310 // If all goes well this listener is called after the
311 // FormShellManager was notified about the dying form shell by the
312 // FormShellManagerFactory.
313 OSL_ASSERT(mpFormShell==NULL);
314 if (mpFormShell != NULL)
316 mpFormShell = NULL;
317 mrBase.GetViewShellManager()->SetFormShell(
318 mrBase.GetMainViewShell().get(),
319 NULL,
320 false);
329 //===== FormShellManagerFactory ===============================================
331 namespace {
333 FormShellManagerFactory::FormShellManagerFactory (
334 ::sd::ViewShell& rViewShell,
335 FormShellManager& rManager)
336 : mrViewShell(rViewShell),
337 mrFormShellManager(rManager)
344 FmFormShell* FormShellManagerFactory::CreateShell (
345 ::sd::ShellId nId,
346 ::Window*,
347 ::sd::FrameView*)
349 FmFormShell* pShell = NULL;
351 ::sd::View* pView = mrViewShell.GetView();
352 if (nId == RID_FORMLAYER_TOOLBOX)
354 pShell = new FmFormShell(&mrViewShell.GetViewShellBase(), pView);
355 mrFormShellManager.SetFormShell(pShell);
358 return pShell;
364 void FormShellManagerFactory::ReleaseShell (SfxShell* pShell)
366 if (pShell != NULL)
368 mrFormShellManager.SetFormShell(NULL);
369 delete pShell;
373 } // end of anonymous namespace
375 } // end of namespace sd
377 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */