1*22de8995SAndre Fischer /**************************************************************
2*22de8995SAndre Fischer  *
3*22de8995SAndre Fischer  * Licensed to the Apache Software Foundation (ASF) under one
4*22de8995SAndre Fischer  * or more contributor license agreements.  See the NOTICE file
5*22de8995SAndre Fischer  * distributed with this work for additional information
6*22de8995SAndre Fischer  * regarding copyright ownership.  The ASF licenses this file
7*22de8995SAndre Fischer  * to you under the Apache License, Version 2.0 (the
8*22de8995SAndre Fischer  * "License"); you may not use this file except in compliance
9*22de8995SAndre Fischer  * with the License.  You may obtain a copy of the License at
10*22de8995SAndre Fischer  *
11*22de8995SAndre Fischer  *   http://www.apache.org/licenses/LICENSE-2.0
12*22de8995SAndre Fischer  *
13*22de8995SAndre Fischer  * Unless required by applicable law or agreed to in writing,
14*22de8995SAndre Fischer  * software distributed under the License is distributed on an
15*22de8995SAndre Fischer  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*22de8995SAndre Fischer  * KIND, either express or implied.  See the License for the
17*22de8995SAndre Fischer  * specific language governing permissions and limitations
18*22de8995SAndre Fischer  * under the License.
19*22de8995SAndre Fischer  *
20*22de8995SAndre Fischer  *************************************************************/
21*22de8995SAndre Fischer 
22*22de8995SAndre Fischer #include "precompiled_sfx2.hxx"
23*22de8995SAndre Fischer 
24*22de8995SAndre Fischer #include "SidebarController.hxx"
25*22de8995SAndre Fischer #include "Deck.hxx"
26*22de8995SAndre Fischer #include "Panel.hxx"
27*22de8995SAndre Fischer #include "TitleBar.hxx"
28*22de8995SAndre Fischer #include "SidebarLayouter.hxx"
29*22de8995SAndre Fischer #include "TabBar.hxx"
30*22de8995SAndre Fischer #include "sfxresid.hxx"
31*22de8995SAndre Fischer #include "sfx2/sfxsids.hrc"
32*22de8995SAndre Fischer 
33*22de8995SAndre Fischer #include <com/sun/star/ui/ContextChangeEventMultiplexer.hpp>
34*22de8995SAndre Fischer #include <com/sun/star/ui/ContextChangeEventObject.hpp>
35*22de8995SAndre Fischer 
36*22de8995SAndre Fischer #include <boost/bind.hpp>
37*22de8995SAndre Fischer #include <comphelper/componentfactory.hxx>
38*22de8995SAndre Fischer #include <comphelper/componentcontext.hxx>
39*22de8995SAndre Fischer #include <comphelper/namedvaluecollection.hxx>
40*22de8995SAndre Fischer 
41*22de8995SAndre Fischer 
42*22de8995SAndre Fischer using namespace css;
43*22de8995SAndre Fischer using namespace cssu;
44*22de8995SAndre Fischer 
45*22de8995SAndre Fischer 
46*22de8995SAndre Fischer #define A2S(pString) (::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(pString)))
47*22de8995SAndre Fischer 
48*22de8995SAndre Fischer namespace sfx2 {
49*22de8995SAndre Fischer 
50*22de8995SAndre Fischer 
51*22de8995SAndre Fischer class SidebarController::Configuration
52*22de8995SAndre Fischer {
53*22de8995SAndre Fischer public:
54*22de8995SAndre Fischer     Deck* mpDeck;
55*22de8995SAndre Fischer     ::std::vector<Panel*> maPanels;
56*22de8995SAndre Fischer 
57*22de8995SAndre Fischer     Configuration (void);
58*22de8995SAndre Fischer     void Disable (void);
59*22de8995SAndre Fischer     void Activate (void);
60*22de8995SAndre Fischer };
61*22de8995SAndre Fischer 
62*22de8995SAndre Fischer 
63*22de8995SAndre Fischer 
64*22de8995SAndre Fischer 
65*22de8995SAndre Fischer SidebarController::SidebarController (
66*22de8995SAndre Fischer     Window* pParentWindow,
67*22de8995SAndre Fischer     const cssu::Reference<css::frame::XFrame>& rxFrame)
68*22de8995SAndre Fischer     : SidebarControllerInterfaceBase(m_aMutex),
69*22de8995SAndre Fischer       mpCurrentConfiguration(),
70*22de8995SAndre Fischer       mpParentWindow(pParentWindow),
71*22de8995SAndre Fischer       mpTabBar(new TabBar(mpParentWindow)),
72*22de8995SAndre Fischer       mxFrame(rxFrame)
73*22de8995SAndre Fischer {
74*22de8995SAndre Fischer     if (pParentWindow == NULL)
75*22de8995SAndre Fischer     {
76*22de8995SAndre Fischer         OSL_ASSERT(pParentWindow!=NULL);
77*22de8995SAndre Fischer             return;
78*22de8995SAndre Fischer     }
79*22de8995SAndre Fischer 
80*22de8995SAndre Fischer     UpdateConfiguration(Context(A2S("default"), A2S("default")));
81*22de8995SAndre Fischer 
82*22de8995SAndre Fischer     // Listen for context change events.
83*22de8995SAndre Fischer     cssu::Reference<css::ui::XContextChangeEventMultiplexer> xMultiplexer (
84*22de8995SAndre Fischer         css::ui::ContextChangeEventMultiplexer::get(
85*22de8995SAndre Fischer             ::comphelper::getProcessComponentContext()));
86*22de8995SAndre Fischer     if (xMultiplexer.is())
87*22de8995SAndre Fischer         xMultiplexer->addContextChangeEventListener(
88*22de8995SAndre Fischer             static_cast<css::ui::XContextChangeEventListener*>(this),
89*22de8995SAndre Fischer             NULL);
90*22de8995SAndre Fischer 
91*22de8995SAndre Fischer     // Listen for window events.
92*22de8995SAndre Fischer     mpParentWindow->AddEventListener(LINK(this, SidebarController, WindowEventHandler));
93*22de8995SAndre Fischer }
94*22de8995SAndre Fischer 
95*22de8995SAndre Fischer 
96*22de8995SAndre Fischer 
97*22de8995SAndre Fischer 
98*22de8995SAndre Fischer SidebarController::~SidebarController (void)
99*22de8995SAndre Fischer {
100*22de8995SAndre Fischer }
101*22de8995SAndre Fischer 
102*22de8995SAndre Fischer 
103*22de8995SAndre Fischer 
104*22de8995SAndre Fischer 
105*22de8995SAndre Fischer void SAL_CALL SidebarController::disposing (void)
106*22de8995SAndre Fischer {
107*22de8995SAndre Fischer     cssu::Reference<css::ui::XContextChangeEventMultiplexer> xMultiplexer (
108*22de8995SAndre Fischer         css::ui::ContextChangeEventMultiplexer::get(
109*22de8995SAndre Fischer             ::comphelper::getProcessComponentContext()));
110*22de8995SAndre Fischer     if (xMultiplexer.is())
111*22de8995SAndre Fischer         xMultiplexer->removeAllContextChangeEventListeners(
112*22de8995SAndre Fischer             static_cast<css::ui::XContextChangeEventListener*>(this));
113*22de8995SAndre Fischer 
114*22de8995SAndre Fischer     if (mpParentWindow != NULL)
115*22de8995SAndre Fischer     {
116*22de8995SAndre Fischer         mpParentWindow->RemoveEventListener(LINK(this, SidebarController, WindowEventHandler));
117*22de8995SAndre Fischer         mpParentWindow = NULL;
118*22de8995SAndre Fischer     }
119*22de8995SAndre Fischer }
120*22de8995SAndre Fischer 
121*22de8995SAndre Fischer 
122*22de8995SAndre Fischer 
123*22de8995SAndre Fischer 
124*22de8995SAndre Fischer void SAL_CALL SidebarController::notifyContextChangeEvent (const css::ui::ContextChangeEventObject& rEvent)
125*22de8995SAndre Fischer     throw(cssu::RuntimeException)
126*22de8995SAndre Fischer {
127*22de8995SAndre Fischer     UpdateConfiguration(Context(rEvent.ApplicationName, rEvent.ContextName));
128*22de8995SAndre Fischer }
129*22de8995SAndre Fischer 
130*22de8995SAndre Fischer 
131*22de8995SAndre Fischer 
132*22de8995SAndre Fischer 
133*22de8995SAndre Fischer void SAL_CALL SidebarController::disposing (const css::lang::EventObject& rEventObject)
134*22de8995SAndre Fischer     throw(cssu::RuntimeException)
135*22de8995SAndre Fischer {
136*22de8995SAndre Fischer     if (mpCurrentConfiguration)
137*22de8995SAndre Fischer     {
138*22de8995SAndre Fischer         mpCurrentConfiguration->Disable();
139*22de8995SAndre Fischer         mpCurrentConfiguration.reset();
140*22de8995SAndre Fischer     }
141*22de8995SAndre Fischer     if (mpTabBar != NULL)
142*22de8995SAndre Fischer     {
143*22de8995SAndre Fischer         mpTabBar->Hide();
144*22de8995SAndre Fischer         delete mpTabBar;
145*22de8995SAndre Fischer         mpTabBar = NULL;
146*22de8995SAndre Fischer     }
147*22de8995SAndre Fischer }
148*22de8995SAndre Fischer 
149*22de8995SAndre Fischer 
150*22de8995SAndre Fischer 
151*22de8995SAndre Fischer 
152*22de8995SAndre Fischer void SidebarController::NotifyResize (void)
153*22de8995SAndre Fischer {
154*22de8995SAndre Fischer     if (mpCurrentConfiguration != NULL)
155*22de8995SAndre Fischer     {
156*22de8995SAndre Fischer         SidebarLayouter::LayoutSidebar(mpCurrentConfiguration->mpDeck, mpTabBar);
157*22de8995SAndre Fischer         SidebarLayouter::LayoutPanels(mpCurrentConfiguration->mpDeck, mpCurrentConfiguration->maPanels);
158*22de8995SAndre Fischer     }
159*22de8995SAndre Fischer }
160*22de8995SAndre Fischer 
161*22de8995SAndre Fischer 
162*22de8995SAndre Fischer 
163*22de8995SAndre Fischer 
164*22de8995SAndre Fischer void SidebarController::UpdateConfiguration (const Context& rContext)
165*22de8995SAndre Fischer {
166*22de8995SAndre Fischer     ::boost::scoped_ptr<Configuration> pConfiguration(new Configuration());
167*22de8995SAndre Fischer 
168*22de8995SAndre Fischer     SharedContentPanelManager pContentManager (ContentPanelManager::Instance());
169*22de8995SAndre Fischer     pContentManager->CallForBestMatchingDeck (
170*22de8995SAndre Fischer         ::boost::bind(&SidebarController::ProcessMatchingDeck, this, _1, ::boost::ref(*pConfiguration)),
171*22de8995SAndre Fischer         rContext);
172*22de8995SAndre Fischer 
173*22de8995SAndre Fischer     if (pConfiguration->mpDeck == NULL)
174*22de8995SAndre Fischer         return;
175*22de8995SAndre Fischer 
176*22de8995SAndre Fischer     pContentManager->CallForMatchingPanels (
177*22de8995SAndre Fischer         ::boost::bind(&SidebarController::ProcessMatchingPanel, this, _1, ::boost::ref(*pConfiguration)),
178*22de8995SAndre Fischer         rContext,
179*22de8995SAndre Fischer         pConfiguration->mpDeck->GetId());
180*22de8995SAndre Fischer 
181*22de8995SAndre Fischer     MakeConfigurationCurrent(*pConfiguration);
182*22de8995SAndre Fischer     mpCurrentConfiguration.swap(pConfiguration);
183*22de8995SAndre Fischer }
184*22de8995SAndre Fischer 
185*22de8995SAndre Fischer 
186*22de8995SAndre Fischer 
187*22de8995SAndre Fischer 
188*22de8995SAndre Fischer void SidebarController::ProcessMatchingDeck (
189*22de8995SAndre Fischer     const DeckDescriptor& rDeckDescriptor,
190*22de8995SAndre Fischer     Configuration& rConfiguration)
191*22de8995SAndre Fischer {
192*22de8995SAndre Fischer     if (rConfiguration.mpDeck != NULL)
193*22de8995SAndre Fischer     {
194*22de8995SAndre Fischer         // When more than one deck matches the context then choose the first.
195*22de8995SAndre Fischer         return;
196*22de8995SAndre Fischer     }
197*22de8995SAndre Fischer 
198*22de8995SAndre Fischer     rConfiguration.mpDeck = new Deck(rDeckDescriptor, mpParentWindow);
199*22de8995SAndre Fischer }
200*22de8995SAndre Fischer 
201*22de8995SAndre Fischer 
202*22de8995SAndre Fischer 
203*22de8995SAndre Fischer 
204*22de8995SAndre Fischer void SidebarController::ProcessMatchingPanel (
205*22de8995SAndre Fischer     const ContentPanelDescriptor& rPanelDescriptor,
206*22de8995SAndre Fischer     Configuration& rConfiguration)
207*22de8995SAndre Fischer {
208*22de8995SAndre Fischer     // Create the panel which is the parent window of the UIElement
209*22de8995SAndre Fischer     // that we are about to create.
210*22de8995SAndre Fischer     Panel* pPanel = new Panel(rPanelDescriptor, rConfiguration.mpDeck);
211*22de8995SAndre Fischer 
212*22de8995SAndre Fischer     Reference<ui::XUIElement> xElement;
213*22de8995SAndre Fischer     try
214*22de8995SAndre Fischer     {
215*22de8995SAndre Fischer         const ::comphelper::ComponentContext aComponentContext (::comphelper::getProcessServiceFactory());
216*22de8995SAndre Fischer         const Reference<ui::XUIElementFactory> xUIElementFactory (
217*22de8995SAndre Fischer             aComponentContext.createComponent("com.sun.star.ui.UIElementFactoryManager"),
218*22de8995SAndre Fischer             UNO_QUERY_THROW);
219*22de8995SAndre Fischer 
220*22de8995SAndre Fischer         ::comphelper::NamedValueCollection aCreationArguments;
221*22de8995SAndre Fischer         aCreationArguments.put("Frame", makeAny(mxFrame));
222*22de8995SAndre Fischer         aCreationArguments.put("ParentWindow", makeAny(pPanel->GetComponentInterface()));
223*22de8995SAndre Fischer 
224*22de8995SAndre Fischer         pPanel->SetUIElement(
225*22de8995SAndre Fischer             Reference<ui::XUIElement>(
226*22de8995SAndre Fischer                 xUIElementFactory->createUIElement(
227*22de8995SAndre Fischer                     rPanelDescriptor.msImplementationURL,
228*22de8995SAndre Fischer                     aCreationArguments.getPropertyValues()),
229*22de8995SAndre Fischer                 UNO_QUERY_THROW));
230*22de8995SAndre Fischer     }
231*22de8995SAndre Fischer     catch(Exception& rException)
232*22de8995SAndre Fischer     {
233*22de8995SAndre Fischer         OSL_TRACE("caught exception: %s",
234*22de8995SAndre Fischer             OUStringToOString(rException.Message, RTL_TEXTENCODING_ASCII_US).getStr());
235*22de8995SAndre Fischer         // For some reason we can not create the actual panel.
236*22de8995SAndre Fischer         // Probably because its factory was not properly registered.
237*22de8995SAndre Fischer         // TODO: provide feedback to developer to better pinpoint the
238*22de8995SAndre Fischer         // source of the error.
239*22de8995SAndre Fischer     }
240*22de8995SAndre Fischer     rConfiguration.maPanels.push_back(pPanel);
241*22de8995SAndre Fischer }
242*22de8995SAndre Fischer 
243*22de8995SAndre Fischer 
244*22de8995SAndre Fischer 
245*22de8995SAndre Fischer 
246*22de8995SAndre Fischer void SidebarController::MakeConfigurationCurrent (Configuration& rConfiguration)
247*22de8995SAndre Fischer {
248*22de8995SAndre Fischer     if (rConfiguration.mpDeck == NULL)
249*22de8995SAndre Fischer         return;
250*22de8995SAndre Fischer 
251*22de8995SAndre Fischer     // Deactivate the current deck and panels.
252*22de8995SAndre Fischer     if (mpCurrentConfiguration && mpCurrentConfiguration->mpDeck!=NULL)
253*22de8995SAndre Fischer         mpCurrentConfiguration->Disable();
254*22de8995SAndre Fischer     SidebarLayouter::LayoutSidebar(rConfiguration.mpDeck, mpTabBar);
255*22de8995SAndre Fischer     rConfiguration.Activate();
256*22de8995SAndre Fischer }
257*22de8995SAndre Fischer 
258*22de8995SAndre Fischer 
259*22de8995SAndre Fischer 
260*22de8995SAndre Fischer 
261*22de8995SAndre Fischer IMPL_LINK(SidebarController, WindowEventHandler, VclWindowEvent*, pEvent)
262*22de8995SAndre Fischer {
263*22de8995SAndre Fischer     if (pEvent != NULL)
264*22de8995SAndre Fischer     {
265*22de8995SAndre Fischer         ::Window* pWindow = pEvent->GetWindow();
266*22de8995SAndre Fischer         switch (pEvent->GetId())
267*22de8995SAndre Fischer         {
268*22de8995SAndre Fischer             case VCLEVENT_WINDOW_GETFOCUS:
269*22de8995SAndre Fischer             case VCLEVENT_WINDOW_LOSEFOCUS:
270*22de8995SAndre Fischer                 break;
271*22de8995SAndre Fischer 
272*22de8995SAndre Fischer             case VCLEVENT_WINDOW_SHOW:
273*22de8995SAndre Fischer             case VCLEVENT_WINDOW_RESIZE:
274*22de8995SAndre Fischer                 NotifyResize();
275*22de8995SAndre Fischer                 break;
276*22de8995SAndre Fischer 
277*22de8995SAndre Fischer             case SFX_HINT_DYING:
278*22de8995SAndre Fischer                 dispose();
279*22de8995SAndre Fischer                 break;
280*22de8995SAndre Fischer 
281*22de8995SAndre Fischer             default:
282*22de8995SAndre Fischer                 break;
283*22de8995SAndre Fischer         }
284*22de8995SAndre Fischer     }
285*22de8995SAndre Fischer 
286*22de8995SAndre Fischer     return sal_True;
287*22de8995SAndre Fischer }
288*22de8995SAndre Fischer 
289*22de8995SAndre Fischer 
290*22de8995SAndre Fischer 
291*22de8995SAndre Fischer 
292*22de8995SAndre Fischer //===== SidebarController::Configuration ======================================
293*22de8995SAndre Fischer 
294*22de8995SAndre Fischer SidebarController::Configuration::Configuration (void)
295*22de8995SAndre Fischer     : mpDeck(NULL),
296*22de8995SAndre Fischer       maPanels()
297*22de8995SAndre Fischer {
298*22de8995SAndre Fischer }
299*22de8995SAndre Fischer 
300*22de8995SAndre Fischer 
301*22de8995SAndre Fischer 
302*22de8995SAndre Fischer 
303*22de8995SAndre Fischer void SidebarController::Configuration::Disable (void)
304*22de8995SAndre Fischer {
305*22de8995SAndre Fischer     // Hide and destroy the panels.
306*22de8995SAndre Fischer     for (::std::vector<Panel*>::const_iterator
307*22de8995SAndre Fischer              iPanel(maPanels.begin()),
308*22de8995SAndre Fischer              iEnd(maPanels.end());
309*22de8995SAndre Fischer          iPanel!=iEnd;
310*22de8995SAndre Fischer          ++iPanel)
311*22de8995SAndre Fischer     {
312*22de8995SAndre Fischer         (*iPanel)->Hide();
313*22de8995SAndre Fischer         mpDeck->removeWindow(*iPanel, NULL);
314*22de8995SAndre Fischer         delete *iPanel;
315*22de8995SAndre Fischer     }
316*22de8995SAndre Fischer     maPanels.clear();
317*22de8995SAndre Fischer 
318*22de8995SAndre Fischer     // Hide and destroy the deck window.
319*22de8995SAndre Fischer     mpDeck->Hide();
320*22de8995SAndre Fischer     mpDeck->GetParent()->removeWindow(mpDeck, NULL);
321*22de8995SAndre Fischer     delete mpDeck;
322*22de8995SAndre Fischer     mpDeck = NULL;
323*22de8995SAndre Fischer }
324*22de8995SAndre Fischer 
325*22de8995SAndre Fischer 
326*22de8995SAndre Fischer 
327*22de8995SAndre Fischer 
328*22de8995SAndre Fischer void SidebarController::Configuration::Activate (void)
329*22de8995SAndre Fischer {
330*22de8995SAndre Fischer     SidebarLayouter::LayoutPanels(mpDeck, maPanels);
331*22de8995SAndre Fischer 
332*22de8995SAndre Fischer     // Show the deck window.
333*22de8995SAndre Fischer     mpDeck->GetTitleBar()->Show();
334*22de8995SAndre Fischer     mpDeck->Show();
335*22de8995SAndre Fischer 
336*22de8995SAndre Fischer     // Show the panels.
337*22de8995SAndre Fischer     for (::std::vector<Panel*>::const_iterator
338*22de8995SAndre Fischer              iPanel(maPanels.begin()),
339*22de8995SAndre Fischer              iEnd(maPanels.end());
340*22de8995SAndre Fischer          iPanel!=iEnd;
341*22de8995SAndre Fischer          ++iPanel)
342*22de8995SAndre Fischer     {
343*22de8995SAndre Fischer         (*iPanel)->GetTitleBar()->Show();
344*22de8995SAndre Fischer         (*iPanel)->Show();
345*22de8995SAndre Fischer     }
346*22de8995SAndre Fischer }
347*22de8995SAndre Fischer 
348*22de8995SAndre Fischer 
349*22de8995SAndre Fischer } // end of namespace sfx2
350